From dd8e44ac3703c72a5a7b9223d50528ec954a5f11 Mon Sep 17 00:00:00 2001 From: Wouter Wijngaards Date: Thu, 2 Dec 2010 12:39:33 +0000 Subject: [PATCH] - feature typetransparent localzone, does not block other RR types. git-svn-id: file:///svn/unbound/trunk@2350 be551aaa-1e26-0410-a405-d3ace91eadb9 --- doc/Changelog | 3 + doc/example.conf.in | 1 + doc/unbound.conf.5.in | 18 +++-- services/localzone.c | 12 +++- services/localzone.h | 2 + testdata/local_typetransparent.rpl | 109 +++++++++++++++++++++++++++++ util/configparser.c | 56 ++++++++------- util/configparser.y | 6 +- 8 files changed, 172 insertions(+), 35 deletions(-) create mode 100644 testdata/local_typetransparent.rpl diff --git a/doc/Changelog b/doc/Changelog index 8711363a1..349fe3907 100644 --- a/doc/Changelog +++ b/doc/Changelog @@ -1,3 +1,6 @@ +2 December 2010: Wouter + - feature typetransparent localzone, does not block other RR types. + 1 December 2010: Wouter - Fix bug#338: print address when socket creation fails. diff --git a/doc/example.conf.in b/doc/example.conf.in index 34d314c67..b0bb830fa 100644 --- a/doc/example.conf.in +++ b/doc/example.conf.in @@ -419,6 +419,7 @@ server: # o transparent gives local data, but resolves normally for other names # o redirect serves the zone data for any subdomain in the zone. # o nodefault can be used to normally resolve AS112 zones. + # o typetransparent resolves normally for other types and other names # # defaults are localhost address, reverse for 127.0.0.1 and ::1 # and nxdomain for AS112 zones. If you configure one of these zones diff --git a/doc/unbound.conf.5.in b/doc/unbound.conf.5.in index 940acf470..c700637ec 100644 --- a/doc/unbound.conf.5.in +++ b/doc/unbound.conf.5.in @@ -699,11 +699,12 @@ A plain number is in bytes, append 'k', 'm' or 'g' for kilobytes, megabytes or gigabytes (1024*1024 bytes in a megabyte). .TP .B local\-zone: \fI -Configure a local zone. The type determines the answer to give if there is -no match from local\-data. The types are deny, refuse, static, transparent, -redirect, nodefault, and are explained below. After that the default settings -are listed. Use local\-data: to enter data into the local zone. Answers for -local zones are authoritative DNS answers. By default the zones are class IN. +Configure a local zone. The type determines the answer to give if +there is no match from local\-data. The types are deny, refuse, static, +transparent, redirect, nodefault, typetransparent, and are explained +below. After that the default settings are listed. Use local\-data: to +enter data into the local zone. Answers for local zones are authoritative +DNS answers. By default the zones are class IN. .IP If you need more complicated authoritative data, with referrals, wildcards, CNAME/DNAME support, or DNSSEC authoritative service, setup a stub\-zone for @@ -731,6 +732,13 @@ given in localdata, then a noerror nodata answer is returned. If no local\-zone is given local\-data causes a transparent zone to be created by default. .TP 10 +\h'5'\fItypetransparent\fR +If there is a match from local data, the query is answered. If the query +is for a different name, or for the same name but for a different type, +the query is resolved normally. So, similar to transparent but types +that are not listed in local data are resolved normally, so if an A record +is in the local data that does not cause a nodata reply for AAAA queries. +.TP 10 \h'5'\fIredirect\fR The query is answered from the local data for the zone name. There may be no local data beneath the zone name. diff --git a/services/localzone.c b/services/localzone.c index c1ad4d2d9..d5cd59572 100644 --- a/services/localzone.c +++ b/services/localzone.c @@ -967,6 +967,10 @@ void local_zones_print(struct local_zones* zones) log_nametypeclass(0, "transparent zone", z->name, 0, z->dclass); break; + case local_zone_typetransparent: + log_nametypeclass(0, "typetransparent zone", + z->name, 0, z->dclass); + break; case local_zone_static: log_nametypeclass(0, "static zone", z->name, 0, z->dclass); @@ -1095,7 +1099,10 @@ lz_zone_answer(struct local_zone* z, struct query_info* qinfo, *(uint16_t*)ldns_buffer_begin(buf), ldns_buffer_read_u16_at(buf, 2), edns); return 1; - } + } else if(z->type == local_zone_typetransparent) { + /* no NODATA or NXDOMAINS for this zone type */ + return 0; + } /* else z->type == local_zone_transparent */ /* if the zone is transparent and the name exists, but the type @@ -1152,6 +1159,7 @@ const char* local_zone_type2str(enum localzone_type t) case local_zone_refuse: return "refuse"; case local_zone_redirect: return "redirect"; case local_zone_transparent: return "transparent"; + case local_zone_typetransparent: return "typetransparent"; case local_zone_static: return "static"; case local_zone_nodefault: return "nodefault"; } @@ -1168,6 +1176,8 @@ int local_zone_str2type(const char* type, enum localzone_type* t) *t = local_zone_static; else if(strcmp(type, "transparent") == 0) *t = local_zone_transparent; + else if(strcmp(type, "typetransparent") == 0) + *t = local_zone_typetransparent; else if(strcmp(type, "redirect") == 0) *t = local_zone_redirect; else return 0; diff --git a/services/localzone.h b/services/localzone.h index 38f4524e5..794988e66 100644 --- a/services/localzone.h +++ b/services/localzone.h @@ -63,6 +63,8 @@ enum localzone_type { local_zone_static, /** resolve normally */ local_zone_transparent, + /** do not block types at localdata names */ + local_zone_typetransparent, /** answer with data at zone apex */ local_zone_redirect, /** remove default AS112 blocking contents for zone diff --git a/testdata/local_typetransparent.rpl b/testdata/local_typetransparent.rpl new file mode 100644 index 000000000..c1c1931aa --- /dev/null +++ b/testdata/local_typetransparent.rpl @@ -0,0 +1,109 @@ +; config options +; The island of trust is at example.com +server: + local-zone: "example.com." typetransparent + local-data: "mail.example.com. IN A 10.20.30.40" + +stub-zone: + name: "." + stub-addr: 193.0.14.129 # K.ROOT-SERVERS.NET. +CONFIG_END + +SCENARIO_BEGIN Test local data with typetransparent zone + +; K.ROOT-SERVERS.NET. +RANGE_BEGIN 0 100 + ADDRESS 193.0.14.129 +ENTRY_BEGIN +MATCH opcode qtype qname +ADJUST copy_id +REPLY QR 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 AA NOERROR +SECTION QUESTION +mail.example.com. IN MX +SECTION ANSWER +mail.example.com. IN MX 100 mail.example.com. +ENTRY_END + +ENTRY_BEGIN +MATCH opcode qtype qname +ADJUST copy_id +REPLY QR AA NOERROR +SECTION QUESTION +www.example.com. IN AAAA +SECTION ANSWER +www.example.com. IN AAAA 2001::1 +ENTRY_END + +RANGE_END + +STEP 1 QUERY +ENTRY_BEGIN +REPLY RD DO +SECTION QUESTION +mail.example.com. IN A +ENTRY_END +; get straight answer from localdata + +STEP 10 CHECK_ANSWER +ENTRY_BEGIN +MATCH all +REPLY QR AA RD RA NOERROR +SECTION QUESTION +mail.example.com. IN A +SECTION ANSWER +mail.example.com. IN A 10.20.30.40 +SECTION AUTHORITY +ENTRY_END + +STEP 20 QUERY +ENTRY_BEGIN +REPLY RD DO +SECTION QUESTION +mail.example.com. IN MX +ENTRY_END + +; get internet answer for other type. + +STEP 30 CHECK_ANSWER +ENTRY_BEGIN +MATCH all +REPLY QR RD RA NOERROR +SECTION QUESTION +mail.example.com. IN MX +SECTION ANSWER +mail.example.com. IN MX 100 mail.example.com. +ENTRY_END + +STEP 40 QUERY +ENTRY_BEGIN +REPLY RD DO +SECTION QUESTION +www.example.com. IN AAAA +ENTRY_END + +; get internet answer for other name. + +STEP 50 CHECK_ANSWER +ENTRY_BEGIN +MATCH all +REPLY QR RD RA NOERROR +SECTION QUESTION +www.example.com. IN AAAA +SECTION ANSWER +www.example.com. IN AAAA 2001::1 +ENTRY_END + + +SCENARIO_END diff --git a/util/configparser.c b/util/configparser.c index 558b5eec1..7009adb90 100644 --- a/util/configparser.c +++ b/util/configparser.c @@ -780,10 +780,10 @@ static const yytype_uint16 yyrline[] = 701, 711, 721, 731, 741, 751, 758, 765, 774, 783, 792, 799, 809, 823, 830, 848, 861, 874, 883, 892, 901, 911, 921, 930, 937, 946, 955, 964, 972, 985, - 993, 1013, 1020, 1035, 1042, 1049, 1056, 1066, 1073, 1080, - 1087, 1092, 1093, 1094, 1094, 1094, 1095, 1095, 1095, 1096, - 1098, 1108, 1117, 1124, 1131, 1138, 1145, 1152, 1157, 1158, - 1159, 1161 + 993, 1015, 1022, 1037, 1044, 1051, 1058, 1068, 1075, 1082, + 1089, 1094, 1095, 1096, 1096, 1096, 1097, 1097, 1097, 1098, + 1100, 1110, 1119, 1126, 1133, 1140, 1147, 1154, 1159, 1160, + 1161, 1163 }; #endif @@ -3174,9 +3174,11 @@ yyreduce: OUTYY(("P(server_local_zone:%s %s)\n", (yyvsp[(2) - (3)].str), (yyvsp[(3) - (3)].str))); if(strcmp((yyvsp[(3) - (3)].str), "static")!=0 && strcmp((yyvsp[(3) - (3)].str), "deny")!=0 && strcmp((yyvsp[(3) - (3)].str), "refuse")!=0 && strcmp((yyvsp[(3) - (3)].str), "redirect")!=0 && - strcmp((yyvsp[(3) - (3)].str), "transparent")!=0 && strcmp((yyvsp[(3) - (3)].str), "nodefault")!=0) + strcmp((yyvsp[(3) - (3)].str), "transparent")!=0 && strcmp((yyvsp[(3) - (3)].str), "nodefault")!=0 + && strcmp((yyvsp[(3) - (3)].str), "typetransparent")!=0) yyerror("local-zone type: expected static, deny, " - "refuse, redirect, transparent or nodefault"); + "refuse, redirect, transparent, " + "typetransparent or nodefault"); else if(strcmp((yyvsp[(3) - (3)].str), "nodefault")==0) { if(!cfg_strlist_insert(&cfg_parser->cfg-> local_zones_nodefault, (yyvsp[(2) - (3)].str))) @@ -3193,7 +3195,7 @@ yyreduce: case 201: /* Line 1455 of yacc.c */ -#line 1014 "util/configparser.y" +#line 1016 "util/configparser.y" { OUTYY(("P(server_local_data:%s)\n", (yyvsp[(2) - (2)].str))); if(!cfg_strlist_insert(&cfg_parser->cfg->local_data, (yyvsp[(2) - (2)].str))) @@ -3204,7 +3206,7 @@ yyreduce: case 202: /* Line 1455 of yacc.c */ -#line 1021 "util/configparser.y" +#line 1023 "util/configparser.y" { char* ptr; OUTYY(("P(server_local_data_ptr:%s)\n", (yyvsp[(2) - (2)].str))); @@ -3223,7 +3225,7 @@ yyreduce: case 203: /* Line 1455 of yacc.c */ -#line 1036 "util/configparser.y" +#line 1038 "util/configparser.y" { OUTYY(("P(name:%s)\n", (yyvsp[(2) - (2)].str))); free(cfg_parser->cfg->stubs->name); @@ -3234,7 +3236,7 @@ yyreduce: case 204: /* Line 1455 of yacc.c */ -#line 1043 "util/configparser.y" +#line 1045 "util/configparser.y" { OUTYY(("P(stub-host:%s)\n", (yyvsp[(2) - (2)].str))); if(!cfg_strlist_insert(&cfg_parser->cfg->stubs->hosts, (yyvsp[(2) - (2)].str))) @@ -3245,7 +3247,7 @@ yyreduce: case 205: /* Line 1455 of yacc.c */ -#line 1050 "util/configparser.y" +#line 1052 "util/configparser.y" { OUTYY(("P(stub-addr:%s)\n", (yyvsp[(2) - (2)].str))); if(!cfg_strlist_insert(&cfg_parser->cfg->stubs->addrs, (yyvsp[(2) - (2)].str))) @@ -3256,7 +3258,7 @@ yyreduce: case 206: /* Line 1455 of yacc.c */ -#line 1057 "util/configparser.y" +#line 1059 "util/configparser.y" { OUTYY(("P(stub-prime:%s)\n", (yyvsp[(2) - (2)].str))); if(strcmp((yyvsp[(2) - (2)].str), "yes") != 0 && strcmp((yyvsp[(2) - (2)].str), "no") != 0) @@ -3270,7 +3272,7 @@ yyreduce: case 207: /* Line 1455 of yacc.c */ -#line 1067 "util/configparser.y" +#line 1069 "util/configparser.y" { OUTYY(("P(name:%s)\n", (yyvsp[(2) - (2)].str))); free(cfg_parser->cfg->forwards->name); @@ -3281,7 +3283,7 @@ yyreduce: case 208: /* Line 1455 of yacc.c */ -#line 1074 "util/configparser.y" +#line 1076 "util/configparser.y" { OUTYY(("P(forward-host:%s)\n", (yyvsp[(2) - (2)].str))); if(!cfg_strlist_insert(&cfg_parser->cfg->forwards->hosts, (yyvsp[(2) - (2)].str))) @@ -3292,7 +3294,7 @@ yyreduce: case 209: /* Line 1455 of yacc.c */ -#line 1081 "util/configparser.y" +#line 1083 "util/configparser.y" { OUTYY(("P(forward-addr:%s)\n", (yyvsp[(2) - (2)].str))); if(!cfg_strlist_insert(&cfg_parser->cfg->forwards->addrs, (yyvsp[(2) - (2)].str))) @@ -3303,7 +3305,7 @@ yyreduce: case 210: /* Line 1455 of yacc.c */ -#line 1088 "util/configparser.y" +#line 1090 "util/configparser.y" { OUTYY(("\nP(remote-control:)\n")); } @@ -3312,7 +3314,7 @@ yyreduce: case 220: /* Line 1455 of yacc.c */ -#line 1099 "util/configparser.y" +#line 1101 "util/configparser.y" { OUTYY(("P(control_enable:%s)\n", (yyvsp[(2) - (2)].str))); if(strcmp((yyvsp[(2) - (2)].str), "yes") != 0 && strcmp((yyvsp[(2) - (2)].str), "no") != 0) @@ -3326,7 +3328,7 @@ yyreduce: case 221: /* Line 1455 of yacc.c */ -#line 1109 "util/configparser.y" +#line 1111 "util/configparser.y" { OUTYY(("P(control_port:%s)\n", (yyvsp[(2) - (2)].str))); if(atoi((yyvsp[(2) - (2)].str)) == 0) @@ -3339,7 +3341,7 @@ yyreduce: case 222: /* Line 1455 of yacc.c */ -#line 1118 "util/configparser.y" +#line 1120 "util/configparser.y" { OUTYY(("P(control_interface:%s)\n", (yyvsp[(2) - (2)].str))); if(!cfg_strlist_insert(&cfg_parser->cfg->control_ifs, (yyvsp[(2) - (2)].str))) @@ -3350,7 +3352,7 @@ yyreduce: case 223: /* Line 1455 of yacc.c */ -#line 1125 "util/configparser.y" +#line 1127 "util/configparser.y" { OUTYY(("P(rc_server_key_file:%s)\n", (yyvsp[(2) - (2)].str))); free(cfg_parser->cfg->server_key_file); @@ -3361,7 +3363,7 @@ yyreduce: case 224: /* Line 1455 of yacc.c */ -#line 1132 "util/configparser.y" +#line 1134 "util/configparser.y" { OUTYY(("P(rc_server_cert_file:%s)\n", (yyvsp[(2) - (2)].str))); free(cfg_parser->cfg->server_cert_file); @@ -3372,7 +3374,7 @@ yyreduce: case 225: /* Line 1455 of yacc.c */ -#line 1139 "util/configparser.y" +#line 1141 "util/configparser.y" { OUTYY(("P(rc_control_key_file:%s)\n", (yyvsp[(2) - (2)].str))); free(cfg_parser->cfg->control_key_file); @@ -3383,7 +3385,7 @@ yyreduce: case 226: /* Line 1455 of yacc.c */ -#line 1146 "util/configparser.y" +#line 1148 "util/configparser.y" { OUTYY(("P(rc_control_cert_file:%s)\n", (yyvsp[(2) - (2)].str))); free(cfg_parser->cfg->control_cert_file); @@ -3394,7 +3396,7 @@ yyreduce: case 227: /* Line 1455 of yacc.c */ -#line 1153 "util/configparser.y" +#line 1155 "util/configparser.y" { OUTYY(("\nP(python:)\n")); } @@ -3403,7 +3405,7 @@ yyreduce: case 231: /* Line 1455 of yacc.c */ -#line 1162 "util/configparser.y" +#line 1164 "util/configparser.y" { OUTYY(("P(python-script:%s)\n", (yyvsp[(2) - (2)].str))); free(cfg_parser->cfg->python_script); @@ -3414,7 +3416,7 @@ yyreduce: /* Line 1455 of yacc.c */ -#line 3418 "util/configparser.c" +#line 3420 "util/configparser.c" default: break; } YY_SYMBOL_PRINT ("-> $$ =", yyr1[yyn], &yyval, &yyloc); @@ -3626,7 +3628,7 @@ yyreturn: /* Line 1675 of yacc.c */ -#line 1167 "util/configparser.y" +#line 1169 "util/configparser.y" /* parse helper routines could be here */ diff --git a/util/configparser.y b/util/configparser.y index abc461b26..7d8007453 100644 --- a/util/configparser.y +++ b/util/configparser.y @@ -995,9 +995,11 @@ server_local_zone: VAR_LOCAL_ZONE STRING_ARG STRING_ARG OUTYY(("P(server_local_zone:%s %s)\n", $2, $3)); if(strcmp($3, "static")!=0 && strcmp($3, "deny")!=0 && strcmp($3, "refuse")!=0 && strcmp($3, "redirect")!=0 && - strcmp($3, "transparent")!=0 && strcmp($3, "nodefault")!=0) + strcmp($3, "transparent")!=0 && strcmp($3, "nodefault")!=0 + && strcmp($3, "typetransparent")!=0) yyerror("local-zone type: expected static, deny, " - "refuse, redirect, transparent or nodefault"); + "refuse, redirect, transparent, " + "typetransparent or nodefault"); else if(strcmp($3, "nodefault")==0) { if(!cfg_strlist_insert(&cfg_parser->cfg-> local_zones_nodefault, $2)) -- 2.47.2