| 
					
				 | 
			
			
				@@ -1654,10 +1654,13 @@ rep_hist_load_state(or_state_t *state, char **err) 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				  
			 | 
		
	
		
			
				 | 
				 | 
			
			
				 /*********************************************************************/ 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				  
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+typedef struct predicted_port_t { 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+  uint16_t port; 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+  time_t time; 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+} predicted_port_t; 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+ 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				 /** A list of port numbers that have been used recently. */ 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				 static smartlist_t *predicted_ports_list=NULL; 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				-/** The corresponding most recently used time for each port. */ 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				-static smartlist_t *predicted_ports_times=NULL; 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				  
			 | 
		
	
		
			
				 | 
				 | 
			
			
				 /** We just got an application request for a connection with 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				  * port <b>port</b>. Remember it for the future, so we can keep 
			 | 
		
	
	
		
			
				| 
					
				 | 
			
			
				@@ -1666,14 +1669,11 @@ static smartlist_t *predicted_ports_times=NULL; 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				 static void 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				 add_predicted_port(time_t now, uint16_t port) 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				 { 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				-  /* XXXX we could just use uintptr_t here, I think. */ 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				-  uint16_t *tmp_port = tor_malloc(sizeof(uint16_t)); 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				-  time_t *tmp_time = tor_malloc(sizeof(time_t)); 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				-  *tmp_port = port; 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				-  *tmp_time = now; 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				-  rephist_total_alloc += sizeof(uint16_t) + sizeof(time_t); 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				-  smartlist_add(predicted_ports_list, tmp_port); 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				-  smartlist_add(predicted_ports_times, tmp_time); 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+  predicted_port_t *pp = tor_malloc(sizeof(predicted_port_t)); 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+  pp->port = port; 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+  pp->time = now; 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+  rephist_total_alloc += sizeof(*pp); 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+  smartlist_add(predicted_ports_list, pp); 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				 } 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				  
			 | 
		
	
		
			
				 | 
				 | 
			
			
				 /** Initialize whatever memory and structs are needed for predicting 
			 | 
		
	
	
		
			
				| 
					
				 | 
			
			
				@@ -1684,7 +1684,6 @@ static void 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				 predicted_ports_init(void) 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				 { 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				   predicted_ports_list = smartlist_create(); 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				-  predicted_ports_times = smartlist_create(); 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				   add_predicted_port(time(NULL), 80); /* add one to kickstart us */ 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				 } 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				  
			 | 
		
	
	
		
			
				| 
					
				 | 
			
			
				@@ -1694,12 +1693,10 @@ predicted_ports_init(void) 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				 static void 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				 predicted_ports_free(void) 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				 { 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				-  rephist_total_alloc -= smartlist_len(predicted_ports_list)*sizeof(uint16_t); 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				-  SMARTLIST_FOREACH(predicted_ports_list, char *, cp, tor_free(cp)); 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+  rephist_total_alloc -= 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+    smartlist_len(predicted_ports_list)*sizeof(predicted_port_t); 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+  SMARTLIST_FOREACH(predicted_ports_list, predicted_port_t *, pp, tor_free(pp)); 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				   smartlist_free(predicted_ports_list); 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				-  rephist_total_alloc -= smartlist_len(predicted_ports_times)*sizeof(time_t); 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				-  SMARTLIST_FOREACH(predicted_ports_times, char *, cp, tor_free(cp)); 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				-  smartlist_free(predicted_ports_times); 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				 } 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				  
			 | 
		
	
		
			
				 | 
				 | 
			
			
				 /** Remember that <b>port</b> has been asked for as of time <b>now</b>. 
			 | 
		
	
	
		
			
				| 
					
				 | 
			
			
				@@ -1709,24 +1706,17 @@ predicted_ports_free(void) 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				 void 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				 rep_hist_note_used_port(time_t now, uint16_t port) 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				 { 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				-  int i; 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				-  uint16_t *tmp_port; 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				-  time_t *tmp_time; 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				- 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				   tor_assert(predicted_ports_list); 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				-  tor_assert(predicted_ports_times); 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				  
			 | 
		
	
		
			
				 | 
				 | 
			
			
				   if (!port) /* record nothing */ 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				     return; 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				  
			 | 
		
	
		
			
				 | 
				 | 
			
			
				-  for (i = 0; i < smartlist_len(predicted_ports_list); ++i) { 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				-    tmp_port = smartlist_get(predicted_ports_list, i); 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				-    tmp_time = smartlist_get(predicted_ports_times, i); 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				-    if (*tmp_port == port) { 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				-      *tmp_time = now; 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+  SMARTLIST_FOREACH_BEGIN(predicted_ports_list, predicted_port_t *, pp) { 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+    if (pp->port == port) { 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+      pp->time = now; 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				       return; 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				     } 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				-  } 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+  } SMARTLIST_FOREACH_END(pp); 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				   /* it's not there yet; we need to add it */ 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				   add_predicted_port(now, port); 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				 } 
			 | 
		
	
	
		
			
				| 
					
				 | 
			
			
				@@ -1735,36 +1725,28 @@ rep_hist_note_used_port(time_t now, uint16_t port) 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				  * we'll want to make connections to the same port in the future.  */ 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				 #define PREDICTED_CIRCS_RELEVANCE_TIME (60*60) 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				  
			 | 
		
	
		
			
				 | 
				 | 
			
			
				-/** Return a pointer to the list of port numbers that 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+/** Return a newly allocated pointer to a list of uint16_t * for ports that 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				  * are likely to be asked for in the near future. 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				- * 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				- * The caller promises not to mess with it. 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				  */ 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				 smartlist_t * 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				 rep_hist_get_predicted_ports(time_t now) 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				 { 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				-  int i; 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				-  uint16_t *tmp_port; 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				-  time_t *tmp_time; 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				- 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+  smartlist_t *out = smartlist_create(); 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				   tor_assert(predicted_ports_list); 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				-  tor_assert(predicted_ports_times); 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				  
			 | 
		
	
		
			
				 | 
				 | 
			
			
				   /* clean out obsolete entries */ 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				-  for (i = 0; i < smartlist_len(predicted_ports_list); ++i) { 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				-    tmp_time = smartlist_get(predicted_ports_times, i); 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				-    if (*tmp_time + PREDICTED_CIRCS_RELEVANCE_TIME < now) { 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				-      tmp_port = smartlist_get(predicted_ports_list, i); 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				-      log_debug(LD_CIRC, "Expiring predicted port %d", *tmp_port); 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				-      smartlist_del(predicted_ports_list, i); 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				-      smartlist_del(predicted_ports_times, i); 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				-      rephist_total_alloc -= sizeof(uint16_t)+sizeof(time_t); 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				-      tor_free(tmp_port); 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				-      tor_free(tmp_time); 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				-      i--; 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+  SMARTLIST_FOREACH_BEGIN(predicted_ports_list, predicted_port_t *, pp) { 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+    if (pp->time + PREDICTED_CIRCS_RELEVANCE_TIME < now) { 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+      log_debug(LD_CIRC, "Expiring predicted port %d", pp->port); 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+ 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+      rephist_total_alloc -= sizeof(predicted_port_t); 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+      tor_free(pp); 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+      SMARTLIST_DEL_CURRENT(predicted_ports_list, pp); 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+    } else { 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+      smartlist_add(out, tor_memdup(&pp->port, sizeof(uint16_t))); 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				     } 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				-  } 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				-  return predicted_ports_list; 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+  } SMARTLIST_FOREACH_END(pp); 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+  return out; 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				 } 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				  
			 | 
		
	
		
			
				 | 
				 | 
			
			
				 /** The user asked us to do a resolve. Rather than keeping track of 
			 |