Hi Holger!
On Wed, Nov 07, 2012 at 03:21:14PM +0100, Holger Hans Peter Freyther wrote:
Dear Pablo,
getaddrinfo does not work for the combination of AF_INET, SOCK_RAW
and IPPROTO_GRE. I have attached an example application that can be
compiled with:
$ gcc -o fr fr.c `pkg-config --cflags --libs libosmocore libosmogb`
this prints:
getaddrinfo returned NULL: Success
FAILED
$ strace ./fr
[...]
socket(PF_NETLINK, SOCK_RAW, 0) = 3
bind(3, {sa_family=AF_NETLINK, pid=0, groups=00000000}, 12) = 0
getsockname(3, {sa_family=AF_NETLINK, pid=5936, groups=00000000}, [12]) = 0
sendto(3, "\24\0\0\0\26\0\1\3+\230\256P\0\0\0\0\0\0\0\0", 20, 0,
{sa_family=AF_NETLINK, pid=0, groups=00000000}, 12) = 20
recvmsg(3, {msg_name(12)={sa_family=AF_NETLINK, pid=0, groups=00000000},
msg_iov(1)=[{"0\0\0\0\24\0\2\0+\230\256P0\27\0\0\2\10\200\376\1\0\0\0\10\0\1\0\177\0\0\1"...,
4096}], msg_controllen=0, msg_flags=0}, 0) = 108
recvmsg(3, {msg_name(12)={sa_family=AF_NETLINK, pid=0, groups=00000000},
msg_iov(1)=[{"@\0\0\0\24\0\2\0+\230\256P0\27\0\0\n\200\200\376\1\0\0\0\24\0\1\0\0\0\0\0"...,
4096}], msg_controllen=0, msg_flags=0}, 0) = 128
recvmsg(3, {msg_name(12)={sa_family=AF_NETLINK, pid=0, groups=00000000},
msg_iov(1)=[{"\24\0\0\0\3\0\2\0+\230\256P0\27\0\0\0\0\0\0\1\0\0\0\24\0\1\0\0\0\0\0"...,
4096}], msg_controllen=0, msg_flags=0}, 0) = 20
The interesting thing is that the function calls rtnetlink to obtain
address information from the kernel, and it seems it gets it right.
Let me decipher that netlink trace:
1) bind(3, {sa_family=AF_NETLINK, pid=0, groups=00000000}, 12) = 0
^^
bind this socket to rtnetlink
2) Send the request message to ask for the address information.
sendto(3, "\24\0\0\0\26\0\1\3+\230\256P\0\0\0\0\0\0\0\0", 20, 0,
{sa_family=AF_NETLINK, pid=0, groups=00000000}, 12) = 20
3) We get the multipart message with the information that we
requested:
recvmsg(3, {msg_name(12)={sa_family=AF_NETLINK, pid=0, groups=00000000},
msg_iov(1)=[{"0\0\0\0\24\0\2\0+\230\256P0\27\0\0\2\10\200\376\1\0\0\0\10\0\1\0\177\0\0\1"...,
4096}], msg_controllen=0, msg_flags=0}, 0) = 108
recvmsg(3, {msg_name(12)={sa_family=AF_NETLINK, pid=0, groups=00000000},
msg_iov(1)=[{"@\0\0\0\24\0\2\0+\230\256P0\27\0\0\n\200\200\376\1\0\0\0\24\0\1\0\0\0\0\0"...,
4096}], msg_controllen=0, msg_flags=0}, 0) = 128
recvmsg(3, {msg_name(12)={sa_family=AF_NETLINK, pid=0, groups=00000000},
The problem seems to be in glibc, at sysdeps/posix/getaddrinfo.c, line 125:
{ SOCK_RAW, 0, GAI_PROTO_PROTOANY|GAI_PROTO_NOSERVICE, true, "raw" }
The GAI_PROTO_NOSERVICE flag is set, while interating over the list of
addresses that it has obtained from the kernel to return the addrinfo
object, it seems to skip the raw protocol and it returns EAI_SERVICE.
To be more precise, it returns EAI_SERVICE before even iterating over
the list of address.
This behaviour seems a bit inconsistent to me, ie. requst data from
the kernel, get it all right and discard it :-)