aboutsummaryrefslogtreecommitdiff
path: root/src/or/connection.c
diff options
context:
space:
mode:
Diffstat (limited to 'src/or/connection.c')
-rw-r--r--src/or/connection.c43
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: