Changes so that the KDC will listen on two ports (i.e., port 88 and
authorTheodore Tso <tytso@mit.edu>
Tue, 1 Sep 1992 14:43:33 +0000 (14:43 +0000)
committerTheodore Tso <tytso@mit.edu>
Tue, 1 Sep 1992 14:43:33 +0000 (14:43 +0000)
port 750).

git-svn-id: svn://anonsvn.mit.edu/krb5/trunk@2375 dc483132-0cff-0310-8789-dd5450dbe970

src/kdc/network.c

index ff572c497f9ae3682d4fe05e0e8adaa4d7856787..5b82d11c6fe54094f3823b37f39fccba96eb34d7 100644 (file)
@@ -44,13 +44,19 @@ static char rcsid_network_c[] =
 #include <sys/types.h>
 #include <netinet/in.h>
 #include <sys/socket.h>
+#include <sys/types.h>
+#include <sys/time.h>
 #include <arpa/inet.h>
 #include <netdb.h>
 
 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;
 }