summaryrefslogtreecommitdiffstats
path: root/src
diff options
context:
space:
mode:
authorKen Raeburn <raeburn@mit.edu>2000-02-25 22:05:02 +0000
committerKen Raeburn <raeburn@mit.edu>2000-02-25 22:05:02 +0000
commit5bae06639e2667c9da241ec9e3d032e0c41e0442 (patch)
tree5dd93c9cd92f084828e64b4606a9a88ebe7feea2 /src
parente838be75e57724228c979502adbaaa8f23088232 (diff)
fix udp_port_fds allocation bug; partial ipv6 support
git-svn-id: svn://anonsvn.mit.edu/krb5/trunk@12073 dc483132-0cff-0310-8789-dd5450dbe970
Diffstat (limited to 'src')
-rw-r--r--src/kdc/ChangeLog10
-rw-r--r--src/kdc/configure.in1
-rw-r--r--src/kdc/network.c96
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 <raeburn@mit.edu>
Alec H. Peterson <ahp@hilander.com>
- * 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 <sys/ioctl.h>, <syslog.h>, <net/if.h>.
(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;