Last active
August 24, 2016 08:39
-
-
Save mimuret/e68b57561dc76214555c0d9718e9ce4d to your computer and use it in GitHub Desktop.
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
manabu-s:~/git/nsd-4.1.11rc2 (master) $ git diff -b 6000ec5d39c409dc3eede9d6e4517f82063e5ea7 | |
diff --git a/configlexer.lex b/configlexer.lex | |
index d536352..914afa8 100644 | |
--- a/configlexer.lex | |
+++ b/configlexer.lex | |
@@ -273,6 +273,7 @@ max-refresh-time{COLON} { LEXOUT(("v(%s) ", yytext)); return VAR_MAX_REFRESH_TIM | |
min-refresh-time{COLON} { LEXOUT(("v(%s) ", yytext)); return VAR_MIN_REFRESH_TIME;} | |
max-retry-time{COLON} { LEXOUT(("v(%s) ", yytext)); return VAR_MAX_RETRY_TIME;} | |
min-retry-time{COLON} { LEXOUT(("v(%s) ", yytext)); return VAR_MIN_RETRY_TIME;} | |
+multi-master-check{COLON} { LEXOUT(("v(%s) ", yytext)); return VAR_MULTI_MASTER_CHECK;} | |
{NEWLINE} { LEXOUT(("NL\n")); cfg_parser->line++;} | |
/* Quoted strings. Strip leading and ending quotes */ | |
diff --git a/configparser.y b/configparser.y | |
index c036c15..17c2c46 100644 | |
--- a/configparser.y | |
+++ b/configparser.y | |
@@ -71,6 +71,7 @@ extern config_parser_state_t* cfg_parser; | |
%token VAR_ROUND_ROBIN VAR_ZONESTATS VAR_REUSEPORT VAR_VERSION | |
%token VAR_MAX_REFRESH_TIME VAR_MIN_REFRESH_TIME | |
%token VAR_MAX_RETRY_TIME VAR_MIN_RETRY_TIME | |
+%token VAR_MULTI_MASTER_CHECK | |
%% | |
toplevelvars: /* empty */ | toplevelvars toplevelvar ; | |
@@ -602,7 +603,7 @@ zone_config_item: zone_zonefile | zone_allow_notify | zone_request_xfr | | |
zone_outgoing_interface | zone_allow_axfr_fallback | include_pattern | | |
zone_rrl_whitelist | zone_zonestats | zone_max_refresh_time | | |
zone_min_refresh_time | zone_max_retry_time | zone_min_retry_time | | |
- zone_size_limit_xfr; | |
+ zone_size_limit_xfr | zone_multi_master_check; | |
pattern_name: VAR_NAME STRING | |
{ | |
OUTYY(("P(pattern_name:%s)\n", $2)); | |
@@ -871,6 +872,15 @@ zone_min_retry_time: VAR_MIN_RETRY_TIME STRING | |
cfg_parser->current_pattern->min_retry_time_is_default = 0; | |
} | |
}; | |
+zone_multi_master_check: VAR_MULTI_MASTER_CHECK STRING | |
+ { | |
+ OUTYY(("P(zone_multi_master_check:%s)\n", $2)); | |
+#ifdef MULTI_MASTER_CHECK | |
+ if(strcmp($2, "yes") != 0 && strcmp($2, "no") != 0) | |
+ yyerror("expected yes or no."); | |
+ else cfg_parser->current_pattern->multi_master_check = (strcmp($2, "yes")==0); | |
+#endif | |
+ } | |
/* key: declaration */ | |
keystart: VAR_KEY | |
diff --git a/configure.ac b/configure.ac | |
index a47ae02..8937d40 100644 | |
--- a/configure.ac | |
+++ b/configure.ac | |
@@ -792,6 +792,15 @@ case "$enable_ratelimit_default_is_off" in | |
esac | |
AC_SUBST(ratelimit_default) | |
+AC_ARG_ENABLE(multi_master_check, AC_HELP_STRING([--enable-multi-master-check], [Enable multi master xfr check])) | |
+case "$enable_ratelimit" in | |
+ yes) | |
+ AC_DEFINE_UNQUOTED([MULTI_MASTER_CHECK], [], [Define this to enable multi master check.]) | |
+ ;; | |
+ *) | |
+ ;; | |
+esac | |
+AC_SUBST(multi_master_check) | |
# we need SSL for TSIG (and maybe also for NSEC3). | |
CHECK_SSL | |
diff --git a/nsd-checkconf.c b/nsd-checkconf.c | |
index b7afdd1..6de41b6 100644 | |
--- a/nsd-checkconf.c | |
+++ b/nsd-checkconf.c | |
@@ -320,6 +320,9 @@ config_print_zone(nsd_options_t* opt, const char* k, int s, const char *o, | |
#ifdef RATELIMIT | |
ZONE_GET_RRL(rrl_whitelist, o, zone->pattern); | |
#endif | |
+#ifdef MULTI_MASTER_CHECK | |
+ ZONE_GET_BIN(multi_master_check, o, zone->pattern); | |
+#endif | |
printf("Zone option not handled: %s %s\n", z, o); | |
exit(1); | |
} else if(pat) { | |
@@ -350,6 +353,9 @@ config_print_zone(nsd_options_t* opt, const char* k, int s, const char *o, | |
#ifdef RATELIMIT | |
ZONE_GET_RRL(rrl_whitelist, o, p); | |
#endif | |
+#ifdef MULTI_MASTER_CHECK | |
+ ZONE_GET_BIN(multi_master_check, o, p); | |
+#endif | |
printf("Pattern option not handled: %s %s\n", pat, o); | |
exit(1); | |
} else { | |
@@ -437,6 +443,9 @@ static void print_zone_content_elems(pattern_options_t* pat) | |
#endif | |
print_acl("allow-notify:", pat->allow_notify); | |
print_acl("request-xfr:", pat->request_xfr); | |
+#ifdef MULTI_MASTER_CHECK | |
+ printf("\tmulti-master-check: %s\n", pat->multi_master_check?"yes":"no"); | |
+#endif | |
if(!pat->notify_retry_is_default) | |
printf("\tnotify-retry: %d\n", pat->notify_retry); | |
print_acl("notify:", pat->notify); | |
diff --git a/nsd.conf.sample.in b/nsd.conf.sample.in | |
index cda7dd0..87e88b8 100644 | |
--- a/nsd.conf.sample.in | |
+++ b/nsd.conf.sample.in | |
@@ -263,6 +263,9 @@ remote-control: | |
#min-refresh-time: 0 | |
#max-retry-time: 1209600 | |
#min-retry-time: 0 | |
++ # Slave server tries a zone transfer to all masters. | |
++ # Default is no, if use this option, compiled with --enable-multi-master-check. | |
++ # multi-master-check: no | |
# limit the zone transfer size (in bytes), stops very large transfers | |
# 0 is no limits enforced. | |
diff --git a/options.c b/options.c | |
index 328be62..b2c1ee6 100644 | |
--- a/options.c | |
+++ b/options.c | |
@@ -834,6 +834,9 @@ pattern_options_create(region_type* region) | |
#ifdef RATELIMIT | |
p->rrl_whitelist = 0; | |
#endif | |
+#ifdef MULTI_MASTER_CHECK | |
+ p->multi_master_check = 0; | |
+#endif | |
return p; | |
} | |
@@ -964,6 +967,9 @@ copy_pat_fixed(region_type* region, pattern_options_t* orig, | |
#ifdef RATELIMIT | |
orig->rrl_whitelist = p->rrl_whitelist; | |
#endif | |
+#ifdef MULTI_MASTER_CHECK | |
+ orig->multi_master_check = p->multi_master_check; | |
+#endif | |
} | |
void | |
@@ -1049,6 +1055,9 @@ pattern_options_equal(pattern_options_t* p, pattern_options_t* q) | |
#ifdef RATELIMIT | |
if(p->rrl_whitelist != q->rrl_whitelist) return 0; | |
#endif | |
+#ifdef MULTI_MASTER_CHECK | |
+ if(!booleq(p->multi_master_check,q->multi_master_check)) return 0; | |
+#endif | |
if(p->size_limit_xfr != q->size_limit_xfr) return 0; | |
return 1; | |
} | |
@@ -1208,6 +1217,9 @@ pattern_options_marshal(struct buffer* b, pattern_options_t* p) | |
marshal_u8(b, p->max_retry_time_is_default); | |
marshal_u32(b, p->min_retry_time); | |
marshal_u8(b, p->min_retry_time_is_default); | |
+#ifdef MULTI_MASTER_CHECK | |
+ marshal_u8(b, p->multi_master_check); | |
+#endif | |
} | |
pattern_options_t* | |
@@ -1239,6 +1251,9 @@ pattern_options_unmarshal(region_type* r, struct buffer* b) | |
p->max_retry_time_is_default = unmarshal_u8(b); | |
p->min_retry_time = unmarshal_u32(b); | |
p->min_retry_time_is_default = unmarshal_u8(b); | |
+#ifdef MULTI_MASTER_CHECK | |
+ p->multi_master_check = unmarshal_u8(b); | |
+#endif | |
return p; | |
} | |
@@ -1979,6 +1994,10 @@ config_apply_pattern(const char* name) | |
pat->provide_xfr); | |
append_acl(&a->outgoing_interface, &cfg_parser-> | |
current_outgoing_interface, pat->outgoing_interface); | |
+#ifdef MULTI_MASTER_CHECK | |
+ if(pat->multi_master_check) | |
+ a->multi_master_check = pat->multi_master_check; | |
+#endif | |
} | |
void | |
diff --git a/options.h b/options.h | |
index e0f749c..1bf339b 100644 | |
--- a/options.h | |
+++ b/options.h | |
@@ -163,6 +163,9 @@ struct pattern_options { | |
uint32_t min_retry_time; | |
uint8_t min_retry_time_is_default; | |
uint64_t size_limit_xfr; | |
+#ifdef MULTI_MASTER_CHECK | |
+ uint8_t multi_master_check; | |
+#endif | |
}; | |
#define PATTERN_IMPLICIT_MARKER "_implicit_" | |
diff --git a/xfrd-tcp.c b/xfrd-tcp.c | |
index 9bc01d3..7777398 100644 | |
--- a/xfrd-tcp.c | |
+++ b/xfrd-tcp.c | |
@@ -870,6 +870,13 @@ xfrd_tcp_read(struct xfrd_tcp_pipeline* tp) | |
tp->num_skip++; | |
/* fall through to remove zone from tp */ | |
case xfrd_packet_transfer: | |
+#ifdef MULTI_MASTER_CHECK | |
+ if(zone->zone_options->pattern->multi_master_check) { | |
+ xfrd_tcp_release(xfrd->tcp_set, zone); | |
+ xfrd_make_request(zone); | |
+ break; | |
+ } | |
+#endif | |
xfrd_tcp_release(xfrd->tcp_set, zone); | |
assert(zone->round_num == -1); | |
break; | |
diff --git a/xfrd.c b/xfrd.c | |
index 0eacce7..2091ec7 100644 | |
--- a/xfrd.c | |
+++ b/xfrd.c | |
@@ -437,6 +437,10 @@ xfrd_init_slave_zone(xfrd_state_t* xfrd, zone_options_t* zone_opt) | |
xzone->udp_waiting = 0; | |
xzone->is_activated = 0; | |
+#ifdef MULTI_MASTER_CHECK | |
+ xzone->multi_master_first_master = -1; | |
+ xzone->multi_master_update_check = -1; | |
+#endif | |
tsig_create_record_custom(&xzone->tsig, NULL, 0, 0, 4); | |
/* set refreshing anyway, if we have data it may be old */ | |
@@ -875,9 +879,30 @@ xfrd_make_request(xfrd_zone_t* zone) | |
DEBUG(DEBUG_XFRD,1, (LOG_INFO, | |
"xfrd zone %s makereq wait_retry, rd %d mr %d nx %d", | |
zone->apex_str, zone->round_num, zone->master_num, zone->next_master)); | |
+#ifdef MULTI_MASTER_CHECK | |
+ zone->multi_master_first_master = -1; | |
+#endif | |
+ return; | |
+ } | |
+ } | |
+#ifdef MULTI_MASTER_CHECK | |
+ if(zone->zone_options->pattern->multi_master_check) { | |
+ if(zone->multi_master_first_master == zone->master_num && zone->round_num > 0 && zone->state != xfrd_zone_expired) { | |
+ /* tried all servers and update zone */ | |
+ if(zone->multi_master_update_check >= 0) { | |
+ VERBOSITY(2, (LOG_INFO, "xfrd: multi master check: zone %s complite transfers",zone->apex_str)); | |
+ } | |
+ zone->round_num = -1; /* next try start anew */ | |
+ zone->multi_master_first_master = -1; | |
+ xfrd_set_timer_refresh(zone); | |
return; | |
} | |
+ if(zone->multi_master_first_master < 0) { | |
+ zone->multi_master_first_master = zone->master_num; | |
+ zone->multi_master_update_check = -1; | |
+ } | |
} | |
+#endif | |
/* cache ixfr_disabled only for XFRD_NO_IXFR_CACHE time */ | |
if (zone->master->ixfr_disabled && | |
@@ -1267,6 +1292,13 @@ xfrd_udp_read(xfrd_zone_t* zone) | |
xfrd_tcp_obtain(xfrd->tcp_set, zone); | |
break; | |
case xfrd_packet_transfer: | |
+#ifdef MULTI_MASTER_CHECK | |
+ if(zone->zone_options->pattern->multi_master_check) { | |
+ xfrd_udp_release(zone); | |
+ xfrd_make_request(zone); | |
+ break; | |
+ } | |
+#endif | |
case xfrd_packet_newlease: | |
/* nothing more to do */ | |
assert(zone->round_num == -1); | |
@@ -1835,7 +1867,14 @@ xfrd_parse_received_xfr_packet(xfrd_zone_t* zone, buffer_type* packet, | |
zone->soa_disk_acquired = xfrd_time(); | |
if(zone->soa_nsd.serial == soa->serial) | |
zone->soa_nsd_acquired = xfrd_time(); | |
+#ifdef MULTI_MASTER_CHECK | |
+ if(zone->zone_options->pattern->multi_master_check) { | |
+ region_destroy(tempregion); | |
+ return xfrd_packet_drop; | |
+ } | |
+#endif | |
xfrd_set_zone_state(zone, xfrd_zone_ok); | |
DEBUG(DEBUG_XFRD,1, (LOG_INFO, "xfrd: zone %s is ok", | |
zone->apex_str)); | |
if(zone->soa_notified_acquired == 0) { | |
@@ -2048,6 +2087,13 @@ xfrd_handle_received_xfr_packet(xfrd_zone_t* zone, buffer_type* packet) | |
DEBUG(DEBUG_XFRD,1, (LOG_INFO, | |
"xfrd: zone %s is waiting for reload", | |
zone->apex_str)); | |
+#ifdef MULTI_MASTER_CHECK | |
+ if(zone->zone_options->pattern->multi_master_check) { | |
+ zone->multi_master_update_check = zone->master_num; | |
+ xfrd_set_reload_timeout(); | |
+ return xfrd_packet_transfer; | |
+ } | |
+#endif | |
zone->round_num = -1; /* next try start anew */ | |
xfrd_set_timer_refresh(zone); | |
xfrd_set_reload_timeout(); | |
diff --git a/xfrd.h b/xfrd.h | |
index ff903db..5ebf9be 100644 | |
--- a/xfrd.h | |
+++ b/xfrd.h | |
@@ -217,6 +217,10 @@ struct xfrd_zone { | |
tsig_record_type tsig; /* tsig state for IXFR/AXFR */ | |
uint64_t xfrfilenumber; /* identifier for file to store xfr into, | |
valid if msg_seq_nr nonzero */ | |
+#ifdef MULTI_MASTER_CHECK | |
+ int multi_master_first_master; /* >0: first check master_num */ | |
+ int multi_master_update_check; /* -1: not update >0: last update master_num */ | |
+#endif | |
}; | |
enum xfrd_packet_result { |
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment