diff options
Diffstat (limited to 'src/or/connection.c')
-rw-r--r-- | src/or/connection.c | 43 |
1 files changed, 36 insertions, 7 deletions
diff --git a/src/or/connection.c b/src/or/connection.c index 5ca2744778..daafc7d7c0 100644 --- a/src/or/connection.c +++ b/src/or/connection.c @@ -48,6 +48,7 @@ conn_type_to_string(int type) case CONN_TYPE_AP_TRANS_LISTENER: return "Transparent pf/netfilter listener"; case CONN_TYPE_AP_NATD_LISTENER: return "Transparent natd listener"; + case CONN_TYPE_AP_DNS_LISTENER: return "DNS listener"; case CONN_TYPE_AP: return "Socks"; case CONN_TYPE_DIR_LISTENER: return "Directory listener"; case CONN_TYPE_DIR: return "Directory"; @@ -74,6 +75,7 @@ conn_state_to_string(int type, int state) case CONN_TYPE_AP_LISTENER: case CONN_TYPE_AP_TRANS_LISTENER: case CONN_TYPE_AP_NATD_LISTENER: + case CONN_TYPE_AP_DNS_LISTENER: case CONN_TYPE_DIR_LISTENER: case CONN_TYPE_CONTROL_LISTENER: if (state == LISTENER_STATE_READY) @@ -240,6 +242,9 @@ connection_unregister_events(connection_t *conn) log_warn(LD_BUG, "Error removing write event for %d", conn->s); tor_free(conn->write_event); } + if (conn->dns_server_port) { + dnsserv_close_listener(conn); + } } /** Deallocate memory used by <b>conn</b>. Deallocate its buffers if @@ -491,6 +496,12 @@ connection_about_to_close_connection(connection_t *conn) " set end_reason.", conn->marked_for_close_file, conn->marked_for_close); } + if (edge_conn->dns_server_request) { + log_warn(LD_BUG,"Closing stream (marked at %s:%d) without having" + " replied to DNS request.", + conn->marked_for_close_file, conn->marked_for_close); + dnsserv_reject_request(edge_conn); + } control_event_stream_status(edge_conn, STREAM_EVENT_CLOSED, edge_conn->end_reason); circ = circuit_get_by_edge_conn(edge_conn); @@ -632,6 +643,7 @@ connection_create_listener(const char *listenaddress, uint16_t listenport, #ifndef MS_WINDOWS int one=1; #endif + int is_tcp = (type != CONN_TYPE_AP_DNS_LISTENER); memset(&listenaddr,0,sizeof(struct sockaddr_in)); if (parse_addr_port(LOG_WARN, listenaddress, &address, &addr, &usePort)<0) { @@ -658,7 +670,9 @@ connection_create_listener(const char *listenaddress, uint16_t listenport, return NULL; } - s = tor_open_socket(PF_INET,SOCK_STREAM,IPPROTO_TCP); + s = tor_open_socket(PF_INET, + is_tcp ? SOCK_STREAM : SOCK_DGRAM, + is_tcp ? IPPROTO_TCP: IPPROTO_UDP); if (s < 0) { log_warn(LD_NET,"Socket creation failed."); goto err; @@ -683,11 +697,13 @@ connection_create_listener(const char *listenaddress, uint16_t listenport, goto err; } - if (listen(s,SOMAXCONN) < 0) { - log_warn(LD_NET, "Could not listen on %s:%u: %s", address, usePort, - tor_socket_strerror(tor_socket_errno(s))); - tor_close_socket(s); - goto err; + if (is_tcp) { + if (listen(s,SOMAXCONN) < 0) { + log_warn(LD_NET, "Could not listen on %s:%u: %s", address, usePort, + tor_socket_strerror(tor_socket_errno(s))); + tor_close_socket(s); + goto err; + } } set_socket_nonblocking(s); @@ -708,7 +724,12 @@ connection_create_listener(const char *listenaddress, uint16_t listenport, conn_type_to_string(type), usePort); conn->state = LISTENER_STATE_READY; - connection_start_reading(conn); + if (is_tcp) { + connection_start_reading(conn); + } else { + tor_assert(type == CONN_TYPE_AP_DNS_LISTENER); + dnsserv_configure_listener(conn); + } return conn; @@ -1125,6 +1146,10 @@ retry_all_listeners(int force, smartlist_t *replaced_conns, options->NatdPort, "127.0.0.1", force, replaced_conns, new_conns, 0)<0) return -1; + if (retry_listeners(CONN_TYPE_AP_DNS_LISTENER, options->DNSListenAddress, + options->DNSPort, "127.0.0.1", force, + replaced_conns, new_conns, 0)<0) + return -1; if (retry_listeners(CONN_TYPE_CONTROL_LISTENER, options->ControlListenAddress, options->ControlPort, "127.0.0.1", force, @@ -1535,6 +1560,10 @@ connection_handle_read(connection_t *conn) return connection_handle_listener_read(conn, CONN_TYPE_DIR); case CONN_TYPE_CONTROL_LISTENER: return connection_handle_listener_read(conn, CONN_TYPE_CONTROL); + case CONN_TYPE_AP_DNS_LISTENER: + /* This should never happen; eventdns.c handles the reads here. */ + tor_fragile_assert(); + return 0; } loop_again: |