diff --git a/unbound-1.4.4-00f12c.patch b/unbound-1.4.4-00f12c.patch new file mode 100644 index 0000000..4f14045 --- /dev/null +++ b/unbound-1.4.4-00f12c.patch @@ -0,0 +1,52 @@ +commit 00f12c3365fbb1f8a185a9972734c6bf225e7c0d +Author: wouter +Date: Tue Apr 27 14:15:19 2010 +0000 + + Fix harden-referral-path so it does not generate lookup failures. + +diff --git a/doc/unbound.conf.5.in b/doc/unbound.conf.5.in +index fbe3748..16a607c 100644 +--- a/doc/unbound.conf.5.in ++++ b/doc/unbound.conf.5.in +@@ -456,6 +456,8 @@ path to the answer. + Default off, because it burdens the authority servers, and it is + not RFC standard, and could lead to performance problems because of the + extra query load that is generated. Experimental option. ++If you enable it consider adding more numbers after the target\-fetch\-policy ++to increase the max depth that is checked to. + .TP + .B use\-caps\-for\-id: \fI + Use 0x20\-encoded random bits in the query to foil spoof attempts. +diff --git a/iterator/iterator.c b/iterator/iterator.c +index 08354e8..19b9a26 100644 +--- a/iterator/iterator.c ++++ b/iterator/iterator.c +@@ -695,12 +695,15 @@ static void + generate_a_aaaa_check(struct module_qstate* qstate, struct iter_qstate* iq, + int id) + { ++ struct iter_env* ie = (struct iter_env*)qstate->env->modinfo[id]; + struct module_qstate* subq; + size_t i; + struct reply_info* rep = iq->response->rep; + struct ub_packed_rrset_key* s; + log_assert(iq->dp); + ++ if(iq->depth == ie->max_dependency_depth) ++ return; + /* walk through additional, and check if in-zone, + * only relevant A, AAAA are left after scrub anyway */ + for(i=rep->an_numrrsets+rep->ns_numrrsets; irrset_count; i++) { +@@ -746,9 +749,12 @@ generate_a_aaaa_check(struct module_qstate* qstate, struct iter_qstate* iq, + static void + generate_ns_check(struct module_qstate* qstate, struct iter_qstate* iq, int id) + { ++ struct iter_env* ie = (struct iter_env*)qstate->env->modinfo[id]; + struct module_qstate* subq; + log_assert(iq->dp); + ++ if(iq->depth == ie->max_dependency_depth) ++ return; + /* is this query the same as the nscheck? */ + if(qstate->qinfo.qtype == LDNS_RR_TYPE_NS && + query_dname_compare(iq->dp->name, qstate->qinfo.qname)==0 && diff --git a/unbound-1.4.4-28093c.patch b/unbound-1.4.4-28093c.patch new file mode 100644 index 0000000..64d4319 --- /dev/null +++ b/unbound-1.4.4-28093c.patch @@ -0,0 +1,196 @@ +commit 28093c6d7d9bafbb9763fc6d9b7f222642e8a835 +Author: wouter +Date: Thu Apr 22 15:01:02 2010 +0000 + + - Fix validation failure for qtype ANY caused by a RRSIG parse failure. + The validator error message was 'no signatures from ...'. + +diff --git a/testcode/unitmsgparse.c b/testcode/unitmsgparse.c +index 43e4377..d1ef854 100644 +--- a/testcode/unitmsgparse.c ++++ b/testcode/unitmsgparse.c +@@ -45,6 +45,7 @@ + #include "util/data/msgparse.h" + #include "util/data/msgreply.h" + #include "util/data/msgencode.h" ++#include "util/data/dname.h" + #include "util/alloc.h" + #include "util/regional.h" + #include "util/net_help.h" +@@ -54,6 +55,8 @@ + static int vbmp = 0; + /** if matching within a section should disregard the order of RRs. */ + static int matches_nolocation = 0; ++/** see if RRSIGs are properly matched to RRsets. */ ++static int check_rrsigs = 0; + + /** match two rr lists */ + static int +@@ -318,6 +321,76 @@ perftestpkt(ldns_buffer* pkt, struct alloc_cache* alloc, ldns_buffer* out, + regional_destroy(region); + } + ++/** debug print a packet that failed */ ++static void ++print_packet_rrsets(struct query_info* qinfo, struct reply_info* rep) ++{ ++ size_t i; ++ ldns_rr_list* l; ++ ldns_buffer* buf = ldns_buffer_new(65536); ++ log_query_info(0, "failed query", qinfo); ++ printf(";; ANSWER SECTION (%d rrsets)\n", (int)rep->an_numrrsets); ++ for(i=0; ian_numrrsets; i++) { ++ l = packed_rrset_to_rr_list(rep->rrsets[i], buf); ++ printf("; rrset %d\n", (int)i); ++ ldns_rr_list_print(stdout, l); ++ ldns_rr_list_deep_free(l); ++ } ++ printf(";; AUTHORITY SECTION (%d rrsets)\n", (int)rep->ns_numrrsets); ++ for(i=rep->an_numrrsets; ian_numrrsets+rep->ns_numrrsets; i++) { ++ l = packed_rrset_to_rr_list(rep->rrsets[i], buf); ++ printf("; rrset %d\n", (int)i); ++ ldns_rr_list_print(stdout, l); ++ ldns_rr_list_deep_free(l); ++ } ++ printf(";; ADDITIONAL SECTION (%d rrsets)\n", (int)rep->ar_numrrsets); ++ for(i=rep->an_numrrsets+rep->ns_numrrsets; irrset_count; i++) { ++ l = packed_rrset_to_rr_list(rep->rrsets[i], buf); ++ printf("; rrset %d\n", (int)i); ++ ldns_rr_list_print(stdout, l); ++ ldns_rr_list_deep_free(l); ++ } ++ printf(";; packet end\n"); ++ ldns_buffer_free(buf); ++} ++ ++/** check that there is no data element that matches the RRSIG */ ++static int ++no_data_for_rrsig(struct reply_info* rep, struct ub_packed_rrset_key* rrsig) ++{ ++ size_t i; ++ for(i=0; irrset_count; i++) { ++ if(ntohs(rep->rrsets[i]->rk.type) == LDNS_RR_TYPE_RRSIG) ++ continue; ++ if(query_dname_compare(rep->rrsets[i]->rk.dname, ++ rrsig->rk.dname) == 0) ++ /* only name is compared right now */ ++ return 0; ++ } ++ return 1; ++} ++ ++/** check RRSIGs in packet */ ++static void ++check_the_rrsigs(struct query_info* qinfo, struct reply_info* rep) ++{ ++ /* every RRSIG must be matched to an RRset */ ++ size_t i; ++ for(i=0; irrset_count; i++) { ++ struct ub_packed_rrset_key* s = rep->rrsets[i]; ++ if(ntohs(s->rk.type) == LDNS_RR_TYPE_RRSIG) { ++ /* see if really a problem, i.e. is there a data ++ * element. */ ++ if(no_data_for_rrsig(rep, rep->rrsets[i])) ++ continue; ++ log_dns_msg("rrsig failed for packet", qinfo, rep); ++ print_packet_rrsets(qinfo, rep); ++ printf("failed rrset is nr %d\n", (int)i); ++ unit_assert(0); ++ } ++ } ++} ++ + /** test a packet */ + static void + testpkt(ldns_buffer* pkt, struct alloc_cache* alloc, ldns_buffer* out, +@@ -355,6 +428,8 @@ testpkt(ldns_buffer* pkt, struct alloc_cache* alloc, ldns_buffer* out, + (unsigned)ldns_buffer_limit(pkt), + (unsigned)ldns_buffer_limit(out)); + test_buffers(pkt, out); ++ if(check_rrsigs) ++ check_the_rrsigs(&qi, rep); + + if(ldns_buffer_limit(out) > lim) { + ret = reply_info_encode(&qi, rep, id, flags, out, +@@ -519,7 +594,9 @@ void msgparse_test() + + matches_nolocation = 1; /* RR order not important for the next test */ + testfromdrillfile(pkt, &alloc, out, "testdata/test_packets.6"); ++ check_rrsigs = 1; + testfromdrillfile(pkt, &alloc, out, "testdata/test_packets.7"); ++ check_rrsigs = 0; + matches_nolocation = 0; + + /* cleanup */ +diff --git a/testdata/test_packets.7 b/testdata/test_packets.7 +index 4f71c2c..357fa40 100644 +--- a/testdata/test_packets.7 ++++ b/testdata/test_packets.7 +@@ -17,3 +17,21 @@ A608C7155005EBEDCA2176A559EFAF28D5DA1E91F540874BAA1C46BB08B1BAAE1812699A18139CF0 + 13BBDA2EC641FB23993A72ED6606C8C85E0D1660CC1770769697CEE7EB8E6474714984D7FF41FBBE48FF4A70669101BF00320340B82DC590B2C19D0006841121DC6AC933002E00010000012C007D000105030000012C4B11ADE94AEA20E9FC600673776974636802636800561C052414445D427CE00A40ACE2DA2EC168523823830CA724B087B8116F46B3CD051C5EC5874F6FC75CF6BA846279E469C474A75F9334242BB66FDD367C73B8BBC3F8748736BC5E6AED8B9B7C5FB5FE2DEDFBF46B403BC173DE958C038CFCCAC933002E00010000012C007D001C05030000012C4B11ADE94AEA20E9FC600673776974636802636800A6F44063C12A5A8BF5BCFADD + 745C5B3915E463DA478131E636347EED414675023BBCA5BA2AABEC2FA3DF976A2343B4AA3403D1AFA3D470D25812BD1A319FBB5B833244D0FA18A59BB69ABB77BBDB3D7F62740D3871A69A5B9D43331D78AB8AE8C91B002E00010000012C007D000105030000012C4B11ADE94AEA20E9FC6006737769746368026368008906D2CFEFC3AA652125DD021CAB6392EBC4A9B4B3CFE3B07E4AFE7DA3263C7B8CE5DC3B66DA45D120E75B3D49ADC1F7D2E9A04A31760698FCFDEAB4AC82915D8E0AD2494DB4F11C02E115C3BD47DC8E57EDA7805BF0E7820A445F93A07698DF0000291000000080000000 + ++;-- es.net IN ANY about RRSIG ordering. ++687D8410000100150000000E026573036E65740000FF0001C00C00060001000151800027036E7331C00C0A686F73746D6173746572C00C77CECF4300001C2000000E100012750000000258C00C002E000100015180011A00300502000151804BE2932A4BD0101A2522026573036E657400AF2107A80A9D98A0712FF20826B95D8E686FFF023BEEAD1019045569D94D1493C84C819446ECB5489EBC6B556F4BE4B51A8E9CAC8BAA69F2B74948B78CBB197044E3D3A9E0E5EA958254637984D34BAE34167E1437D275E01C4B7C04C34053333514E1FE7EAC7C4777B02F24356F1F775526E19F54A21D3A134DC74DE153F9267008F5605D3BE38E61352BA9495D77 ++97A76735BD68350CD648F40F95ADA4B25464A615E7CD4870E23C21D681F5C68C3DE9477D2EC7216FDF3269F5993428D0F1A4B7E203A04AB6807836263FDD7D6796BE6D84478B906B802DEBDCB1E0870481388503F0396CAD24147BC819A855E6CBCE98526ECAF8423450E30CB4F59C7062C069002E000100015180009A00300502000151804BE2932A4BD0101A4BA3026573036E657400602356C2D379E94F97D2900473D118288D46CFBCAAFF73D8A6FDF0B4305E8B338DD53A90106CDD78BF82A1AEC20B7C02067FDE1BEEC912E5581687BB32DD8BDC7E84B3F844F01E198E75C179194447C13B568886B33933FF35370060440D64E2DB7446962CA348C199 ++DDFE4AA252AFFDEB3A818D1BF45CD795EA0907332B4508C18F002E000100015180009A00060502000151804BE2932A4BD0101A4BA3026573036E6574004FFB07563C6F88028C0E09CF163BAC777065BDCC826C583A3B3ABD525D6AF5101A6D5533888E5BAAA33DE28B52330815E14034506C4C69EDE8AD1A1F00B486C670FE0DC2F3B5F7210EBAC66695CC8679F2CA2353666A143A2E3E87377DCD8D3E6E450934BBD4CC6F9EE033E11D05CA3F44B1A64A2666E3AF2A8710F16FF8CC33C235002E000100000258009A002F0502000002584BE2932A4BD0101A4BA3026573036E6574003D2DDC713285C7338263BD338AFEEAB77571054B1F483A7BADC87BAF32 ++0740A8D1B8B28CB23E04A80F90979704B44FE379103F4D91482D0EBC1D7005E326668F30B2A434F9DE76BB90DFEF2BFEDEE8CAD62164CA089651AB31498F18ED9A1E5694B4D460FFA4E667950322B2A75E8FD408B6A54EDB00257CE44AC865D1567346C2DB002E000100000258009A00100502000002584BE2932A4BD0101A4BA3026573036E6574004367180234A327C0AF72B3963518FC6E53A43E92CE6F5560E383FE8E7EF258FEA28BA666C026A90DAB67F46FBA4FF82F2704FEB3A27E25F3A8E6874B78938D70C5A20D94BEC90596B55C594F94A1438B14C8F890CE61D9630EFD897DEA9B3995D2C668469F62DB9346BB6AAF2EB6F3EE20EC31EAC80BCB ++962105A64CCD5783EFC381002E000100000258009A000F0502000002584BE2932A4BD0101A4BA3026573036E657400D36D367D4D95060CB2952870BE9E826E6F7835CF6517FF83957F5097B6FC401FE5815B8895D02C68E23A47D7015A3DCE9FDE63AF9D9E1D697016444355633D0BE03177B35BE54980B241C12978A7F3EBF2420861EBFAA028CAF9FCBBF54C069869BFB7F9AB9E60D4791ACCA276AE698EB6EF7582235977E158DA8530EC84327EC427002E000100000258009A00010502000002584BE2932A4BD0101A4BA3026573036E65740068E7176D8561B49621F80DB36DC12A3C5DCD2DE5FE3973F5D7DE15769F099F2A1A9BB088042E794747E3AB ++BB4AE48651F815D5D38BE7F4FB94F08F51FC209246296BE108111E90A7A5E2A5A79D305F81DBE313569B72598F36F3CFAA02FD9F321FBC2BDA10861F1D537D48DDF80BBF4B228724636FD79C06C4487365F602E6F5C4CD002E000100000258009A00020502000002584BE2932A4BD0101A4BA3026573036E657400BAA98093DDB57F38CA58C599EEED47F16AA20C1CCF668FF0A022AFAAC97059A28C50FE63034E58FBE361059B43FCBAE3876AC6AE8450987B8A00BEC29093267B9B655E645B7478294FF5E149984459A39D191585463BD80F635C21DBCF30462E60E4EACF8EECC25E4D02C181954CCBB8BDF5D19882CF6F9E982B1BEBEF14797DC573003000 ++0100015180008801000305030100017D08356710D7E8A11F9B4C29E5E0F6B65F18CE64B4AAFAD7EA0E08DB85013CD777436CB8BC4EE33C0B4E6EEDFBE4227B25354F2EA2F978EE3222F3F32C1D4D3AF0F6014A527981FC5A0D2B65BF78B86A1D37965A98CAE3746CBB250655C2200FB9B8EBCC8C0AFD3182738F246AD0DAACA3199C54F08CF5F666477281872710E7C573003000010001518000880100030503010001DF43A43270EA741D5E79034C5E46A8310C9CFC7BD65C532D815D6B8C245EFF8F0C365DE400B6CDAC0124B00E08017DFB98D91133D5C18251EE0868852AD9E7FED091B393DAD1CD57381A5A1E7EA74E8FB4B708DB0F93B9EA4296EA4A71 ++6E3572F168779CB5288880699413B3FFD4B7432EBE2AA2767B8EA6CB576A65C5163A3DC5730030000100015180010801010305030100017DA2FA058940109205AA36338EB8AA8B5B0D9788C4229368D371DBDE4BD24F0805C60EDD8DF223D250F23D189CDC434F388A91D6CEC1A9D6F305817409ACA784F381DFFD7EC3EC688FFE16D2AC57BD7F0B625EFC3099B3A9A5EDA1742460229669DD67D81F12069877F6AFA497F81EB12D179B183F5C8185B2786B790BEAFB6D02E0F94C780065511CF46AF80D40055022867DF712869CC262C0D315B92DFA96D58BC2336DAB5D1258DD60406913D116DC2EC1135D89C6D2092C35A19C67959743B407A3C30F3C6B8B ++C4763504FE12541EDD947A5FBE8E402D31816D1824867E2CD89AEE5FF6ED7A2D683B8C5E6B7B5972BDFF355BFD9128F0D0EDB59A60F321C573003000010001518001080101030503010001DD8EC709089B6D74BAF2D294E4C626CF789B89A74B7E320D7002A03D0F94EA62DF1F19717FE8C4BFD732DA495E481353C78167255CC6256A98ACBFF5977B81A48C5E2A5AF23E8377423C4034D5D84E9E3548B9D0A07955586F67324B6B5720CC4456D86AEE3A21A4EBED9BA13358C8127D182A5083739B042D7E06307E417D020DD68EC0628E9C8279AF0F7E608A3C5D51AB33BF7C32EBD27B45D72B1AD5752BB485D52488FBA9A1B5BF3B2B50F074F481171E4B65 ++3AF846E58FE46DEB3491FA683959B38B893BF55721CED8FC4A64DBEDB6BF1C7FADE650EE219A01E81DD0212B89259319CA5DC81F26821A5CC29B4CC1059AE28227B89B8816039E43C35E33C57300300001000151800108018103050301000188F31BEFA3466D6FCAF11E0D1954D2011D6EAECF922D9E1B8D620095A0D15E7CFF8EA33F8E2A8C3B3F45A1ADACFED62E3E4EDC884AEF8A7CADBCFF8EDF2158730136D01BDB6D057BEBF3D35A92ADB5E8ACB1152FE1244B2D36DCB500E952CFB6D744BF7DBAB24A901B984F869FF47113C9515D53FE1A57293B01C24195A1D40580566CDAE5B04348CB60507267BB38F34839EE959D43FB9605652157014059FDBD ++39EB0836D4043A63F8660D241006F757DB92B35B39B5ABCA32A16A81C65C9F53DA79A99F1134CF3ED5304F189434AF787A3A10D63862E6C2E5FBA08B6EF6701783DB00CB41851DF13070947EEC090FCED3539F3F494170BD90E68F99453DF9C573002F00010000025800220B726573657276652D3132380231340131026573036E657400000762018000000380CA7C0010000100000258009C9B763D73706631206D7820613A6D61696C312E65732E6E657420613A6D61696C322E65732E6E657420613A6D61696C332E65732E6E657420613A6D61696C342E65732E6E657420613A6D61696C2E65732E6E657420613A6D61696C67772E65732E6E657420613A ++706F7374616C312E65732E6E657420613A706F7374616C322E65732E6E657420613A706F7374616C332E65732E6E6574207E616C6CCA7C000F00010000025800090032046D61696CCA7CCA7C00010001000002580004C6800370CA7C00020001000002580009066E732D616F61CA7CCA7C00020001000002580002C024CA7C00020001000002580009066E732D6C766BCA7CCB4300010001000002580004C0BC1609CB43001C000100000258001020010400FFFFFFFFFFFFFFFFFFFFFF81C02400010001000151800004C680020AC024001C000100000258001020010400001400020000000000000010CB6600010001000002580004C67CFC16CB66001C0001 ++00000258001020010400600000000000000000000022CB8900010001000002580004C681FC22CB89001C000100000258001020010400091000010000000000000002CB43002E000100000258009A00010503000002584BE2932A4BD0101A4BA3026573036E657400B425467E45E411066B99B85420FB7E844D734F414FFAF6B9528867B3DF808733BF479A0F125C84179401306579994AB8D84DF0173E2824527CEDA45C75ED4D818722EEB2D5A37641108B112D9A6D832D29A507C35DBBEBD46D50DE9915E924F53F55B5A2A263A48B48209FB50A13A7DF40AE697B1BCCE71A2B95C1BB9E47ACCACB43002E000100000258009A001C0503000002584BE2932A ++4BD0101A4BA3026573036E6574002588E73F85BE8FAFD09628232906913DB78592B59F9C3C95A4AD1334D383C1326EE0C6FCF38892D8BB74631D680A6E4DB2D603D32394BC7B4EC798A1511667D246A0C30B33D03AB144C3704AA80AFCA27F197B2F83F20A9F0D2835C7C0A9B49E47E7CF2E192DC7DBF4635C39ECCCB291DB4B2832E0B8FF430A75726500194D9EC024002E000100015180009A00010503000151804BE2932A4BD0101A4BA3026573036E6574000E9F4098B1EF4F429B802007E3A9EA8E267A1F78EA7241AADD120A74CEBF70DC1DF76065A2CE0CDAA51AAB2F68411D9DEDC1F9DBEB3AB114A1FCBE122610756DE205EEC576CA5E62BD02497F ++84D5DDB7110AC7F2BF02485B3E7B28FC1EB2999724B64D811270B085D1D10E184295D423F0141D652BD7E97633AC2E98C2819EDAC024002E000100000258009A001C0503000002584BE2932A4BD0101A4BA3026573036E657400936ADA283A90836E92BD42E2B6C8A0299147BCB8E47D9D4464C4151FCC99DC4F2D1C39FB691F6E322715B22F61E7BB8D5507982A3119674B350C569BDC2CD95C708EC73B4E5DEA516D053A4FD725326FFC5B0D0562B542BA96124D9FFBBF787CA0BBE6960951CC2FDD074376A1D184287C2C56A93FBBC1C7FFAA6977B30AE808CB66002E000100000258009A00010503000002584BE2932A4BD0101A4BA3026573036E657400 ++0CE145578E56BB359606C9B85538450D2BCA3E9AD0DEFC8FF865DA646F900B9CBC7325B7F04706B60E2770107E62894FE9CF3B1A432F0FB53C5C7A8F37D0F60354C7D52F4DF88BDD4C46774AA728DFC1C807EF5276641CA28774F323C7326B7C1D99DFCB9498C6E096392009AA972B83F0583A5D1002CA26B59B5C97F6A8309C0000291000000080000000 ++ +diff --git a/util/data/msgparse.c b/util/data/msgparse.c +index 2db8832..ae6dfc1 100644 +--- a/util/data/msgparse.c ++++ b/util/data/msgparse.c +@@ -335,16 +335,20 @@ moveover_rrsigs(ldns_buffer* pkt, struct regional* region, + struct rr_parse* sig = sigset->rr_first; + struct rr_parse* prev = NULL; + struct rr_parse* insert; ++ struct rr_parse* nextsig; + while(sig) { ++ nextsig = sig->next; + if(pkt_rrsig_covered_equals(pkt, sig->ttl_data, + dataset->type)) { + if(duplicate) { + /* new */ + insert = (struct rr_parse*)regional_alloc( + region, sizeof(struct rr_parse)); ++ if(!insert) return 0; + insert->outside_packet = 0; + insert->ttl_data = sig->ttl_data; + insert->size = sig->size; ++ /* prev not used */ + } else { + /* remove from sigset */ + if(prev) prev->next = sig->next; +@@ -354,6 +358,7 @@ moveover_rrsigs(ldns_buffer* pkt, struct regional* region, + sigset->rr_count--; + sigset->size -= sig->size; + insert = sig; ++ /* prev not changed */ + } + /* add to dataset */ + dataset->rrsig_count++; +@@ -363,9 +368,9 @@ moveover_rrsigs(ldns_buffer* pkt, struct regional* region, + else dataset->rrsig_first = insert; + dataset->rrsig_last = insert; + dataset->size += insert->size; +- } +- prev = sig; +- sig = sig->next; ++ } else ++ prev = sig; ++ sig = nextsig; + } + return 1; + } diff --git a/unbound-1.4.4-374822.patch b/unbound-1.4.4-374822.patch new file mode 100644 index 0000000..f99b55a --- /dev/null +++ b/unbound-1.4.4-374822.patch @@ -0,0 +1,38 @@ +commit 374822322e33503d3576c85b3e43fef158a80e42 +Author: wouter +Date: Thu Apr 29 12:36:12 2010 +0000 + + dnssec lameness detection looks in key cache if dnssec is expected. + +diff --git a/iterator/iter_utils.c b/iterator/iter_utils.c +index 6124650..f63b6fe 100644 +--- a/iterator/iter_utils.c ++++ b/iterator/iter_utils.c +@@ -60,6 +60,8 @@ + #include "util/random.h" + #include "util/fptr_wlist.h" + #include "validator/val_anchor.h" ++#include "validator/val_kcache.h" ++#include "validator/val_kentry.h" + + /** time when nameserver glue is said to be 'recent' */ + #define SUSPICION_RECENT_EXPIRY 86400 +@@ -570,6 +572,18 @@ iter_indicates_dnssec(struct module_env* env, struct delegpt* dp, + reply_find_rrset_section_ns(msg->rep, dp->name, dp->namelen, + LDNS_RR_TYPE_DS, dclass)) + return 1; ++ /* look in key cache */ ++ if(env->key_cache) { ++ struct key_entry_key* kk = key_cache_obtain(env->key_cache, ++ dp->name, dp->namelen, dclass, env->scratch, *env->now); ++ if(kk) { ++ if(key_entry_isgood(kk) || key_entry_isbad(kk)) { ++ regional_free_all(env->scratch); ++ return 1; ++ } ++ regional_free_all(env->scratch); ++ } ++ } + return 0; + } + diff --git a/unbound-1.4.4-40d18f.patch b/unbound-1.4.4-40d18f.patch new file mode 100644 index 0000000..23e73ae --- /dev/null +++ b/unbound-1.4.4-40d18f.patch @@ -0,0 +1,153 @@ +commit 40d18f7cfb64a806699545410858b655e76660e1 +Author: wouter +Date: Tue May 4 08:39:04 2010 +0000 + + - Fix dnssec-missing detection that was turned off by server selection. + +diff --git a/iterator/iter_utils.c b/iterator/iter_utils.c +index b3a31fa..3a75d03 100644 +--- a/iterator/iter_utils.c ++++ b/iterator/iter_utils.c +@@ -310,7 +310,7 @@ iter_filter_order(struct iter_env* iter_env, struct module_env* env, + struct delegpt_addr* + iter_server_selection(struct iter_env* iter_env, + struct module_env* env, struct delegpt* dp, +- uint8_t* name, size_t namelen, uint16_t qtype, int* dnssec_expected, ++ uint8_t* name, size_t namelen, uint16_t qtype, int* dnssec_lame, + int* chase_to_rd, int open_target, struct sock_list* blacklist) + { + int sel; +@@ -331,7 +331,7 @@ iter_server_selection(struct iter_env* iter_env, + if(selrtt-BLACKLIST_PENALTY > USEFUL_SERVER_TOP_TIMEOUT) { + verbose(VERB_ALGO, "chase to " + "blacklisted dnssec lame server"); +- *dnssec_expected = 0; ++ *dnssec_lame = 1; + } + } else { + if(selrtt > USEFUL_SERVER_TOP_TIMEOUT*2) { +@@ -340,7 +340,7 @@ iter_server_selection(struct iter_env* iter_env, + } + if(selrtt > USEFUL_SERVER_TOP_TIMEOUT) { + verbose(VERB_ALGO, "chase to dnssec lame server"); +- *dnssec_expected = 0; ++ *dnssec_lame = 1; + } + if(selrtt == USEFUL_SERVER_TOP_TIMEOUT) { + verbose(VERB_ALGO, "chase to blacklisted lame server"); +diff --git a/iterator/iter_utils.h b/iterator/iter_utils.h +index a9f4247..d3870ec 100644 +--- a/iterator/iter_utils.h ++++ b/iterator/iter_utils.h +@@ -80,7 +80,7 @@ int iter_apply_cfg(struct iter_env* iter_env, struct config_file* cfg); + * @param name: zone name (for lameness check). + * @param namelen: length of name. + * @param qtype: query type that we want to send. +- * @param dnssec_expected: set to 0, if a known dnssec-lame server is selected ++ * @param dnssec_lame: set to 1, if a known dnssec-lame server is selected + * these are not preferred, but are used as a last resort. + * @param chase_to_rd: set to 1 if a known recursion lame server is selected + * these are not preferred, but are used as a last resort. +@@ -92,7 +92,7 @@ int iter_apply_cfg(struct iter_env* iter_env, struct config_file* cfg); + */ + struct delegpt_addr* iter_server_selection(struct iter_env* iter_env, + struct module_env* env, struct delegpt* dp, uint8_t* name, +- size_t namelen, uint16_t qtype, int* dnssec_expected, ++ size_t namelen, uint16_t qtype, int* dnssec_lame, + int* chase_to_rd, int open_target, struct sock_list* blacklist); + + /** +diff --git a/iterator/iterator.c b/iterator/iterator.c +index 19b9a26..6f486bf 100644 +--- a/iterator/iterator.c ++++ b/iterator/iterator.c +@@ -120,6 +120,7 @@ iter_new(struct module_qstate* qstate, int id) + iq->wait_priming_stub = 0; + iq->refetch_glue = 0; + iq->dnssec_expected = 0; ++ iq->dnssec_lame_query = 0; + iq->chase_flags = qstate->query_flags; + /* Start with the (current) qname. */ + iq->qchase = qstate->qinfo; +@@ -1451,8 +1452,8 @@ processQueryTargets(struct module_qstate* qstate, struct iter_qstate* iq, + /* Select the next usable target, filtering out unsuitable targets. */ + target = iter_server_selection(ie, qstate->env, iq->dp, + iq->dp->name, iq->dp->namelen, iq->qchase.qtype, +- &iq->dnssec_expected, &iq->chase_to_rd, iq->num_target_queries, +- qstate->blacklist); ++ &iq->dnssec_lame_query, &iq->chase_to_rd, ++ iq->num_target_queries, qstate->blacklist); + + /* If no usable target was selected... */ + if(!target) { +@@ -1530,10 +1531,14 @@ processQueryTargets(struct module_qstate* qstate, struct iter_qstate* iq, + } + + /* We have a valid target. */ +- if(iq->dnssec_expected) verbose(VERB_ALGO, "dnssec is expected"); +- log_query_info(VERB_QUERY, "sending query:", &iq->qchase); +- log_name_addr(VERB_QUERY, "sending to target:", iq->dp->name, +- &target->addr, target->addrlen); ++ if(verbosity >= VERB_QUERY) { ++ log_query_info(VERB_QUERY, "sending query:", &iq->qchase); ++ log_name_addr(VERB_QUERY, "sending to target:", iq->dp->name, ++ &target->addr, target->addrlen); ++ verbose(VERB_ALGO, "dnssec status: %s%s", ++ iq->dnssec_expected?"expected": "not expected", ++ iq->dnssec_lame_query?" but lame_query anyway": ""); ++ } + fptr_ok(fptr_whitelist_modenv_send_query(qstate->env->send_query)); + outq = (*qstate->env->send_query)( + iq->qchase.qname, iq->qchase.qname_len, +@@ -1587,6 +1592,7 @@ processQueryResponse(struct module_qstate* qstate, struct iter_qstate* iq, + iq->num_current_queries--; + if(iq->response == NULL) { + iq->chase_to_rd = 0; ++ iq->dnssec_lame_query = 0; + verbose(VERB_ALGO, "query response was timeout"); + return next_state(iq, QUERYTARGETS_STATE); + } +@@ -1599,7 +1605,8 @@ processQueryResponse(struct module_qstate* qstate, struct iter_qstate* iq, + * differently. No queries should be sent elsewhere */ + type = RESPONSE_TYPE_ANSWER; + } +- if(iq->dnssec_expected && !(iq->chase_flags&BIT_RD) ++ if(iq->dnssec_expected && !iq->dnssec_lame_query && ++ !(iq->chase_flags&BIT_RD) + && type != RESPONSE_TYPE_LAME + && type != RESPONSE_TYPE_REC_LAME + && type != RESPONSE_TYPE_THROWAWAY +@@ -1615,7 +1622,7 @@ processQueryResponse(struct module_qstate* qstate, struct iter_qstate* iq, + type = RESPONSE_TYPE_LAME; + dnsseclame = 1; + } +- } ++ } else iq->dnssec_lame_query = 0; + /* see if referral brings us close to the target */ + if(type == RESPONSE_TYPE_REFERRAL) { + struct ub_packed_rrset_key* ns = find_NS( +@@ -1764,7 +1771,6 @@ processQueryResponse(struct module_qstate* qstate, struct iter_qstate* iq, + /* Clear the query state, since this is a query restart. */ + iq->deleg_msg = NULL; + iq->dp = NULL; +- iq->dnssec_expected = 0; + /* Note the query restart. */ + iq->query_restart_count++; + +diff --git a/iterator/iterator.h b/iterator/iterator.h +index 736af51..350fb1d 100644 +--- a/iterator/iterator.h ++++ b/iterator/iterator.h +@@ -255,6 +255,12 @@ struct iter_qstate { + int dnssec_expected; + + /** ++ * We are expecting dnssec information, but we also know the server ++ * is DNSSEC lame. The response need not be marked dnssec-lame again. ++ */ ++ int dnssec_lame_query; ++ ++ /** + * This is flag that, if true, means that this event is + * waiting for a stub priming query. + */ diff --git a/unbound-1.4.4-41b631.patch b/unbound-1.4.4-41b631.patch new file mode 100644 index 0000000..29cff37 --- /dev/null +++ b/unbound-1.4.4-41b631.patch @@ -0,0 +1,159 @@ +commit 41b631ca4182e68b09eecdaec7d67ac576f3800d +Author: wouter +Date: Tue Apr 27 11:10:35 2010 +0000 + + - fix retry sequence if prime hints are recursion-lame. + +diff --git a/iterator/iterator.c b/iterator/iterator.c +index b1a948d..08354e8 100644 +--- a/iterator/iterator.c ++++ b/iterator/iterator.c +@@ -1897,8 +1897,11 @@ static int + processPrimeResponse(struct module_qstate* qstate, int id) + { + struct iter_qstate* iq = (struct iter_qstate*)qstate->minfo[id]; +- enum response_type type = response_type_from_server(0, iq->response, +- &iq->qchase, iq->dp); ++ enum response_type type; ++ iq->response->rep->flags &= ~(BIT_RD|BIT_RA); /* ignore rec-lame */ ++ type = response_type_from_server( ++ (int)((iq->chase_flags&BIT_RD) || iq->chase_to_rd), ++ iq->response, &iq->qchase, iq->dp); + if(type == RESPONSE_TYPE_ANSWER) { + qstate->return_rcode = LDNS_RCODE_NOERROR; + qstate->return_msg = iq->response; +@@ -2230,7 +2233,7 @@ void + iter_inform_super(struct module_qstate* qstate, int id, + struct module_qstate* super) + { +- if(super->qinfo.qclass == LDNS_RR_CLASS_ANY) ++ if(!qstate->is_priming && super->qinfo.qclass == LDNS_RR_CLASS_ANY) + processClassResponse(qstate, id, super); + else if(qstate->return_rcode != LDNS_RCODE_NOERROR) + error_supers(qstate, id, super); +diff --git a/testdata/iter_hint_lame.rpl b/testdata/iter_hint_lame.rpl +new file mode 100644 +index 0000000..8cbede1 +--- /dev/null ++++ b/testdata/iter_hint_lame.rpl +@@ -0,0 +1,120 @@ ++; config options ++server: ++ target-fetch-policy: "0 0 0 0 0" ++ ++stub-zone: ++ name: "." ++ stub-addr: 193.0.14.129 # K.ROOT-SERVERS.NET. ++CONFIG_END ++ ++SCENARIO_BEGIN Test iterative resolve with lame hints. ++ ++; K.ROOT-SERVERS.NET. ++RANGE_BEGIN 0 100 ++ ADDRESS 193.0.14.129 ++ENTRY_BEGIN ++MATCH opcode qtype qname ++ADJUST copy_id ++REPLY QR RA NOERROR ++SECTION QUESTION ++. IN NS ++SECTION ANSWER ++. IN NS K.ROOT-SERVERS.NET. ++SECTION ADDITIONAL ++K.ROOT-SERVERS.NET. IN A 193.0.14.129 ++ENTRY_END ++ ++ENTRY_BEGIN ++MATCH opcode qtype qname ++ADJUST copy_id ++REPLY QR RA NOERROR ++SECTION QUESTION ++www.example.com. IN A ++SECTION AUTHORITY ++com. IN NS a.gtld-servers.net. ++SECTION ADDITIONAL ++a.gtld-servers.net. IN A 192.5.6.30 ++ENTRY_END ++RANGE_END ++ ++; a.gtld-servers.net. ++RANGE_BEGIN 0 100 ++ ADDRESS 192.5.6.30 ++ENTRY_BEGIN ++MATCH opcode qtype qname ++ADJUST copy_id ++REPLY QR NOERROR ++SECTION QUESTION ++com. IN NS ++SECTION ANSWER ++com. IN NS a.gtld-servers.net. ++SECTION ADDITIONAL ++a.gtld-servers.net. IN A 192.5.6.30 ++ENTRY_END ++ ++ENTRY_BEGIN ++MATCH opcode qtype qname ++ADJUST copy_id ++REPLY QR NOERROR ++SECTION QUESTION ++www.example.com. IN A ++SECTION AUTHORITY ++example.com. IN NS ns.example.com. ++SECTION ADDITIONAL ++ns.example.com. IN A 1.2.3.4 ++ENTRY_END ++RANGE_END ++ ++; ns.example.com. ++RANGE_BEGIN 0 100 ++ ADDRESS 1.2.3.4 ++ENTRY_BEGIN ++MATCH opcode qtype qname ++ADJUST copy_id ++REPLY QR NOERROR ++SECTION QUESTION ++example.com. IN NS ++SECTION ANSWER ++example.com. IN NS ns.example.com. ++SECTION ADDITIONAL ++ns.example.com. IN A 1.2.3.4 ++ENTRY_END ++ ++ENTRY_BEGIN ++MATCH opcode qtype qname ++ADJUST copy_id ++REPLY QR NOERROR ++SECTION QUESTION ++www.example.com. IN A ++SECTION ANSWER ++www.example.com. IN A 10.20.30.40 ++SECTION AUTHORITY ++example.com. IN NS ns.example.com. ++SECTION ADDITIONAL ++ns.example.com. IN A 1.2.3.4 ++ENTRY_END ++RANGE_END ++ ++STEP 1 QUERY ++ENTRY_BEGIN ++REPLY RD ++SECTION QUESTION ++www.example.com. IN A ++ENTRY_END ++ ++; recursion happens here. ++STEP 10 CHECK_ANSWER ++ENTRY_BEGIN ++MATCH all ++REPLY QR RD RA NOERROR ++SECTION QUESTION ++www.example.com. IN A ++SECTION ANSWER ++www.example.com. IN A 10.20.30.40 ++SECTION AUTHORITY ++example.com. IN NS ns.example.com. ++SECTION ADDITIONAL ++ns.example.com. IN A 1.2.3.4 ++ENTRY_END ++ ++SCENARIO_END diff --git a/unbound-1.4.4-5e989a.patch b/unbound-1.4.4-5e989a.patch new file mode 100644 index 0000000..2c66bb4 --- /dev/null +++ b/unbound-1.4.4-5e989a.patch @@ -0,0 +1,51 @@ +commit 5e989a15b927094a83d0f3a08be0cd559e29d3ff +Author: wouter +Date: Fri Apr 23 09:07:05 2010 +0000 + + - Fix to fetch data as last resort more tenaciously. When cycle + targets cause the server selection to believe there are more options + when they really are not there, the server selection is reinitiated. + - Fix fetch from blacklisted dnssec lame servers as last resort. The + servers IP address is then given in validator errors as well. + +diff --git a/iterator/iter_utils.c b/iterator/iter_utils.c +index a706e6b..9082055 100644 +--- a/iterator/iter_utils.c ++++ b/iterator/iter_utils.c +@@ -322,9 +322,15 @@ iter_server_selection(struct iter_env* iter_env, + verbose(VERB_ALGO, "selrtt %d", selrtt); + if(selrtt > BLACKLIST_PENALTY) { + if(selrtt-BLACKLIST_PENALTY > USEFUL_SERVER_TOP_TIMEOUT*2) { +- verbose(VERB_ALGO, "chase to recursion lame server"); ++ verbose(VERB_ALGO, "chase to " ++ "blacklisted recursion lame server"); + *chase_to_rd = 1; + } ++ if(selrtt-BLACKLIST_PENALTY > USEFUL_SERVER_TOP_TIMEOUT) { ++ verbose(VERB_ALGO, "chase to " ++ "blacklisted dnssec lame server"); ++ *dnssec_expected = 0; ++ } + } else { + if(selrtt > USEFUL_SERVER_TOP_TIMEOUT*2) { + verbose(VERB_ALGO, "chase to recursion lame server"); +diff --git a/iterator/iterator.c b/iterator/iterator.c +index e8345c8..c7cdbc8 100644 +--- a/iterator/iterator.c ++++ b/iterator/iterator.c +@@ -1469,6 +1469,15 @@ processQueryTargets(struct module_qstate* qstate, struct iter_qstate* iq, + return error_response(qstate, id, + LDNS_RCODE_SERVFAIL); + } ++ if(qs == 0 && ++ delegpt_count_missing_targets(iq->dp) == 0){ ++ /* it looked like there were missing ++ * targets, but they did not turn up. ++ * Try the bad choices again (if any), ++ * when we get back here missing==0, ++ * so this is not a loop. */ ++ return 1; ++ } + iq->num_target_queries += qs; + } + /* Since a target query might have been made, we diff --git a/unbound-1.4.4-5f58ed.patch b/unbound-1.4.4-5f58ed.patch new file mode 100644 index 0000000..5664e1b --- /dev/null +++ b/unbound-1.4.4-5f58ed.patch @@ -0,0 +1,18 @@ +commit 5f58ed252d7bcd500ebedfb351e3ce7c84c44211 +Author: wouter +Date: Tue Apr 27 09:16:23 2010 +0000 + + unbound-control get_option domain-insecure works. + +diff --git a/util/config_file.c b/util/config_file.c +index aca82e1..ec0866c 100644 +--- a/util/config_file.c ++++ b/util/config_file.c +@@ -609,6 +609,7 @@ config_get_option(struct config_file* cfg, const char* opt, + else O_LST(opt, "trusted-keys-file", trusted_keys_file_list) + else O_LST(opt, "dlv-anchor", dlv_anchor_list) + else O_LST(opt, "control-interface", control_ifs) ++ else O_LST(opt, "domain-insecure", domain_insecure) + else O_UNS(opt, "val-override-date", val_date_override) + /* not here: + * outgoing-permit, outgoing-avoid - have list of ports diff --git a/unbound-1.4.4-74d75e.patch b/unbound-1.4.4-74d75e.patch new file mode 100644 index 0000000..95a88ad --- /dev/null +++ b/unbound-1.4.4-74d75e.patch @@ -0,0 +1,26 @@ +commit 74d75e591a6f5343109922f2bf1f83eba59f0a4f +Author: wouter +Date: Thu Apr 29 12:52:44 2010 +0000 + + fix for key cache lookup + +diff --git a/iterator/iter_utils.c b/iterator/iter_utils.c +index f63b6fe..b3a31fa 100644 +--- a/iterator/iter_utils.c ++++ b/iterator/iter_utils.c +@@ -577,9 +577,14 @@ iter_indicates_dnssec(struct module_env* env, struct delegpt* dp, + struct key_entry_key* kk = key_cache_obtain(env->key_cache, + dp->name, dp->namelen, dclass, env->scratch, *env->now); + if(kk) { +- if(key_entry_isgood(kk) || key_entry_isbad(kk)) { ++ if(query_dname_compare(kk->name, dp->name) == 0) { ++ if(key_entry_isgood(kk) || key_entry_isbad(kk)) { + regional_free_all(env->scratch); + return 1; ++ } else if(key_entry_isnull(kk)) { ++ regional_free_all(env->scratch); ++ return 0; ++ } + } + regional_free_all(env->scratch); + } diff --git a/unbound-1.4.4-778d4a.patch b/unbound-1.4.4-778d4a.patch new file mode 100644 index 0000000..de05c0e --- /dev/null +++ b/unbound-1.4.4-778d4a.patch @@ -0,0 +1,77 @@ +commit 778d4ab54a4e9efb41b042607b9a685853c5483c +Author: wouter +Date: Fri Apr 23 14:03:09 2010 +0000 + + - Fix local-zone type redirect that did not use the query name for + the answer rrset. + +diff --git a/services/localzone.c b/services/localzone.c +index dba7f3b..b8da77a 100644 +--- a/services/localzone.c ++++ b/services/localzone.c +@@ -1040,10 +1040,10 @@ local_data_answer(struct local_zone* z, struct query_info* qinfo, + if(!lr) + return 0; + if(z->type == local_zone_redirect) { +- /* convert rrset name to zone name; like a wildcard */ ++ /* convert rrset name to query name; like a wildcard */ + struct ub_packed_rrset_key r = *lr->rrset; +- r.rk.dname = z->name; +- r.rk.dname_len = z->namelen; ++ r.rk.dname = qinfo->qname; ++ r.rk.dname_len = qinfo->qname_len; + return local_encode(qinfo, edns, buf, temp, &r, 1, + LDNS_RCODE_NOERROR); + } +diff --git a/testdata/localdata.rpl b/testdata/localdata.rpl +index 5bb259e..08aec6d 100644 +--- a/testdata/localdata.rpl ++++ b/testdata/localdata.rpl +@@ -30,6 +30,10 @@ server: + ; refuse zone (error) + local-zone: "refuse.top." refuse + ++ ; redirect zone ++ local-zone: "redirect.top." redirect ++ local-data: "redirect.top. A 20.30.40.54" ++ + ; create implicit data in the IN domain as well + local-data: "a.a.implicit. A 20.30.41.50" + local-data: "b.a.implicit. A 20.30.42.50" +@@ -318,4 +322,36 @@ www.deny.top. IN A + ENTRY_END + ; no answer is checked at exit of testbound. + ++; redirect zone apex ++STEP 50 QUERY ++ENTRY_BEGIN ++SECTION QUESTION ++redirect.top. IN A ++ENTRY_END ++STEP 51 CHECK_ANSWER ++ENTRY_BEGIN ++MATCH all ++REPLY QR RA AA NOERROR ++SECTION QUESTION ++redirect.top. IN A ++SECTION ANSWER ++redirect.top. IN A 20.30.40.54 ++ENTRY_END ++ ++; redirect zone ++STEP 52 QUERY ++ENTRY_BEGIN ++SECTION QUESTION ++www.redirect.top. IN A ++ENTRY_END ++STEP 53 CHECK_ANSWER ++ENTRY_BEGIN ++MATCH all ++REPLY QR RA AA NOERROR ++SECTION QUESTION ++www.redirect.top. IN A ++SECTION ANSWER ++www.redirect.top. IN A 20.30.40.54 ++ENTRY_END ++ + SCENARIO_END diff --git a/unbound-1.4.4-7f27d6.patch b/unbound-1.4.4-7f27d6.patch new file mode 100644 index 0000000..76b8d77 --- /dev/null +++ b/unbound-1.4.4-7f27d6.patch @@ -0,0 +1,88 @@ +commit 7f27d6c9992fec6847ae914f38db6a3d1b28e81a +Author: wouter +Date: Thu Apr 29 14:12:54 2010 +0000 + + - infra cache entries that are expired are wiped clean. Previously + it was possible to not expire host data (if accessed often). + +diff --git a/services/cache/infra.c b/services/cache/infra.c +index 9c32c81..6066f98 100644 +--- a/services/cache/infra.c ++++ b/services/cache/infra.c +@@ -187,6 +187,19 @@ infra_lookup_host(struct infra_cache* infra, + return data; + } + ++/** init the host elements (not lame elems) */ ++static void ++host_entry_init(struct infra_cache* infra, struct lruhash_entry* e, ++ uint32_t timenow) ++{ ++ struct infra_host_data* data = (struct infra_host_data*)e->data; ++ data->ttl = timenow + infra->host_ttl; ++ rtt_init(&data->rtt); ++ data->edns_version = 0; ++ data->edns_lame_known = 0; ++ data->num_timeouts = 0; ++} ++ + /** + * Create and init a new entry for a host + * @param infra: infra structure with config parameters. +@@ -216,12 +229,8 @@ new_host_entry(struct infra_cache* infra, struct sockaddr_storage* addr, + key->entry.data = (void*)data; + key->addrlen = addrlen; + memcpy(&key->addr, addr, addrlen); +- data->ttl = tm + infra->host_ttl; + data->lameness = NULL; +- data->edns_version = 0; +- data->edns_lame_known = 0; +- data->num_timeouts = 0; +- rtt_init(&data->rtt); ++ host_entry_init(infra, &key->entry, tm); + return &key->entry; + } + +@@ -240,12 +249,8 @@ infra_host(struct infra_cache* infra, struct sockaddr_storage* addr, + if(e) { + /* if its still there we have a writelock, init */ + /* re-initialise */ +- data = (struct infra_host_data*)e->data; +- data->ttl = timenow + infra->host_ttl; +- rtt_init(&data->rtt); + /* do not touch lameness, it may be valid still */ +- data->edns_version = 0; +- data->edns_lame_known = 0; ++ host_entry_init(infra, e, timenow); + } + } + if(!e) { +@@ -469,10 +474,11 @@ infra_rtt_update(struct infra_cache* infra, + if(!(e = new_host_entry(infra, addr, addrlen, timenow))) + return 0; + needtoinsert = 1; +- } +- /* have an entry, update the rtt, and the ttl */ ++ } else if(((struct infra_host_data*)e->data)->ttl < timenow) { ++ host_entry_init(infra, e, timenow); ++ } ++ /* have an entry, update the rtt */ + data = (struct infra_host_data*)e->data; +- data->ttl = timenow + infra->host_ttl; + if(roundtrip == -1) { + rtt_lost(&data->rtt, orig_rtt); + if(data->num_timeouts<255) +@@ -503,10 +509,11 @@ infra_edns_update(struct infra_cache* infra, + if(!(e = new_host_entry(infra, addr, addrlen, timenow))) + return 0; + needtoinsert = 1; +- } ++ } else if(((struct infra_host_data*)e->data)->ttl < timenow) { ++ host_entry_init(infra, e, timenow); ++ } + /* have an entry, update the rtt, and the ttl */ + data = (struct infra_host_data*)e->data; +- data->ttl = timenow + infra->host_ttl; + data->edns_version = edns_version; + data->edns_lame_known = 1; + diff --git a/unbound-1.4.4-a6f07b.patch b/unbound-1.4.4-a6f07b.patch new file mode 100644 index 0000000..7285f03 --- /dev/null +++ b/unbound-1.4.4-a6f07b.patch @@ -0,0 +1,62 @@ +commit a6f07ba49319bbb62772a99cc3267fe8409a39d4 +Author: wouter +Date: Fri Apr 23 06:48:49 2010 +0000 + + - Squelch log message: sendto failed permission denied for + 255.255.255.255, it is visible in VERB_DETAIL (verbosity 2). + +diff --git a/util/net_help.c b/util/net_help.c +index 182f39d..7b2a3f4 100644 +--- a/util/net_help.c ++++ b/util/net_help.c +@@ -494,6 +494,14 @@ addr_is_ip4mapped(struct sockaddr_storage* addr, socklen_t addrlen) + return (memcmp(s, map_prefix, 12) == 0); + } + ++int addr_is_broadcast(struct sockaddr_storage* addr, socklen_t addrlen) ++{ ++ int af = (int)((struct sockaddr_in*)addr)->sin_family; ++ void* sinaddr = &((struct sockaddr_in*)addr)->sin_addr; ++ return af == AF_INET && addrlen>=(socklen_t)sizeof(struct sockaddr_in) ++ && memcmp(sinaddr, "\377\377\377\377", 4) == 0; ++} ++ + void sock_list_insert(struct sock_list** list, struct sockaddr_storage* addr, + socklen_t len, struct regional* region) + { +diff --git a/util/net_help.h b/util/net_help.h +index 9ac96eb..8afa84b 100644 +--- a/util/net_help.h ++++ b/util/net_help.h +@@ -280,6 +280,14 @@ void addr_to_str(struct sockaddr_storage* addr, socklen_t addrlen, + int addr_is_ip4mapped(struct sockaddr_storage* addr, socklen_t addrlen); + + /** ++ * See if sockaddr is 255.255.255.255. ++ * @param addr: address ++ * @param addrlen: length of address ++ * @return true if so ++ */ ++int addr_is_broadcast(struct sockaddr_storage* addr, socklen_t addrlen); ++ ++/** + * Insert new socket list item. If fails logs error. + * @param list: pointer to pointer to first item. + * @param addr: address or NULL if 'cache'. +diff --git a/util/netevent.c b/util/netevent.c +index 4b6a0a3..3f3c6ce 100644 +--- a/util/netevent.c ++++ b/util/netevent.c +@@ -301,6 +301,12 @@ comm_point_send_udp_msg(struct comm_point *c, ldns_buffer* packet, + (struct sockaddr_storage*)addr, addrlen) && + verbosity < VERB_DETAIL) + return 0; ++ /* SO_BROADCAST sockopt can give access to 255.255.255.255, ++ * but a dns cache does not need it. */ ++ if(errno == EACCES && addr_is_broadcast( ++ (struct sockaddr_storage*)addr, addrlen) && ++ verbosity < VERB_DETAIL) ++ return 0; + #ifndef USE_WINSOCK + verbose(VERB_OPS, "sendto failed: %s", strerror(errno)); + #else diff --git a/unbound-1.4.4-c2baa7.patch b/unbound-1.4.4-c2baa7.patch new file mode 100644 index 0000000..bf54a54 --- /dev/null +++ b/unbound-1.4.4-c2baa7.patch @@ -0,0 +1,61 @@ +commit c2baa73db1a2a0b0c0c8bba3d203a28ca86c5f31 +Author: wouter +Date: Tue May 4 10:50:27 2010 +0000 + + - Conforms to draft-ietf-dnsop-default-local-zones-13. Added default + reverse lookup blocks for IPv4 test nets 100.51.198.in-addr.arpa, + 113.0.203.in-addr.arpa and Orchid prefix 0.1.1.0.0.2.ip6.arpa. + +diff --git a/doc/unbound.conf.5.in b/doc/unbound.conf.5.in +index 16a607c..40b4bad 100644 +--- a/doc/unbound.conf.5.in ++++ b/doc/unbound.conf.5.in +@@ -778,7 +778,8 @@ records are provided. + .TP 10 + \h'5'\fIreverse RFC3330 IP4 this, link\-local, testnet and broadcast\fR + Reverse data for zones 0.in\-addr.arpa, 254.169.in\-addr.arpa, +-2.0.192.in\-addr.arpa, 255.255.255.255.in\-addr.arpa. ++2.0.192.in\-addr.arpa (TEST NET 1), 100.51.198.in\-addr.arpa (TEST NET 2), ++113.0.203.in\-addr.arpa (TEST NET 3), 255.255.255.255.in\-addr.arpa. + .TP 10 + \h'5'\fIreverse RFC4291 IP6 unspecified\fR + Reverse data for zone +@@ -793,12 +794,17 @@ Reverse data for zone D.F.ip6.arpa. + \h'5'\fIreverse RFC4291 IPv6 Link Local Addresses\fR + Reverse data for zones 8.E.F.ip6.arpa to B.E.F.ip6.arpa. + .TP 10 ++\h'5'\fIreverse RFC4843 Orchid Prefix\fR ++Reverse data for zone 0.1.1.0.0.2.ip6.arpa. ++.TP 10 + \h'5'\fIreverse IPv6 Example Prefix\fR + Reverse data for zone 8.B.D.0.1.0.0.2.ip6.arpa. This zone is used for + tutorials and examples. You can remove the block on this zone with: + .nf + local\-zone: 8.B.D.0.1.0.0.2.ip6.arpa. nodefault + .fi ++You can also selectively unblock a part of the zone by making that part ++transparent with a local\-zone statement. + This also works with the other default zones. + .\" End of local-zone listing. + .TP 5 +diff --git a/services/localzone.c b/services/localzone.c +index b8da77a..248d45f 100644 +--- a/services/localzone.c ++++ b/services/localzone.c +@@ -689,6 +689,8 @@ lz_enter_defaults(struct local_zones* zones, struct config_file* cfg, + !add_as112_default(zones, cfg, buf, "0.in-addr.arpa.") || + !add_as112_default(zones, cfg, buf, "254.169.in-addr.arpa.") || + !add_as112_default(zones, cfg, buf, "2.0.192.in-addr.arpa.") || ++ !add_as112_default(zones, cfg, buf, "100.51.198.in-addr.arpa.") || ++ !add_as112_default(zones, cfg, buf, "113.0.203.in-addr.arpa.") || + !add_as112_default(zones, cfg, buf, "255.255.255.255.in-addr.arpa.") || + !add_as112_default(zones, cfg, buf, "0.0.0.0.0.0.0.0.0.0.0.0.0.0.0.0.0.0.0.0.0.0.0.0.0.0.0.0.0.0.0.0.ip6.arpa.") || + !add_as112_default(zones, cfg, buf, "d.f.ip6.arpa.") || +@@ -696,6 +698,7 @@ lz_enter_defaults(struct local_zones* zones, struct config_file* cfg, + !add_as112_default(zones, cfg, buf, "9.e.f.ip6.arpa.") || + !add_as112_default(zones, cfg, buf, "a.e.f.ip6.arpa.") || + !add_as112_default(zones, cfg, buf, "b.e.f.ip6.arpa.") || ++ !add_as112_default(zones, cfg, buf, "0.1.1.0.0.2.ip6.arpa.") || + !add_as112_default(zones, cfg, buf, "8.b.d.0.1.0.0.2.ip6.arpa.")) { + log_err("out of memory adding default zone"); + return 0; diff --git a/unbound-1.4.4-d7ef7b.patch b/unbound-1.4.4-d7ef7b.patch new file mode 100644 index 0000000..868f826 --- /dev/null +++ b/unbound-1.4.4-d7ef7b.patch @@ -0,0 +1,123 @@ +commit d7ef7b31e0dbb0a73b201649c3729508b270f43f +Author: wouter +Date: Mon Apr 26 14:59:44 2010 +0000 + + Fix bug#307: 0x20 fallback outstanding query count, together with rec_lame, + and canonical rrset comparison. + +diff --git a/iterator/iter_utils.c b/iterator/iter_utils.c +index 9082055..6124650 100644 +--- a/iterator/iter_utils.c ++++ b/iterator/iter_utils.c +@@ -674,7 +674,7 @@ rrset_equal(struct ub_packed_rrset_key* k1, struct ub_packed_rrset_key* k2) + } + + int +-reply_equal(struct reply_info* p, struct reply_info* q) ++reply_equal(struct reply_info* p, struct reply_info* q, ldns_buffer* scratch) + { + size_t i; + if(p->flags != q->flags || +@@ -688,8 +688,29 @@ reply_equal(struct reply_info* p, struct reply_info* q) + p->rrset_count != q->rrset_count) + return 0; + for(i=0; irrset_count; i++) { +- if(!rrset_equal(p->rrsets[i], q->rrsets[i])) +- return 0; ++ if(!rrset_equal(p->rrsets[i], q->rrsets[i])) { ++ /* fallback procedure: try to sort and canonicalize */ ++ ldns_rr_list* pl, *ql; ++ pl = packed_rrset_to_rr_list(p->rrsets[i], scratch); ++ ql = packed_rrset_to_rr_list(q->rrsets[i], scratch); ++ if(!pl || !ql) { ++ ldns_rr_list_deep_free(pl); ++ ldns_rr_list_deep_free(ql); ++ return 0; ++ } ++ ldns_rr_list2canonical(pl); ++ ldns_rr_list2canonical(ql); ++ ldns_rr_list_sort(pl); ++ ldns_rr_list_sort(ql); ++ if(ldns_rr_list_compare(pl, ql) != 0) { ++ ldns_rr_list_deep_free(pl); ++ ldns_rr_list_deep_free(ql); ++ return 0; ++ } ++ ldns_rr_list_deep_free(pl); ++ ldns_rr_list_deep_free(ql); ++ continue; ++ } + } + return 1; + } +@@ -792,3 +813,18 @@ iter_scrub_ds(struct dns_msg* msg, struct ub_packed_rrset_key* ns, uint8_t* z) + i++; + } + } ++ ++void iter_dec_attempts(struct delegpt* dp, int d) ++{ ++ struct delegpt_addr* a; ++ for(a=dp->target_list; a; a = a->next_target) { ++ if(a->attempts >= OUTBOUND_MSG_RETRY) { ++ /* add back to result list */ ++ a->next_result = dp->result_list; ++ dp->result_list = a; ++ } ++ if(a->attempts > d) ++ a->attempts -= d; ++ else a->attempts = 0; ++ } ++} +diff --git a/iterator/iter_utils.h b/iterator/iter_utils.h +index 9a1db5f..a9f4247 100644 +--- a/iterator/iter_utils.h ++++ b/iterator/iter_utils.h +@@ -211,9 +211,10 @@ int iter_msg_from_zone(struct dns_msg* msg, struct delegpt* dp, + * @param p: reply one. The reply has rrset data pointers in region. + * Does not check rrset-IDs + * @param q: reply two ++ * @param buf: scratch buffer. + * @return if one and two are equal. + */ +-int reply_equal(struct reply_info* p, struct reply_info* q); ++int reply_equal(struct reply_info* p, struct reply_info* q, ldns_buffer* buf); + + /** + * Store in-zone glue in seperate rrset cache entries for later last-resort +@@ -257,4 +258,11 @@ int iter_get_next_root(struct iter_hints* hints, struct iter_forwards* fwd, + void iter_scrub_ds(struct dns_msg* msg, struct ub_packed_rrset_key* ns, + uint8_t* z); + ++/** ++ * Remove query attempts from all available ips. For 0x20. ++ * @param dp: delegpt. ++ * @param d: decrease. ++ */ ++void iter_dec_attempts(struct delegpt* dp, int d); ++ + #endif /* ITERATOR_ITER_UTILS_H */ +diff --git a/iterator/iterator.c b/iterator/iterator.c +index c7cdbc8..b1a948d 100644 +--- a/iterator/iterator.c ++++ b/iterator/iterator.c +@@ -1416,6 +1416,9 @@ processQueryTargets(struct module_qstate* qstate, struct iter_qstate* iq, + "match for %d wanted, done.", + (int)iq->caps_server+1, (int)naddr*3); + iq->caps_fallback = 0; ++ iter_dec_attempts(iq->dp, 3); /* space for fallback */ ++ iq->num_current_queries++; /* RespState decrements it*/ ++ iq->referral_count++; /* make sure we don't loop */ + iq->state = QUERY_RESP_STATE; + return 1; + } +@@ -2384,7 +2387,8 @@ process_response(struct module_qstate* qstate, struct iter_qstate* iq, + goto handle_it; + } else { + /* check if reply is the same, otherwise, fail */ +- if(!reply_equal(iq->response->rep, iq->caps_reply)) { ++ if(!reply_equal(iq->response->rep, iq->caps_reply, ++ qstate->env->scratch_buffer)) { + verbose(VERB_DETAIL, "Capsforid fallback: " + "getting different replies, failed"); + outbound_list_remove(&iq->outlist, outbound); diff --git a/unbound.spec b/unbound.spec index ccdab08..bee396e 100644 --- a/unbound.spec +++ b/unbound.spec @@ -9,7 +9,7 @@ Summary: Validating, recursive, and caching DNS(SEC) resolver Name: unbound Version: 1.4.4 -Release: 1%{?dist} +Release: 2%{?dist} License: BSD Url: http://www.nlnetlabs.nl/unbound/ Source: http://www.unbound.net/downloads/%{name}-%{version}.tar.gz @@ -222,6 +222,9 @@ fi %postun libs -p /sbin/ldconfig %changelog +* Mon May 31 2010 Paul Wouters - 1.4.4-2 +- Added accidentally omitted svn patches to cvs + * Mon May 31 2010 Paul Wouters - 1.4.4-1 - Upgraded to 1.4.4 with svn patches - Obsolete dnssec-conf to ensure it is de-installed