| 
					
				 | 
			
			
				@@ -1610,12 +1610,50 @@ router_rebuild_descriptor(int force) 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				   return 0; 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				 } 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				  
			 | 
		
	
		
			
				 | 
				 | 
			
			
				-/** Mark descriptor out of date if it's older than <b>when</b> */ 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+/** If our router descriptor ever goes this long without being regenerated 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+ * because something changed, we force an immediate regenerate-and-upload. */ 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+#define FORCE_REGENERATE_DESCRIPTOR_INTERVAL (18*60*60) 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+ 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+/** If our router descriptor seems to be missing or unacceptable according 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+ * to the authorities, regenerate and reupload it _this_ often. */ 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+#define FAST_RETRY_DESCRIPTOR_INTERVAL (90*60) 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+ 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+/** Mark descriptor out of date if it's been "too long" since we last tried 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+ * to upload one. */ 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				 void 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				-mark_my_descriptor_dirty_if_older_than(time_t when) 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+mark_my_descriptor_dirty_if_too_old(time_t now) 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				 { 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				-  if (desc_clean_since < when) 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+  networkstatus_t *ns; 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+  routerstatus_t *rs; 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+  const char *retry_fast_reason = NULL; /* Set if we should retry frequently */ 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+  const time_t slow_cutoff = now - FORCE_REGENERATE_DESCRIPTOR_INTERVAL; 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+  const time_t fast_cutoff = now - FAST_RETRY_DESCRIPTOR_INTERVAL; 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+ 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+  /* If it's already dirty, don't mark it. */ 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+  if (! desc_clean_since) 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+    return; 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+ 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+  /* If it's older than FORCE_REGENERATE_DESCRIPTOR_INTERVAL, it's always 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+   * time to rebuild it. */ 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+  if (desc_clean_since < slow_cutoff) { 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				     mark_my_descriptor_dirty("time for new descriptor"); 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+    return; 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+  } 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+  /* Now we see whether we want to be retrying frequently or no.  The 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+   * rule here is that we'll retry frequently if we aren't listed in the 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+   * live consensus we have, or if the publication time of the 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+   * descriptor listed for us in the consensus is very old. */ 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+  ns = networkstatus_get_live_consensus(now); 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+  if (ns) { 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+    rs = networkstatus_vote_find_entry(ns, server_identitykey_digest); 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+    if (rs == NULL) 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+      retry_fast_reason = "not listed in consensus"; 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+    else if (rs->published_on < slow_cutoff) 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+      retry_fast_reason = "version listed in consensus is quite old"; 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+  } 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+ 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+  if (retry_fast_reason && desc_clean_since < fast_cutoff) 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+    mark_my_descriptor_dirty(retry_fast_reason); 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				 } 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				  
			 | 
		
	
		
			
				 | 
				 | 
			
			
				 /** Call when the current descriptor is out of date. */ 
			 |