From: Wouter Wijngaards Date: Tue, 17 Jul 2007 15:26:45 +0000 (+0000) Subject: Remove old forwarder mode, new @port option and tests ported over. X-Git-Tag: release-0.4~34 X-Git-Url: http://git.ipfire.org/cgi-bin/gitweb.cgi?a=commitdiff_plain;h=c7883a9ebec98ae7fd31efb7c485dd38c738dc26;p=thirdparty%2Funbound.git Remove old forwarder mode, new @port option and tests ported over. git-svn-id: file:///svn/unbound/trunk@432 be551aaa-1e26-0410-a405-d3ace91eadb9 --- diff --git a/doc/Changelog b/doc/Changelog index a9693e8bb..e97782f23 100644 --- a/doc/Changelog +++ b/doc/Changelog @@ -2,6 +2,13 @@ - forward zone options in config file. - forward per zone in iterator. takes precendence over stubs. - fixup commithooks. + - removed forward-to and forward-to-port features, subsumed by + new forward zones. + - fix parser to handle absent server: clause. + - change untrusted rrset test to account for scrubber that is now + applied during the test (which removes the poison, by the way). + - feature, addresses can be specified with @portnumber, like nsd.conf. + - test config files changed over to new forwarder syntax. 27 June 2007: Wouter - delete of mesh does a postorder traverse of the tree. diff --git a/doc/example.conf b/doc/example.conf index 3bba6531a..9926bcd16 100644 --- a/doc/example.conf +++ b/doc/example.conf @@ -93,14 +93,6 @@ server: # Enable TCP, "yes" or "no". # do-tcp: yes - # Set this to configure unbound to act as a forwarder. All queries are - # sent to the remote nameserver that will resolve them. - # Set to "" to disable forwarding, or give ip-address to enable. - # forward-to: "" - - # The port number to send forwarded queries to. - # forward-to-port: 53 - # if given, a chroot(2) is done to the given directory. # i.e. you can chroot to the working directory, for example, # for extra security, but make sure all files are in that directory. @@ -154,6 +146,7 @@ server: # forward-zone: # name: "example.com" # forward-addr: 192.0.2.68 +# forward-addr: 192.0.2.73@5355 # forward to port 5355. # forward-zone: # name: "example.org" # forward-host: fwd.example.com diff --git a/doc/unbound.conf.5 b/doc/unbound.conf.5 index 69cd64cf6..8ebc31047 100644 --- a/doc/unbound.conf.5 +++ b/doc/unbound.conf.5 @@ -99,12 +99,6 @@ Enable or disable whether ip6 queries are answered. Default is yes. Enable or disable whether UDP queries are answered. Default is yes. .It \fBdo-tcp:\fR Enable or disable whether TCP queries are answered. Default is yes. -.It \fBforward-to:\fR -If set (not "") then forwarder mode is enabled. Default is "" (disabled). -The ip address is used to forward all DNS queries to. -.It \fBforward-to-port:\fR -The port on which the remote server is running that answers forwarded queries. -Default is 53. .It \fBchroot:\fR If given a chroot is done to the given directory. The default is none (""). .It \fBusername:\fR @@ -156,6 +150,7 @@ Name of the stub zone. Name of stub zone nameserver. Is itself resolved before it is used. .It \fBstub-addr:\fR IP address of stub zone nameserver. Can be IP 4 or IP 6. +To use a nondefault port for DNS communication append '@' with the port number. .El .Ss Forward Zone Options @@ -173,6 +168,7 @@ Name of the forward zone. Name of server to forward to. Is itself resolved before it is used. .It \fBforward-addr:\fR IP address of server to forward to. Can be IP 4 or IP 6. +To use a nondefault port for DNS communication append '@' with the port number. .El .Sh FILES diff --git a/iterator/iter_fwd.c b/iterator/iter_fwd.c index d3addb8c8..d9646a05e 100644 --- a/iterator/iter_fwd.c +++ b/iterator/iter_fwd.c @@ -199,7 +199,7 @@ read_fwds_addr(struct iter_forwards* fwd, struct config_stub* s, socklen_t addrlen; for(p = s->addrs; p; p = p->next) { log_assert(p->str); - if(!ipstrtoaddr(p->str, UNBOUND_DNS_PORT, &addr, &addrlen)) { + if(!extstrtoaddr(p->str, &addr, &addrlen)) { log_err("cannot parse forward %s ip address: '%s'", s->name, p->str); return 0; diff --git a/iterator/iter_hints.c b/iterator/iter_hints.c index def25eb81..25df77d7e 100644 --- a/iterator/iter_hints.c +++ b/iterator/iter_hints.c @@ -101,7 +101,7 @@ ah(struct delegpt* dp, struct region* r, const char* sv, const char* ip) return 0; } if(!delegpt_add_ns(dp, r, ldns_rdf_data(rdf)) || - !ipstrtoaddr(ip, UNBOUND_DNS_PORT, &addr, &addrlen) || + !extstrtoaddr(ip, &addr, &addrlen) || !delegpt_add_target(dp, r, ldns_rdf_data(rdf), ldns_rdf_size(rdf), &addr, addrlen)) { ldns_rdf_deep_free(rdf); @@ -256,7 +256,7 @@ read_stubs_addr(struct iter_hints* hints, struct config_stub* s, socklen_t addrlen; for(p = s->addrs; p; p = p->next) { log_assert(p->str); - if(!ipstrtoaddr(p->str, UNBOUND_DNS_PORT, &addr, &addrlen)) { + if(!extstrtoaddr(p->str, &addr, &addrlen)) { log_err("cannot parse stub %s ip address: '%s'", s->name, p->str); return 0; diff --git a/iterator/iter_utils.c b/iterator/iter_utils.c index 2a887b40a..6986bb659 100644 --- a/iterator/iter_utils.c +++ b/iterator/iter_utils.c @@ -139,17 +139,6 @@ iter_apply_cfg(struct iter_env* iter_env, struct config_file* cfg) return 0; } iter_env->supports_ipv6 = cfg->do_ip6; - - /* forwarder address */ - if(cfg->fwd_address && cfg->fwd_address[0]) { - if(!ipstrtoaddr(cfg->fwd_address, cfg->fwd_port, - &iter_env->fwd_addr, &iter_env->fwd_addrlen)) { - log_err("iterator: could not set forwarder address"); - return 0; - } - verbose(VERB_ALGO, "iterator: fwd queries to: %s %d", - cfg->fwd_address, cfg->fwd_port); - } return 1; } diff --git a/iterator/iterator.c b/iterator/iterator.c index 08625d9db..661add47d 100644 --- a/iterator/iterator.c +++ b/iterator/iterator.c @@ -119,101 +119,6 @@ iter_new(struct module_qstate* qstate, int id) return 1; } -/** new query for iterator in forward mode */ -static int -fwd_new(struct module_qstate* qstate, int id) -{ - struct iter_qstate* iq = (struct iter_qstate*)region_alloc( - qstate->region, sizeof(struct iter_qstate)); - struct module_env* env = qstate->env; - struct iter_env* ie = (struct iter_env*)env->modinfo[id]; - struct outbound_entry* e; - uint16_t flags = 0; /* opcode=query, no flags */ - int dnssec = 1; /* always get dnssec info */ - qstate->minfo[id] = iq; - if(!iq) - return 0; - memset(iq, 0, sizeof(*iq)); - outbound_list_init(&iq->outlist); - e = (*env->send_query)(qstate->qinfo.qname, qstate->qinfo.qname_len, - qstate->qinfo.qtype, qstate->qinfo.qclass, flags, dnssec, - &ie->fwd_addr, ie->fwd_addrlen, qstate); - if(!e) - return 0; - outbound_list_insert(&iq->outlist, e); - qstate->ext_state[id] = module_wait_reply; - return 1; -} - -/** iterator handle reply from authoritative server */ -static int -iter_handlereply(struct module_qstate* qstate, int id) -{ - struct module_env* env = qstate->env; - struct query_info reply_qinfo; - struct reply_info* reply_msg; - struct edns_data reply_edns; - hashvalue_t h; - int r; - if((r=reply_info_parse(qstate->reply->c->buffer, env->alloc, - &reply_qinfo, &reply_msg, qstate->env->scratch, - &reply_edns))!=0) - return 0; - - h = query_info_hash(&qstate->qinfo); - (*qstate->env->query_done)(qstate, LDNS_RCODE_NOERROR, reply_msg); - /* there should be no dependencies in this forwarding mode */ - (*qstate->env->walk_supers)(qstate, id, NULL); - dns_cache_store_msg(qstate->env, &reply_qinfo, h, reply_msg); - qstate->ext_state[id] = module_finished; - return 1; -} - -/** perform forwarder functionality */ -static void -perform_forward(struct module_qstate* qstate, enum module_ev event, int id, - struct outbound_entry* outbound) -{ - verbose(VERB_ALGO, "iterator: forwarding"); - if(event == module_event_new) { - if(!fwd_new(qstate, id)) { - (*qstate->env->query_done)(qstate, - LDNS_RCODE_SERVFAIL, NULL); - (*qstate->env->walk_supers)(qstate, id, NULL); - qstate->ext_state[id] = module_error; - return; - } - return; - } - /* it must be a query reply */ - if(!outbound) { - verbose(VERB_ALGO, "query reply was not serviced"); - (*qstate->env->query_done)(qstate, LDNS_RCODE_SERVFAIL, NULL); - (*qstate->env->walk_supers)(qstate, id, NULL); - qstate->ext_state[id] = module_error; - return; - } - if(event == module_event_timeout || event == module_event_error) { - (*qstate->env->query_done)(qstate, LDNS_RCODE_SERVFAIL, NULL); - (*qstate->env->walk_supers)(qstate, id, NULL); - qstate->ext_state[id] = module_error; - return; - } - if(event == module_event_reply) { - if(!iter_handlereply(qstate, id)) { - (*qstate->env->query_done)(qstate, - LDNS_RCODE_SERVFAIL, NULL); - (*qstate->env->walk_supers)(qstate, id, NULL); - qstate->ext_state[id] = module_error; - } - return; - } - log_err("bad event for iterator[forwarding]"); - (*qstate->env->query_done)(qstate, LDNS_RCODE_SERVFAIL, NULL); - (*qstate->env->walk_supers)(qstate, id, NULL); - qstate->ext_state[id] = module_error; -} - /** * Transition to the next state. This can be used to advance a currently * processing event. It cannot be used to reactivate a forEvent. @@ -1599,10 +1504,6 @@ iter_operate(struct module_qstate* qstate, enum module_ev event, int id, log_query_info(VERB_DETAIL, "iterator operate: chased to", &iq->qchase); - if(ie->fwd_addrlen != 0) { - perform_forward(qstate, event, id, outbound); - return; - } /* perform iterator state machine */ if(event == module_event_new && iq == NULL) { if(!iter_new(qstate, id)) { diff --git a/iterator/iterator.h b/iterator/iterator.h index 81b1ec920..e543e614d 100644 --- a/iterator/iterator.h +++ b/iterator/iterator.h @@ -68,11 +68,6 @@ struct iter_prep_list; * Global state for the iterator. */ struct iter_env { - /** address to forward to */ - struct sockaddr_storage fwd_addr; - /** length of fwd_addr, if not 0, forward mode is used */ - socklen_t fwd_addrlen; - /** * The hints -- these aren't stored in the cache because they don't * expire. The hints are always used to "prime" the cache. Note diff --git a/testdata/fwd.rpl b/testdata/fwd.rpl index 85212f11b..b1355a9b6 100644 --- a/testdata/fwd.rpl +++ b/testdata/fwd.rpl @@ -1,6 +1,6 @@ ; This is a comment. ; config options go here. -server: forward-to: "127.0.0.1" +forward-zone: name: "." forward-addr: 127.0.0.1 CONFIG_END SCENARIO_BEGIN Sample of a valid query diff --git a/testdata/fwd_cached.rpl b/testdata/fwd_cached.rpl index 28c3315d6..d566d0a6d 100644 --- a/testdata/fwd_cached.rpl +++ b/testdata/fwd_cached.rpl @@ -1,6 +1,6 @@ ; This is a comment. ; config options go here. -server: forward-to: "127.0.0.1" +forward-zone: name: "." forward-addr: 127.0.0.1 CONFIG_END SCENARIO_BEGIN Query receives answer from the cache diff --git a/testdata/fwd_error.rpl b/testdata/fwd_error.rpl index 9f3554c11..e60b90ccd 100644 --- a/testdata/fwd_error.rpl +++ b/testdata/fwd_error.rpl @@ -1,5 +1,5 @@ ; config options go here. -server: forward-to: "127.0.0.1" +forward-zone: name: "." forward-addr: 127.0.0.1 CONFIG_END SCENARIO_BEGIN Forwarder and an error happens on server query. STEP 1 QUERY diff --git a/testdata/fwd_lrudrop.rpl b/testdata/fwd_lrudrop.rpl index 06f7c2c9e..5cda894c7 100644 --- a/testdata/fwd_lrudrop.rpl +++ b/testdata/fwd_lrudrop.rpl @@ -4,7 +4,7 @@ server: msg-cache-size: 1 # one whole byte! msg-cache-slabs: 1 - forward-to: "127.0.0.1" +forward-zone: name: "." forward-addr: 127.0.0.1 CONFIG_END SCENARIO_BEGIN Old answer is dropped from the cache diff --git a/testdata/fwd_no_edns.tpkg b/testdata/fwd_no_edns.tpkg index 9415f0190..6326c1595 100644 Binary files a/testdata/fwd_no_edns.tpkg and b/testdata/fwd_no_edns.tpkg differ diff --git a/testdata/fwd_notcached.rpl b/testdata/fwd_notcached.rpl index 1a2cd8127..9f47d0d4c 100644 --- a/testdata/fwd_notcached.rpl +++ b/testdata/fwd_notcached.rpl @@ -5,7 +5,9 @@ ; here config file options: server: msg-cache-size: 1024 - forward-to: "127.0.0.1" +forward-zone: + name: "." + forward-addr: 127.0.0.1 CONFIG_END SCENARIO_BEGIN Query receives answer not from the cache diff --git a/testdata/fwd_tcp.tpkg b/testdata/fwd_tcp.tpkg index 48507bba3..5f2c9ce92 100644 Binary files a/testdata/fwd_tcp.tpkg and b/testdata/fwd_tcp.tpkg differ diff --git a/testdata/fwd_tcp_tc.tpkg b/testdata/fwd_tcp_tc.tpkg index 66010d329..9708246b6 100644 Binary files a/testdata/fwd_tcp_tc.tpkg and b/testdata/fwd_tcp_tc.tpkg differ diff --git a/testdata/fwd_three.tpkg b/testdata/fwd_three.tpkg index ce0a7414b..b4c55ef55 100644 Binary files a/testdata/fwd_three.tpkg and b/testdata/fwd_three.tpkg differ diff --git a/testdata/fwd_three_service.tpkg b/testdata/fwd_three_service.tpkg index b0e74bc83..45859671c 100644 Binary files a/testdata/fwd_three_service.tpkg and b/testdata/fwd_three_service.tpkg differ diff --git a/testdata/fwd_timeout.rpl b/testdata/fwd_timeout.rpl index b56fb5bc4..07669e27a 100644 --- a/testdata/fwd_timeout.rpl +++ b/testdata/fwd_timeout.rpl @@ -1,5 +1,5 @@ ; config options go here. -server: forward-to: "127.0.0.1" +forward-zone: name: "." forward-addr: 127.0.0.1 CONFIG_END SCENARIO_BEGIN Forwarder and a timeout happens on server query. STEP 1 QUERY diff --git a/testdata/fwd_ttlexpire.tpkg b/testdata/fwd_ttlexpire.tpkg index fb6159cf5..f29ede27f 100644 Binary files a/testdata/fwd_ttlexpire.tpkg and b/testdata/fwd_ttlexpire.tpkg differ diff --git a/testdata/fwd_two.rpl b/testdata/fwd_two.rpl index 7b040c6a1..8f863086a 100644 --- a/testdata/fwd_two.rpl +++ b/testdata/fwd_two.rpl @@ -1,7 +1,9 @@ ; config options go here. server: num-queries-per-thread: 1 - forward-to: "127.0.0.1" +forward-zone: + name: "." + forward-addr: 127.0.0.1 CONFIG_END SCENARIO_BEGIN Sample of a valid query diff --git a/testdata/fwd_udp.tpkg b/testdata/fwd_udp.tpkg index a175f34ed..9dd837a9e 100644 Binary files a/testdata/fwd_udp.tpkg and b/testdata/fwd_udp.tpkg differ diff --git a/testdata/rrset_rettl.rpl b/testdata/rrset_rettl.rpl index 0e9dda933..a2c7dc2c6 100644 --- a/testdata/rrset_rettl.rpl +++ b/testdata/rrset_rettl.rpl @@ -1,6 +1,6 @@ ; This is a comment. ; config options go here. -server: forward-to: "127.0.0.1" +forward-zone: name: "." forward-addr: 127.0.0.1 CONFIG_END SCENARIO_BEGIN RRset TTL is updated from message. diff --git a/testdata/rrset_untrusted.rpl b/testdata/rrset_untrusted.rpl index 7dcfd22ce..f3c12fdac 100644 --- a/testdata/rrset_untrusted.rpl +++ b/testdata/rrset_untrusted.rpl @@ -1,6 +1,6 @@ ; This is a comment. ; config options go here. -server: forward-to: "127.0.0.1" +forward-zone: name: "." forward-addr: 127.0.0.1 CONFIG_END SCENARIO_BEGIN Untrusted rrset not used for update @@ -91,8 +91,6 @@ ENTRY_BEGIN SECTION ADDITIONAL example.com. IN NS ns.eeeek.com. example.com. IN NS ns2.eeeek.com. - ns.eeeek.com. IN A 55.44.33.22 - ns2.eeeek.com. IN A 55.44.33.24 ENTRY_END diff --git a/testdata/rrset_updated.rpl b/testdata/rrset_updated.rpl index 4cd4a421d..1828080e6 100644 --- a/testdata/rrset_updated.rpl +++ b/testdata/rrset_updated.rpl @@ -1,6 +1,6 @@ ; This is a comment. ; config options go here. -server: forward-to: "127.0.0.1" +forward-zone: name: "." forward-addr: 127.0.0.1 CONFIG_END SCENARIO_BEGIN RRset is updated from other message that passes by. diff --git a/util/config_file.c b/util/config_file.c index 5318ba3f7..3f5bbd49f 100644 --- a/util/config_file.c +++ b/util/config_file.c @@ -88,14 +88,12 @@ config_create() cfg->infra_cache_slabs = 4; cfg->infra_cache_numhosts = 1000; cfg->infra_cache_numlame = 1000; - if(!(cfg->fwd_address = strdup(""))) goto error_exit; if(!(cfg->username = strdup(""))) goto error_exit; if(!(cfg->chrootdir = strdup(""))) goto error_exit; if(!(cfg->directory = strdup("/etc/unbound"))) goto error_exit; if(!(cfg->logfile = strdup(""))) goto error_exit; if(!(cfg->pidfile = strdup("unbound.pid"))) goto error_exit; if(!(cfg->target_fetch_policy = strdup("3 2 1 0 0"))) goto error_exit; - cfg->fwd_port = UNBOUND_DNS_PORT; cfg->do_daemonize = 1; cfg->num_ifs = 0; cfg->ifs = NULL; @@ -178,7 +176,6 @@ void config_delete(struct config_file* cfg) { if(!cfg) return; - free(cfg->fwd_address); free(cfg->username); free(cfg->chrootdir); free(cfg->directory); diff --git a/util/config_file.h b/util/config_file.h index a64428b4c..f141d7627 100644 --- a/util/config_file.h +++ b/util/config_file.h @@ -94,11 +94,6 @@ struct config_file { /** max number of lame zones per host in the infra cache */ size_t infra_cache_numlame; - /** forwarder address. string. If not NULL fwder mode is enabled. */ - char* fwd_address; - /** forwarder port */ - int fwd_port; - /** the target fetch policy for the iterator */ char* target_fetch_policy; @@ -109,7 +104,7 @@ struct config_file { /** the stub definitions, linked list */ struct config_stub* stubs; - /** the forward definitions, linked list */ + /** the forward zone definitions, linked list */ struct config_stub* forwards; /** harden against very small edns buffer sizes */ diff --git a/util/configlexer.lex b/util/configlexer.lex index 59fa47266..e93989de0 100644 --- a/util/configlexer.lex +++ b/util/configlexer.lex @@ -109,8 +109,6 @@ do-ip4{COLON} { YDOUT; return VAR_DO_IP4;} do-ip6{COLON} { YDOUT; return VAR_DO_IP6;} do-udp{COLON} { YDOUT; return VAR_DO_UDP;} do-tcp{COLON} { YDOUT; return VAR_DO_TCP;} -forward-to{COLON} { YDOUT; return VAR_FORWARD_TO;} -forward-to-port{COLON} { YDOUT; return VAR_FORWARD_TO_PORT;} interface{COLON} { YDOUT; return VAR_INTERFACE;} chroot{COLON} { YDOUT; return VAR_CHROOT;} username{COLON} { YDOUT; return VAR_USERNAME;} diff --git a/util/configparser.y b/util/configparser.y index 72c6b3a79..0e32bb71f 100644 --- a/util/configparser.y +++ b/util/configparser.y @@ -69,9 +69,8 @@ extern struct config_parser_state* cfg_parser; %token STRING %token VAR_SERVER VAR_VERBOSITY VAR_NUM_THREADS VAR_PORT %token VAR_OUTGOING_PORT VAR_OUTGOING_RANGE VAR_INTERFACE -%token VAR_DO_IP4 VAR_DO_IP6 VAR_DO_UDP VAR_DO_TCP -%token VAR_FORWARD_TO VAR_FORWARD_TO_PORT VAR_CHROOT -%token VAR_USERNAME VAR_DIRECTORY VAR_LOGFILE VAR_PIDFILE +%token VAR_DO_IP4 VAR_DO_IP6 VAR_DO_UDP VAR_DO_TCP +%token VAR_CHROOT VAR_USERNAME VAR_DIRECTORY VAR_LOGFILE VAR_PIDFILE %token VAR_MSG_CACHE_SIZE VAR_MSG_CACHE_SLABS VAR_NUM_QUERIES_PER_THREAD %token VAR_RRSET_CACHE_SIZE VAR_RRSET_CACHE_SLABS VAR_OUTGOING_NUM_TCP %token VAR_INFRA_HOST_TTL VAR_INFRA_LAME_TTL VAR_INFRA_CACHE_SLABS @@ -82,7 +81,9 @@ extern struct config_parser_state* cfg_parser; %% toplevelvars: /* empty */ | toplevelvars toplevelvar ; -toplevelvar: serverstart contents_server ; +toplevelvar: serverstart contents_server | stubstart contents_stub | + forwardstart contents_forward + ; /* server: declaration */ serverstart: VAR_SERVER @@ -97,17 +98,16 @@ contents_server: contents_server content_server | ; content_server: server_num_threads | server_verbosity | server_port | server_outgoing_port | server_outgoing_range | server_do_ip4 | - server_do_ip6 | server_do_udp | server_do_tcp | server_forward_to | - server_forward_to_port | server_interface | server_chroot | - server_username | server_directory | server_logfile | server_pidfile | + server_do_ip6 | server_do_udp | server_do_tcp | + server_interface | server_chroot | server_username | + server_directory | server_logfile | server_pidfile | server_msg_cache_size | server_msg_cache_slabs | server_num_queries_per_thread | server_rrset_cache_size | server_rrset_cache_slabs | server_outgoing_num_tcp | server_infra_host_ttl | server_infra_lame_ttl | server_infra_cache_slabs | server_infra_cache_numhosts | - server_infra_cache_numlame | stubstart contents_stub | - server_target_fetch_policy | server_harden_short_bufsize | - server_harden_large_queries | forwardstart contents_forward + server_infra_cache_numlame | server_target_fetch_policy | + server_harden_short_bufsize | server_harden_large_queries ; stubstart: VAR_STUB_ZONE { @@ -244,22 +244,6 @@ server_do_tcp: VAR_DO_TCP STRING free($2); } ; -server_forward_to: VAR_FORWARD_TO STRING - { - OUTYY(("P(server_forward_to:%s)\n", $2)); - free(cfg_parser->cfg->fwd_address); - cfg_parser->cfg->fwd_address = $2; - } - ; -server_forward_to_port: VAR_FORWARD_TO_PORT STRING - { - OUTYY(("P(server_forward_to_port:%s)\n", $2)); - if(atoi($2) == 0) - yyerror("number expected"); - else cfg_parser->cfg->fwd_port = atoi($2); - free($2); - } - ; server_chroot: VAR_CHROOT STRING { OUTYY(("P(server_chroot:%s)\n", $2)); diff --git a/util/net_help.c b/util/net_help.c index 7ba79e00a..6656398aa 100644 --- a/util/net_help.c +++ b/util/net_help.c @@ -43,6 +43,9 @@ #include "util/data/dname.h" #include +/** max length of an IP address (the address portion) that we allow */ +#define MAX_ADDR_STRLEN 128 /* characters */ + /** returns true is string addr is an ip6 specced address */ int str_is_ip6(const char* str) @@ -147,6 +150,31 @@ log_addr(const char* str, struct sockaddr_storage* addr, socklen_t addrlen) str, family, dest, (int)port, (int)addrlen); } +int +extstrtoaddr(const char* str, struct sockaddr_storage* addr, + socklen_t* addrlen) +{ + char* s; + int port = UNBOUND_DNS_PORT; + if((s=strchr(str, '@'))) { + char buf[MAX_ADDR_STRLEN]; + if(s-str >= MAX_ADDR_STRLEN) { + log_err("address too long: '%s'", str); + return 0; + } + strncpy(buf, str, MAX_ADDR_STRLEN); + buf[s-str] = 0; + port = atoi(s+1); + if(port == 0 && strcmp(s+1,"0")!=0) { + log_err("bad port spec in address: '%s", str); + return 0; + } + return ipstrtoaddr(buf, port, addr, addrlen); + } + return ipstrtoaddr(str, port, addr, addrlen); +} + + int ipstrtoaddr(const char* ip, int port, struct sockaddr_storage* addr, socklen_t* addrlen) diff --git a/util/net_help.h b/util/net_help.h index aa76e6e25..f01dd351f 100644 --- a/util/net_help.h +++ b/util/net_help.h @@ -139,6 +139,17 @@ void log_addr(const char* str, struct sockaddr_storage* addr, void log_name_addr(enum verbosity_value v, const char* str, uint8_t* zone, struct sockaddr_storage* addr, socklen_t addrlen); +/** + * Convert address string, with @port appendix, to sockaddr. + * Uses DNS port by default. + * @param str: the string + * @param addr: where to store sockaddr. + * @param addrlen: length of stored sockaddr is returned. + * @return 0 on error. + */ +int extstrtoaddr(const char* str, struct sockaddr_storage* addr, + socklen_t* addrlen); + /** * Convert ip address string and port to sockaddr. * @param ip: ip4 or ip6 address string.