diff --git a/src/or/connection.c b/src/or/connection.c index 3ed6b8bc9f..f72c1ee64c 100644 --- a/src/or/connection.c +++ b/src/or/connection.c @@ -319,30 +319,20 @@ void connection_expire_held_open(void) static int connection_create_listener(const char *bindaddress, uint16_t bindport, int type) { struct sockaddr_in bindaddr; /* where to bind */ connection_t *conn; - char *hostname, *cp; - int usePort; + uint16_t usePort; int s; /* the socket we're going to make */ int one=1; - - cp = strchr(bindaddress, ':'); - if (cp) { - hostname = tor_strndup(bindaddress, cp-bindaddress); - usePort = atoi(cp+1); - } else { - hostname = tor_strdup(bindaddress); - usePort = bindport; - } - memset(&bindaddr,0,sizeof(struct sockaddr_in)); - bindaddr.sin_family = AF_INET; - bindaddr.sin_port = htons((uint16_t) usePort); - if(tor_lookup_hostname(hostname, &(bindaddr.sin_addr.s_addr)) != 0) { - log_fn(LOG_WARN,"Can't resolve BindAddress %s",hostname); - tor_free(hostname); + if (parse_addr_port(bindaddress, NULL, &(bindaddr.sin_addr.s_addr), + &usePort)<0) { + log_fn(LOG_WARN, "Error parsing/resolving BindAddress %s",bindaddress); return -1; } - tor_free(hostname); + if (usePort==0) + usePort = bindport; + bindaddr.sin_family = AF_INET; + bindaddr.sin_port = htons((uint16_t) usePort); s = socket(PF_INET,SOCK_STREAM,IPPROTO_TCP); if (s < 0) { diff --git a/src/or/connection_edge.c b/src/or/connection_edge.c index 40669a555e..20c09e2abe 100644 --- a/src/or/connection_edge.c +++ b/src/or/connection_edge.c @@ -737,7 +737,8 @@ void connection_ap_handshake_socks_reply(connection_t *conn, char *reply, int connection_exit_begin_conn(cell_t *cell, circuit_t *circ) { connection_t *n_stream; relay_header_t rh; - char *colon; + char *address=NULL; + uint16_t port; assert_circuit_ok(circ); relay_header_unpack(&rh, cell->payload); @@ -750,15 +751,13 @@ int connection_exit_begin_conn(cell_t *cell, circuit_t *circ) { log_fn(LOG_WARN,"relay begin cell has no \\0. Dropping."); return 0; } - colon = strchr(cell->payload+RELAY_HEADER_SIZE, ':'); - if(!colon) { - log_fn(LOG_WARN,"relay begin cell has no colon. Dropping."); + if (parse_addr_port(cell->payload+RELAY_HEADER_SIZE, &address, NULL,&port)<0){ + log_fn(LOG_WARN,"Unable to parse addr:port in relay begin cell. Dropping."); return 0; } - *colon = 0; - - if(!atoi(colon+1)) { /* bad port */ - log_fn(LOG_WARN,"relay begin cell has invalid port '%s'. Dropping.", colon+1); + if (port==0) { + log_fn(LOG_WARN,"Missing port in relay begin cell. Dropping."); + tor_free(address); return 0; } @@ -767,7 +766,7 @@ int connection_exit_begin_conn(cell_t *cell, circuit_t *circ) { n_stream->purpose = EXIT_PURPOSE_CONNECT; n_stream->stream_id = rh.stream_id; - n_stream->port = atoi(colon+1); + n_stream->port = port; /* leave n_stream->s at -1, because it's not yet valid */ n_stream->package_window = STREAMWINDOW_START; n_stream->deliver_window = STREAMWINDOW_START; @@ -784,6 +783,7 @@ int connection_exit_begin_conn(cell_t *cell, circuit_t *circ) { connection_edge_end(n_stream, END_STREAM_REASON_EXITPOLICY, n_stream->cpath_layer); connection_free(n_stream); circuit_mark_for_close(circ); /* knock the whole thing down, somebody screwed up */ + tor_free(address); return 0; } assert_circuit_ok(circ); @@ -796,9 +796,10 @@ int connection_exit_begin_conn(cell_t *cell, circuit_t *circ) { assert_circuit_ok(circ); connection_exit_connect(n_stream); + tor_free(address); return 0; } - n_stream->address = tor_strdup(cell->payload + RELAY_HEADER_SIZE); + n_stream->address = address; n_stream->state = EXIT_CONN_STATE_RESOLVEFAILED; /* default to failed, change in dns_resolve if it turns out not to fail */ diff --git a/src/or/rendservice.c b/src/or/rendservice.c index 3a8fdbf666..06014df53a 100644 --- a/src/or/rendservice.c +++ b/src/or/rendservice.c @@ -127,9 +127,10 @@ static void add_service(rend_service_t *service) */ static rend_service_port_config_t *parse_port_config(const char *string) { - int virtport, realport, r; - struct in_addr addr; - char *endptr, *colon, *addrstring; + int virtport; + uint16_t realport; + uint32_t addr; + char *endptr; rend_service_port_config_t *result; virtport = (int) strtol(string, &endptr, 10); @@ -145,45 +146,28 @@ static rend_service_port_config_t *parse_port_config(const char *string) if (!*string) { /* No addr:port part; use default. */ realport = virtport; - addr.s_addr = htonl(0x7F000001u); /* 127.0.0.1 */ - } else { - colon = strchr(string, ':'); - if (colon) { - /* Try to parse addr:port. */ - addrstring = tor_strndup(string, colon-string); - r = tor_inet_aton(addrstring, &addr); - tor_free(addrstring); - if (!r) { - log_fn(LOG_WARN,"Unparseable address in hidden service port configuration"); - return NULL; - } - realport = strtol(colon+1, &endptr, 10); - if (*endptr) { - log_fn(LOG_WARN,"Unparseable or missing port in hidden service port configuration."); - return NULL; - } - } else if (strchr(string, '.') && tor_inet_aton(string, &addr)) { - /* We have addr; use deafult port. */ - realport = virtport; - } else { - /* No addr:port, no addr -- must be port. */ - realport = strtol(string, &endptr, 10); - if (*endptr) { - log_fn(LOG_WARN, "Unparseable of missing port in hidden service port configuration."); - return NULL; - } - addr.s_addr = htonl(0x7F000001u); /* Default to 127.0.0.1 */ + addr = 0x7F000001u; /* 127.0.0.1 */ + } else if (strchr(string, ':') || strchr(string, '.')) { + if (parse_addr_port(string, NULL, &addr, &realport)<0) { + log_fn(LOG_WARN,"Unparseable address in hidden service port configuration"); + return NULL; } - } - if (realport < 1 || realport > 65535) { - log_fn(LOG_WARN, "Port out of range in hidden service port configuration."); - return NULL; + if (!realport) + realport = virtport; + } else { + /* No addr:port, no addr -- must be port. */ + realport = strtol(string, &endptr, 10); + if (*endptr) { + log_fn(LOG_WARN, "Unparseable of missing port in hidden service port configuration."); + return NULL; + } + addr = 0x7F000001u; /* Default to 127.0.0.1 */ } result = tor_malloc(sizeof(rend_service_port_config_t)); result->virtual_port = virtport; result->real_port = realport; - result->real_address = (uint32_t) ntohl(addr.s_addr); + result->real_address = addr; return result; }