| 
					
				 | 
			
			
				@@ -408,109 +408,6 @@ static void conn_write_callback(int fd, short events, void *_conn) 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				     close_closeable_connections(); 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				 } 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				  
			 | 
		
	
		
			
				 | 
				 | 
			
			
				-#if 0 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				-static void conn_read(int i) { 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				-  connection_t *conn = connection_array[i]; 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				- 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				-  if (conn->marked_for_close) 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				-    return; 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				- 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				-  /* post 0.0.9, sometimes we get into loops like: 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				-Jan 06 13:54:14.999 [debug] connection_consider_empty_buckets(): global bucket exhausted. Pausing. 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				-Jan 06 13:54:14.999 [debug] connection_stop_reading() called. 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				-Jan 06 13:54:14.999 [debug] conn_read(): socket 14 wants to read. 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				-Jan 06 13:54:14.999 [debug] connection_consider_empty_buckets(): global bucket exhausted. Pausing. 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				-... 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				-  We finish the loop after a couple of seconds go by, but nothing seems 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				-  to happen during the loop except tight looping over poll. Perhaps the 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				-  tls buffer has pending bytes but we don't allow ourselves to read them? 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				-  */ 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				- 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				-  /* see http://www.greenend.org.uk/rjk/2001/06/poll.html for 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				-   * discussion of POLLIN vs POLLHUP */ 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				-  if (!(poll_array[i].revents & (POLLIN|POLLHUP|POLLERR))) 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				-    /* Sometimes read events get triggered for things that didn't ask 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				-     * for them (XXX due to unknown poll wonkiness) and sometime we 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				-     * want to read even though there was no read event (due to 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				-     * pending TLS data). 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				-     */ 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				- 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				-    /* XXX Post 0.0.9, we should rewrite this whole if statement; 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				-     * something sane may result.  Nick suspects that the || below 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				-     * should be a &&. 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				-     * 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				-     * No, it should remain a ||. Here's why: when we reach the end 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				-     * of a read bucket, we stop reading on a conn. We don't want to 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				-     * read any more bytes on it, until we're allowed to resume reading. 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				-     * So if !connection_is_reading, then return right then. Also, if 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				-     * poll() said nothing (true because the if above), and there's 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				-     * nothing pending, then also return because nothing to do. 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				-     * 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				-     * If poll *does* have something to say, even though 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				-     * !connection_is_reading, then we want to handle it in connection.c 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				-     * to make it stop reading for next time, else we loop. 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				-     */ 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				-    if (!connection_is_reading(conn) || 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				-        !connection_has_pending_tls_data(conn)) 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				-      return; /* this conn should not read */ 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				- 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				-  log_fn(LOG_DEBUG,"socket %d wants to read.",conn->s); 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				- 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				-  assert_connection_ok(conn, time(NULL)); 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				-  assert_all_pending_dns_resolves_ok(); 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				- 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				-  if ( 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				-    /* XXX does POLLHUP also mean it's definitely broken? */ 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				-#ifdef MS_WINDOWS 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				-      (poll_array[i].revents & POLLERR) || 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				-#endif 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				-      connection_handle_read(conn) < 0) { 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				-    if (!conn->marked_for_close) { 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				-      /* this connection is broken. remove it */ 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				-#ifndef MS_WINDOWS 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				-      log_fn(LOG_WARN,"Bug: unhandled error on read for %s connection (fd %d); removing", 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				-             CONN_TYPE_TO_STRING(conn->type), conn->s); 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				-#endif 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				-      connection_mark_for_close(conn); 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				-    } 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				-  } 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				-  assert_connection_ok(conn, time(NULL)); 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				-  assert_all_pending_dns_resolves_ok(); 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				-} 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				- 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				-/** Called when the connection at connection_array[i] has a write event: 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				- * checks for validity, catches numerous errors, and dispatches to 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				- * connection_handle_write. 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				- */ 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				-static void conn_write(int i) { 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				-  connection_t *conn; 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				- 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				-  if (!(poll_array[i].revents & POLLOUT)) 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				-    return; /* this conn doesn't want to write */ 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				- 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				-  conn = connection_array[i]; 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				-  log_fn(LOG_DEBUG,"socket %d wants to write.",conn->s); 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				-  if (conn->marked_for_close) 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				-    return; 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				- 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				-  assert_connection_ok(conn, time(NULL)); 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				-  assert_all_pending_dns_resolves_ok(); 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				- 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				-  if (connection_handle_write(conn) < 0) { 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				-    if (!conn->marked_for_close) { 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				-      /* this connection is broken. remove it. */ 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				-      log_fn(LOG_WARN,"Bug: unhandled error on write for %s connection (fd %d); removing", 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				-             CONN_TYPE_TO_STRING(conn->type), conn->s); 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				-      conn->has_sent_end = 1; /* otherwise we cry wolf about duplicate close */ 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				-      /* XXX do we need a close-immediate here, so we don't try to flush? */ 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				-      connection_mark_for_close(conn); 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				-    } 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				-  } 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				-  assert_connection_ok(conn, time(NULL)); 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				-  assert_all_pending_dns_resolves_ok(); 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				-} 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				-#endif 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				- 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				 /** If the connection at connection_array[i] is marked for close, then: 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				  *    - If it has data that it wants to flush, try to flush it. 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				  *    - If it _still_ has data to flush, and conn->hold_open_until_flushed is 
			 |