Index: filters/apache/mod_cosign.c
===================================================================
RCS file: /cvsroot/cosign/cosign/filters/apache/mod_cosign.c,v
retrieving revision 1.79
diff -u -r1.79 mod_cosign.c
--- filters/apache/mod_cosign.c	13 Nov 2007 03:14:52 -0000	1.79
+++ filters/apache/mod_cosign.c	7 Feb 2008 18:34:27 -0000
@@ -634,7 +644,7 @@
     portarg = strtol( arg, (char **)NULL, 10 );
     cfg->port = htons( portarg );
 
-    for ( cur = cfg->cl; cur != NULL; cur = cur->conn_next ) {
+    for ( cur = *(cfg->cl); cur != NULL; cur = cur->conn_next ) {
 	if ( cfg->port == 0 ) {
 	    cur->conn_sin.sin_port = htons( 6663 );
 	} else {
@@ -848,9 +858,19 @@
 	return( err );
     }
 
+    /* This is hairy. During operation, we re-order the connection list
+     * so that the most responsive server is at the head of the list.
+     * This requires updates to the pointer to the list head from the cfg
+     * structure. However, the cfg structure gets copied around when
+     * Apache does configuration merges, so there isn't a single cfg
+     * structure in any one process. Instead, we point to a pointer
+     * to the list head. */
+    cfg->cl = (struct connlist **)
+		ap_palloc(params->pool, sizeof(struct connlist *));
+
     /* preserve address order as returned from DNS */
     /* actually, here we will randomize for "load balancing" */
-    cur = &cfg->cl;
+    cur = cfg->cl;
     for ( i = 0; he->h_addr_list[ i ] != NULL; i++ ) {
 	new = ( struct connlist * )
 		ap_palloc( params->pool, sizeof( struct connlist ));
@@ -922,7 +942,7 @@
     /* upon child exit, close all open SNETs */
     cfg = (cosign_host_config *) ap_get_module_config( s->module_config,
 	    &cosign_module );
-    if ( teardown_conn( cfg->cl, s ) != 0 ) {
+    if ( teardown_conn( *(cfg->cl), s ) != 0 ) {
 	cosign_log( APLOG_ERR, s, "mod_cosign: teardown conn err" );
     }
     return;
Index: filters/apache2/mod_cosign.c
===================================================================
RCS file: /cvsroot/cosign/cosign/filters/apache2/mod_cosign.c,v
retrieving revision 1.38
diff -u -r1.38 mod_cosign.c
--- filters/apache2/mod_cosign.c	13 Nov 2007 03:14:52 -0000	1.38
+++ filters/apache2/mod_cosign.c	7 Feb 2008 18:34:27 -0000
@@ -644,7 +644,7 @@
     portarg = strtol( arg, (char **)NULL, 10 );
     cfg->port = htons( portarg );
 
-    for ( cur = cfg->cl; cur != NULL; cur = cur->conn_next ) {
+    for ( cur = *(cfg->cl); cur != NULL; cur = cur->conn_next ) {
         if ( cfg->port == 0 ) {
             cur->conn_sin.sin_port = htons( 6663 );
         } else {
@@ -858,9 +858,18 @@
 	return( err );
     }
 
+    /* This is hairy. During operation, we re-order the connection list
+     * so that the most responsive server is at the head of the list.
+     * This requires updates to the pointer to the list head from the cfg
+     * structure. However, the cfg structure gets copied around when
+     * Apache does configuration merges, so there isn't a single cfg
+     * structure in any one process. Instead, we point to a pointer
+     * to the list head. */
+    cfg->cl = (struct connlist **)
+                apr_palloc(params->pool, sizeof(struct connlist *));
     /* preserve address order as returned from DNS */
     /* actually, here we will randomize for "load balancing" */
-    cur = &cfg->cl;
+    cur = cfg->cl;
     for ( i = 0; he->h_addr_list[ i ] != NULL; i++ ) {
 	new = ( struct connlist * )
 		apr_palloc( params->pool, sizeof( struct connlist ));
Index: filters/common/connect.c
===================================================================
RCS file: /cvsroot/cosign/cosign/filters/common/connect.c,v
retrieving revision 1.69
diff -u -r1.69 connect.c
--- filters/common/connect.c	6 Jun 2007 17:49:44 -0000	1.69
+++ filters/common/connect.c	7 Feb 2008 18:34:29 -0000
@@ -472,7 +472,7 @@
     /* use connection, then shuffle if there is a problem
      * what happens if they are all bad?
      */
-    for ( cur = &cfg->cl; *cur != NULL; cur = &(*cur)->conn_next ) {
+    for ( cur = cfg->cl; *cur != NULL; cur = &(*cur)->conn_next ) {
 	if ( (*cur)->conn_sn == NULL ) {
 	    continue;
 	}
@@ -500,7 +500,7 @@
     }
 
     /* all are closed or we didn't like their answer */
-    for ( cur = &cfg->cl; *cur != NULL; cur = &(*cur)->conn_next ) {
+    for ( cur = cfg->cl; *cur != NULL; cur = &(*cur)->conn_next ) {
 	if ( (*cur)->conn_sn != NULL ) {
 	    continue;
 	}
@@ -536,17 +536,17 @@
     return( COSIGN_ERROR );
 
 done:
-    if ( cur != &cfg->cl ) {
+    if ( cur != cfg->cl ) {
 	tmp = *cur;
 	*cur = (*cur)->conn_next;
-	tmp->conn_next = cfg->cl;
-	cfg->cl = tmp;
+	tmp->conn_next = *(cfg->cl);
+	*(cfg->cl) = tmp;
     }
     if ( rc == COSIGN_LOGGED_OUT ) {
 	return( COSIGN_RETRY );
     } else {
 	if (( first ) && ( cfg->proxy == 1 )) {
-	    if ( netretr_proxy( scookie, si, cfg->cl->conn_sn,
+	    if ( netretr_proxy( scookie, si, (*(cfg->cl))->conn_sn,
 		    cfg->proxydb, s ) != COSIGN_OK ) {
 		cosign_log( APLOG_ERR, s, "mod_cosign: choose_conn: " 
 			"can't retrieve proxy cookies" );
@@ -554,7 +554,7 @@
 	}
 #ifdef KRB
 	if (( first ) && ( cfg->krbtkt == 1 )) {
-	    if ( netretr_ticket( scookie, si, cfg->cl->conn_sn, 
+	    if ( netretr_ticket( scookie, si, (*(cfg->cl))->conn_sn, 
 		    cfg->tkt_prefix, s ) != COSIGN_OK ) {
 		cosign_log( APLOG_ERR, s, "mod_cosign: choose_conn: " 
 			"can't retrieve kerberos ticket" );
Index: filters/common/cosign.h
===================================================================
RCS file: /cvsroot/cosign/cosign/filters/common/cosign.h,v
retrieving revision 1.28
diff -u -r1.28 cosign.h
--- filters/common/cosign.h	5 Jun 2006 20:15:38 -0000	1.28
+++ filters/common/cosign.h	7 Feb 2008 18:34:29 -0000
@@ -13,7 +13,7 @@
     int                 protect;
     int                 configured;
     int			checkip;
-    struct connlist     *cl;
+    struct connlist     **cl;
     SSL_CTX		*ctx;
     char		*cert;
     char		*key;
