Loading ChangeLog +2 −0 Original line number Diff line number Diff line Loading @@ -15,6 +15,8 @@ Changes in version 0.2.0.3-alpha - 2007-??-?? match requests to applications. (Patch from Robert Hogan.) - Report address and port correctly on connections to DNSPort. (Patch from Robert Hogan.) - Add a RESOLVE command to launch hostname lookups. (Original patch from Robert Hogan.) o Performance improvements (win32): - Use Critical Sections rather than Mutexes for synchronizing threads Loading doc/TODO +1 −1 Original line number Diff line number Diff line Loading @@ -206,7 +206,7 @@ Things we'd like to do in 0.2.0.x: o Make it handle .onion and .exit correctly. - Document. - Handle TCP DNS requests too? - Add a way to request DNS resolves from the controller. o Add a way to request DNS resolves from the controller. - A better UI for authority ops. - Follow weasel's proposal, crossed with mixminion dir config format - Write a proposal Loading doc/spec/control-spec.txt +14 −2 Original line number Diff line number Diff line Loading @@ -683,6 +683,18 @@ $Id$ stable releases after 0.1.2.2-alpha, the release where it was first available.) 3.20. RESOLVE The syntax is "RESOLVE" *Option *Address CRLF Option = "mode=reverse" Address = a hostname or IPv4 address This command launches a remote hostname lookup request for every specified request (or reverse lookup if "mode=reverse" is specified). Note that the request is done in the background: to see the answers, your controller will need to listen for ADDRMAP events; see 4.1.7 below. 4. Replies Reply codes follow the same 3-character format as used by SMTP, with the Loading Loading @@ -947,8 +959,8 @@ $Id$ Expiry is expressed as the local time (rather than GMT). [XXX We should rename this to ADDRESSMAP. -RD] [Why? Surely it can't be worth the compatibility issues. -NM] These events are generated when a new address mapping is entered in the cache, or when the answer for a RESOLVE command is found. 4.1.8. Descriptors uploaded to us in our role as authoritative dirserver Loading src/or/connection_edge.c +81 −18 Original line number Diff line number Diff line Loading @@ -59,7 +59,7 @@ _connection_mark_unattached_ap(edge_connection_t *conn, int endreason, else if (SOCKS_COMMAND_IS_RESOLVE(conn->socks_request->command)) connection_ap_handshake_socks_resolved(conn, RESOLVED_TYPE_ERROR_TRANSIENT, 0, NULL, -1); 0, NULL, -1, -1); else /* unknown or no handshake at all. send no response. */ conn->socks_request->has_finished = 1; } Loading Loading @@ -655,23 +655,30 @@ addressmap_free_all(void) * more rewrites; but don't get into an infinite loop. * Don't write more than maxlen chars into address. Return true if the * address changed; false otherwise. * DOCDOC expires_out */ int addressmap_rewrite(char *address, size_t maxlen) addressmap_rewrite(char *address, size_t maxlen, time_t *expires_out) { addressmap_entry_t *ent; int rewrites; char *cp; time_t expires = TIME_MAX; for (rewrites = 0; rewrites < 16; rewrites++) { ent = strmap_get(addressmap, address); if (!ent || !ent->new_address) if (!ent || !ent->new_address) { if (expires_out) *expires_out = expires; return (rewrites > 0); /* done, no rewrite needed */ } cp = tor_strdup(escaped_safe_str(ent->new_address)); log_info(LD_APP, "Addressmap: rewriting %s to %s", escaped_safe_str(address), cp); if (ent->expires > 1 && ent->expires < expires) expires = ent->expires; tor_free(cp); strlcpy(address, ent->new_address, maxlen); } Loading @@ -679,14 +686,17 @@ addressmap_rewrite(char *address, size_t maxlen) "Loop detected: we've rewritten %s 16 times! Using it as-is.", escaped_safe_str(address)); /* it's fine to rewrite a rewrite, but don't loop forever */ if (expires_out) *expires_out = TIME_MAX; return 1; } /** If we have a cached reverse DNS entry for the address stored in the * <b>maxlen</b>-byte buffer <b>address</b> (typically, a dotted quad) then * rewrite to the cached value and return 1. Otherwise return 0. */ * rewrite to the cached value and return 1. Otherwise return 0. * DOCDOC expires_out */ static int addressmap_rewrite_reverse(char *address, size_t maxlen) addressmap_rewrite_reverse(char *address, size_t maxlen, time_t *expires_out) { size_t len = maxlen + 16; char *s = tor_malloc(len), *cp; Loading @@ -702,6 +712,10 @@ addressmap_rewrite_reverse(char *address, size_t maxlen) strlcpy(address, ent->new_address, maxlen); r = 1; } if (expires_out) *expires_out = (ent && ent->expires > 1) ? ent->expires : TIME_MAX; tor_free(s); return r; } Loading Loading @@ -765,7 +779,7 @@ addressmap_register(const char *address, char *new_address, time_t expires) log_info(LD_CONFIG, "Addressmap: (re)mapped '%s' to '%s'", safe_str(address), safe_str(ent->new_address)); control_event_address_mapped(address, ent->new_address, expires); control_event_address_mapped(address, ent->new_address, expires, NULL); } /** An attempt to resolve <b>address</b> failed at some OR. Loading Loading @@ -1182,6 +1196,7 @@ connection_ap_handshake_rewrite_and_attach(edge_connection_t *conn, struct in_addr addr_tmp; int automap = 0; char orig_address[MAX_SOCKS_ADDR_LEN]; time_t map_expires = TIME_MAX; tor_strlower(socks->address); /* normalize it */ strlcpy(orig_address, socks->address, sizeof(orig_address)); Loading Loading @@ -1209,12 +1224,14 @@ connection_ap_handshake_rewrite_and_attach(edge_connection_t *conn, } if (socks->command == SOCKS_COMMAND_RESOLVE_PTR) { if (addressmap_rewrite_reverse(socks->address, sizeof(socks->address))) { if (addressmap_rewrite_reverse(socks->address, sizeof(socks->address), &map_expires)) { char *result = tor_strdup(socks->address); /* remember _what_ is supposed to have been resolved. */ strlcpy(socks->address, orig_address, sizeof(socks->address)); connection_ap_handshake_socks_resolved(conn, RESOLVED_TYPE_HOSTNAME, strlen(result), result, -1); strlen(result), result, -1, map_expires); connection_mark_unattached_ap(conn, END_STREAM_REASON_DONE | END_STREAM_REASON_FLAG_ALREADY_SOCKS_REPLIED); Loading @@ -1222,7 +1239,8 @@ connection_ap_handshake_rewrite_and_attach(edge_connection_t *conn, } } else if (!automap) { /* For address map controls, remap the address. */ if (addressmap_rewrite(socks->address, sizeof(socks->address))) { if (addressmap_rewrite(socks->address, sizeof(socks->address), &map_expires)) { control_event_stream_status(conn, STREAM_EVENT_REMAP, REMAP_STREAM_SOURCE_CACHE); } Loading Loading @@ -1309,7 +1327,7 @@ connection_ap_handshake_rewrite_and_attach(edge_connection_t *conn, escaped(socks->address)); connection_ap_handshake_socks_resolved(conn, RESOLVED_TYPE_ERROR_TRANSIENT, 0,NULL,-1); 0,NULL,-1,TIME_MAX); connection_mark_unattached_ap(conn, END_STREAM_REASON_SOCKSPROTOCOL | END_STREAM_REASON_FLAG_ALREADY_SOCKS_REPLIED); Loading @@ -1321,7 +1339,7 @@ connection_ap_handshake_rewrite_and_attach(edge_connection_t *conn, /* remember _what_ is supposed to have been resolved. */ strlcpy(socks->address, orig_address, sizeof(socks->address)); connection_ap_handshake_socks_resolved(conn,RESOLVED_TYPE_IPV4,4, (char*)&answer,-1); (char*)&answer,-1,map_expires); connection_mark_unattached_ap(conn, END_STREAM_REASON_DONE | END_STREAM_REASON_FLAG_ALREADY_SOCKS_REPLIED); Loading Loading @@ -1382,7 +1400,7 @@ connection_ap_handshake_rewrite_and_attach(edge_connection_t *conn, log_warn(LD_APP, "Resolve requests to hidden services not allowed. Failing."); connection_ap_handshake_socks_resolved(conn,RESOLVED_TYPE_ERROR, 0,NULL,-1); 0,NULL,-1,TIME_MAX); connection_mark_unattached_ap(conn, END_STREAM_REASON_SOCKSPROTOCOL | END_STREAM_REASON_FLAG_ALREADY_SOCKS_REPLIED); Loading Loading @@ -1962,17 +1980,52 @@ connection_ap_make_link(char *address, uint16_t port, return conn; } /** DOCDOC */ static void tell_controller_about_resolved_result(edge_connection_t *conn, int answer_type, size_t answer_len, const char *answer, int ttl, time_t expires) { if (ttl >= 0 && (answer_type == RESOLVED_TYPE_IPV4 || answer_type == RESOLVED_TYPE_HOSTNAME)) { return; /* we already told the controller. */ } else if (answer_type == RESOLVED_TYPE_IPV4 && answer_len >= 4) { struct in_addr in; char buf[INET_NTOA_BUF_LEN]; in.s_addr = get_uint32(answer); tor_inet_ntoa(&in, buf, sizeof(buf)); control_event_address_mapped(conn->socks_request->address, buf, expires, NULL); } else if (answer_type == RESOLVED_TYPE_HOSTNAME && answer_len <256) { char *cp = tor_strndup(answer, answer_len); control_event_address_mapped(conn->socks_request->address, cp, expires, NULL); tor_free(cp); } else { control_event_address_mapped(conn->socks_request->address, "<error>", time(NULL)+ttl, "error=yes"); } } /** Send an answer to an AP connection that has requested a DNS lookup * via SOCKS. The type should be one of RESOLVED_TYPE_(IPV4|IPV6|HOSTNAME) or * -1 for unreachable; the answer should be in the format specified * in the socks extensions document. * DOCDOC expires **/ void connection_ap_handshake_socks_resolved(edge_connection_t *conn, int answer_type, size_t answer_len, const char *answer, int ttl) int ttl, time_t expires) { char buf[384]; size_t replylen; Loading @@ -1992,11 +2045,21 @@ connection_ap_handshake_socks_resolved(edge_connection_t *conn, } } if (conn->is_dns_request) { if (conn->dns_server_request) { /* We had a request on our DNS port: answer it. */ dnsserv_resolved(conn, answer_type, answer_len, answer, ttl); conn->socks_request->has_finished = 1; return; } else { /* This must be a request from the controller. We already sent * a mapaddress if there's a ttl. */ tell_controller_about_resolved_result(conn, answer_type, answer_len, answer, ttl, expires); conn->socks_request->has_finished = 1; return; } /* XXXX020 are we freeing conn anywhere? */ } if (conn->socks_request->socks_version == 4) { Loading src/or/control.c +21 −10 Original line number Diff line number Diff line Loading @@ -2221,9 +2221,10 @@ handle_control_resolve(control_connection_t *conn, uint32_t len, const char *body) { smartlist_t *args; int is_reverse = 0; (void) len; /* body is nul-terminated; it's safe to ignore the length */ if (!(conn->event_mask & EVENT_ADDRMAP)) { if (!(conn->event_mask & (1L<<EVENT_ADDRMAP))) { log_warn(LD_CONTROL, "Controller asked us to resolve an address, but " "isn't listening for ADDRMAP events. It probably won't see " "the answer."); Loading @@ -2231,8 +2232,15 @@ handle_control_resolve(control_connection_t *conn, uint32_t len, args = smartlist_create(); smartlist_split_string(args, body, " ", SPLIT_SKIP_SPACE|SPLIT_IGNORE_BLANK, 0); if (smartlist_len(args) && !strcasecmp(smartlist_get(args, 0), "mode=reverse")) { char *cp = smartlist_get(args, 0); smartlist_del_keeporder(args, 0); tor_free(cp); is_reverse = 1; } SMARTLIST_FOREACH(args, const char *, arg, { evdns_server_control(arg); dnsserv_launch_request(arg, is_reverse); }); SMARTLIST_FOREACH(args, char *, cp, tor_free(cp)); Loading Loading @@ -3058,22 +3066,25 @@ control_event_descriptors_changed(smartlist_t *routers) } /** Called whenever an address mapping on <b>from<b> from changes to <b>to</b>. * <b>expires</b> values less than 3 are special; see connection_edge.c. */ * <b>expires</b> values less than 3 are special; see connection_edge.c. * DOCDOC source. */ int control_event_address_mapped(const char *from, const char *to, time_t expires) control_event_address_mapped(const char *from, const char *to, time_t expires, const char *error) { if (!EVENT_IS_INTERESTING(EVENT_ADDRMAP)) return 0; if (expires < 3) send_control_event(EVENT_ADDRMAP, ALL_NAMES, "650 ADDRMAP %s %s NEVER\r\n", from, to); if (expires < 3 || expires == TIME_MAX) send_control_event_extended(EVENT_ADDRMAP, ALL_NAMES, "650 ADDRMAP %s %s NEVER@%s\r\n", from, to, error); else { char buf[ISO_TIME_LEN+1]; format_local_iso_time(buf,expires); send_control_event(EVENT_ADDRMAP, ALL_NAMES, "650 ADDRMAP %s %s \"%s\"\r\n", from, to, buf); send_control_event_extended(EVENT_ADDRMAP, ALL_NAMES, "650 ADDRMAP %s %s \"%s\"@%s\r\n", from, to, buf, error); } return 0; Loading Loading
ChangeLog +2 −0 Original line number Diff line number Diff line Loading @@ -15,6 +15,8 @@ Changes in version 0.2.0.3-alpha - 2007-??-?? match requests to applications. (Patch from Robert Hogan.) - Report address and port correctly on connections to DNSPort. (Patch from Robert Hogan.) - Add a RESOLVE command to launch hostname lookups. (Original patch from Robert Hogan.) o Performance improvements (win32): - Use Critical Sections rather than Mutexes for synchronizing threads Loading
doc/TODO +1 −1 Original line number Diff line number Diff line Loading @@ -206,7 +206,7 @@ Things we'd like to do in 0.2.0.x: o Make it handle .onion and .exit correctly. - Document. - Handle TCP DNS requests too? - Add a way to request DNS resolves from the controller. o Add a way to request DNS resolves from the controller. - A better UI for authority ops. - Follow weasel's proposal, crossed with mixminion dir config format - Write a proposal Loading
doc/spec/control-spec.txt +14 −2 Original line number Diff line number Diff line Loading @@ -683,6 +683,18 @@ $Id$ stable releases after 0.1.2.2-alpha, the release where it was first available.) 3.20. RESOLVE The syntax is "RESOLVE" *Option *Address CRLF Option = "mode=reverse" Address = a hostname or IPv4 address This command launches a remote hostname lookup request for every specified request (or reverse lookup if "mode=reverse" is specified). Note that the request is done in the background: to see the answers, your controller will need to listen for ADDRMAP events; see 4.1.7 below. 4. Replies Reply codes follow the same 3-character format as used by SMTP, with the Loading Loading @@ -947,8 +959,8 @@ $Id$ Expiry is expressed as the local time (rather than GMT). [XXX We should rename this to ADDRESSMAP. -RD] [Why? Surely it can't be worth the compatibility issues. -NM] These events are generated when a new address mapping is entered in the cache, or when the answer for a RESOLVE command is found. 4.1.8. Descriptors uploaded to us in our role as authoritative dirserver Loading
src/or/connection_edge.c +81 −18 Original line number Diff line number Diff line Loading @@ -59,7 +59,7 @@ _connection_mark_unattached_ap(edge_connection_t *conn, int endreason, else if (SOCKS_COMMAND_IS_RESOLVE(conn->socks_request->command)) connection_ap_handshake_socks_resolved(conn, RESOLVED_TYPE_ERROR_TRANSIENT, 0, NULL, -1); 0, NULL, -1, -1); else /* unknown or no handshake at all. send no response. */ conn->socks_request->has_finished = 1; } Loading Loading @@ -655,23 +655,30 @@ addressmap_free_all(void) * more rewrites; but don't get into an infinite loop. * Don't write more than maxlen chars into address. Return true if the * address changed; false otherwise. * DOCDOC expires_out */ int addressmap_rewrite(char *address, size_t maxlen) addressmap_rewrite(char *address, size_t maxlen, time_t *expires_out) { addressmap_entry_t *ent; int rewrites; char *cp; time_t expires = TIME_MAX; for (rewrites = 0; rewrites < 16; rewrites++) { ent = strmap_get(addressmap, address); if (!ent || !ent->new_address) if (!ent || !ent->new_address) { if (expires_out) *expires_out = expires; return (rewrites > 0); /* done, no rewrite needed */ } cp = tor_strdup(escaped_safe_str(ent->new_address)); log_info(LD_APP, "Addressmap: rewriting %s to %s", escaped_safe_str(address), cp); if (ent->expires > 1 && ent->expires < expires) expires = ent->expires; tor_free(cp); strlcpy(address, ent->new_address, maxlen); } Loading @@ -679,14 +686,17 @@ addressmap_rewrite(char *address, size_t maxlen) "Loop detected: we've rewritten %s 16 times! Using it as-is.", escaped_safe_str(address)); /* it's fine to rewrite a rewrite, but don't loop forever */ if (expires_out) *expires_out = TIME_MAX; return 1; } /** If we have a cached reverse DNS entry for the address stored in the * <b>maxlen</b>-byte buffer <b>address</b> (typically, a dotted quad) then * rewrite to the cached value and return 1. Otherwise return 0. */ * rewrite to the cached value and return 1. Otherwise return 0. * DOCDOC expires_out */ static int addressmap_rewrite_reverse(char *address, size_t maxlen) addressmap_rewrite_reverse(char *address, size_t maxlen, time_t *expires_out) { size_t len = maxlen + 16; char *s = tor_malloc(len), *cp; Loading @@ -702,6 +712,10 @@ addressmap_rewrite_reverse(char *address, size_t maxlen) strlcpy(address, ent->new_address, maxlen); r = 1; } if (expires_out) *expires_out = (ent && ent->expires > 1) ? ent->expires : TIME_MAX; tor_free(s); return r; } Loading Loading @@ -765,7 +779,7 @@ addressmap_register(const char *address, char *new_address, time_t expires) log_info(LD_CONFIG, "Addressmap: (re)mapped '%s' to '%s'", safe_str(address), safe_str(ent->new_address)); control_event_address_mapped(address, ent->new_address, expires); control_event_address_mapped(address, ent->new_address, expires, NULL); } /** An attempt to resolve <b>address</b> failed at some OR. Loading Loading @@ -1182,6 +1196,7 @@ connection_ap_handshake_rewrite_and_attach(edge_connection_t *conn, struct in_addr addr_tmp; int automap = 0; char orig_address[MAX_SOCKS_ADDR_LEN]; time_t map_expires = TIME_MAX; tor_strlower(socks->address); /* normalize it */ strlcpy(orig_address, socks->address, sizeof(orig_address)); Loading Loading @@ -1209,12 +1224,14 @@ connection_ap_handshake_rewrite_and_attach(edge_connection_t *conn, } if (socks->command == SOCKS_COMMAND_RESOLVE_PTR) { if (addressmap_rewrite_reverse(socks->address, sizeof(socks->address))) { if (addressmap_rewrite_reverse(socks->address, sizeof(socks->address), &map_expires)) { char *result = tor_strdup(socks->address); /* remember _what_ is supposed to have been resolved. */ strlcpy(socks->address, orig_address, sizeof(socks->address)); connection_ap_handshake_socks_resolved(conn, RESOLVED_TYPE_HOSTNAME, strlen(result), result, -1); strlen(result), result, -1, map_expires); connection_mark_unattached_ap(conn, END_STREAM_REASON_DONE | END_STREAM_REASON_FLAG_ALREADY_SOCKS_REPLIED); Loading @@ -1222,7 +1239,8 @@ connection_ap_handshake_rewrite_and_attach(edge_connection_t *conn, } } else if (!automap) { /* For address map controls, remap the address. */ if (addressmap_rewrite(socks->address, sizeof(socks->address))) { if (addressmap_rewrite(socks->address, sizeof(socks->address), &map_expires)) { control_event_stream_status(conn, STREAM_EVENT_REMAP, REMAP_STREAM_SOURCE_CACHE); } Loading Loading @@ -1309,7 +1327,7 @@ connection_ap_handshake_rewrite_and_attach(edge_connection_t *conn, escaped(socks->address)); connection_ap_handshake_socks_resolved(conn, RESOLVED_TYPE_ERROR_TRANSIENT, 0,NULL,-1); 0,NULL,-1,TIME_MAX); connection_mark_unattached_ap(conn, END_STREAM_REASON_SOCKSPROTOCOL | END_STREAM_REASON_FLAG_ALREADY_SOCKS_REPLIED); Loading @@ -1321,7 +1339,7 @@ connection_ap_handshake_rewrite_and_attach(edge_connection_t *conn, /* remember _what_ is supposed to have been resolved. */ strlcpy(socks->address, orig_address, sizeof(socks->address)); connection_ap_handshake_socks_resolved(conn,RESOLVED_TYPE_IPV4,4, (char*)&answer,-1); (char*)&answer,-1,map_expires); connection_mark_unattached_ap(conn, END_STREAM_REASON_DONE | END_STREAM_REASON_FLAG_ALREADY_SOCKS_REPLIED); Loading Loading @@ -1382,7 +1400,7 @@ connection_ap_handshake_rewrite_and_attach(edge_connection_t *conn, log_warn(LD_APP, "Resolve requests to hidden services not allowed. Failing."); connection_ap_handshake_socks_resolved(conn,RESOLVED_TYPE_ERROR, 0,NULL,-1); 0,NULL,-1,TIME_MAX); connection_mark_unattached_ap(conn, END_STREAM_REASON_SOCKSPROTOCOL | END_STREAM_REASON_FLAG_ALREADY_SOCKS_REPLIED); Loading Loading @@ -1962,17 +1980,52 @@ connection_ap_make_link(char *address, uint16_t port, return conn; } /** DOCDOC */ static void tell_controller_about_resolved_result(edge_connection_t *conn, int answer_type, size_t answer_len, const char *answer, int ttl, time_t expires) { if (ttl >= 0 && (answer_type == RESOLVED_TYPE_IPV4 || answer_type == RESOLVED_TYPE_HOSTNAME)) { return; /* we already told the controller. */ } else if (answer_type == RESOLVED_TYPE_IPV4 && answer_len >= 4) { struct in_addr in; char buf[INET_NTOA_BUF_LEN]; in.s_addr = get_uint32(answer); tor_inet_ntoa(&in, buf, sizeof(buf)); control_event_address_mapped(conn->socks_request->address, buf, expires, NULL); } else if (answer_type == RESOLVED_TYPE_HOSTNAME && answer_len <256) { char *cp = tor_strndup(answer, answer_len); control_event_address_mapped(conn->socks_request->address, cp, expires, NULL); tor_free(cp); } else { control_event_address_mapped(conn->socks_request->address, "<error>", time(NULL)+ttl, "error=yes"); } } /** Send an answer to an AP connection that has requested a DNS lookup * via SOCKS. The type should be one of RESOLVED_TYPE_(IPV4|IPV6|HOSTNAME) or * -1 for unreachable; the answer should be in the format specified * in the socks extensions document. * DOCDOC expires **/ void connection_ap_handshake_socks_resolved(edge_connection_t *conn, int answer_type, size_t answer_len, const char *answer, int ttl) int ttl, time_t expires) { char buf[384]; size_t replylen; Loading @@ -1992,11 +2045,21 @@ connection_ap_handshake_socks_resolved(edge_connection_t *conn, } } if (conn->is_dns_request) { if (conn->dns_server_request) { /* We had a request on our DNS port: answer it. */ dnsserv_resolved(conn, answer_type, answer_len, answer, ttl); conn->socks_request->has_finished = 1; return; } else { /* This must be a request from the controller. We already sent * a mapaddress if there's a ttl. */ tell_controller_about_resolved_result(conn, answer_type, answer_len, answer, ttl, expires); conn->socks_request->has_finished = 1; return; } /* XXXX020 are we freeing conn anywhere? */ } if (conn->socks_request->socks_version == 4) { Loading
src/or/control.c +21 −10 Original line number Diff line number Diff line Loading @@ -2221,9 +2221,10 @@ handle_control_resolve(control_connection_t *conn, uint32_t len, const char *body) { smartlist_t *args; int is_reverse = 0; (void) len; /* body is nul-terminated; it's safe to ignore the length */ if (!(conn->event_mask & EVENT_ADDRMAP)) { if (!(conn->event_mask & (1L<<EVENT_ADDRMAP))) { log_warn(LD_CONTROL, "Controller asked us to resolve an address, but " "isn't listening for ADDRMAP events. It probably won't see " "the answer."); Loading @@ -2231,8 +2232,15 @@ handle_control_resolve(control_connection_t *conn, uint32_t len, args = smartlist_create(); smartlist_split_string(args, body, " ", SPLIT_SKIP_SPACE|SPLIT_IGNORE_BLANK, 0); if (smartlist_len(args) && !strcasecmp(smartlist_get(args, 0), "mode=reverse")) { char *cp = smartlist_get(args, 0); smartlist_del_keeporder(args, 0); tor_free(cp); is_reverse = 1; } SMARTLIST_FOREACH(args, const char *, arg, { evdns_server_control(arg); dnsserv_launch_request(arg, is_reverse); }); SMARTLIST_FOREACH(args, char *, cp, tor_free(cp)); Loading Loading @@ -3058,22 +3066,25 @@ control_event_descriptors_changed(smartlist_t *routers) } /** Called whenever an address mapping on <b>from<b> from changes to <b>to</b>. * <b>expires</b> values less than 3 are special; see connection_edge.c. */ * <b>expires</b> values less than 3 are special; see connection_edge.c. * DOCDOC source. */ int control_event_address_mapped(const char *from, const char *to, time_t expires) control_event_address_mapped(const char *from, const char *to, time_t expires, const char *error) { if (!EVENT_IS_INTERESTING(EVENT_ADDRMAP)) return 0; if (expires < 3) send_control_event(EVENT_ADDRMAP, ALL_NAMES, "650 ADDRMAP %s %s NEVER\r\n", from, to); if (expires < 3 || expires == TIME_MAX) send_control_event_extended(EVENT_ADDRMAP, ALL_NAMES, "650 ADDRMAP %s %s NEVER@%s\r\n", from, to, error); else { char buf[ISO_TIME_LEN+1]; format_local_iso_time(buf,expires); send_control_event(EVENT_ADDRMAP, ALL_NAMES, "650 ADDRMAP %s %s \"%s\"\r\n", from, to, buf); send_control_event_extended(EVENT_ADDRMAP, ALL_NAMES, "650 ADDRMAP %s %s \"%s\"@%s\r\n", from, to, buf, error); } return 0; Loading