summaryrefslogtreecommitdiff
path: root/src/or/dnsserv.c
diff options
context:
space:
mode:
authorNick Mathewson <nickm@torproject.org>2007-07-10 17:13:24 +0000
committerNick Mathewson <nickm@torproject.org>2007-07-10 17:13:24 +0000
commit77053147771164dd53c78bef1d27fb2be180eb5d (patch)
treee1d7278cb9e135552c5216d3831f7ce285431c1e /src/or/dnsserv.c
parentef246793d36e0cf5f2493b5b43ccac1e5677ad55 (diff)
downloadtor-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.c116
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;
}