[krb5] - backport RT#6905: use poll() so that we can use higher descriptor numbers when the client is talki

Nalin Dahyabhai nalin at fedoraproject.org
Tue Jul 19 19:55:55 UTC 2011


commit 4e66f1237b4d9d990438157d7f8737cd40577f3f
Author: Nalin Dahyabhai <nalin at dahyabhai.net>
Date:   Tue Jul 19 14:44:10 2011 -0400

    - backport RT#6905: use poll() so that we can use higher descriptor numbers when the client is talking to a KDC

 krb5-1.9.1-sendto_poll.patch |  625 ++++++++++++++++++++++++++++++++++++++++++
 krb5.spec                    |    9 +-
 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 at 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 at 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


More information about the scm-commits mailing list