From 5bae06639e2667c9da241ec9e3d032e0c41e0442 Mon Sep 17 00:00:00 2001 From: Ken Raeburn Date: Fri, 25 Feb 2000 22:05:02 +0000 Subject: [PATCH] fix udp_port_fds allocation bug; partial ipv6 support git-svn-id: svn://anonsvn.mit.edu/krb5/trunk@12073 dc483132-0cff-0310-8789-dd5450dbe970 --- src/kdc/ChangeLog | 10 ++++- src/kdc/configure.in | 1 + src/kdc/network.c | 96 +++++++++++++++++++++++++++++++++++++------- 3 files changed, 92 insertions(+), 15 deletions(-) diff --git a/src/kdc/ChangeLog b/src/kdc/ChangeLog index 2eeecba32..ec22618cc 100644 --- a/src/kdc/ChangeLog +++ b/src/kdc/ChangeLog @@ -1,8 +1,16 @@ 2000-02-25 Ken Raeburn Alec H. Peterson - * configure.in: Invoke KRB5_SOCKADDR_SA_LEN. + * configure.in: Invoke KRB5_AC_INET6. + * network.c (max_udp_sockets): New variable. + (setup_port): Add IPv6 support. Reallocate udp_port_fds array as + needed here. + (add_port): Don't do buggy udp_port_fds allocation here. + (setup_network): On failure, exit. + (process_packet): Handle inet6 addresses when building + krb5_address structure. + * configure.in: Invoke KRB5_SOCKADDR_SA_LEN. * network.c: Include , , . (foreach_localaddr): New function, copied from lib/krb5/os/localaddr.c. diff --git a/src/kdc/configure.in b/src/kdc/configure.in index 76b3ab83e..8b56a1c83 100644 --- a/src/kdc/configure.in +++ b/src/kdc/configure.in @@ -5,6 +5,7 @@ AC_HEADER_CHECK(termios.h,AC_FUNC_CHECK([tcsetattr],AC_DEFINE(POSIX_TERMIOS))) AC_CHECK_HEADERS(syslog.h stdarg.h sys/select.h) AC_CHECK_FUNCS(openlog syslog closelog strftime vsprintf) AC_PROG_AWK +KRB5_AC_INET6 KRB5_SOCKADDR_SA_LEN CHECK_SIGNALS HAS_ANSI_VOLATILE diff --git a/src/kdc/network.c b/src/kdc/network.c index b725b2798..713ef02f1 100644 --- a/src/kdc/network.c +++ b/src/kdc/network.c @@ -54,7 +54,7 @@ static int *udp_port_fds = (int *) NULL; static u_short *udp_port_nums = (u_short *) NULL; static int n_udp_ports = 0; static int n_sockets = 0; -static int max_udp_ports = 0; +static int max_udp_ports = 0, max_udp_sockets = 0; static fd_set select_fds; static int select_nfds; @@ -64,7 +64,6 @@ static krb5_error_code add_port(port) u_short port; { int i; - int *new_fds; u_short *new_ports; int new_max; @@ -75,11 +74,6 @@ static krb5_error_code add_port(port) if (n_udp_ports >= max_udp_ports) { new_max = max_udp_ports + 10; - new_fds = safe_realloc(udp_port_fds, new_max * sizeof(int)); - if (new_fds == 0) - return ENOMEM; - udp_port_fds = new_fds; - new_ports = safe_realloc(udp_port_nums, new_max * sizeof(u_short)); if (new_ports == 0) return ENOMEM; @@ -91,7 +85,6 @@ static krb5_error_code add_port(port) udp_port_nums[n_udp_ports++] = port; return 0; } -#undef safe_realloc /* Keep in sync with lib/krb5/os/localaddr.c version. */ @@ -232,7 +225,7 @@ static int setup_port(void *P_data, struct sockaddr *addr) { struct socksetup *data = P_data; - int sock, i; + int sock = -1, i; switch (addr->sa_family) { case AF_INET: @@ -259,14 +252,71 @@ setup_port(void *P_data, struct sockaddr *addr) FD_SET (sock, &select_fds); if (sock > select_nfds) select_nfds = sock; - udp_port_fds[n_sockets++] = sock; krb5_klog_syslog (LOG_INFO, "listening on fd %d: %s port %d", sock, inet_ntoa (sin->sin_addr), udp_port_nums[i]); } } + break; +#ifdef KRB5_USE_INET6 + case AF_INET6: + /* XXX We really should be using a single AF_INET6 socket and + specify/receive local address info through sendmsg/recvmsg + control data. */ + { + struct sockaddr_in6 *sin6 = (struct sockaddr_in6 *) addr, psin6; + for (i = 0; i < n_udp_ports; i++) { +#ifdef HAVE_INET_NTOP + char abuf[46] = { 0 }; + const char *addr_str = 0; + addr_str = inet_ntop (sin6->sin6_family, &sin6->sin6_addr, abuf, + sizeof (abuf)); +#endif + if (addr_str == 0) + addr_str = "[some ipv6 address]"; + sock = socket (PF_INET6, SOCK_DGRAM, 0); + if (sock == -1) { + data->retval = errno; + com_err(data->prog, data->retval, + "Cannot create server socket for port %d address %s", + udp_port_nums[i], addr_str); + return 1; + } + psin6 = *sin6; + psin6.sin6_port = htons (udp_port_nums[i]); + if (bind (sock, (struct sockaddr *)&psin6, sizeof (psin6)) == -1) { + data->retval = errno; + com_err(data->prog, data->retval, + "Cannot bind server socket to port %d address %s", + udp_port_nums[i], addr_str); + return 1; + } + FD_SET (sock, &select_fds); + if (sock > select_nfds) + select_nfds = sock; + krb5_klog_syslog (LOG_INFO, "listening on fd %d: %s port %d", sock, + addr_str, udp_port_nums[i]); + } + } + break; +#endif default: break; } + if (sock >= 0) { + if (n_sockets == max_udp_sockets) { + int *new_fds; + int new_max = max_udp_sockets + n_udp_ports; + new_fds = safe_realloc(udp_port_fds, new_max * sizeof(int)); + if (new_fds == 0) { + data->retval = errno; + com_err(data->prog, data->retval, "cannot save socket info"); + return 1; + } + udp_port_fds = new_fds; + max_udp_sockets = new_max; + } + udp_port_fds[n_sockets++] = sock; + } return 0; } @@ -308,7 +358,7 @@ setup_network(prog) krb5_klog_syslog (LOG_INFO, "set up %d sockets", n_sockets); if (n_sockets == 0) { com_err(prog, 0, "no sockets set up?"); - return -1; + exit (1); } return 0; @@ -322,7 +372,11 @@ void process_packet(port_fd, prog, portnum) int cc, saddr_len; krb5_fulladdr faddr; krb5_error_code retval; +#ifdef KRB5_USE_INET6 + struct sockaddr_storage saddr; +#else struct sockaddr_in saddr; +#endif krb5_address addr; krb5_data request; krb5_data *response; @@ -346,10 +400,24 @@ void process_packet(port_fd, prog, portnum) request.data = pktbuf; faddr.port = ntohs(saddr.sin_port); faddr.address = &addr; - addr.addrtype = ADDRTYPE_INET; - addr.length = 4; + switch (((struct sockaddr *)&saddr)->sa_family) { + case AF_INET: + addr.addrtype = ADDRTYPE_INET; + addr.length = 4; + addr.contents = (krb5_octet *) &((struct sockaddr_in *)&saddr)->sin_addr; + break; + case AF_INET6: + addr.addrtype = ADDRTYPE_INET6; + addr.length = 16; + addr.contents = (krb5_octet *) &((struct sockaddr_in6 *)&saddr)->sin6_addr; + break; + default: + addr.addrtype = -1; + addr.length = 0; + addr.contents = 0; + break; + } /* this address is in net order */ - addr.contents = (krb5_octet *) &saddr.sin_addr; if ((retval = dispatch(&request, &faddr, portnum, &response))) { com_err(prog, retval, "while dispatching"); return; -- 2.26.2