pullup from trunk
authorTom Yu <tlyu@mit.edu>
Wed, 20 Jul 2005 22:52:33 +0000 (22:52 +0000)
committerTom Yu <tlyu@mit.edu>
Wed, 20 Jul 2005 22:52:33 +0000 (22:52 +0000)
ticket: 3060
version_fixed: 1.4.2

git-svn-id: svn://anonsvn.mit.edu/krb5/branches/krb5-1-4@17313 dc483132-0cff-0310-8789-dd5450dbe970

src/lib/krb5/os/ChangeLog
src/lib/krb5/os/sendto_kdc.c

index 78679a84e1c5e23e72749335430c0029888a4a5a..aaeec718b6d514cdd70bc8ef9b0be2369758c521 100644 (file)
@@ -1,3 +1,11 @@
+2005-06-09  Ken Raeburn  <raeburn@mit.edu>
+
+       * sendto_kdc.c (service_fds): Don't create a select_state on the
+       stack; take an additional argument pointing to it.
+       (krb5int_sendto): Don't create a select_state on the stack;
+       instead, allocate two on the heap, passing the second as the new
+       argument to service_fds.
+
 2005-04-22  Jeffrey Altman <jaltman@mit.edu>
 
         * init_os_ctx.c:  use krb5_init_ctx and krb5_free_ctx
index 599c28515cbeac1ed34d869d059d2b90b67afa53..d27c085601ff9d895b291c0b46fc192609a9e36a 100644 (file)
@@ -1,7 +1,7 @@
 /*
  * lib/krb5/os/sendto_kdc.c
  *
- * Copyright 1990,1991,2001,2002 by the Massachusetts Institute of Technology.
+ * Copyright 1990,1991,2001,2002,2004,2005 by the Massachusetts Institute of Technology.
  * All Rights Reserved.
  *
  * Export of this software from the United States of America may
@@ -948,14 +948,14 @@ service_udp_fd(struct conn_state *conn, struct select_state *selstate,
 
 static int
 service_fds (struct select_state *selstate,
-            struct conn_state *conns, size_t n_conns, int *winning_conn)
+            struct conn_state *conns, size_t n_conns, int *winning_conn,
+            struct select_state *seltemp)
 {
     int e, selret;
-    struct select_state sel_results;
 
     e = 0;
     while (selstate->nfds > 0
-          && (e = krb5int_cm_call_select(selstate, &sel_results, &selret)) == 0) {
+          && (e = krb5int_cm_call_select(selstate, seltemp, &selret)) == 0) {
        int i;
 
        dprint("service_fds examining results, selret=%d\n", selret);
@@ -971,11 +971,11 @@ service_fds (struct select_state *selstate,
            if (conns[i].fd == INVALID_SOCKET)
                continue;
            ssflags = 0;
-           if (FD_ISSET(conns[i].fd, &sel_results.rfds))
+           if (FD_ISSET(conns[i].fd, &seltemp->rfds))
                ssflags |= SSF_READ, selret--;
-           if (FD_ISSET(conns[i].fd, &sel_results.wfds))
+           if (FD_ISSET(conns[i].fd, &seltemp->wfds))
                ssflags |= SSF_WRITE, selret--;
-           if (FD_ISSET(conns[i].fd, &sel_results.xfds))
+           if (FD_ISSET(conns[i].fd, &seltemp->xfds))
                ssflags |= SSF_EXCEPTION, selret--;
            if (!ssflags)
                continue;
@@ -1035,7 +1035,7 @@ krb5int_sendto (krb5_context context, const krb5_data *message,
     krb5_error_code retval;
     struct conn_state *conns;
     size_t n_conns, host;
-    struct select_state select_state;
+    struct select_state *sel_state;
     struct timeval now;
     int winning_conn = -1, e = 0;
     unsigned char message_len_buf[4];
@@ -1056,12 +1056,19 @@ krb5int_sendto (krb5_context context, const krb5_data *message,
        conns[i].fd = INVALID_SOCKET;
     }
 
-    select_state.max = 0;
-    select_state.nfds = 0;
-    select_state.end_time.tv_sec = select_state.end_time.tv_usec = 0;
-    FD_ZERO(&select_state.rfds);
-    FD_ZERO(&select_state.wfds);
-    FD_ZERO(&select_state.xfds);
+    /* One for use here, listing all our fds in use, and one for
+       temporary use in service_fds, for the fds of interest.  */
+    sel_state = malloc(2 * sizeof(*sel_state));
+    if (sel_state == NULL) {
+       free(conns);
+       return ENOMEM;
+    }
+    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);
 
     message_len_buf[0] = (message->length >> 24) & 0xff;
     message_len_buf[1] = (message->length >> 16) & 0xff;
@@ -1083,18 +1090,19 @@ krb5int_sendto (krb5_context context, const krb5_data *message,
            dprint("host %d\n", host);
 
            /* Send to the host, wait for a response, then move on. */
-           if (maybe_send(&conns[host], &select_state))
+           if (maybe_send(&conns[host], sel_state))
                continue;
 
            retval = getcurtime(&now);
            if (retval)
                goto egress;
-           select_state.end_time = now;
-           select_state.end_time.tv_sec += 1;
-           e = service_fds(&select_state, conns, host+1, &winning_conn);
+           sel_state->end_time = now;
+           sel_state->end_time.tv_sec += 1;
+           e = service_fds(sel_state, conns, host+1, &winning_conn,
+                           sel_state+1);
            if (e)
                break;
-           if (pass > 0 && select_state.nfds == 0)
+           if (pass > 0 && sel_state->nfds == 0)
                /*
                 * After the first pass, if we close all fds, break
                 * out right away.  During the first pass, it's okay,
@@ -1110,16 +1118,16 @@ krb5int_sendto (krb5_context context, const krb5_data *message,
        /* Possible optimization: Find a way to integrate this select
           call with the last one from the above loop, if the loop
           actually calls select.  */
-       select_state.end_time.tv_sec += delay_this_pass;
-       e = service_fds(&select_state, conns, host+1, &winning_conn);
+       sel_state->end_time.tv_sec += delay_this_pass;
+       e = service_fds(sel_state, conns, host+1, &winning_conn, sel_state+1);
        if (e)
            break;
-       if (select_state.nfds == 0)
+       if (sel_state->nfds == 0)
            break;
        delay_this_pass *= 2;
     }
 
-    if (select_state.nfds == 0) {
+    if (sel_state->nfds == 0) {
        /* No addresses?  */
        retval = KRB5_KDC_UNREACH;
        goto egress;
@@ -1152,5 +1160,6 @@ egress:
     free(conns);
     if (reply->data != udpbuf)
        free(udpbuf);
+    free(sel_state);
     return retval;
 }