summaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorNalin Dahyabhai <nalin@dahyabhai.net>2011-07-19 14:44:10 -0400
committerNalin Dahyabhai <nalin@dahyabhai.net>2011-07-19 14:54:29 -0400
commit4e66f1237b4d9d990438157d7f8737cd40577f3f (patch)
treed471458e0bfda1d2b50c93e526662931f2f52f9f
parentba9d039a3a5dd4a27875c67cef00db358710f403 (diff)
downloadkrb5-4e66f1237b4d9d990438157d7f8737cd40577f3f.tar.gz
krb5-4e66f1237b4d9d990438157d7f8737cd40577f3f.tar.xz
krb5-4e66f1237b4d9d990438157d7f8737cd40577f3f.zip
- backport RT#6905: use poll() so that we can use higher descriptor numbers when the client is talking to a KDC
-rw-r--r--krb5-1.9.1-sendto_poll.patch625
-rw-r--r--krb5.spec9
2 files changed, 633 insertions, 1 deletions
diff --git a/krb5-1.9.1-sendto_poll.patch b/krb5-1.9.1-sendto_poll.patch
new file mode 100644
index 0000000..9f0d4a1
--- /dev/null
+++ b/krb5-1.9.1-sendto_poll.patch
@@ -0,0 +1,625 @@
+Pulled from SVN, then munged to apply to 1.9. Modifies cm.h so that a
+struct select_state has an alternate layout when USE_POLL is defined,
+and if we detect <poll.h> at configure-time, have sendto_kdc.c define
+USE_POLL to force its use. Adapts sendto_kdc.c to handle both cases,
+so that the previous behavior is preserved when <poll.h> is not found.
+RT#6905
+
+Index: src/include/cm.h
+===================================================================
+--- src/include/cm.h (revision 24907)
++++ src/include/cm.h (revision 24908)
+@@ -24,11 +24,20 @@
+ * or implied warranty.
+ */
+
+-/* Since fd_set is large on some platforms (8K on AIX 5.2), this
+- probably shouldn't be allocated in automatic storage. */
++/*
++ * Since fd_set is large on some platforms (8K on AIX 5.2), this probably
++ * shouldn't be allocated in automatic storage. Define USE_POLL and
++ * MAX_POLLFDS in the consumer of this header file to use poll state instead of
++ * select state.
++ */
+ struct select_state {
+- int max, nfds;
++#ifdef USE_POLL
++ struct pollfd fds[MAX_POLLFDS];
++#else
++ int max;
+ fd_set rfds, wfds, xfds;
++#endif
++ int nfds;
+ struct timeval end_time; /* magic: tv_sec==0 => never time out */
+ };
+
+Index: src/configure.in
+===================================================================
+--- src/configure.in (revision 24907)
++++ src/configure.in (revision 24908)
+@@ -67,7 +67,7 @@
+ ])
+ AC_SUBST(LIBUTIL)
+ # for kdc
+-AC_CHECK_HEADERS(syslog.h stdarg.h sys/select.h sys/sockio.h ifaddrs.h unistd.h)
++AC_CHECK_HEADERS(syslog.h stdarg.h sys/sockio.h ifaddrs.h unistd.h)
+ AC_CHECK_FUNCS(openlog syslog closelog strftime vsprintf vasprintf vsnprintf)
+ AC_CHECK_FUNCS(strlcpy)
+ EXTRA_SUPPORT_SYMS=
+@@ -472,7 +472,7 @@
+ AC_DEFINE(POSIX_TERMIOS,1,[Define if termios.h exists and tcsetattr exists]))])
+
+ KRB5_SIGTYPE
+-AC_CHECK_HEADERS(stdlib.h string.h stddef.h sys/types.h sys/file.h sys/param.h sys/stat.h sys/time.h netinet/in.h sys/uio.h sys/filio.h sys/select.h time.h paths.h errno.h)
++AC_CHECK_HEADERS(poll.h stdlib.h string.h stddef.h sys/types.h sys/file.h sys/param.h sys/stat.h sys/time.h netinet/in.h sys/uio.h sys/filio.h sys/select.h time.h paths.h errno.h)
+ AC_HEADER_STDARG
+ KRB5_AC_INET6
+
+Index: src/lib/krb5/os/cm.c
+===================================================================
+--- src/lib/krb5/os/cm.c (revision 0)
++++ src/lib/krb5/os/cm.c (revision 24908)
+@@ -0,0 +1,97 @@
++/* -*- mode: c; c-basic-offset: 4; indent-tabs-mode: nil -*- */
++/* lib/krb5/os/cm.c - Connection manager functions */
++/*
++ * Copyright (C) 2011 by the Massachusetts Institute of Technology.
++ * All rights reserved.
++ *
++ * Export of this software from the United States of America may
++ * require a specific license from the United States Government.
++ * It is the responsibility of any person or organization contemplating
++ * export to obtain such a license before exporting.
++ *
++ * WITHIN THAT CONSTRAINT, permission to use, copy, modify, and
++ * distribute this software and its documentation for any purpose and
++ * without fee is hereby granted, provided that the above copyright
++ * notice appear in all copies and that both that copyright notice and
++ * this permission notice appear in supporting documentation, and that
++ * the name of M.I.T. not be used in advertising or publicity pertaining
++ * to distribution of the software without specific, written prior
++ * permission. Furthermore if you modify this software you must label
++ * your software as modified software and not distribute it in such a
++ * fashion that it might be confused with the original M.I.T. software.
++ * M.I.T. makes no representations about the suitability of
++ * this software for any purpose. It is provided "as is" without express
++ * or implied warranty.
++ */
++
++/*
++ * This file include krb5int_cm_call_select, which is used by
++ * lib/apputils/net-server.c and sometimes by sendto_kdc.c.
++ */
++
++#include "k5-int.h"
++#ifdef HAVE_SYS_SELECT_H
++#include <sys/select.h>
++#endif
++#ifdef _WIN32
++#include <sys/timeb.h>
++#endif
++#include "cm.h"
++
++int
++k5_getcurtime(struct timeval *tvp)
++{
++#ifdef _WIN32
++ struct _timeb tb;
++ _ftime(&tb);
++ tvp->tv_sec = tb.time;
++ tvp->tv_usec = tb.millitm * 1000;
++ /* Can _ftime fail? */
++ return 0;
++#else
++ if (gettimeofday(tvp, 0))
++ return errno;
++ return 0;
++#endif
++}
++
++/*
++ * Call select and return results.
++ * Input: interesting file descriptors and absolute timeout
++ * Output: select return value (-1 or num fds ready) and fd_sets
++ * Return: 0 (for i/o available or timeout) or error code.
++ */
++krb5_error_code
++krb5int_cm_call_select (const struct select_state *in,
++ struct select_state *out, int *sret)
++{
++ struct timeval now, *timo;
++ krb5_error_code e;
++
++ *out = *in;
++ e = k5_getcurtime(&now);
++ if (e)
++ return e;
++ if (out->end_time.tv_sec == 0)
++ timo = 0;
++ else {
++ timo = &out->end_time;
++ out->end_time.tv_sec -= now.tv_sec;
++ out->end_time.tv_usec -= now.tv_usec;
++ if (out->end_time.tv_usec < 0) {
++ out->end_time.tv_usec += 1000000;
++ out->end_time.tv_sec--;
++ }
++ if (out->end_time.tv_sec < 0) {
++ *sret = 0;
++ return 0;
++ }
++ }
++
++ *sret = select(out->max, &out->rfds, &out->wfds, &out->xfds, timo);
++ e = SOCKET_ERRNO;
++
++ if (*sret < 0)
++ return e;
++ return 0;
++}
+Index: src/lib/krb5/os/Makefile.in
+===================================================================
+--- src/lib/krb5/os/Makefile.in (revision 24907)
++++ src/lib/krb5/os/Makefile.in (revision 24908)
+@@ -18,6 +18,7 @@
+ def_realm.o \
+ ccdefname.o \
+ changepw.o \
++ cm.o \
+ dnsglue.o \
+ dnssrv.o \
+ free_krbhs.o \
+@@ -62,6 +63,7 @@
+ $(OUTPRE)def_realm.$(OBJEXT) \
+ $(OUTPRE)ccdefname.$(OBJEXT) \
+ $(OUTPRE)changepw.$(OBJEXT) \
++ $(OUTPRE)cm.$(OBJEXT) \
+ $(OUTPRE)dnsglue.$(OBJEXT) \
+ $(OUTPRE)dnssrv.$(OBJEXT) \
+ $(OUTPRE)free_krbhs.$(OBJEXT) \
+@@ -106,6 +108,7 @@
+ $(srcdir)/def_realm.c \
+ $(srcdir)/ccdefname.c \
+ $(srcdir)/changepw.c \
++ $(srcdir)/cm.c \
+ $(srcdir)/dnsglue.c \
+ $(srcdir)/dnssrv.c \
+ $(srcdir)/free_krbhs.c \
+Index: src/lib/krb5/os/os-proto.h
+===================================================================
+--- src/lib/krb5/os/os-proto.h (revision 24907)
++++ src/lib/krb5/os/os-proto.h (revision 24908)
+@@ -32,6 +32,10 @@
+ #ifndef KRB5_LIBOS_INT_PROTO__
+ #define KRB5_LIBOS_INT_PROTO__
+
++#ifdef HAVE_SYS_TIME_H
++#include <sys/time.h>
++#endif
++
+ struct addrlist;
+ krb5_error_code krb5_locate_kdc(krb5_context, const krb5_data *,
+ struct addrlist *, int, int, int);
+@@ -101,6 +105,8 @@
+ /* The io vector is *not* const here, unlike writev()! */
+ int krb5int_net_writev (krb5_context, int, sg_buf *, int);
+
++int k5_getcurtime(struct timeval *tvp);
++
+ #include "k5-thread.h"
+ extern k5_mutex_t krb5int_us_time_mutex;
+
+Index: src/lib/krb5/os/sendto_kdc.c
+===================================================================
+--- src/lib/krb5/os/sendto_kdc.c (revision 24907)
++++ src/lib/krb5/os/sendto_kdc.c (revision 24908)
+@@ -30,17 +30,16 @@
+ #include "fake-addrinfo.h"
+ #include "k5-int.h"
+
+-#ifdef HAVE_SYS_TIME_H
+-#include <sys/time.h>
+-#else
+-#include <time.h>
+-#endif
+ #include "os-proto.h"
+ #ifdef _WIN32
+ #include <sys/timeb.h>
+ #endif
+
+-#ifdef _AIX
++#if defined(HAVE_POLL_H)
++#include <poll.h>
++#define USE_POLL
++#define MAX_POLLFDS 1024
++#elif defined(HAVE_SYS_SELECT_H)
+ #include <sys/select.h>
+ #endif
+
+@@ -168,29 +167,6 @@
+ p = strerror(err);
+ putstr(p);
+ break;
+- case 'F':
+- /* %F => fd_set *, fd_set *, fd_set *, int */
+- rfds = va_arg(args, fd_set *);
+- wfds = va_arg(args, fd_set *);
+- xfds = va_arg(args, fd_set *);
+- maxfd = va_arg(args, int);
+-
+- for (i = 0; i < maxfd; i++) {
+- int r = FD_ISSET(i, rfds);
+- int w = wfds && FD_ISSET(i, wfds);
+- int x = xfds && FD_ISSET(i, xfds);
+- if (r || w || x) {
+- putf(" %d", i);
+- if (r)
+- putstr("r");
+- if (w)
+- putstr("w");
+- if (x)
+- putstr("x");
+- }
+- }
+- putstr(" ");
+- break;
+ case 's':
+ /* %s => char * */
+ p = va_arg(args, const char *);
+@@ -437,75 +413,154 @@
+
+ #include "cm.h"
+
+-static int
+-getcurtime (struct timeval *tvp)
++/*
++ * Currently only sendto_kdc.c knows how to use poll(); the other candidate
++ * user, lib/apputils/net-server.c, is stuck using select() for the moment
++ * since it is entangled with the RPC library. The following cm_* functions
++ * are not fully generic, are O(n^2) in the poll case, and are limited to
++ * handling 1024 connections (in order to maintain a constant-sized selstate).
++ * More rearchitecting would be appropriate before extending this support to
++ * the KDC and kadmind.
++ */
++
++static void
++cm_init_selstate(struct select_state *selstate)
+ {
+-#ifdef _WIN32
+- struct _timeb tb;
+- _ftime(&tb);
+- tvp->tv_sec = tb.time;
+- tvp->tv_usec = tb.millitm * 1000;
+- /* Can _ftime fail? */
+- return 0;
++ selstate->nfds = 0;
++ selstate->end_time.tv_sec = selstate->end_time.tv_usec = 0;
++#ifndef USE_POLL
++ selstate->max = 0;
++ selstate->nfds = 0;
++ FD_ZERO(&selstate->rfds);
++ FD_ZERO(&selstate->wfds);
++ FD_ZERO(&selstate->xfds);
++#endif
++}
++
++static krb5_boolean
++cm_add_fd(struct select_state *selstate, int fd, unsigned int ssflags)
++{
++#ifdef USE_POLL
++ if (selstate->nfds >= MAX_POLLFDS)
++ return FALSE;
++ selstate->fds[selstate->nfds].fd = fd;
++ selstate->fds[selstate->nfds].events = 0;
++ if (ssflags & SSF_READ)
++ selstate->fds[selstate->nfds].events |= POLLIN;
++ if (ssflags & SSF_WRITE)
++ selstate->fds[selstate->nfds].events |= POLLOUT;
+ #else
+- if (gettimeofday(tvp, 0)) {
+- dperror("gettimeofday");
+- return errno;
++#ifndef _WIN32 /* On Windows FD_SETSIZE is a count, not a max value. */
++ if (fd >= FD_SETSIZE)
++ return FALSE;
++#endif
++ if (ssflags & SSF_READ)
++ FD_SET(fd, &selstate->rfds);
++ if (ssflags & SSF_WRITE)
++ FD_SET(fd, &selstate->wfds);
++ if (ssflags & SSF_EXCEPTION)
++ FD_SET(fd, &selstate->xfds);
++ if (selstate->max <= fd)
++ selstate->max = fd + 1;
++#endif
++ selstate->nfds++;
++ return TRUE;
++}
++
++static void
++cm_remove_fd(struct select_state *selstate, int fd)
++{
++#ifdef USE_POLL
++ int i;
++
++ /* Find the FD in the array and move the last entry to its place. */
++ assert(selstate->nfds > 0);
++ for (i = 0; i < selstate->nfds && selstate->fds[i].fd != fd; i++);
++ assert(i < selstate->nfds);
++ selstate->fds[i] = selstate->fds[selstate->nfds - 1];
++#else
++ FD_CLR(fd, &selstate->rfds);
++ FD_CLR(fd, &selstate->wfds);
++ FD_CLR(fd, &selstate->xfds);
++ if (selstate->max == 1 + fd) {
++ while (selstate->max > 0
++ && ! FD_ISSET(selstate->max-1, &selstate->rfds)
++ && ! FD_ISSET(selstate->max-1, &selstate->wfds)
++ && ! FD_ISSET(selstate->max-1, &selstate->xfds))
++ selstate->max--;
++ dprint("new max_fd + 1 is %d\n", selstate->max);
+ }
+- return 0;
+ #endif
++ selstate->nfds--;
+ }
+
+-/*
+- * Call select and return results.
+- * Input: interesting file descriptors and absolute timeout
+- * Output: select return value (-1 or num fds ready) and fd_sets
+- * Return: 0 (for i/o available or timeout) or error code.
+- */
+-krb5_error_code
+-krb5int_cm_call_select (const struct select_state *in,
+- struct select_state *out, int *sret)
++static void
++cm_unset_write(struct select_state *selstate, int fd)
+ {
+- struct timeval now, *timo;
+- krb5_error_code e;
++#ifdef USE_POLL
++ int i;
+
+- *out = *in;
+- e = getcurtime(&now);
+- if (e)
+- return e;
+- if (out->end_time.tv_sec == 0)
+- timo = 0;
++ for (i = 0; i < selstate->nfds && selstate->fds[i].fd != fd; i++);
++ assert(i < selstate->nfds);
++ selstate->fds[i].events &= ~POLLOUT;
++#else
++ FD_CLR(fd, &selstate->wfds);
++#endif
++}
++
++static krb5_error_code
++cm_select_or_poll(const struct select_state *in, struct select_state *out,
++ int *sret)
++{
++#ifdef USE_POLL
++ struct timeval now;
++ int e, timeout;
++
++ if (in->end_time.tv_sec == 0)
++ timeout = -1;
+ else {
+- timo = &out->end_time;
+- out->end_time.tv_sec -= now.tv_sec;
+- out->end_time.tv_usec -= now.tv_usec;
+- if (out->end_time.tv_usec < 0) {
+- out->end_time.tv_usec += 1000000;
+- out->end_time.tv_sec--;
+- }
+- if (out->end_time.tv_sec < 0) {
+- *sret = 0;
+- return 0;
+- }
++ e = k5_getcurtime(&now);
++ if (e)
++ return e;
++ timeout = (in->end_time.tv_sec - now.tv_sec) * 1000 +
++ (in->end_time.tv_usec - now.tv_usec) / 1000;
+ }
+- dprint("selecting on max=%d sockets [%F] timeout %t\n",
+- out->max,
+- &out->rfds, &out->wfds, &out->xfds, out->max,
+- timo);
+- *sret = select(out->max, &out->rfds, &out->wfds, &out->xfds, timo);
++ /* We don't need a separate copy of the selstate for poll, but use one
++ * anyone for consistency with the select wrapper. */
++ *out = *in;
++ *sret = poll(out->fds, out->nfds, timeout);
+ e = SOCKET_ERRNO;
++ return (*sret < 0) ? e : 0;
++#else
++ /* Use the select wrapper from cm.c. */
++ return krb5int_cm_call_select(in, out, sret);
++#endif
++}
+
+- dprint("select returns %d", *sret);
+- if (*sret < 0)
+- dprint(", error = %E\n", e);
+- else if (*sret == 0)
+- dprint(" (timeout)\n");
+- else
+- dprint(":%F\n", &out->rfds, &out->wfds, &out->xfds, out->max);
++static unsigned int
++cm_get_ssflags(struct select_state *selstate, int fd)
++{
++ unsigned int ssflags = 0;
++#ifdef USE_POLL
++ int i;
+
+- if (*sret < 0)
+- return e;
+- return 0;
++ for (i = 0; i < selstate->nfds && selstate->fds[i].fd != fd; i++);
++ assert(i < selstate->nfds);
++ if (selstate->fds[i].revents & POLLIN)
++ ssflags |= SSF_READ;
++ if (selstate->fds[i].revents & POLLOUT)
++ ssflags |= SSF_WRITE;
++ if (selstate->fds[i].revents & POLLERR)
++ ssflags |= SSF_EXCEPTION;
++#else
++ if (FD_ISSET(fd, &selstate->rfds))
++ ssflags |= SSF_READ;
++ if (FD_ISSET(fd, &selstate->wfds))
++ ssflags |= SSF_WRITE;
++ if (FD_ISSET(fd, &selstate->xfds))
++ ssflags |= SSF_EXCEPTION;
++#endif
++ return ssflags;
+ }
+
+ static int service_tcp_fd(krb5_context context, struct conn_state *conn,
+@@ -702,6 +757,7 @@
+ krb5_data *callback_buffer)
+ {
+ int fd, e;
++ unsigned int ssflags;
+ struct addrinfo *ai = state->addr;
+
+ dprint("start_connection(@%p)\ngetting %s socket in family %d...", state,
+@@ -711,14 +767,6 @@
+ dprint("socket: %m creating with af %d\n", state->err, ai->ai_family);
+ return -1; /* try other hosts */
+ }
+-#ifndef _WIN32 /* On Windows FD_SETSIZE is a count, not a max value. */
+- if (fd >= FD_SETSIZE) {
+- closesocket(fd);
+- state->err = EMFILE;
+- dprint("socket: fd %d too high\n", fd);
+- return -1;
+- }
+-#endif
+ set_cloexec_fd(fd);
+ /* Make it non-blocking. */
+ if (ai->ai_socktype == SOCK_STREAM) {
+@@ -801,17 +849,16 @@
+ }
+ }
+ #endif
+- FD_SET(state->fd, &selstate->rfds);
++ ssflags = SSF_READ | SSF_EXCEPTION;
+ if (state->state == CONNECTING || state->state == WRITING)
+- FD_SET(state->fd, &selstate->wfds);
+- FD_SET(state->fd, &selstate->xfds);
+- if (selstate->max <= state->fd)
+- selstate->max = state->fd + 1;
+- selstate->nfds++;
++ ssflags |= SSF_WRITE;
++ if (!cm_add_fd(selstate, state->fd, ssflags)) {
++ (void) closesocket(state->fd);
++ state->fd = INVALID_SOCKET;
++ state->state = FAILED;
++ return -1;
++ }
+
+- dprint("new select vectors: %F\n",
+- &selstate->rfds, &selstate->wfds, &selstate->xfds, selstate->max);
+-
+ return 0;
+ }
+
+@@ -868,22 +915,11 @@
+ kill_conn(struct conn_state *conn, struct select_state *selstate, int err)
+ {
+ conn->state = FAILED;
++ conn->err = err;
+ shutdown(conn->fd, SHUTDOWN_BOTH);
+- FD_CLR(conn->fd, &selstate->rfds);
+- FD_CLR(conn->fd, &selstate->wfds);
+- FD_CLR(conn->fd, &selstate->xfds);
+- conn->err = err;
++ cm_remove_fd(selstate, conn->fd);
+ dprint("abandoning connection %d: %m\n", conn->fd, err);
+ /* Fix up max fd for next select call. */
+- if (selstate->max == 1 + conn->fd) {
+- while (selstate->max > 0
+- && ! FD_ISSET(selstate->max-1, &selstate->rfds)
+- && ! FD_ISSET(selstate->max-1, &selstate->wfds)
+- && ! FD_ISSET(selstate->max-1, &selstate->xfds))
+- selstate->max--;
+- dprint("new max_fd + 1 is %d\n", selstate->max);
+- }
+- selstate->nfds--;
+ }
+
+ /* Check socket for error. */
+@@ -1005,7 +1041,7 @@
+ /* Done writing, switch to reading. */
+ /* Don't call shutdown at this point because
+ * some implementations cannot deal with half-closed connections.*/
+- FD_CLR(conn->fd, &selstate->wfds);
++ cm_unset_write(selstate, conn->fd);
+ /* Q: How do we detect failures to send the remaining data
+ to the remote side, since we're in non-blocking mode?
+ Will we always get errors on the reading side? */
+@@ -1125,7 +1161,8 @@
+ while (selstate->nfds > 0) {
+ unsigned int i;
+
+- e = krb5int_cm_call_select(selstate, seltemp, &selret);
++ selret = 0;
++ e = cm_select_or_poll(selstate, seltemp, &selret);
+ if (e == EINTR)
+ continue;
+ if (e != 0)
+@@ -1149,18 +1149,12 @@ service_fds (krb5_context context,
+ return 0;
+
+ /* Got something on a socket, process it. */
+- for (i = 0; i <= (unsigned int)selstate->max && selret > 0 && i < n_conns; i++) {
++ for (i = 0; i < n_conns; i++) {
+ int ssflags;
+
+ if (conns[i].fd == INVALID_SOCKET)
+ continue;
+- ssflags = 0;
+- if (FD_ISSET(conns[i].fd, &seltemp->rfds))
+- ssflags |= SSF_READ, selret--;
+- if (FD_ISSET(conns[i].fd, &seltemp->wfds))
+- ssflags |= SSF_WRITE, selret--;
+- if (FD_ISSET(conns[i].fd, &seltemp->xfds))
+- ssflags |= SSF_EXCEPTION, selret--;
++ ssflags = cm_get_ssflags(seltemp, conns[i].fd);
+ if (!ssflags)
+ continue;
+
+@@ -1229,12 +1259,7 @@
+ retval = ENOMEM;
+ goto egress;
+ }
+- sel_state->max = 0;
+- sel_state->nfds = 0;
+- sel_state->end_time.tv_sec = sel_state->end_time.tv_usec = 0;
+- FD_ZERO(&sel_state->rfds);
+- FD_ZERO(&sel_state->wfds);
+- FD_ZERO(&sel_state->xfds);
++ cm_init_selstate(sel_state);
+
+
+ /* Set up connections. */
+@@ -1295,7 +1295,7 @@ krb5int_sendto (krb5_context context, co
+ (callback_info ? &callback_data[host] : NULL)))
+ continue;
+
+- retval = getcurtime(&now);
++ retval = k5_getcurtime(&now);
+ if (retval)
+ goto egress;
+ sel_state->end_time = now;
+@@ -1314,7 +1314,7 @@ krb5int_sendto (krb5_context context, co
+ }
+ if (e)
+ break;
+- retval = getcurtime(&now);
++ retval = k5_getcurtime(&now);
+ if (retval)
+ goto egress;
+ /* Possible optimization: Find a way to integrate this select
diff --git a/krb5.spec b/krb5.spec
index 513e17a..311b065 100644
--- a/krb5.spec
+++ b/krb5.spec
@@ -6,7 +6,7 @@
Summary: The Kerberos network authentication system
Name: krb5
Version: 1.9.1
-Release: 5%{?dist}
+Release: 6%{?dist}
# Maybe we should explode from the now-available-to-everybody tarball instead?
# http://web.mit.edu/kerberos/dist/krb5/1.9/krb5-1.9.1-signed.tar
Source0: krb5-%{version}.tar.gz
@@ -57,6 +57,7 @@ Patch80: krb5-trunk-kadmin-oldproto.patch
Patch81: krb5-1.9-canonicalize-fallback.patch
Patch82: krb5-1.9.1-ai_addrconfig.patch
Patch83: krb5-1.9.1-ai_addrconfig2.patch
+Patch84: krb5-1.9.1-sendto_poll.patch
License: MIT
URL: http://web.mit.edu/kerberos/www/
@@ -205,6 +206,7 @@ ln -s NOTICE LICENSE
%patch81 -p1 -b .canonicalize-fallback
%patch82 -p0 -b .ai_addrconfig
%patch83 -p0 -b .ai_addrconfig2
+%patch84 -p0 -b .sendto_poll
gzip doc/*.ps
sed -i -e '1s!\[twoside\]!!;s!%\(\\usepackage{hyperref}\)!\1!' doc/api/library.tex
@@ -664,6 +666,11 @@ exit 0
%{_sbindir}/uuserver
%changelog
+* Tue Jul 19 2011 Nalin Dahyabhai <nalin@redhat.com> 1.9.1-6
+- backport fixes to teach libkrb5 to use descriptors higher than FD_SETSIZE
+ to talk to a KDC by using poll() if it's detected at compile-time (#701446,
+ RT#6905)
+
* Thu Jun 23 2011 Nalin Dahyabhai <nalin@redhat.com> 1.9.1-5
- pull a fix from SVN to try to avoid triggering a PTR lookup in getaddrinfo()
during krb5_sname_to_principal(), and to let getaddrinfo() decide whether or