[or-cvs] fixed the deadlock bug

Roger Dingledine arma at seul.org
Wed Jul 10 20:17:29 UTC 2002


Update of /home/or/cvsroot/src/or
In directory moria.seul.org:/home/arma/work/onion/cvs/src/or

Modified Files:
	connection_exit.c 
Log Message:
fixed the deadlock bug

this was another bug i introduced with the 5 july patch.
i should look at that patch more closely. :)


Index: connection_exit.c
===================================================================
RCS file: /home/or/cvsroot/src/or/connection_exit.c,v
retrieving revision 1.5
retrieving revision 1.6
diff -u -d -r1.5 -r1.6
--- connection_exit.c	10 Jul 2002 18:39:33 -0000	1.5
+++ connection_exit.c	10 Jul 2002 20:17:27 -0000	1.6
@@ -37,6 +37,7 @@
           log(LOG_DEBUG,"connection_exit_finished_flushing(): in-progress connect failed. Removing.");
           return -1;
         } else {
+          log(LOG_DEBUG,"connection_exit_finished_flushing(): in-progress connect still waiting.");
           return 0; /* no change, see if next time is better */
         }
       }
@@ -46,6 +47,7 @@
           conn->address,ntohs(conn->port));
       
       conn->state = EXIT_CONN_STATE_OPEN;
+      connection_flush_buf(conn); /* in case there are any queued data cells */
       connection_watch_events(conn, POLLIN);
       return 0;
     case EXIT_CONN_STATE_OPEN:
