From 261758d2d82af5aee7651107a9bfccb5dd6bab02 Mon Sep 17 00:00:00 2001 From: Theodore Tso Date: Thu, 19 Jan 1995 03:58:15 +0000 Subject: [PATCH] Fix use of connected sockets; previously krb5_sendto_kdc only used one socket per address family. This doesn't work; it now uses one socket per address. (krb5-bugs #938) git-svn-id: svn://anonsvn.mit.edu/krb5/trunk@4831 dc483132-0cff-0310-8789-dd5450dbe970 --- src/lib/krb5/os/ChangeLog | 7 ++++ src/lib/krb5/os/sendto_kdc.c | 67 ++++++++++++++++++++---------------- 2 files changed, 45 insertions(+), 29 deletions(-) diff --git a/src/lib/krb5/os/ChangeLog b/src/lib/krb5/os/ChangeLog index 8df0732dc..5d55be148 100644 --- a/src/lib/krb5/os/ChangeLog +++ b/src/lib/krb5/os/ChangeLog @@ -1,3 +1,10 @@ +Wed Jan 18 11:08:59 1995 + + * sendto_kdc.c (krb5_sendto_kdc): Fix use of connected sockets; + previously krb5_sendto_kdc only used one socket per + address family. This doesn't work; it now uses one + socket per address. (krb5-bugs #938) + Fri Jan 13 15:23:47 1995 Chris Provenzano (proven@mit.edu) * Actually move the file init_ctx.c to init_os_ctx.c in the CVS diff --git a/src/lib/krb5/os/sendto_kdc.c b/src/lib/krb5/os/sendto_kdc.c index 9a1fcd65a..55c85603d 100644 --- a/src/lib/krb5/os/sendto_kdc.c +++ b/src/lib/krb5/os/sendto_kdc.c @@ -28,6 +28,7 @@ #include #include +#include #include #include @@ -40,11 +41,6 @@ #include #endif -#ifndef AF_MAX -/* good enough -- only missing on old linux so far anyhow. */ -#define AF_MAX 10 -#endif - /* * send the formatted request 'message' to a KDC for realm 'realm' and * return the response (if any) in 'reply'. @@ -75,7 +71,7 @@ krb5_sendto_kdc (context, message, realm, reply) int naddr; int sent, nready; krb5_error_code retval; - int socklist[AF_MAX]; /* one for each, if necessary! */ + int *socklist; fd_set readable; struct timeval waitlen; int cc; @@ -88,12 +84,19 @@ krb5_sendto_kdc (context, message, realm, reply) return retval; if (naddr == 0) return KRB5_REALM_UNKNOWN; - - for (i = 0; i < AF_MAX; i++) + + socklist = (int *)malloc(naddr * sizeof(int)); + if (socklist == NULL) { + krb5_xfree(addr); + krb5_xfree(socklist); + return ENOMEM; + } + for (i = 0; i < naddr; i++) socklist[i] = -1; if (!(reply->data = malloc(krb5_max_dgram_size))) { krb5_xfree(addr); + krb5_xfree(socklist); return ENOMEM; } reply->length = krb5_max_dgram_size; @@ -108,35 +111,40 @@ krb5_sendto_kdc (context, message, realm, reply) for (host = 0; host < naddr; host++) { /* send to the host, wait timeout seconds for a response, then move on. */ - /* cache some sockets for various address families in the - list */ - if (socklist[addr[host].sa_family] == -1) { + /* cache some sockets for each host */ + if (socklist[host] == -1) { /* XXX 4.2/4.3BSD has PF_xxx = AF_xxx, so the socket creation here will work properly... */ - socklist[addr[host].sa_family] = socket(addr[host].sa_family, - SOCK_DGRAM, - 0); /* XXX always zero? */ - if (socklist[addr[host].sa_family] == -1) + /* + * From socket(2): + * + * The protocol specifies a particular protocol to be + * used with the socket. Normally only a single + * protocol exists to support a particular socket type + * within a given protocol family. + */ + socklist[host] = socket(addr[host].sa_family, SOCK_DGRAM, 0); + if (socklist[host] == -1) continue; /* try other hosts */ + /* have a socket to send/recv from */ + /* On BSD systems, a connected UDP socket will get connection + refused and net unreachable errors while an unconnected + socket will time out, so use connect, send, recv instead of + sendto, recvfrom. The connect here may return an error if + the destination host is known to be unreachable. */ + if (connect(socklist[host], + &addr[host], sizeof(addr[host])) == -1) + continue; } - /* have a socket to send/recv from */ - /* On BSD systems, a connected UDP socket will get connection - refused and net unreachable errors while an unconnected - socket will time out, so use connect, send, recv instead of - sendto, recvfrom. The connect here may return an error if - the destination host is known to be unreachable. */ - if (connect(socklist[addr[host].sa_family], - &addr[host], sizeof(addr[host])) == -1) - continue; - if (send(socklist[addr[host].sa_family], + if (send(socklist[host], message->data, message->length, 0) != message->length) continue; retry: waitlen.tv_usec = 0; waitlen.tv_sec = timeout; FD_ZERO(&readable); - FD_SET(socklist[addr[host].sa_family], &readable); - if (nready = select(1 + socklist[addr[host].sa_family], + FD_SET(socklist[host], &readable); + if (nready = select(1 + socklist[host], &readable, 0, 0, @@ -147,7 +155,7 @@ krb5_sendto_kdc (context, message, realm, reply) retval = errno; goto out; } - if ((cc = recv(socklist[addr[host].sa_family], + if ((cc = recv(socklist[host], reply->data, reply->length, 0)) == -1) { /* man page says error could be: @@ -192,10 +200,11 @@ krb5_sendto_kdc (context, message, realm, reply) } retval = KRB5_KDC_UNREACH; out: - for (i = 0; i < AF_MAX; i++) + for (i = 0; i < naddr; i++) if (socklist[i] != -1) (void) close(socklist[i]); krb5_xfree(addr); + krb5_xfree(socklist); if (retval) { free(reply->data); reply->data = 0; -- 2.26.2