[Date Prev][Date Next][Thread Prev][Thread Next][Date Index][Thread Index]

Re: getifaddrs/netlink problem




Miroslav Ruda <ruda@ics.muni.cz> writes:

> Hi,
>
>   when testing heimdal-0.7pre3, we have found problem with
> getifaddrs() implementation from lib/roken (on linux. debian stable,
> but it should be general linux problem). Program, which was doing
> krb5_get_in_tkt_with_keytab() repeatedly, sometimes froze in netlink
> functions (when reading list of interfaces). From man 7 netlink I have
> found that at least on my linux:
>
>   Netlink is not a reliable protocol.  It tries its  best  to  deliver
> a message  to  its  destination(s),  but may drop messages when an out
> of memory condition or other error  occurs.
>
> See attached trace from gdb - it looks like some netlink message was
> really lost. Suggested solution would be not use blocking recvmsg()
> but select()
> with timeout and repeat nl_sendreq() in case of problems...

I couldn't reproduce the problem so can you test the patch below ?

> My second question is about krb5_get_in_tkt_with_keytab() function. We have
> no-addresses = yes in krb5.conf, so I would expect that getifaddrs()
> is not needed to call. However, it's not clear to me how I should set
> parameter "addrs"
> to avoid detection of IP addresses etc. Or is it really needed when doing
> as_req?

Its a bug in krb5_get_in_tkt_with_keytab. First krb5_get_in_tkt is
deprecated, you should use krb5_get_init_creds. If we are going to keep
get_in_tkt they should be rewritten in terms of krb5_get_init_creds.

Love

diff -u -u -w -r1.11 lib/roken/getifaddrs.c
--- lib/roken/getifaddrs.c	30 Apr 2005 15:45:47 -0000	1.11
+++ lib/roken/getifaddrs.c	11 Jun 2005 18:03:55 -0000
@@ -108,6 +108,7 @@
 #include <linux/rtnetlink.h>
 #include <sys/types.h>
 #include <sys/socket.h>
+#include <sys/poll.h>
 #include <netpacket/packet.h>
 #include <net/ethernet.h>     /* the L2 protocols */
 #include <sys/uio.h>
@@ -378,13 +379,30 @@
   struct nlmsghdr *nlh = NULL;
   int status;
   int done = 0;
+  int tries = 3;
 
+ try_again:
   status = nl_sendreq(sd, request, NLM_F_ROOT|NLM_F_MATCH, &seq);
   if (status < 0)
     return status;
   if (seq == 0)
     seq = (int)time(NULL);
   while(!done){
+    struct pollfd pfd;
+
+    pfd.fd = sd;
+    pfd.events = POLLIN | POLLPRI;
+    pfd.revents = 0;
+    status = poll(&pfd, 1, 1000);
+    if (status < 0)
+	return status;
+    else if (status == 0) {
+	seq++;
+	if (tries-- > 0)
+	    goto try_again;
+	return -1;
+    }
+
     status = nl_getmsg(sd, request, seq, &nlh, &done);
     if (status < 0)
       return status;

PGP signature