@@ -63,7 +65,6 @@
 int connection_exit_process_data_cell(cell_t *cell, connection_t *conn) {
   struct hostent *rent;
   struct sockaddr_in dest_addr;
-  int retval;
   int s; /* for the new socket, if we're on connecting_wait */
 
   /* an outgoing data cell has arrived */
@@ -72,47 +73,47 @@
 
   switch(conn->state) {
     case EXIT_CONN_STATE_CONNECTING_WAIT:
-      log(LOG_DEBUG,"connection_exit_process_cell(): state is connecting_wait. cell length %d.", cell->length);
+      log(LOG_DEBUG,"connection_exit_process_data_cell(): state is connecting_wait. cell length %d.", cell->length);
       if(!conn->ss_received) { /* this cell contains the ss */
         if(cell->length != sizeof(ss_t)) {
-          log(LOG_DEBUG,"connection_exit_process_cell(): Supposed to contain SS but wrong size. Closing.");
+          log(LOG_DEBUG,"connection_exit_process_data_cell(): Supposed to contain SS but wrong size. Closing.");
           return -1;
         }
         memcpy(&conn->ss, cell->payload, cell->length);
         if(conn->ss.addr_fmt != SS_ADDR_FMT_ASCII_HOST_PORT) { /* unrecognized address format */
-          log(LOG_DEBUG,"connection_exit_process_cell(): SS has unrecognized address format. Closing.");
+          log(LOG_DEBUG,"connection_exit_process_data_cell(): SS has unrecognized address format. Closing.");
           return -1;
         }
         conn->ss_received = 1;
-	log(LOG_DEBUG,"connection_exit_process_cell(): SS received.");
+	log(LOG_DEBUG,"connection_exit_process_data_cell(): SS received.");
       } else if (!conn->addr) { /* this cell contains the dest addr */
         if(!memchr(cell->payload,0,cell->length)) {
-          log(LOG_DEBUG,"connection_exit_process_cell(): dest_addr cell has no \\0. Closing.");
+          log(LOG_DEBUG,"connection_exit_process_data_cell(): dest_addr cell has no \\0. Closing.");
           return -1;
         }
         conn->address = strdup(cell->payload);
         rent = gethostbyname(cell->payload);
         if (!rent) { 
-          log(LOG_ERR,"connection_exit_process_cell(): Could not resolve dest addr %s.",cell->payload);
+          log(LOG_ERR,"connection_exit_process_data_cell(): Could not resolve dest addr %s.",cell->payload);
           return -1;
         }
         memcpy(&conn->addr, rent->h_addr,rent->h_length); 
-	log(LOG_DEBUG,"connection_exit_process_cell(): addr %s resolves to %d.",cell->payload,conn->addr);
+	log(LOG_DEBUG,"connection_exit_process_data_cell(): addr %s resolves to %d.",cell->payload,conn->addr);
       } else if (!conn->port) { /* this cell contains the dest port */
         if(!memchr(cell->payload,'\0',cell->length)) {
-          log(LOG_DEBUG,"connection_exit_process_cell(): dest_port cell has no \\0. Closing.");
+          log(LOG_DEBUG,"connection_exit_process_data_cell(): dest_port cell has no \\0. Closing.");
           return -1;
         }
         conn->port = atoi(cell->payload);
         if(!conn->port) { /* bad port */
-          log(LOG_DEBUG,"connection_exit_process_cell(): dest_port cell isn't a valid number. Closing.");
+          log(LOG_DEBUG,"connection_exit_process_data_cell(): dest_port cell isn't a valid number. Closing.");
           return -1;
         }
         /* all the necessary info is here. Start the connect() */
         s=socket(PF_INET,SOCK_STREAM,IPPROTO_TCP);
         if (s < 0)
         {
-          log(LOG_ERR,"connection_exit_process_cell(): Error creating network socket.");
+          log(LOG_ERR,"connection_exit_process_data_cell(): Error creating network socket.");
           return -1;
         }
         fcntl(s, F_SETFL, O_NONBLOCK); /* set s to non-blocking */
@@ -122,12 +123,12 @@
         dest_addr.sin_port = conn->port;
         memcpy((void *)&dest_addr.sin_addr, &conn->addr, sizeof(uint32_t));
       
-        log(LOG_DEBUG,"connection_exit_process_cell(): Connecting to %s:%u.",conn->address,ntohs(conn->port)); 
+        log(LOG_DEBUG,"connection_exit_process_data_cell(): Connecting to %s:%u.",conn->address,ntohs(conn->port)); 
 
         if(connect(s,(struct sockaddr *)&dest_addr,sizeof(dest_addr)) < 0){
           if(errno != EINPROGRESS){
             /* yuck. kill it. */
-            log(LOG_DEBUG,"connection_exit_process_cell(): Connect failed.");
+            log(LOG_DEBUG,"connection_exit_process_data_cell(): Connect failed.");
             return -1;
           } else {
             /* it's in progress. set state appropriately and return. */
@@ -136,14 +137,14 @@
             conn->state = EXIT_CONN_STATE_CONNECTING;
       
             /* i think only pollout is needed, but i'm curious if pollin ever gets caught -RD */
-            log(LOG_DEBUG,"connection_exit_process_cell(): connect in progress, socket %d.",s);
+            log(LOG_DEBUG,"connection_exit_process_data_cell(): connect in progress, socket %d.",s);
             connection_watch_events(conn, POLLOUT | POLLIN);
             return 0;
           }
         }
 
         /* it succeeded. we're connected. */
-        log(LOG_DEBUG,"connection_exit_process_cell(): Connection to %s:%u established.",conn->address,ntohs(conn->port));
+        log(LOG_DEBUG,"connection_exit_process_data_cell(): Connection to %s:%u established.",conn->address,ntohs(conn->port));
 
         conn->s = s;
         connection_set_poll_socket(conn);
@@ -151,15 +152,15 @@
         connection_watch_events(conn, POLLIN);
 	return 0;
       } else {
-	log(LOG_DEBUG,"connection_exit_process_cell(): in connecting_wait, but I've already received everything. Closing.");
+	log(LOG_DEBUG,"connection_exit_process_data_cell(): in connecting_wait, but I've already received everything. Closing.");
 	return -1;
       }
       return 0;
     case EXIT_CONN_STATE_CONNECTING:
-      log(LOG_DEBUG,"connection_exit_process_cell(): Data receiving while connecting. Queueing.");
-      retval = connection_write_to_buf(cell->payload, cell->length, conn);
-      connection_watch_events(conn, POLLIN); /* make it stop trying to write */
-      return retval; 
+      log(LOG_DEBUG,"connection_exit_process_data_cell(): Data receiving while connecting. Queueing.");
+      /* this sets us to POLLOUT | POLLIN, which is ok because we need to keep listening for
+       * writable for connect() to finish */
+      return connection_write_to_buf(cell->payload, cell->length, conn);
     case EXIT_CONN_STATE_OPEN:
       return connection_write_to_buf(cell->payload, cell->length, conn);
   }



More information about the tor-commits mailing list