|  | @@ -33,6 +33,7 @@ static char *eat_whitespace(char *s);
 | 
	
		
			
				|  |  |  static char *eat_whitespace_no_nl(char *s);
 | 
	
		
			
				|  |  |  static char *find_whitespace(char *s);
 | 
	
		
			
				|  |  |  static void router_free_exit_policy(routerinfo_t *router);
 | 
	
		
			
				|  |  | +static int router_add_exit_policy_from_string(routerinfo_t *router, char *s);
 | 
	
		
			
				|  |  |  static int router_add_exit_policy(routerinfo_t *router, 
 | 
	
		
			
				|  |  |                                    directory_token_t *tok);
 | 
	
		
			
				|  |  |  static int router_resolve_directory(directory_t *dir);
 | 
	
	
		
			
				|  | @@ -946,8 +947,37 @@ static void router_free_exit_policy(routerinfo_t *router) {
 | 
	
		
			
				|  |  |    }
 | 
	
		
			
				|  |  |  }
 | 
	
		
			
				|  |  |  
 | 
	
		
			
				|  |  | -int router_add_exit_policy_from_string(routerinfo_t *router,
 | 
	
		
			
				|  |  | -                                       char *s)
 | 
	
		
			
				|  |  | +void router_add_exit_policy_from_config(routerinfo_t *router) {
 | 
	
		
			
				|  |  | +  char *s = options.ExitPolicy, *e;
 | 
	
		
			
				|  |  | +  int last=0;
 | 
	
		
			
				|  |  | +
 | 
	
		
			
				|  |  | +  if(!s) {
 | 
	
		
			
				|  |  | +    log_fn(LOG_INFO,"No exit policy configured. Ok.");
 | 
	
		
			
				|  |  | +    return; /* nothing to see here */
 | 
	
		
			
				|  |  | +  }
 | 
	
		
			
				|  |  | +  if(!*s) {
 | 
	
		
			
				|  |  | +    log_fn(LOG_INFO,"Exit policy is empty. Ok.");
 | 
	
		
			
				|  |  | +    return; /* nothing to see here */
 | 
	
		
			
				|  |  | +  }
 | 
	
		
			
				|  |  | +
 | 
	
		
			
				|  |  | +  for(;;) {
 | 
	
		
			
				|  |  | +    e = strchr(s,',');
 | 
	
		
			
				|  |  | +    if(!e)
 | 
	
		
			
				|  |  | +      last = 1;
 | 
	
		
			
				|  |  | +    else
 | 
	
		
			
				|  |  | +      *e = 0;
 | 
	
		
			
				|  |  | +    log_fn(LOG_DEBUG,"Adding new entry '%s'",s);
 | 
	
		
			
				|  |  | +    if(router_add_exit_policy_from_string(router,s) < 0)
 | 
	
		
			
				|  |  | +      log_fn(LOG_WARNING,"Malformed exit policy %s; skipping.", s);
 | 
	
		
			
				|  |  | +    if(last)
 | 
	
		
			
				|  |  | +      return;
 | 
	
		
			
				|  |  | +    s = e+1;
 | 
	
		
			
				|  |  | +  }
 | 
	
		
			
				|  |  | +}
 | 
	
		
			
				|  |  | +
 | 
	
		
			
				|  |  | +static int
 | 
	
		
			
				|  |  | +router_add_exit_policy_from_string(routerinfo_t *router,
 | 
	
		
			
				|  |  | +                                   char *s)
 | 
	
		
			
				|  |  |  {
 | 
	
		
			
				|  |  |    directory_token_t tok;
 | 
	
		
			
				|  |  |    char *tmp, *cp;
 | 
	
	
		
			
				|  | @@ -1048,11 +1078,12 @@ int router_compare_to_exit_policy(connection_t *conn) {
 | 
	
		
			
				|  |  |      assert(tmpe->address);
 | 
	
		
			
				|  |  |      assert(tmpe->port);
 | 
	
		
			
				|  |  |  
 | 
	
		
			
				|  |  | +    log_fn(LOG_DEBUG,"Considering exit policy %s:%s",tmpe->address, tmpe->port);
 | 
	
		
			
				|  |  |      if(inet_aton(tmpe->address,&in) == 0) { /* malformed IP. reject. */
 | 
	
		
			
				|  |  |        log_fn(LOG_WARNING,"Malformed IP %s in exit policy. Rejecting.",tmpe->address);
 | 
	
		
			
				|  |  |        return -1;
 | 
	
		
			
				|  |  |      }
 | 
	
		
			
				|  |  | -    if(conn->addr == ntohl(in.s_addr) &&
 | 
	
		
			
				|  |  | +    if((!strcmp(tmpe->address,"*") || conn->addr == ntohl(in.s_addr)) &&
 | 
	
		
			
				|  |  |         (!strcmp(tmpe->port,"*") || atoi(tmpe->port) == conn->port)) {
 | 
	
		
			
				|  |  |        log_fn(LOG_INFO,"Address '%s' matches '%s' and port '%s' matches '%d'. %s.",
 | 
	
		
			
				|  |  |            tmpe->address, conn->address,
 | 
	
	
		
			
				|  | @@ -1107,7 +1138,8 @@ int router_rebuild_descriptor(void) {
 | 
	
		
			
				|  |  |    ri->link_pkey = crypto_pk_dup_key(get_link_key());
 | 
	
		
			
				|  |  |    ri->identity_pkey = crypto_pk_dup_key(get_identity_key());
 | 
	
		
			
				|  |  |    ri->bandwidth = options.TotalBandwidth;
 | 
	
		
			
				|  |  | -  ri->exit_policy = NULL; /* XXX implement this. */
 | 
	
		
			
				|  |  | +  ri->exit_policy = NULL; /* zero it out first */
 | 
	
		
			
				|  |  | +  router_add_exit_policy_from_config(ri);
 | 
	
		
			
				|  |  |    if (desc_routerinfo)
 | 
	
		
			
				|  |  |      routerinfo_free(desc_routerinfo);
 | 
	
		
			
				|  |  |    desc_routerinfo = ri;
 |