IPV6_PKTINFO/recvfromto

Alexander Clouter alex at digriz.org.uk
Wed Dec 15 01:50:41 CET 2010


Alan DeKok <aland at deployingradius.com> wrote:
>
> Alexander Clouter wrote:
>
>> Turns out 'struct in6_pktinfo' is a GNU extension[1] and so you need to 
>> define _GNU_SOURCE when ./configure is running otherwise you get 
>> HAVE_IN6_PKTINFO is undefined.  I just gave it a whirl, config.cache 
>> shows 'yes' now for the presence of ipi6_pktinfo:
> 
>  I think that check isn't really necessary.  If the "IPV6_PKTINFO"
> definition exists, the compiler can be pretty sure that the "struct
> in6_pktinfo" entry exists.
> 
>  I've pushed some changes to the v2.1.x branch which should help.  They
> should also fix Linux kernel version issues with using IPV6_RECVPKTINFO
> versus IPV6_PKTINFO.
> 
>  The only thing the changes *don't* do is update src/lib/radius.c to
> allow IPv6 for "udpfromto" sockets.
> 
>  If the rest of the changes work for you, I can then re-add the IPv6
> support in src/lib/radius.c.
> 
rlm_dbm_parser gets upset...
-----
make[6]: Entering directory 
`/usr/src/deb-src/freeradius/freeradius-2.1.10+dfsg/src/modules/rlm_dbm'
/usr/bin/libtool --mode=link gcc   \
                -o rlm_dbm_parser rlm_dbm_parser.lo 
/usr/src/deb-src/freeradius/freeradius-2.1.10+dfsg/src/lib/libfreeradius-radius.la 
-lgdbm_compat  -lnsl -lresolv  -lpthread
libtool: link: gcc -o .libs/rlm_dbm_parser .libs/rlm_dbm_parser.o  
/usr/src/deb-src/freeradius/freeradius-2.1.10+dfsg/src/lib/.libs/libfreeradius-radius.so 
/usr/lib/libgdbm_compat.so -lnsl -lresolv -lpthread  -Wl,-rpath 
-Wl,/usr/lib/freeradius
/usr/src/deb-src/freeradius/freeradius-2.1.10+dfsg/src/lib/.libs/libfreeradius-radius.so: 
undefined reference to `recvfromto'
/usr/src/deb-src/freeradius/freeradius-2.1.10+dfsg/src/lib/.libs/libfreeradius-radius.so: 
undefined reference to `sendfromto'
/usr/src/deb-src/freeradius/freeradius-2.1.10+dfsg/src/lib/.libs/libfreeradius-radius.so: 
undefined reference to `udpfromto_init'
collect2: ld returned 1 exit status
make[6]: *** [rlm_dbm_parser] Error 1
-----

Moving '#include <freeradius-devel/udpfromto.h>' back to outside of the 
'#ifdef WITH_UDPFROMTO ... #endif' clause, gets things cooking again 
though; although it feels 'wrong'.

Having retinkered with src/lib/radius.c and compiled the lot, thinks do 
not work.  IPv6 RADIUS requests come in, nothing goes out, strace'ing 
tells me that when sendmsg() is called, -EINVAL is returned on IPv6 
sockets.  I also notice recvmsg() is not being called anywhere for IPv6 
sockets:
----
[pid 26841] recvfrom(15, "\1A\0\\", 4, MSG_PEEK, {sa_family=AF_INET6, sin6_port=htons(57447), inet_pton(AF_INET6, "2001:630:1:12a::233", &sin6_addr), sin6_flowinfo=0, sin6_scope_id=0}, [28]) = 4
[pid 26841] getsockname(15, {sa_family=AF_INET6, sin6_port=htons(1812), inet_pton(AF_INET6, "::", &sin6_addr), sin6_flowinfo=0, sin6_scope_id=0}, [28]) = 0
[pid 26841] recvfrom(15, "\1A\0\\", 4, MSG_PEEK, {sa_family=AF_INET6, sin6_port=htons(57447), inet_pton(AF_INET6, "2001:630:1:12a::233", &sin6_addr), sin6_flowinfo=0, sin6_scope_id=0}, [28]) = 4
[pid 26841] getsockname(15, {sa_family=AF_INET6, sin6_port=htons(1812), inet_pton(AF_INET6, "::", &sin6_addr), sin6_flowinfo=0, sin6_scope_id=0}, [28]) = 0
[pid 26841] recvfrom(15, "\1A\0\\\270u\200\31H\4\r\317v\266\257\220\335FQ\376\1\25testauth at s"..., 92, 0, {sa_family=AF_INET6, sin6_port=htons(57447), inet_pton(AF_INET6, "2001:630:1:12a::233", &sin6_addr), sin6_flowinfo=0, sin6_scope_id=0}, [28]) = 92
[pid 26841] gettimeofday({1292369722, 367383}, NULL) = 0
[pid 26841] gettimeofday({1292369722, 367639}, NULL) = 0
[pid 26841] futex(0x4c554, FUTEX_WAKE_PRIVATE, 1 <unfinished ...>
[pid 26843] <... futex resumed> )       = 0
[pid 26841] <... futex resumed> )       = 1
[pid 26843] wait4(0,  <unfinished ...>
[pid 26841] gettimeofday( <unfinished ...>
[pid 26843] <... wait4 resumed> 0x41378d7c, WNOHANG, NULL) = -1 ECHILD (No child processes)
[pid 26841] <... gettimeofday resumed> {1292369722, 368277}, NULL) = 0
[pid 26843] socket(PF_NETLINK, SOCK_RAW, 0 <unfinished ...>
[pid 26841] select(36, [13 15 16 17 18 19 20 21 22 23 24 25 32 35], NULL, NULL, {0, 95942} <unfinished ...>
[pid 26843] <... socket resumed> )      = 38
[pid 26843] bind(38, {sa_family=AF_NETLINK, pid=0, groups=00000000}, 12) = 0
[pid 26843] getsockname(38, {sa_family=AF_NETLINK, pid=26841, groups=00000000}, [12]) = 0
[pid 26843] gettimeofday({1292369722, 369697}, NULL) = 0
[pid 26843] sendto(38, "\24\0\0\0\26\0\1\3:\377\7M\0\0\0\0\0\0\0\0", 20, 0, {sa_family=AF_NETLINK, pid=0, groups=00000000}, 12) = 20
[pid 26843] recvmsg(38, {msg_name(12)={sa_family=AF_NETLINK, pid=0, groups=00000000}, msg_iov(1)=[{"0\0\0\0\24\0\2\0:\377\7M\331h\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) = 156
[pid 26843] recvmsg(38, {msg_name(12)={sa_family=AF_NETLINK, pid=0, groups=00000000}, msg_iov(1)=[{"@\0\0\0\24\0\2\0:\377\7M\331h\0\0\n\200\200\0\1\0\0\0\24\0\1\0 \1\0060"..., 4096}], msg_controllen=0, msg_flags=0}, 0) = 320
[pid 26843] recvmsg(38, {msg_name(12)={sa_family=AF_NETLINK, pid=0, groups=00000000}, msg_iov(1)=[{"\24\0\0\0\3\0\2\0:\377\7M\331h\0\0\0\0\0\0\1\0\0\0\24\0\1\0 \1\0060"..., 4096}], msg_controllen=0, msg_flags=0}, 0) = 20
[pid 26843] close(38)                   = 0
[pid 26843] gettimeofday({1292369722, 372103}, NULL) = 0
[pid 26843] gettimeofday({1292369722, 374812}, NULL) = 0
[pid 26843] sendmsg(15, {msg_name(28)={sa_family=AF_INET6, sin6_port=htons(57447), inet_pton(AF_INET6, "2001:630:1:12a::233", &sin6_addr), sin6_flowinfo=0, sin6_scope_id=0}, msg_iov(1)=[{"\2A\0)\20JW*D\223\277\323B\300\231\243\215Q\276\320!\25OSC-Extend"..., 41}], msg_controllen=32, {cmsg_len=32, cmsg_level=SOL_IPV6, cmsg_type=, ...}, msg_flags=0}, 0) = -1 EINVAL (Invalid argument)
----

Noseying at 'cpp -I src/ src/lib/udpfromto.c' I see for v6 we never 
actually get to recvmsg():
----
 else if (si.ss_family == 10) {
  struct sockaddr_in6 *dst = (struct sockaddr_in6 *) to;
  struct sockaddr_in6 *src = (struct sockaddr_in6 *) &si;

  if (*tolen < sizeof(*dst)) {
   (*__errno_location ()) = 22;
   return -1;
  }
  *tolen = sizeof(*dst);
  *dst = *src;





  return recvfrom(s, buf, len, flags, from, fromlen);

 }
----

Tells me you forgot to 's/IN6_PKTINFO/IPV6_PKTINFO/g' :)

I still get -EINVAL for sendmsg() after that, however recvmsg() is now 
being called.  I'm pondering if you do need some memcpy() action (GCC 
bug?) but it is getting late, and I'll pick this up in the morning.

Cheers

-- 
Alexander Clouter
.sigmonster says: Does the name Pavlov ring a bell?




More information about the Freeradius-Devel mailing list