|
@@ -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:
|