[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