diff options
author | Nick Mathewson <nickm@torproject.org> | 2007-07-10 17:13:24 +0000 |
---|---|---|
committer | Nick Mathewson <nickm@torproject.org> | 2007-07-10 17:13:24 +0000 |
commit | 77053147771164dd53c78bef1d27fb2be180eb5d (patch) | |
tree | e1d7278cb9e135552c5216d3831f7ce285431c1e /src/or/dnsserv.c | |
parent | ef246793d36e0cf5f2493b5b43ccac1e5677ad55 (diff) | |
download | tor-77053147771164dd53c78bef1d27fb2be180eb5d.tar.gz tor-77053147771164dd53c78bef1d27fb2be180eb5d.zip |
r13637@catbus: nickm | 2007-07-06 14:24:27 -0400
fix copy-paste error in config message src/or/config.c . Apply
initial (but pared-down) version of launch-resolve-via-controller
patch from Robert Hogan.
svn:r10780
Diffstat (limited to 'src/or/dnsserv.c')
-rw-r--r-- | src/or/dnsserv.c | 116 |
1 files changed, 105 insertions, 11 deletions
diff --git a/src/or/dnsserv.c b/src/or/dnsserv.c index 268f44a0ea..b1262cc7c5 100644 --- a/src/or/dnsserv.c +++ b/src/or/dnsserv.c @@ -145,6 +145,78 @@ evdns_server_callback(struct evdns_server_request *req, void *_data) tor_free(q_name); } +/* Helper function: called whenever the client sends a resolve request to our + * controller. We need to eventually answer the request <b>req</b>. + */ +void +dnsserv_launch_request(const char *name) +{ + edge_connection_t *conn; + struct evdns_server_request *server_req; + struct in_addr in; + char *q_name; + int i; + int is_ip_address; + + /* Make a new dummy AP connection, and attach the request to it. */ + conn = TO_EDGE_CONN(connection_new(CONN_TYPE_AP, AF_INET)); + conn->_base.state = AP_CONN_STATE_RESOLVE_WAIT; + + is_ip_address = tor_inet_aton(name, &in); + + if (!is_ip_address) + conn->socks_request->command = SOCKS_COMMAND_RESOLVE_CONTROL; + else + conn->socks_request->command = SOCKS_COMMAND_RESOLVE_PTR_CONTROL; + + strlcpy(conn->socks_request->address, name, + sizeof(conn->socks_request->address)); + + server_req = malloc(sizeof(struct evdns_server_request)); + if (server_req == NULL) return; + memset(server_req, 0, sizeof(struct evdns_server_request)); + + server_req->flags = 0; + server_req->nquestions = 0; + + server_req->questions = malloc(sizeof(struct evdns_server_question *) * 1); + if (server_req->questions == NULL) + return; + + for ( i = 0; i < 1; ++i) { + struct evdns_server_question *q; + int namelen; + namelen = strlen(name); + q = malloc(sizeof(struct evdns_server_question) + namelen); + if (!q) + return; + if (!is_ip_address) + q->type = EVDNS_TYPE_A; + else + q->type = EVDNS_TYPE_PTR; + q->class = EVDNS_CLASS_INET; + memcpy(q->name, name, namelen+1); + server_req->questions[server_req->nquestions++] = q; + } + + conn->dns_server_request = server_req; + + connection_add(TO_CONN(conn)); + + /* Now, throw the connection over to get rewritten (which will answer it + * immediately if it's in the cache, or completely bogus, or automapped), + * and then attached to a circuit. */ + log_info(LD_APP, "Passing request for %s to rewrite_and_attach.", + escaped_safe_str(name)); + q_name = tor_strdup(name); /* q could be freed in rewrite_and_attach */ + connection_ap_handshake_rewrite_and_attach(conn, NULL, NULL); + /* Now, the connection is marked if it was bad. */ + + log_info(LD_APP, "Passed request for %s to rewrite_and_attach.", + escaped_safe_str(q_name)); + tor_free(q_name); +} + /** If there is a pending request on <b>conn</b> that's waiting for an answer, * send back an error and free the request. */ void @@ -181,27 +253,49 @@ dnsserv_resolved(edge_connection_t *conn, * or more of the questions in the request); then, call * evdns_server_request_respond. */ if (answer_type == RESOLVED_TYPE_IPV6) { - log_info(LD_APP, "Got an IPv6 answer; that's not implemented."); - err = DNS_ERR_NOTIMPL; + if (SOCKS_COMMAND_IS_RESOLVE_CONTROL(conn->socks_request->command)) + handle_control_resolve_response(req->questions[0]->name, + "IPv6 not implemented"); + else { + log_info(LD_APP, "Got an IPv6 answer; that's not implemented."); + err = DNS_ERR_NOTIMPL; + } } else if (answer_type == RESOLVED_TYPE_IPV4 && answer_len == 4 && conn->socks_request->command == SOCKS_COMMAND_RESOLVE) { - evdns_server_request_add_a_reply(req, - conn->socks_request->address, - 1, (char*)answer, ttl); + if (SOCKS_COMMAND_IS_RESOLVE_CONTROL(conn->socks_request->command)) + handle_control_resolve_response(req->questions[0]->name, + tor_dup_addr(ntohl(get_uint32(answer)))); + else + evdns_server_request_add_a_reply(req, + conn->socks_request->address, + 1, (char*)answer, ttl); } else if (answer_type == RESOLVED_TYPE_HOSTNAME && conn->socks_request->command == SOCKS_COMMAND_RESOLVE_PTR) { - char *ans = tor_strndup(answer, answer_len); - evdns_server_request_add_ptr_reply(req, NULL, + if (SOCKS_COMMAND_IS_RESOLVE_CONTROL(conn->socks_request->command)) + handle_control_resolve_response(req->questions[0]->name, answer); + else { + char *ans = tor_strndup(answer, answer_len); + evdns_server_request_add_ptr_reply(req, NULL, conn->socks_request->address, (char*)answer, ttl); - tor_free(ans); + tor_free(ans); + } } else if (answer_type == RESOLVED_TYPE_ERROR) { - err = DNS_ERR_NOTEXIST; + if (SOCKS_COMMAND_IS_RESOLVE_CONTROL(conn->socks_request->command)) + handle_control_resolve_response(req->questions[0]->name, "Unknown Host"); + else + err = DNS_ERR_NOTEXIST; } else { /* answer_type == RESOLVED_TYPE_ERROR_TRANSIENT */ - err = DNS_ERR_SERVERFAILED; + if (SOCKS_COMMAND_IS_RESOLVE_CONTROL(conn->socks_request->command)) + handle_control_resolve_response(req->questions[0]->name, + "Temporary Error"); + else + err = DNS_ERR_SERVERFAILED; } - evdns_server_request_respond(req, err); + if (!SOCKS_COMMAND_IS_RESOLVE_CONTROL(conn->socks_request->command)) + evdns_server_request_respond(req, err); + conn->dns_server_request = NULL; } |