From e15250c4aec8663ce6a3b5c340e28e21ef09300b Mon Sep 17 00:00:00 2001 From: Theodore Tso Date: Tue, 1 Sep 1992 14:43:33 +0000 Subject: [PATCH] Changes so that the KDC will listen on two ports (i.e., port 88 and port 750). git-svn-id: svn://anonsvn.mit.edu/krb5/trunk@2375 dc483132-0cff-0310-8789-dd5450dbe970 --- src/kdc/network.c | 173 ++++++++++++++++++++++++++++++++++------------ 1 file changed, 127 insertions(+), 46 deletions(-) diff --git a/src/kdc/network.c b/src/kdc/network.c index ff572c497..5b82d11c6 100644 --- a/src/kdc/network.c +++ b/src/kdc/network.c @@ -44,13 +44,19 @@ static char rcsid_network_c[] = #include #include #include +#include +#include #include #include extern char *krb5_kdc_udp_portname; +extern char *krb5_kdc_sec_udp_portname; extern int errno; static int udp_port_fd = -1; +static int sec_udp_port_fd = -1; +static fd_set select_fds; +static int select_nfsd; krb5_error_code setup_network(prog) @@ -60,6 +66,8 @@ const char *prog; struct sockaddr_in sin; krb5_error_code retval; + FD_ZERO(&select_fds); + select_nfsd = 0; sp = getservbyname(krb5_kdc_udp_portname, "udp"); if (!sp) { com_err(prog, 0, "%s/udp service unknown\n", @@ -78,6 +86,39 @@ const char *prog; com_err(prog, 0, "Cannot bind server socket"); return retval; } + FD_SET(udp_port_fd, &select_fds); + if (udp_port_fd+1 > select_nfsd) + select_nfsd = udp_port_fd+1; + + /* + * Now we set up the secondary listening port, if it is enabled + */ + if (!krb5_kdc_sec_udp_portname) + return 0; /* No secondary listening port defined */ + + sp = getservbyname(krb5_kdc_sec_udp_portname, "udp"); + if (!sp) { + com_err(prog, 0, "%s/udp service unknown\n", + krb5_kdc_sec_udp_portname); + return 0; /* Don't give an error if we can't */ + /* find it */ + } + if ((sec_udp_port_fd = socket(PF_INET, SOCK_DGRAM, 0)) == -1) { + retval = errno; + com_err(prog, 0, "Cannot create secondary server socket"); + return retval; + } + memset((char *)&sin, 0, sizeof(sin)); + sin.sin_port = sp->s_port; + if (bind(sec_udp_port_fd, (struct sockaddr *)&sin, sizeof(sin)) == -1) { + retval = errno; + com_err(prog, 0, "Cannot bind secondary server socket"); + return retval; + } + FD_SET(sec_udp_port_fd, &select_fds); + if (sec_udp_port_fd+1 > select_nfsd) + select_nfsd = sec_udp_port_fd+1; + return 0; } @@ -85,64 +126,100 @@ krb5_error_code listen_and_process(prog) const char *prog; { - int cc, saddr_len; - krb5_error_code retval; - struct sockaddr_in saddr; - krb5_fulladdr faddr; - krb5_address addr; - krb5_data request; - krb5_data *response; - char pktbuf[MAX_DGRAM_SIZE]; + static int errcount = 0; + int nfound; + fd_set readfds; + krb5_error_code retval; if (udp_port_fd == -1) return KDC5_NONET; while (!signal_requests_exit) { - saddr_len = sizeof(saddr); - if ((cc = recvfrom(udp_port_fd, pktbuf, sizeof(pktbuf), 0, - (struct sockaddr *)&saddr, &saddr_len)) != -1) { - if (!cc) - continue; /* zero-length packet? */ - request.length = cc; - request.data = pktbuf; - faddr.port = ntohs(saddr.sin_port); - faddr.address = &addr; - addr.addrtype = ADDRTYPE_INET; - addr.length = 4; - /* this address is in net order */ - addr.contents = (krb5_octet *) &saddr.sin_addr; - if (retval = dispatch(&request, &faddr, &response)) { - com_err(prog, retval, "while dispatching"); + readfds = select_fds; + nfound = select(select_nfsd, &readfds, 0, 0, 0); + if (nfound == -1) { + if (errno == EINTR) + continue; + com_err(prog, errno, "while selecting for network input"); + if (errcount++ > 3) + break; continue; - } - if ((cc = sendto(udp_port_fd, response->data, response->length, 0, - (struct sockaddr *)&saddr, saddr_len)) != response->length) { - switch (cc) { - case -1: - com_err(prog, errno, "while sending reply to %s/%d", - inet_ntoa(saddr.sin_addr), ntohs(saddr.sin_port)); - break; - default: - com_err(prog, 0, "short reply write %d vs %d\n", - response->length, cc); - break; + } + if (FD_ISSET(udp_port_fd, &readfds)) { + retval = process_packet(udp_port_fd, prog, 0); + if (retval) { + if (errcount++ > 3) + break; + } + } + if (FD_ISSET(sec_udp_port_fd, &readfds)) { + retval = process_packet(sec_udp_port_fd, prog, 1); + if (retval) { + if (errcount++ > 3) + break; } - } - krb5_free_data(response); - } else { - switch (errno) { - case EINTR: - continue; - default: - com_err(prog, errno, "while receiving from network"); - break; - } } - + errcount = 0; + } + return 0; +} + +krb5_error_code +process_packet(port_fd, prog, is_secondary) + int port_fd; + char *prog; + int is_secondary; +{ + int cc, saddr_len; + krb5_fulladdr faddr; + krb5_error_code retval; + struct sockaddr_in saddr; + krb5_address addr; + krb5_data request; + krb5_data *response; + char pktbuf[MAX_DGRAM_SIZE]; + + saddr_len = sizeof(saddr); + cc = recvfrom(port_fd, pktbuf, sizeof(pktbuf), 0, + (struct sockaddr *)&saddr, &saddr_len); + if (cc == -1) { + if (errno == EINTR) + return 0; + com_err(prog, errno, "while receiving from network"); + return errno; + } + if (!cc) + return 0; /* zero-length packet? */ + + request.length = cc; + request.data = pktbuf; + faddr.port = ntohs(saddr.sin_port); + faddr.address = &addr; + addr.addrtype = ADDRTYPE_INET; + addr.length = 4; + /* this address is in net order */ + addr.contents = (krb5_octet *) &saddr.sin_addr; + if (retval = dispatch(&request, &faddr, is_secondary, &response)) { + com_err(prog, retval, "while dispatching"); + return 0; + } + cc = sendto(port_fd, response->data, response->length, 0, + (struct sockaddr *)&saddr, saddr_len); + krb5_free_data(response); + if (cc == -1) { + com_err(prog, errno, "while sending reply to %s/%d", + inet_ntoa(saddr.sin_addr), ntohs(saddr.sin_port)); + return errno; + } + if (cc != response->length) { + com_err(prog, 0, "short reply write %d vs %d\n", + response->length, cc); + return KDC5_IO_RESPONSE; } return 0; } + krb5_error_code closedown_network(prog) const char *prog; @@ -152,6 +229,10 @@ const char *prog; (void) close(udp_port_fd); udp_port_fd = -1; + + if (sec_udp_port_fd != -1) + (void) close(sec_udp_port_fd); + sec_udp_port_fd = -1; return 0; } -- 2.26.2