| 
					
				 | 
			
			
				@@ -1547,8 +1547,8 @@ connection_or_exact_get_by_addr_port(uint32_t addr, uint16_t port) 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				   return best; 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				 } 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				  
			 | 
		
	
		
			
				 | 
				 | 
			
			
				-/** Return a connection with give type, address, port, and purpose or NULL if 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				- * no such connection exists. */ 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+/** Return a connection with given type, address, port, and purpose; 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+ * or NULL if no such connection exists. */ 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				 connection_t * 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				 connection_get_by_type_addr_port_purpose(int type, uint32_t addr, uint16_t port, 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				                                          int purpose) 
			 | 
		
	
	
		
			
				| 
					
				 | 
			
			
				@@ -1570,22 +1570,42 @@ connection_get_by_type_addr_port_purpose(int type, uint32_t addr, uint16_t port, 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				   return NULL; 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				 } 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				  
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+/** Return the best connection of type OR with the 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+ * digest <b>digest</b> that we have, or NULL if we have none. 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+ * 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+ * 1) Don't return it if it's marked for close. 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+ * 2) If there are any open conns, ignore non-open conns. 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+ * 3) If there are any non-obsolete conns, ignore obsolete conns. 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+ * 4) Then if there are any non-empty conns, ignore empty conns. 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+ * 5) Of the remaining conns, prefer newer conns. 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+ */ 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				 connection_t * 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				-connection_get_by_identity_digest(const char *digest, int type) 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+connection_get_by_identity_digest(const char *digest) 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				 { 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				-  int i, n; 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+  int i, n, newer; 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				   connection_t *conn, *best=NULL; 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				   connection_t **carray; 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				  
			 | 
		
	
		
			
				 | 
				 | 
			
			
				   get_connection_array(&carray,&n); 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				   for (i=0;i<n;i++) { 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				     conn = carray[i]; 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				-    if (conn->type != type) 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+    if (conn->marked_for_close || 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+        memcmp(conn->identity_digest, digest, DIGEST_LEN)) 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				       continue; 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				-    if (!memcmp(conn->identity_digest, digest, DIGEST_LEN) && 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				-        !conn->marked_for_close && 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				-        (!best || best->timestamp_created < conn->timestamp_created)) 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				-      best = conn; 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+    if (!best) { 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+      best = conn; /* whatever it is, it's better than nothing. */ 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+      continue; 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+    } 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+    if (best->state == OR_CONN_STATE_OPEN && 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+        conn->state != OR_CONN_STATE_OPEN) 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+      continue; /* avoid non-open conns if we can */ 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+    newer = best->timestamp_created < conn->timestamp_created; 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+    if (conn->is_obsolete && (!best->is_obsolete || !newer)) 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+      continue; /* we have something, and it's better than this. */ 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+    if (circuit_get_by_conn(best) && !circuit_get_by_conn(conn)) 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+      continue; /* prefer conns with circuits on them */ 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+    if (newer) 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+      best = conn; /* lastly, prefer newer conns */ 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				   } 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				   return best; 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				 } 
			 |