From c7883a9ebec98ae7fd31efb7c485dd38c738dc26 Mon Sep 17 00:00:00 2001 From: Wouter Wijngaards Date: Tue, 17 Jul 2007 15:26:45 +0000 Subject: [PATCH] Remove old forwarder mode, new @port option and tests ported over. git-svn-id: file:///svn/unbound/trunk@432 be551aaa-1e26-0410-a405-d3ace91eadb9 --- doc/Changelog | 7 +++ doc/example.conf | 9 +-- doc/unbound.conf.5 | 8 +-- iterator/iter_fwd.c | 2 +- iterator/iter_hints.c | 4 +- iterator/iter_utils.c | 11 ---- iterator/iterator.c | 99 -------------------------------- iterator/iterator.h | 5 -- testdata/fwd.rpl | 2 +- testdata/fwd_cached.rpl | 2 +- testdata/fwd_error.rpl | 2 +- testdata/fwd_lrudrop.rpl | 2 +- testdata/fwd_no_edns.tpkg | Bin 1634 -> 1643 bytes testdata/fwd_notcached.rpl | 4 +- testdata/fwd_tcp.tpkg | Bin 1626 -> 1633 bytes testdata/fwd_tcp_tc.tpkg | Bin 1624 -> 1645 bytes testdata/fwd_three.tpkg | Bin 1964 -> 1969 bytes testdata/fwd_three_service.tpkg | Bin 1946 -> 1957 bytes testdata/fwd_timeout.rpl | 2 +- testdata/fwd_ttlexpire.tpkg | Bin 1645 -> 1652 bytes testdata/fwd_two.rpl | 4 +- testdata/fwd_udp.tpkg | Bin 1626 -> 1636 bytes testdata/rrset_rettl.rpl | 2 +- testdata/rrset_untrusted.rpl | 4 +- testdata/rrset_updated.rpl | 2 +- util/config_file.c | 3 - util/config_file.h | 7 +-- util/configlexer.lex | 2 - util/configparser.y | 36 ++++-------- util/net_help.c | 28 +++++++++ util/net_help.h | 11 ++++ 31 files changed, 77 insertions(+), 181 deletions(-) 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 9415f01907db6cb77dd2c4e35028660712810d4a..6326c15959af03b9fc558df5f09795412b061170 100644 GIT binary patch literal 1643 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 literal 1626 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 rV%j#sUQ)H1tl*D&8kg^V7&h>YuI+76Ya z15|@f(MJ?d+jsBY34y>6H!}{IHf&-z?e6W~?cVO~qG4?Qm-j@Icp<1mZ z-^b;p?-}f=%CV+sRZS})pIR!bS3x!N)6p&-x!dKli^e`>3?UP}nE?5U|L%D1>7Q zQ!~Kb!v{3g(3wz($J7NUJPbJ1r{otX3_+HQa_HTSWMq?PGk$}EgH+HO`m&agqV7j@ z%moPMCGkrn!gpXZxJM!iHhr7LE(k$LxN{~GzH3~87#38>pWn0wy^9u7r{*1nAVO9_ zOes(=+Vn%wjS#2R57fD!$h~EeYcE7ycV2a`JDbF1s1HPL+y9&6-wv!N((zdQm&?cV z_*Yep$G@hjyZGM*yfOpYF{f0|@5AYI{m%6IzB@LSGt3GJxdU9zxZis)>*TME>xRIN3 z1HYU<+>wdm1JXn(Bj(@hK$>joF_*fbPMTA@MLp`;0pb^<*L33Pq~|YfLiRA;dYH`g z)$B(4bOkH&MI-unj%kMr?3qD8ZJnH(&IH3&-+EMT4>rd?H;NlPg^ow>e>D^T6%qf{ z>hAvE3Y>t8(H~I%1ND>pm*2f4-!(42zvuw{XimKel`S@vNxt8I1Epg{A*9{u8}A0M z+Q>sL8~x^MV4j6(0N#i99)5D6aNX(=quqP+4&EBjXke~@PPc6sU4t}QKU`xru$Xs0 zaBOnbZuT#_9e8_BLEx0CdHJa(+HXkgmL@6rkPmrHWVwBndeX)!t1#aqWMX5|bWlFWjF z2lHjE7ENvdbwtS%HWKX%9FSSBRLeihZjK{ngAH2~O_Igjp)*RZAgsWkK;bYbo^jQ` zo)r(5%z0QmOzHjZoFiRnhKdfGlT+t$@@aNATr<=mx)r0jsb`&?IFA?zx2APB@HijHT0&+X)|$&Q!!;(1O(%(-^g3rSVi0-X ziRgh-TmrW&zXR)V8iYOu6laRf&>GjtFmf$k!3#NqM8+WUp1*)UN$#@o^WeHSz?-V3 zY6{8SG%oss{%fOsRV(2m*NOp#O+ih86aEdSHOMb!CCH;A3_2XzjO23ZQN@FrS9u5z zM?UpH%4-rwEIQ-#*yeJHscdWq0N2U2avB znr{Sg9Lw1syClM~XA@?bld*Uu=D||?@n8o0g;KFDjY84Bq{4aiI4isZNfhpBnI;}G zRn%h2m|AyWxj>{9Ly WcCdpT>|h7qF#H3;#jmCSC;$K(S~$`G diff --git a/testdata/fwd_three.tpkg b/testdata/fwd_three.tpkg index ce0a7414b4e0988af6ce6430ebe8884b6f42f47a..b4c55ef554610438a2b6448794a346cd951e01f9 100644 GIT binary patch literal 1969 zc-jH62Tu4OiwFQ(-ke4N1MOLRbK5o&_rJoY*wC6dnN$>ClBP|ltsw#IVX(_P?xfu035>qWpsLl5HcsPq% za}T60*v<@AtCcF#&*su!P}%a9*qD)z7oKG<<{tBj57n!|>*3YlbaF8qjqi4WKTs|O zj1%UgT)bsQu<&M#7D|M@p|@qE0Dp{)Q{vZ*$2x;~{@FHNe3jORvppvOW)_!2V!5H9b z9A@l)?}Bb>g$hquZ{M-iPW8#x2-3C-(sDuCR|?X%3(|8zIujHwD0;9#Zk)veYTrUN zwRV%BZ4z`+n%Qi;$;{@X-_}Mewb8b=(MxUghYF&QN72UYeld*HavZ7Pgs>S*oao+- zsJnt2Yr$Gsu(nOG_SJ%$Yr%S1u)a;OzC$qKj|zG0-FW}lmH+*KKA4Vs^1rU?MxOt5 z9qUA_12vKV_kzv*kMsWjl>J9(V(3(#J%j3~H#i->gBQ@y8wNaoPKvpsQ_UKav-j&> zITgF9*kyP%&Usn87mShYFlC9wHwn7kP5Y8QYjxSvwzh0eFjTpNR%T$M|FC&~)LGbW zSYu7xknND%Cr_B4qz|jPW6hz;+kKF-4KnFgpL?YQ-#9NZI=UOdHSW-+1P zZWN1d2;D3fY2BwR@$=^Ar!37D2FM8M!;axC%^M1q=T0%n^AakgHqm_8sl4m`G`YH%j7L9rR81k3 z_r3G+Wc+5-zwGGv%CzDdi-OyZ0x#Jwyy`%8-76u!c!BE zuWAw_bn7<#RCnXWB8%Kgn#XO=#X{TVTB;GNiIH_3Q1j*`K4I{#WivL0!N;O0o8m4L zZ{ZZ9R@xs*wHqVl3py3<7}Da;~utGY`b_uiBTkz>)F+KPcK zg&Vz4;bZ4Ef%~zu{`2;B|D!6c2G)O#ma6EQp)~mYk7kJaZy&f*|9N}9|0!t6O1>}Y z`0CQ{FuCoyMJ5Wy-PK#Uzy%?LpXqVXXhCwkS0SrSvN|M;u_ z_Ia90WhHquvC_{U?ik8bPB!dx*Ip02P-<)$e1UsM?qdh9z@Nsh{hyVt52fRt{a;~c z{_^*qCi2DpzYiqUT$@zz|7$OFqT4oTq~gZQ8Vdx|4%^Tm6;?vFfuF*TNd;Xo^RQN| zrR4N@RpbPwJEL4wPU12xpA#|Is1Tq=a-T45DpHfJ5Jbnv0P7)#g0Uo0#ulv}Byz7lm-hk&@o=xFn zbnD~)Oeh)kFW&wPKaQZ+gTb&r8VyIJcl!O+in` zOZGt6r=`mIpwi1(y}{-C{%Fmp6h2#|_Vfp*`!P-1Wtz5OT4V2~>AOtRH%x1mOndA& z6nGr$+W+m)dN3XL)qh4aJO67frK#}mKdLVF|9#-K8PWkSs`9xf|DZwWcrKP-vO-R2 zXa$ZRal%=oOnwg%Rx74lar-=N`30G zGL@{K-q3~LCKo|*SnSglx$wfMy>Z<^#Ta%MUUJQ%md zW+@;bARr(hARr(hARr(hARr(hARr(hARr(hARr(hARr(hARr(h@R;}yl8^4A08jt` DaoO|K literal 1964 zc-jH12UGYTiwFSX1XD%;1MOLRbJ|D}_rJ`i=*X0vR2HEJk6Ik45F1~7mw*@J%Wdsl z5m_2QXV7RR5#rk2?|wa_2NH(ZwMU%V-TC>!sC%Y+rl)78BMLB;r?UWJOFKPGx!4j;`{%`3TfY3&=zESPyR`R z&}Ci=bX6l~G_(WPj|AbI1uH9XK=gy3mo#u`2v!8lv*~xR3|((3n3fZ&!cfLfK3&Ze9eDuh3wwN<2mcvyNjZ0QNYddQ60w_thU3QfqZ!B;+y zFWftYxD%KL)CWb^R6|ouO|5B4s`rF1&?BW-*5Drsq4SWY&wUmFr z)P2GAwP2$t*w`l6c(mZgTCiCZY;F^5?hs5wQ~NW0u|E>KzW;6JP4=bZq4*!Oy>l_5EfDS@KzcA@XZ}$G#>dG{uzR zS5hS*53Wa>oWSy?REWw*LZ0;7C{({H&cVpN2=ZVq2bUbkWb*-7^|E5vX>LUI(YV!O)1vcY zpVN{C{9n@X=)nIlj`r`6iGuM;VJi=WAY_P`4i}9xh{HP_%I6<2hP*gK?!vmI5Mrhu zGgA(9st)~B^_EC8I!8JeG;uu#EF{p+QDE^X>y|oVAzp~FmlJEk1uRs8!QN>ywYc(1FJqb?0vlcXt0^9%r2ulAOCZqWZ1iW z_apo;gl-r5gWhmB7?SSU->^dOQ@U}^=dZ(j{K_7m&?p^T);iZMrMZeU| zSl#~Bhu(0_DCN@DWInzA+0#tT*flj{V`}v$pPIRAYUak&8ilESYd@6uHrN^e2Xt>b z9=QKa-K=fA|E)I-S^s|$+>8GM`e&;C50k=hyZrn)l!x8^+2B3Agt}R;!HX9pUpsD> z)6PT${K=?{ioeAM>zI;#6RfU0gi3IJ3 z-Fw6K-0{Ln9Ix>Tsj$g2ZYSmAYUbKAk-+qZAChba0htCqTsHr!3qC_S8XV-N5#aKFY(+#oVS)zZ$-B%>--canQ_@rIANV` zrk-0$>i9gN1)L|>QjYjLF=X8Y)Ve*v7CP@*HfN(7{G6Z4rnsxvT0F7V!NCBFzakKZ zdnP1vW0!T&U%WEdp=3&-ytc|(N&K!!PX>u({I|kxWha{N1%}!bH46t6`*ZvbGkxmu zCN7y*MUVMZaW7R;+^DRIpxhgx6cnbOx>enk@Ow59PUPBjr?$LfE8)f{MaGm85)u*; y5)u*;5)u*;5)u*;5)u*;5)u*;5)u*;5)u*;5)u*;5)u+$1OEeF*Oco3PyhgdK--r9 diff --git a/testdata/fwd_three_service.tpkg b/testdata/fwd_three_service.tpkg index b0e74bc8383f1e223ab95843e33ea1331bfdfb2d..45859671ca8b53156243ea40815c2c29014df7ef 100644 GIT binary patch literal 1957 zc-jG_2U_?aiwFQI-ke4N1MOLRciP4h_rL6?n8=(sIVnO99xVwR6Pq-?HwG8ux;bqR zk);JxgQV&a;(Ocg-r1D|5*9V}ah=m;&!_j6!4|l&vF@4m*HwJR^;fi7qoFfD(Ns;T?Sb-u^W2IreEs)fzfyt1 z^{!O*$vy;bXA^?D7SKPMOc*Mo~ym$Wl^bGaV1YQ~Cdw9Zo% zp2lW8Ic}GqWGBiRl7}tRTo~6BOxKy%Q|@pipcYgp90b)vrp8Z))q|XA52^<#eKc70 zNVU#Taq(8izia)KaA30ZUvW zrJ8oF;IEl7f=<$$wbW`dS!?AQGcSc!GmWsol1symHx!!`ZphGusSAz^fqiagVW1OCvOA9Wsd=GqhcY^BKoH#*z2zIsBiLPP;#hFV4oJ;rlio+oW{a zJsFKhZ->3}wvMk%D(<<^ziBJ*l6}LgHk8++;>H&*a3A8M<&sh<^;WpBmRM@d=%I&6|#dOGY8r|h|Yc)(P}wUkMIp&;Fm(ybveR?`|R|HJf8(eRh$e|kd``QKw;TmBcHzyG2P zFdLQkG0gD!WRkBA9`I9GE|;oIKN$;e&LaN;JG17)xoaBpnagZ~c~CazxIF}ZL%tY> zqL3#oDSH+yk~kYkJWi*lGJnY&n(HAmYF>lk1WW42;Tva;HuyE7EVf~kiQ}TG$eJSS zid<8qRBjq(VqSy)N`%e>n!fijkg>KTaIrjZZ3ku>^aU=)X3G9`6Lb^l^)+KH&sZyBtnJLWv1Y92 z8S6!i^(~AEe^kDp3}x5&&#o-@m2pS>S9Dd+*Z(m7>#B(VkAXOAZ;=vyUb%rC-n2j? zB_~=`m;)GA&|)_fc2#HrzjYsy5}IP_VkoL4&B=8-OYse7N;xa^Cu)YSkBlWL=A0Zo z6_5If6cmDaAW1GfmH**g2z6rjQ5=OqxRg>1%kr^F)ta(`Kk8v}(?68HpiTRL*t!1e z{%!fcsw(x(`mf#;_1{Oq*7~pe$oYRpN}BNhnT(wi|NS`Izd<50#v{aCI=~qrf#-BM zdDI|I?^H-@l4<=hh_EXsrj$(miP!BIqlxWUU|<9N6#53svaYEGNj=m+8s~r$SjYsE z$GIJZ?GH&+E9s2QEoqg`{RZn|XQl&Gs|O$0F$o?oOC`MGx>>BHw|cmxC@(Rk(@t{5 z^~5u!#e&IasJHljZYLJFH+DV$t-!pujJxu`IwpJR`Crp@cK)mNx;XzI1FwyM_Ia9h zYt6~`cww|%2Xix7A;&Z@ecKCp!<#r8%ikn{U05BHeg#nwSC}cp*_}*|@QV#SHbNA2 ziKp2qT3!1Z)Ot&6v@{itdgmk1&@srVVLKuIVOk27FT7OZC^aBQ$Yshi zN^;~bJQU=FEpoK5j;Ti-ma>xd(_1?CTI9?xnj-r*Cpp7VS4hKlGNQ#q9$UK6r#I{- zj#AEy01xaId1KgfJTzPXlr!8kQe%-@9+x)z=V;f;r%j42uR&fdL; z?}pIrLVwU34hKWhJ^s%HZgkW2ZpO9+y!_VI$$9T+bTa6}cNcgJ-~(YL#nMT?)LoIf z{qxJ-a7`#>%2kOzz5emzsHSaGP1{hd{^+Xd+f>sxRBPl^``msgARr(hARr(hARr(h rARr(hARr(hARr(hARr(hARr(hARr(hARr(hup9mW!xYx&08jt`)FI4$ literal 1946 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 literal 1645 zc-jGN29o(7iwFQ8kU>TO1ML|7ciJ{EzoNh5>hO~GWf+^UY$WhPfv(vapblBqx9u@w z3-AKAYuR=3w*Bur$sd@IjBV+o>&CUgl1_Ig-Iq?9gyzWi=k(UKJSv-(SKRyPpdcI{ zSEFyOvhs~#PgQCqrK~E7dc3Eo6}57_2i1?ilywN0uX_M{p%eJjdwkv|{AUW2HT$oQ zxDNB5DuWxicF*ov``1e4*#63KwN^s=qqmgyK=~LO+ywt~`|rbkp#bYPheBbW>;rQG z&!FJXC@ge_3V;u&t%)_K5YDI#mVd}N)}!PHC`>?>i?Z+DOl6!V#}q%o!9l|40sN{I zpQ7vyGExR&@(TME6yZBC9k@dzGS)rQ32hLJ5OHJ8=X~S10?{m}kbiaE84b=mh+XJ6 z6j*>$1v0@vvuM%}MLWQ;Qu9Df83p#(32bx8>ZE!-49)uI38Gbnhq>|j3Ql~G0UF*-84W3TDKu_ z(Xtd}ge21tYRnvvnqXQ}2*XgOxB9}JQ`vA9IG2x}%^gFZ&qPXeGlARJhHDh?8*-(9 zp29VhGB;+_xB=Z}A@w9;O9HB52Iyd#c?^3f{C zY)^t_^ZxoGnx(j;_0U{y6LeRhpb+a>)E`doYK^&RvjU%DGoE6FPM&c+Nk4}(%b1A* zwyXUtB`G!{E6$t+Ek>?g99woV%LnsoL?u#xvaAPc1)D)L$+x_Mg#!|o%Z>cA?Ed&b z+<0VnqE0p(dxB?=I7JvWp+Mn~70RR%3!AR zpvL&=wywprBw*D0fH8v;YlUn<&CCaZ=@iyvu?L|PG; zc^cgZNLfe zDln-N#oddS-TA(D{`GkevhO=2KODY+a!pYP>GrUG8olh|9CFbbwqJwe8jeZfy?^K8 zFK0@$?%>Tkc&kCH1-*V()A|}|b-uZ}9AdfQ-i<7iTz1>T^L`KBUUe^dgM?w2JMZOM zDW=uCyzXjZyd*HW%*#={j&85BOCtXaHpRcmj3>+36#rFa`Tk$4R>b>HdH4Ra6?myL z+QVS2uU>=6chqBe1;nFYR!E03!?Rpp48-R+Ty+MZpG3cR$&Ok17%l7dPOA#V7&2*!0YZHEf! z0M#HVdPH#_|Gj&s2g1g6+i{#}!X`#{yLY>H`#haykvR!XS28WHwD*xfMyS=a_*t!N zJQLVc|Zmi2L9RxBouu7mJX$JQR!jWFLGd^b88Y zg2GDoaqI9N^)$1V6ru&S!3qw2M)fH95sEXAq>>c4*K-MnNy&_#;ou-;w1tjRLLVs^ znv0(~9#}T;HX<#3iXvUz_bq##h}xX6A!UO^$Z*ta2u!pjpfuCr`{5*NEF2J;U|MsC zqDZ12^p(4$lHsgyEW@^zj-f9X4pWH>;${Ek;IiMH3k&<|Ds3Yl4i@TN?1_TLu&u16o$#~z6PvZ5+1{%eYiNub8^ zzb4n@UHm@+%|oXfMPPfaLNIP^;`CikaS>2O1rho!@m zJ|1Kv(q-nTXswK#T8@!VvaK+&(1dWxTbYuR#LPVrLtv^K*K?0yHVTS}ol-iqi2se0 z5j1nDJ=IUPg}jb7kh#uQU9p;RSAUUi#c|_P?>)v{;K1C0(EW>u3)&9; z6>K~Iu?+T@G9G&WQr+_%H>!g6cQ^&W0n>whZun%^)Dh3P8uBKmS zX^iEQI`D$rA_Y{&+`+_AOwdWCZIL9a6@SBohg@0Fse^#UvXD}A)ASIfs5ME(e@ZJU z;;mis_ylm@{g3TGo{Wd$zpTjF{ZFMVv-q#dyZC<+I0hD?>B*75fw3dFI2fIMbJmCa z9S0G|KmTr1{`r3S8&j6xaey;2$1A!1N@zk~&fwAJ(t-Tt`_x=^&H2Bu-=lXM}`nYq?}w#ue~pQGxV|GQE!UG3sMtO37VJ@e93-QF0-&W|h0e i+rlnKy~FZTJHrlku!9}!UV7&2*!0YZHEZy z0L4P5=n>*+``^2FdLSHJw;jixHrgcUZuf5YZXb7ho7u{ogr+N-mRH{SLZBej>(%I6 zJKXrju%jx~x~kw$1@Wp@uT*xR`lS|>h0qUl4`64-!hm{rkGqflAB9=Q{%PAc9#jT5 zaP5}ev-UqctaJO*p%ajE-Eso_N4*A^o(xxVM{eWCdhg72l;x8SGMO{)rU9hGmM(Ls z6EsL?X?Ceg9n(kry7h|MZi5WH^>$>}qh!eZAcMgk8PhB(z#eIbpH3~Cay~=d_o>++ zr@Cc_$c;R;nZ6ioi+@zvgUYxk{wu1crssdHu8R1tD|!4s2JFIasgwayzzNh?FpxGmW_uE}TDR91%~^{} zTHD5Qo1mi#1@S`|^@qcIqo!>-eu)opd}7Ta#XaMClHRQrma%}M823&(;`VY#A(~cR zuq7==PFt_p+sTdFQ0I^znql!H*~pQ-cRV`K{_H?W`>H^O38`kIQcl;3Kt74 z2&bZzDmiqfEW~?_dm@Iw6mPn@$1!9$>NO?q&9X#_*eNGNOZeAF7(pvWXZ4eAA*-Ve zWTvxKSB4&J(cen9qPX#?_YvbRU@&J8y5ESnfn!_(SF3}!d<%~Kz{61DgI0QAELvn1 zItIV31)oX8V-mX0U%+pqaNhoDaygugM{k>|rjWu_`)oWJzZ&%}nicGFsTf*;chgkh zh=1X@3B~oS2zhXT;f76)b22)?hwM^rv%842g(gO+re%V|f=F@C1ZS@7qAJFJ zLItaL2$@qTuC=lj;@cE=rN)!^+Q}aq)=C4J+rq$TM9IPdg?;v4TX;x1yop}@`n{3WBfd6 zfVhxPNCA~GXLxXwVsw1do`@@fA8Vz6H9%6ex~$+IRmu{QNzvtflAjq*2;1U6%I_Xd z#(nW$QI)v90AV@lgv@Pz<3H?9E{GsJL?1eq%U2Y;+3$JNpU=W z4R}B+g!KBDQB7X}`tqN!TLOZ3j`xjTeQHn39imWMeMUfAccon^V zH$OuDEo`m-Fh6)m8TZA1O|2&N-)cqC#Qk5ZiUeS%JW0|x^O2j0^rfBNm2Z>PIr%Auh0^qo~e8r2pL^PE= YS;`@Y9CFAZhp!v{1eLrtA^<1=0QY4oiU0rr 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. -- 2.47.2