Java程序辅导

C C++ Java Python Processing编程在线培训 程序编写 软件开发 视频讲解

客服在线QQ:2653320439 微信:ittutor Email:itutor@qq.com
wx: cjtutor
QQ: 2653320439
discuss@menelaus.mit.edu: [938] in Kerberos-V5-bugs [938] in Kerberos-V5-bugs home help back first fref pref prev next nref lref last post Kerberos 5-B4-pl3 bug report (lib/krb5/os/sendto_kdc.c) patch #2 daemon@ATHENA.MIT.EDU (Craig Leres) Fri Nov 4 01:57:13 1994 To: krb5-bugs@MIT.EDU Cc: hobbit@asylum.sf.ca.us Date: Thu, 03 Nov 94 22:57:04 PST From: Craig Leres We noticed that retries when doing things like getting an initial ticket with kinit were broken. It usually took two tries to get a ticket over an isdn line and it didn't seem to be possible over a slip line. The problem was krb5_sendto_kdc() was opening one socket per address family (!?!?) and trying to do a connect to change the address before each send(). It may not be obvious from the man page but the kernel source clearly shows that you fail with EISCONN when you attempt to connect() an already connected socket. This means that only the first send() works and all the others are aborted on the connect() attempt. So if the reply doesn't come back within the initial timeout (1 second), you lose. I changed the code to open one socket per host socket address (i.e. host and port) and only do the connect once. My appended context diff also includes another change I submited: This source wants to include krb5/sysincl.h to pick the FD_ZERO() and FD_SET() macros. Craig ------ *** kerberosV.virgin/src/lib/krb5/os/sendto_kdc.c Thu Aug 18 15:08:02 1994 --- kerberosV/src/lib/krb5/os/sendto_kdc.c Thu Nov 3 22:55:14 1994 *************** *** 28,33 **** --- 28,34 ---- #include #include + #include #include #include *************** *** 40,50 **** #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'. --- 41,46 ---- *************** *** 76,82 **** int naddr; int sent, nready; krb5_error_code retval; ! int socklist[AF_MAX]; /* one for each, if necessary! */ fd_set readable; struct timeval waitlen; int cc; --- 72,78 ---- int naddr; int sent, nready; krb5_error_code retval; ! int *socklist; fd_set readable; struct timeval waitlen; int cc; *************** *** 89,100 **** return retval; if (naddr == 0) return KRB5_REALM_UNKNOWN; ! ! for (i = 0; i < AF_MAX; i++) socklist[i] = -1; if (!(reply->data = malloc(krb5_max_dgram_size))) { krb5_xfree(addr); return ENOMEM; } reply->length = krb5_max_dgram_size; --- 85,103 ---- return retval; if (naddr == 0) return KRB5_REALM_UNKNOWN; ! ! 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; *************** *** 109,135 **** 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) { /* 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) 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[addr[host].sa_family], ! &addr[host], sizeof(addr[host])) == -1) ! continue; ! if (send(socklist[addr[host].sa_family], message->data, message->length, 0) != message->length) continue; retry: --- 112,143 ---- for (host = 0; host < naddr; host++) { /* send to the host, wait timeout seconds for a response, then move on. */ ! /* 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... */ ! /* ! * 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; } ! if (send(socklist[host], message->data, message->length, 0) != message->length) continue; retry: *************** *** 136,143 **** 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], &readable, 0, 0, --- 144,151 ---- waitlen.tv_usec = 0; waitlen.tv_sec = timeout; FD_ZERO(&readable); ! FD_SET(socklist[host], &readable); ! if (nready = select(1 + socklist[host], &readable, 0, 0, *************** *** 148,154 **** retval = errno; goto out; } ! if ((cc = recv(socklist[addr[host].sa_family], reply->data, reply->length, 0)) == -1) { /* man page says error could be: --- 156,162 ---- retval = errno; goto out; } ! if ((cc = recv(socklist[host], reply->data, reply->length, 0)) == -1) { /* man page says error could be: *************** *** 193,202 **** } retval = KRB5_KDC_UNREACH; out: ! for (i = 0; i < AF_MAX; i++) if (socklist[i] != -1) (void) close(socklist[i]); krb5_xfree(addr); if (retval) { free(reply->data); reply->data = 0; --- 201,211 ---- } retval = KRB5_KDC_UNREACH; out: ! 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; home help back first fref pref prev next nref lref last post