diff options
author | Dag-Erling Smørgrav <des@FreeBSD.org> | 2016-09-29 18:24:29 +0000 |
---|---|---|
committer | Dag-Erling Smørgrav <des@FreeBSD.org> | 2016-09-29 18:24:29 +0000 |
commit | b5663de9eb877cb7ebb54c4ae4eb81007bb17df4 (patch) | |
tree | c71a63b65af86d3bb13a920be50d4e4c00d96647 /contrib/unbound/util | |
parent | 863ef2ca62df17d196f6b9c642b607910b28864f (diff) | |
parent | 27c2fff0f2fef695b0599fc3931cacfc16376e88 (diff) | |
download | src-test2-b5663de9eb877cb7ebb54c4ae4eb81007bb17df4.tar.gz src-test2-b5663de9eb877cb7ebb54c4ae4eb81007bb17df4.zip |
Notes
Diffstat (limited to 'contrib/unbound/util')
-rw-r--r-- | contrib/unbound/util/alloc.c | 4 | ||||
-rw-r--r-- | contrib/unbound/util/config_file.c | 70 | ||||
-rw-r--r-- | contrib/unbound/util/config_file.h | 53 | ||||
-rw-r--r-- | contrib/unbound/util/configlexer.lex | 8 | ||||
-rw-r--r-- | contrib/unbound/util/configparser.y | 104 | ||||
-rw-r--r-- | contrib/unbound/util/iana_ports.inc | 3 | ||||
-rw-r--r-- | contrib/unbound/util/net_help.c | 6 | ||||
-rw-r--r-- | contrib/unbound/util/netevent.c | 110 | ||||
-rw-r--r-- | contrib/unbound/util/netevent.h | 13 | ||||
-rw-r--r-- | contrib/unbound/util/storage/dnstree.c | 13 | ||||
-rw-r--r-- | contrib/unbound/util/storage/dnstree.h | 11 | ||||
-rw-r--r-- | contrib/unbound/util/storage/lookup3.c | 10 | ||||
-rw-r--r-- | contrib/unbound/util/ub_event.c | 16 | ||||
-rw-r--r-- | contrib/unbound/util/ub_event_pluggable.c | 16 | ||||
-rw-r--r-- | contrib/unbound/util/winsock_event.c | 5 |
15 files changed, 385 insertions, 57 deletions
diff --git a/contrib/unbound/util/alloc.c b/contrib/unbound/util/alloc.c index 05d2fa36207b..a1152a7cf9fa 100644 --- a/contrib/unbound/util/alloc.c +++ b/contrib/unbound/util/alloc.c @@ -64,7 +64,7 @@ alloc_setup_special(alloc_special_t* t) * @param alloc: the structure to fill up. */ static void -prealloc(struct alloc_cache* alloc) +prealloc_setup(struct alloc_cache* alloc) { alloc_special_t* p; int i; @@ -216,7 +216,7 @@ alloc_special_obtain(struct alloc_cache* alloc) } } /* allocate new */ - prealloc(alloc); + prealloc_setup(alloc); if(!(p = (alloc_special_t*)malloc(sizeof(alloc_special_t)))) { log_err("alloc_special_obtain: out of memory"); return NULL; diff --git a/contrib/unbound/util/config_file.c b/contrib/unbound/util/config_file.c index 2b79bd9a859a..688211c2bf84 100644 --- a/contrib/unbound/util/config_file.c +++ b/contrib/unbound/util/config_file.c @@ -212,6 +212,7 @@ config_create(void) cfg->local_zones = NULL; cfg->local_zones_nodefault = NULL; cfg->local_data = NULL; + cfg->local_zone_overrides = NULL; cfg->unblock_lan_zones = 0; cfg->insecure_lan_zones = 0; cfg->python_script = NULL; @@ -640,6 +641,14 @@ config_collate_cat(struct config_strlist* list) func(buf, arg); \ } \ } +/** compare and print list option */ +#define O_LS3(opt, name, lst) if(strcmp(opt, name)==0) { \ + struct config_str3list* p = cfg->lst; \ + for(p = cfg->lst; p; p = p->next) { \ + snprintf(buf, len, "%s %s %s", p->str, p->str2, p->str3); \ + func(buf, arg); \ + } \ + } /** compare and print taglist option */ #define O_LTG(opt, name, lst) if(strcmp(opt, name)==0) { \ char* tmpstr = NULL; \ @@ -784,6 +793,10 @@ config_get_option(struct config_file* cfg, const char* opt, else O_YNO(opt, "qname-minimisation", qname_minimisation) else O_IFC(opt, "define-tag", num_tags, tagname) else O_LTG(opt, "local-zone-tag", local_zone_tags) + else O_LTG(opt, "access-control-tag", acl_tags) + else O_LS3(opt, "local-zone-override", local_zone_overrides) + else O_LS3(opt, "access-control-tag-action", acl_tag_actions) + else O_LS3(opt, "access-control-tag-data", acl_tag_datas) /* not here: * outgoing-permit, outgoing-avoid - have list of ports * local-zone - zones and nodefault variables @@ -936,6 +949,20 @@ config_deldblstrlist(struct config_str2list* p) } void +config_deltrplstrlist(struct config_str3list* p) +{ + struct config_str3list *np; + while(p) { + np = p->next; + free(p->str); + free(p->str2); + free(p->str3); + free(p); + p = np; + } +} + +void config_delstub(struct config_stub* p) { if(!p) return; @@ -969,8 +996,7 @@ config_del_strarray(char** array, int num) free(array); } -/** delete stringbytelist */ -static void +void config_del_strbytelist(struct config_strbytelist* p) { struct config_strbytelist* np; @@ -1020,8 +1046,12 @@ config_delete(struct config_file* cfg) config_deldblstrlist(cfg->local_zones); config_delstrlist(cfg->local_zones_nodefault); config_delstrlist(cfg->local_data); + config_deltrplstrlist(cfg->local_zone_overrides); config_del_strarray(cfg->tagname, cfg->num_tags); config_del_strbytelist(cfg->local_zone_tags); + config_del_strbytelist(cfg->acl_tags); + config_deltrplstrlist(cfg->acl_tag_actions); + config_deltrplstrlist(cfg->acl_tag_datas); config_delstrlist(cfg->control_ifs); free(cfg->server_key_file); free(cfg->server_cert_file); @@ -1180,6 +1210,23 @@ int cfg_strlist_append(struct config_strlist_head* list, char* item) } int +cfg_region_strlist_insert(struct regional* region, + struct config_strlist** head, char* item) +{ + struct config_strlist *s; + if(!item || !head) + return 0; + s = (struct config_strlist*)regional_alloc_zero(region, + sizeof(struct config_strlist)); + if(!s) + return 0; + s->str = item; + s->next = *head; + *head = s; + return 1; +} + +int cfg_strlist_insert(struct config_strlist** head, char* item) { struct config_strlist *s; @@ -1210,6 +1257,24 @@ cfg_str2list_insert(struct config_str2list** head, char* item, char* i2) return 1; } +int +cfg_str3list_insert(struct config_str3list** head, char* item, char* i2, + char* i3) +{ + struct config_str3list *s; + if(!item || !i2 || !i3 || !head) + return 0; + s = (struct config_str3list*)calloc(1, sizeof(struct config_str3list)); + if(!s) + return 0; + s->str = item; + s->str2 = i2; + s->str3 = i3; + s->next = *head; + *head = s; + return 1; +} + int cfg_strbytelist_insert(struct config_strbytelist** head, char* item, uint8_t* i2, size_t i2len) @@ -1373,6 +1438,7 @@ cfg_set_bit(uint8_t* bitlist, size_t len, int id) { int pos = id/8; log_assert((size_t)pos < len); + (void)len; bitlist[pos] |= 1<<(id%8); } diff --git a/contrib/unbound/util/config_file.h b/contrib/unbound/util/config_file.h index a51cdb464c0c..07edff7b4cf4 100644 --- a/contrib/unbound/util/config_file.h +++ b/contrib/unbound/util/config_file.h @@ -44,10 +44,12 @@ struct config_stub; struct config_strlist; struct config_str2list; +struct config_str3list; struct config_strbytelist; struct module_qstate; struct sock_list; struct ub_packed_rrset_key; +struct regional; /** * The configuration options. @@ -73,6 +75,8 @@ struct config_file { int do_ip4; /** do ip6 query support. */ int do_ip6; + /** prefer ip6 upstream queries. */ + int prefer_ip6; /** do udp query support. */ int do_udp; /** do tcp query support. */ @@ -292,12 +296,20 @@ struct config_file { struct config_strlist* local_zones_nodefault; /** local data RRs configured */ struct config_strlist* local_data; + /** local zone override types per netblock */ + struct config_str3list* local_zone_overrides; /** unblock lan zones (reverse lookups for AS112 zones) */ int unblock_lan_zones; /** insecure lan zones (don't validate AS112 zones) */ int insecure_lan_zones; /** list of zonename, tagbitlist */ struct config_strbytelist* local_zone_tags; + /** list of aclname, tagbitlist */ + struct config_strbytelist* acl_tags; + /** list of aclname, tagname, localzonetype */ + struct config_str3list* acl_tag_actions; + /** list of aclname, tagname, redirectdata */ + struct config_str3list* acl_tag_datas; /** tag list, array with tagname[i] is malloced string */ char** tagname; /** number of items in the taglist */ @@ -434,6 +446,21 @@ struct config_str2list { }; /** + * List of three strings for config options + */ +struct config_str3list { + /** next item in list */ + struct config_str3list* next; + /** first string */ + char* str; + /** second string */ + char* str2; + /** third string */ + char* str3; +}; + + +/** * List of string, bytestring for config options */ struct config_strbytelist { @@ -575,6 +602,10 @@ int cfg_strlist_append(struct config_strlist_head* list, char* item); */ int cfg_strlist_insert(struct config_strlist** head, char* item); +/** insert with region for allocation. */ +int cfg_region_strlist_insert(struct regional* region, + struct config_strlist** head, char* item); + /** * Insert string into str2list. * @param head: pointer to str2list head variable. @@ -585,8 +616,19 @@ int cfg_strlist_insert(struct config_strlist** head, char* item); int cfg_str2list_insert(struct config_str2list** head, char* item, char* i2); /** + * Insert string into str3list. + * @param head: pointer to str3list head variable. + * @param item: new item. malloced by caller. If NULL the insertion fails. + * @param i2: 2nd string, malloced by caller. If NULL the insertion fails. + * @param i3: 3rd string, malloced by caller. If NULL the insertion fails. + * @return: true on success. + */ +int cfg_str3list_insert(struct config_str3list** head, char* item, char* i2, + char* i3); + +/** * Insert string into strbytelist. - * @param head: pointer to str2list head variable. + * @param head: pointer to strbytelist head variable. * @param item: new item. malloced by caller. If NULL the insertion fails. * @param i2: 2nd string, malloced by caller. If NULL the insertion fails. * @param i2len: length of the i2 bytestring. @@ -619,6 +661,15 @@ void config_delstrlist(struct config_strlist* list); void config_deldblstrlist(struct config_str2list* list); /** + * Delete items in config triple string list. + * @param list: list. + */ +void config_deltrplstrlist(struct config_str3list* list); + +/** delete stringbytelist */ +void config_del_strbytelist(struct config_strbytelist* list); + +/** * Delete a stub item * @param p: stub item */ diff --git a/contrib/unbound/util/configlexer.lex b/contrib/unbound/util/configlexer.lex index 852733b559be..a8d4a96638c3 100644 --- a/contrib/unbound/util/configlexer.lex +++ b/contrib/unbound/util/configlexer.lex @@ -9,6 +9,9 @@ */ #include "config.h" +/* because flex keeps having sign-unsigned compare problems that are unfixed*/ +#pragma GCC diagnostic ignored "-Wsign-compare" + #include <ctype.h> #include <string.h> #include <strings.h> @@ -218,6 +221,7 @@ outgoing-num-tcp{COLON} { YDVAR(1, VAR_OUTGOING_NUM_TCP) } incoming-num-tcp{COLON} { YDVAR(1, VAR_INCOMING_NUM_TCP) } do-ip4{COLON} { YDVAR(1, VAR_DO_IP4) } do-ip6{COLON} { YDVAR(1, VAR_DO_IP6) } +prefer-ip6{COLON} { YDVAR(1, VAR_PREFER_IP6) } do-udp{COLON} { YDVAR(1, VAR_DO_UDP) } do-tcp{COLON} { YDVAR(1, VAR_DO_TCP) } tcp-upstream{COLON} { YDVAR(1, VAR_TCP_UPSTREAM) } @@ -347,6 +351,10 @@ dns64-prefix{COLON} { YDVAR(1, VAR_DNS64_PREFIX) } dns64-synthall{COLON} { YDVAR(1, VAR_DNS64_SYNTHALL) } define-tag{COLON} { YDVAR(1, VAR_DEFINE_TAG) } local-zone-tag{COLON} { YDVAR(2, VAR_LOCAL_ZONE_TAG) } +access-control-tag{COLON} { YDVAR(2, VAR_ACCESS_CONTROL_TAG) } +access-control-tag-action{COLON} { YDVAR(3, VAR_ACCESS_CONTROL_TAG_ACTION) } +access-control-tag-data{COLON} { YDVAR(3, VAR_ACCESS_CONTROL_TAG_DATA) } +local-zone-override{COLON} { YDVAR(3, VAR_LOCAL_ZONE_OVERRIDE) } dnstap{COLON} { YDVAR(0, VAR_DNSTAP) } dnstap-enable{COLON} { YDVAR(1, VAR_DNSTAP_ENABLE) } dnstap-socket-path{COLON} { YDVAR(1, VAR_DNSTAP_SOCKET_PATH) } diff --git a/contrib/unbound/util/configparser.y b/contrib/unbound/util/configparser.y index 4ff18f0ce5c7..7240ee4bdd00 100644 --- a/contrib/unbound/util/configparser.y +++ b/contrib/unbound/util/configparser.y @@ -69,7 +69,7 @@ extern struct config_parser_state* cfg_parser; %token <str> STRING_ARG %token VAR_SERVER VAR_VERBOSITY VAR_NUM_THREADS VAR_PORT %token VAR_OUTGOING_RANGE VAR_INTERFACE -%token VAR_DO_IP4 VAR_DO_IP6 VAR_DO_UDP VAR_DO_TCP +%token VAR_DO_IP4 VAR_DO_IP6 VAR_PREFER_IP6 VAR_DO_UDP VAR_DO_TCP %token VAR_TCP_MSS VAR_OUTGOING_TCP_MSS %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 @@ -126,6 +126,8 @@ extern struct config_parser_state* cfg_parser; %token VAR_RATELIMIT_FOR_DOMAIN VAR_RATELIMIT_BELOW_DOMAIN VAR_RATELIMIT_FACTOR %token VAR_CAPS_WHITELIST VAR_CACHE_MAX_NEGATIVE_TTL VAR_PERMIT_SMALL_HOLDDOWN %token VAR_QNAME_MINIMISATION VAR_IP_FREEBIND VAR_DEFINE_TAG VAR_LOCAL_ZONE_TAG +%token VAR_ACCESS_CONTROL_TAG VAR_LOCAL_ZONE_OVERRIDE +%token VAR_ACCESS_CONTROL_TAG_ACTION VAR_ACCESS_CONTROL_TAG_DATA %% toplevelvars: /* empty */ | toplevelvars toplevelvar ; @@ -144,7 +146,8 @@ contents_server: contents_server content_server | ; content_server: server_num_threads | server_verbosity | server_port | server_outgoing_range | server_do_ip4 | - server_do_ip6 | server_do_udp | server_do_tcp | + server_do_ip6 | server_prefer_ip6 | + server_do_udp | server_do_tcp | server_tcp_mss | server_outgoing_tcp_mss | server_interface | server_chroot | server_username | server_directory | server_logfile | server_pidfile | @@ -194,7 +197,9 @@ content_server: server_num_threads | server_verbosity | server_port | server_caps_whitelist | server_cache_max_negative_ttl | server_permit_small_holddown | server_qname_minimisation | server_ip_freebind | server_define_tag | server_local_zone_tag | - server_disable_dnssec_lame_check + server_disable_dnssec_lame_check | server_access_control_tag | + server_local_zone_override | server_access_control_tag_action | + server_access_control_tag_data ; stubstart: VAR_STUB_ZONE { @@ -402,6 +407,15 @@ server_do_tcp: VAR_DO_TCP STRING_ARG free($2); } ; +server_prefer_ip6: VAR_PREFER_IP6 STRING_ARG + { + OUTYY(("P(server_prefer_ip6:%s)\n", $2)); + if(strcmp($2, "yes") != 0 && strcmp($2, "no") != 0) + yyerror("expected yes or no."); + else cfg_parser->cfg->prefer_ip6 = (strcmp($2, "yes")==0); + free($2); + } + ; server_tcp_mss: VAR_TCP_MSS STRING_ARG { OUTYY(("P(server_tcp_mss:%s)\n", $2)); @@ -521,6 +535,23 @@ server_directory: VAR_DIRECTORY STRING_ARG OUTYY(("P(server_directory:%s)\n", $2)); free(cfg_parser->cfg->directory); cfg_parser->cfg->directory = $2; + /* change there right away for includes relative to this */ + if($2[0]) { + char* d; +#ifdef UB_ON_WINDOWS + w_config_adjust_directory(cfg_parser->cfg); +#endif + d = cfg_parser->cfg->directory; + /* adjust directory if we have already chroot, + * like, we reread after sighup */ + if(cfg_parser->chroot && cfg_parser->chroot[0] && + strncmp(d, cfg_parser->chroot, strlen( + cfg_parser->chroot)) == 0) + d += strlen(cfg_parser->chroot); + if(chdir(d)) + log_err("cannot chdir to directory: %s (%s)", + d, strerror(errno)); + } } ; server_logfile: VAR_LOGFILE STRING_ARG @@ -1216,12 +1247,16 @@ server_local_zone: VAR_LOCAL_ZONE STRING_ARG STRING_ARG 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, "typetransparent")!=0 && - strcmp($3, "inform")!=0 && strcmp($3, "inform_deny")!=0) + && strcmp($3, "typetransparent")!=0 + && strcmp($3, "always_transparent")!=0 + && strcmp($3, "always_refuse")!=0 + && strcmp($3, "always_nxdomain")!=0 + && strcmp($3, "inform")!=0 && strcmp($3, "inform_deny")!=0) yyerror("local-zone type: expected static, deny, " "refuse, redirect, transparent, " - "typetransparent, inform, inform_deny " - "or nodefault"); + "typetransparent, inform, inform_deny, " + "always_transparent, always_refuse, " + "always_nxdomain or nodefault"); else if(strcmp($3, "nodefault")==0) { if(!cfg_strlist_insert(&cfg_parser->cfg-> local_zones_nodefault, $2)) @@ -1332,6 +1367,61 @@ server_local_zone_tag: VAR_LOCAL_ZONE_TAG STRING_ARG STRING_ARG } } ; +server_access_control_tag: VAR_ACCESS_CONTROL_TAG STRING_ARG STRING_ARG + { + size_t len = 0; + uint8_t* bitlist = config_parse_taglist(cfg_parser->cfg, $3, + &len); + free($3); + OUTYY(("P(server_access_control_tag:%s)\n", $2)); + if(!bitlist) + yyerror("could not parse tags, (define-tag them first)"); + if(bitlist) { + if(!cfg_strbytelist_insert( + &cfg_parser->cfg->acl_tags, + $2, bitlist, len)) { + yyerror("out of memory"); + free($2); + } + } + } + ; +server_access_control_tag_action: VAR_ACCESS_CONTROL_TAG_ACTION STRING_ARG STRING_ARG STRING_ARG + { + OUTYY(("P(server_access_control_tag_action:%s %s %s)\n", $2, $3, $4)); + if(!cfg_str3list_insert(&cfg_parser->cfg->acl_tag_actions, + $2, $3, $4)) { + yyerror("out of memory"); + free($2); + free($3); + free($4); + } + } + ; +server_access_control_tag_data: VAR_ACCESS_CONTROL_TAG_DATA STRING_ARG STRING_ARG STRING_ARG + { + OUTYY(("P(server_access_control_tag_data:%s %s %s)\n", $2, $3, $4)); + if(!cfg_str3list_insert(&cfg_parser->cfg->acl_tag_datas, + $2, $3, $4)) { + yyerror("out of memory"); + free($2); + free($3); + free($4); + } + } + ; +server_local_zone_override: VAR_LOCAL_ZONE_OVERRIDE STRING_ARG STRING_ARG STRING_ARG + { + OUTYY(("P(server_local_zone_override:%s %s %s)\n", $2, $3, $4)); + if(!cfg_str3list_insert(&cfg_parser->cfg->local_zone_overrides, + $2, $3, $4)) { + yyerror("out of memory"); + free($2); + free($3); + free($4); + } + } + ; server_ratelimit: VAR_RATELIMIT STRING_ARG { OUTYY(("P(server_ratelimit:%s)\n", $2)); diff --git a/contrib/unbound/util/iana_ports.inc b/contrib/unbound/util/iana_ports.inc index 3856488ba347..0ac3efb68954 100644 --- a/contrib/unbound/util/iana_ports.inc +++ b/contrib/unbound/util/iana_ports.inc @@ -1186,6 +1186,7 @@ 1525, 1526, 1527, +1528, 1529, 1530, 1531, @@ -4526,7 +4527,6 @@ 6786, 6787, 6788, -6789, 6790, 6791, 6801, @@ -5425,6 +5425,7 @@ 44900, 45000, 45054, +45514, 45678, 45825, 45966, diff --git a/contrib/unbound/util/net_help.c b/contrib/unbound/util/net_help.c index 5d6c033d6597..248598918b8e 100644 --- a/contrib/unbound/util/net_help.c +++ b/contrib/unbound/util/net_help.c @@ -783,7 +783,7 @@ void* outgoing_ssl_fd(void* sslctx, int fd) #endif } -#if defined(HAVE_SSL) && defined(OPENSSL_THREADS) && !defined(THREADS_DISABLED) && defined(CRYPTO_LOCK) +#if defined(HAVE_SSL) && defined(OPENSSL_THREADS) && !defined(THREADS_DISABLED) && defined(CRYPTO_LOCK) && OPENSSL_VERSION_NUMBER < 0x10100000L /** global lock list for openssl locks */ static lock_basic_t *ub_openssl_locks = NULL; @@ -808,7 +808,7 @@ ub_crypto_lock_cb(int mode, int type, const char *ATTR_UNUSED(file), int ub_openssl_lock_init(void) { -#if defined(HAVE_SSL) && defined(OPENSSL_THREADS) && !defined(THREADS_DISABLED) && defined(CRYPTO_LOCK) +#if defined(HAVE_SSL) && defined(OPENSSL_THREADS) && !defined(THREADS_DISABLED) && defined(CRYPTO_LOCK) && OPENSSL_VERSION_NUMBER < 0x10100000L int i; ub_openssl_locks = (lock_basic_t*)reallocarray( NULL, (size_t)CRYPTO_num_locks(), sizeof(lock_basic_t)); @@ -825,7 +825,7 @@ int ub_openssl_lock_init(void) void ub_openssl_lock_delete(void) { -#if defined(HAVE_SSL) && defined(OPENSSL_THREADS) && !defined(THREADS_DISABLED) && defined(CRYPTO_LOCK) +#if defined(HAVE_SSL) && defined(OPENSSL_THREADS) && !defined(THREADS_DISABLED) && defined(CRYPTO_LOCK) && OPENSSL_VERSION_NUMBER < 0x10100000L int i; if(!ub_openssl_locks) return; diff --git a/contrib/unbound/util/netevent.c b/contrib/unbound/util/netevent.c index bdb35739327b..8960b362c78d 100644 --- a/contrib/unbound/util/netevent.c +++ b/contrib/unbound/util/netevent.c @@ -80,8 +80,10 @@ # endif #endif -/** The TCP reading or writing query timeout in seconds */ -#define TCP_QUERY_TIMEOUT 120 +/** The TCP reading or writing query timeout in milliseconds */ +#define TCP_QUERY_TIMEOUT 120000 +/** The TCP timeout in msec for fast queries, above half are used */ +#define TCP_QUERY_TIMEOUT_FAST 200 #ifndef NONBLOCKING_IS_BROKEN /** number of UDP reads to perform per read indication from select */ @@ -710,14 +712,20 @@ comm_point_udp_callback(int fd, short event, void* arg) /** Use a new tcp handler for new query fd, set to read query */ static void -setup_tcp_handler(struct comm_point* c, int fd) +setup_tcp_handler(struct comm_point* c, int fd, int cur, int max) { log_assert(c->type == comm_tcp); log_assert(c->fd == -1); sldns_buffer_clear(c->buffer); c->tcp_is_reading = 1; c->tcp_byte_count = 0; - comm_point_start_listening(c, fd, TCP_QUERY_TIMEOUT); + c->tcp_timeout_msec = TCP_QUERY_TIMEOUT; + /* if more than half the tcp handlers are in use, use a shorter + * timeout for this TCP connection, we need to make space for + * other connections to be able to get attention */ + if(cur > max/2) + c->tcp_timeout_msec = TCP_QUERY_TIMEOUT_FAST; + comm_point_start_listening(c, fd, c->tcp_timeout_msec); } void comm_base_handle_slow_accept(int ATTR_UNUSED(fd), @@ -769,7 +777,7 @@ int comm_point_perform_accept(struct comm_point* c, (*b->stop_accept)(b->cb_arg); /* set timeout, no mallocs */ tv.tv_sec = NETEVENT_SLOW_ACCEPT_TIME/1000; - tv.tv_usec = NETEVENT_SLOW_ACCEPT_TIME%1000; + tv.tv_usec = (NETEVENT_SLOW_ACCEPT_TIME%1000)*1000; b->eb->slow_accept = ub_event_new(b->eb->base, -1, UB_EV_TIMEOUT, comm_base_handle_slow_accept, b); @@ -862,6 +870,7 @@ comm_point_tcp_accept_callback(int fd, short event, void* arg) /* accept incoming connection. */ c_hdl = c->tcp_free; log_assert(fd != -1); + (void)fd; new_fd = comm_point_perform_accept(c, &c_hdl->repinfo.addr, &c_hdl->repinfo.addrlen); if(new_fd == -1) @@ -886,7 +895,7 @@ comm_point_tcp_accept_callback(int fd, short event, void* arg) /* stop accepting incoming queries for now. */ comm_point_stop_listening(c); } - setup_tcp_handler(c_hdl, new_fd); + setup_tcp_handler(c_hdl, new_fd, c->cur_tcp_count, c->max_tcp_count); } /** Make tcp handler free for next assignment */ @@ -940,7 +949,7 @@ tcp_callback_reader(struct comm_point* c) comm_point_stop_listening(c); fptr_ok(fptr_whitelist_comm_point(c->callback)); if( (*c->callback)(c, c->cb_arg, NETEVENT_NOERROR, &c->repinfo) ) { - comm_point_start_listening(c, -1, TCP_QUERY_TIMEOUT); + comm_point_start_listening(c, -1, c->tcp_timeout_msec); } } @@ -1348,6 +1357,59 @@ comm_point_tcp_handle_write(int fd, struct comm_point* c) if(c->ssl) return ssl_handle_it(c); +#ifdef USE_MSG_FASTOPEN + /* Only try this on first use of a connection that uses tfo, + otherwise fall through to normal write */ + /* Also, TFO support on WINDOWS not implemented at the moment */ + if(c->tcp_do_fastopen == 1) { + /* this form of sendmsg() does both a connect() and send() so need to + look for various flavours of error*/ + uint16_t len = htons(sldns_buffer_limit(c->buffer)); + struct msghdr msg; + struct iovec iov[2]; + c->tcp_do_fastopen = 0; + memset(&msg, 0, sizeof(msg)); + iov[0].iov_base = (uint8_t*)&len + c->tcp_byte_count; + iov[0].iov_len = sizeof(uint16_t) - c->tcp_byte_count; + iov[1].iov_base = sldns_buffer_begin(c->buffer); + iov[1].iov_len = sldns_buffer_limit(c->buffer); + log_assert(iov[0].iov_len > 0); + log_assert(iov[1].iov_len > 0); + msg.msg_name = &c->repinfo.addr; + msg.msg_namelen = c->repinfo.addrlen; + msg.msg_iov = iov; + msg.msg_iovlen = 2; + r = sendmsg(fd, &msg, MSG_FASTOPEN); + if (r == -1) { +#if defined(EINPROGRESS) && defined(EWOULDBLOCK) + /* Handshake is underway, maybe because no TFO cookie available. + Come back to write the messsage*/ + if(errno == EINPROGRESS || errno == EWOULDBLOCK) + return 1; +#endif + if(errno == EINTR || errno == EAGAIN) + return 1; + /* Not handling EISCONN here as shouldn't ever hit that case.*/ + if(errno != 0 && verbosity < 2) + return 0; /* silence lots of chatter in the logs */ + else if(errno != 0) + log_err_addr("tcp sendmsg", strerror(errno), + &c->repinfo.addr, c->repinfo.addrlen); + return 0; + } else { + c->tcp_byte_count += r; + if(c->tcp_byte_count < sizeof(uint16_t)) + return 1; + sldns_buffer_set_position(c->buffer, c->tcp_byte_count - + sizeof(uint16_t)); + if(sldns_buffer_remaining(c->buffer) == 0) { + tcp_callback_writer(c); + return 1; + } + } + } +#endif /* USE_MSG_FASTOPEN */ + if(c->tcp_byte_count < sizeof(uint16_t)) { uint16_t len = htons(sldns_buffer_limit(c->buffer)); #ifdef HAVE_WRITEV @@ -1540,6 +1602,9 @@ comm_point_create_udp(struct comm_base *base, int fd, sldns_buffer* buffer, c->do_not_close = 0; c->tcp_do_toggle_rw = 0; c->tcp_check_nb_connect = 0; +#ifdef USE_MSG_FASTOPEN + c->tcp_do_fastopen = 0; +#endif c->inuse = 0; c->callback = callback; c->cb_arg = callback_arg; @@ -1593,6 +1658,9 @@ comm_point_create_udp_ancil(struct comm_base *base, int fd, c->inuse = 0; c->tcp_do_toggle_rw = 0; c->tcp_check_nb_connect = 0; +#ifdef USE_MSG_FASTOPEN + c->tcp_do_fastopen = 0; +#endif c->callback = callback; c->cb_arg = callback_arg; evbits = UB_EV_READ | UB_EV_PERSIST; @@ -1655,6 +1723,9 @@ comm_point_create_tcp_handler(struct comm_base *base, c->do_not_close = 0; c->tcp_do_toggle_rw = 1; c->tcp_check_nb_connect = 0; +#ifdef USE_MSG_FASTOPEN + c->tcp_do_fastopen = 0; +#endif c->repinfo.c = c; c->callback = callback; c->cb_arg = callback_arg; @@ -1715,6 +1786,9 @@ comm_point_create_tcp(struct comm_base *base, int fd, int num, size_t bufsize, c->do_not_close = 0; c->tcp_do_toggle_rw = 0; c->tcp_check_nb_connect = 0; +#ifdef USE_MSG_FASTOPEN + c->tcp_do_fastopen = 0; +#endif c->callback = NULL; c->cb_arg = NULL; evbits = UB_EV_READ | UB_EV_PERSIST; @@ -1780,6 +1854,9 @@ comm_point_create_tcp_out(struct comm_base *base, size_t bufsize, c->do_not_close = 0; c->tcp_do_toggle_rw = 1; c->tcp_check_nb_connect = 1; +#ifdef USE_MSG_FASTOPEN + c->tcp_do_fastopen = 1; +#endif c->repinfo.c = c; c->callback = callback; c->cb_arg = callback_arg; @@ -1834,6 +1911,9 @@ comm_point_create_local(struct comm_base *base, int fd, size_t bufsize, c->do_not_close = 1; c->tcp_do_toggle_rw = 0; c->tcp_check_nb_connect = 0; +#ifdef USE_MSG_FASTOPEN + c->tcp_do_fastopen = 0; +#endif c->callback = callback; c->cb_arg = callback_arg; /* ub_event stuff */ @@ -1887,6 +1967,9 @@ comm_point_create_raw(struct comm_base* base, int fd, int writing, c->do_not_close = 1; c->tcp_do_toggle_rw = 0; c->tcp_check_nb_connect = 0; +#ifdef USE_MSG_FASTOPEN + c->tcp_do_fastopen = 0; +#endif c->callback = callback; c->cb_arg = callback_arg; /* ub_event stuff */ @@ -1983,7 +2066,8 @@ comm_point_send_reply(struct comm_reply *repinfo) dt_msg_send_client_response(repinfo->c->tcp_parent->dtenv, &repinfo->addr, repinfo->c->type, repinfo->c->buffer); #endif - comm_point_start_listening(repinfo->c, -1, TCP_QUERY_TIMEOUT); + comm_point_start_listening(repinfo->c, -1, + repinfo->c->tcp_timeout_msec); } } @@ -2009,7 +2093,7 @@ comm_point_stop_listening(struct comm_point* c) } void -comm_point_start_listening(struct comm_point* c, int newfd, int sec) +comm_point_start_listening(struct comm_point* c, int newfd, int msec) { verbose(VERB_ALGO, "comm point start listening %d", c->fd==-1?newfd:c->fd); @@ -2017,7 +2101,7 @@ comm_point_start_listening(struct comm_point* c, int newfd, int sec) /* no use to start listening no free slots. */ return; } - if(sec != -1 && sec != 0) { + if(msec != -1 && msec != 0) { if(!c->timeout) { c->timeout = (struct timeval*)malloc(sizeof( struct timeval)); @@ -2028,8 +2112,8 @@ comm_point_start_listening(struct comm_point* c, int newfd, int sec) } ub_event_add_bits(c->ev->ev, UB_EV_TIMEOUT); #ifndef S_SPLINT_S /* splint fails on struct timeval. */ - c->timeout->tv_sec = sec; - c->timeout->tv_usec = 0; + c->timeout->tv_sec = msec/1000; + c->timeout->tv_usec = (msec%1000)*1000; #endif /* S_SPLINT_S */ } if(c->type == comm_tcp) { @@ -2049,7 +2133,7 @@ comm_point_start_listening(struct comm_point* c, int newfd, int sec) c->fd = newfd; ub_event_set_fd(c->ev->ev, c->fd); } - if(ub_event_add(c->ev->ev, sec==0?NULL:c->timeout) != 0) { + if(ub_event_add(c->ev->ev, msec==0?NULL:c->timeout) != 0) { log_err("event_add failed. in cpsl."); } } diff --git a/contrib/unbound/util/netevent.h b/contrib/unbound/util/netevent.h index bdcddd848bd0..1d7ac0bc118b 100644 --- a/contrib/unbound/util/netevent.h +++ b/contrib/unbound/util/netevent.h @@ -225,9 +225,17 @@ struct comm_point { So that when that is done the callback is called. */ int tcp_do_toggle_rw; + /** timeout in msec for TCP wait times for this connection */ + int tcp_timeout_msec; + /** if set, checks for pending error from nonblocking connect() call.*/ int tcp_check_nb_connect; +#ifdef USE_MSG_FASTOPEN + /** used to track if the sendto() call should be done when using TFO. */ + int tcp_do_fastopen; +#endif + /** number of queries outstanding on this socket, used by * outside network for udp ports */ int inuse; @@ -496,9 +504,10 @@ void comm_point_stop_listening(struct comm_point* c); * Start listening again for input on the comm point. * @param c: commpoint to enable again. * @param newfd: new fd, or -1 to leave fd be. - * @param sec: timeout in seconds, or -1 for no (change to the) timeout. + * @param msec: timeout in milliseconds, or -1 for no (change to the) timeout. + * So seconds*1000. */ -void comm_point_start_listening(struct comm_point* c, int newfd, int sec); +void comm_point_start_listening(struct comm_point* c, int newfd, int msec); /** * Stop listening and start listening again for reading or writing. diff --git a/contrib/unbound/util/storage/dnstree.c b/contrib/unbound/util/storage/dnstree.c index 0df490ee5566..7664c479d47a 100644 --- a/contrib/unbound/util/storage/dnstree.c +++ b/contrib/unbound/util/storage/dnstree.c @@ -231,6 +231,19 @@ struct addr_tree_node* addr_tree_lookup(rbtree_t* tree, return result; } +struct addr_tree_node* addr_tree_find(rbtree_t* tree, + struct sockaddr_storage* addr, socklen_t addrlen, int net) +{ + rbnode_t* res = NULL; + struct addr_tree_node key; + key.node.key = &key; + memcpy(&key.addr, addr, addrlen); + key.addrlen = addrlen; + key.net = net; + res = rbtree_search(tree, &key); + return (struct addr_tree_node*)res; +} + int name_tree_next_root(rbtree_t* tree, uint16_t* dclass) { diff --git a/contrib/unbound/util/storage/dnstree.h b/contrib/unbound/util/storage/dnstree.h index ec8189100f9e..b4595e19ee0f 100644 --- a/contrib/unbound/util/storage/dnstree.h +++ b/contrib/unbound/util/storage/dnstree.h @@ -183,6 +183,17 @@ void addr_tree_init_parents(rbtree_t* tree); struct addr_tree_node* addr_tree_lookup(rbtree_t* tree, struct sockaddr_storage* addr, socklen_t addrlen); +/** + * Find element in addr tree. (search a netblock, not a match for an address) + * @param tree: addr tree + * @param addr: netblock to lookup. + * @param addrlen: length of addr + * @param net: size of subnet + * @return addr tree element, or NULL if not found. + */ +struct addr_tree_node* addr_tree_find(rbtree_t* tree, + struct sockaddr_storage* addr, socklen_t addrlen, int net); + /** compare name tree nodes */ int name_tree_compare(const void* k1, const void* k2); diff --git a/contrib/unbound/util/storage/lookup3.c b/contrib/unbound/util/storage/lookup3.c index ddcb56e7470f..e9b05af37e31 100644 --- a/contrib/unbound/util/storage/lookup3.c +++ b/contrib/unbound/util/storage/lookup3.c @@ -820,7 +820,7 @@ uint32_t hashbig( const void *key, size_t length, uint32_t initval) #ifdef SELF_TEST /* used for timings */ -void driver1() +void driver1(void) { uint8_t buf[256]; uint32_t i; @@ -842,7 +842,7 @@ void driver1() #define HASHLEN 1 #define MAXPAIR 60 #define MAXLEN 70 -void driver2() +void driver2(void) { uint8_t qa[MAXLEN+1], qb[MAXLEN+2], *a = &qa[0], *b = &qb[1]; uint32_t c[HASHSTATE], d[HASHSTATE], i=0, j=0, k, l, m=0, z; @@ -912,7 +912,7 @@ void driver2() } /* Check for reading beyond the end of the buffer and alignment problems */ -void driver3() +void driver3(void) { uint8_t buf[MAXLEN+20], *b; uint32_t len; @@ -1003,7 +1003,7 @@ void driver3() } /* check for problems with nulls */ - void driver4() + void driver4(void) { uint8_t buf[1]; uint32_t h,i,state[HASHSTATE]; @@ -1020,7 +1020,7 @@ void driver3() } -int main() +int main(void) { driver1(); /* test that the key is hashed: used for timings */ driver2(); /* test that whole key is hashed thoroughly */ diff --git a/contrib/unbound/util/ub_event.c b/contrib/unbound/util/ub_event.c index af2a18ea0fc8..3b92be1a3025 100644 --- a/contrib/unbound/util/ub_event.c +++ b/contrib/unbound/util/ub_event.c @@ -132,16 +132,12 @@ static void (*NATIVE_BITS_CB(void (*cb)(int, short, void*)))(int, short, void*) #define EVFLAG_AUTO 0 #endif -#define AS_EVENT_BASE(x) \ - (((union {struct ub_event_base* a; struct event_base* b;})x).b) -#define AS_UB_EVENT_BASE(x) \ - (((union {struct event_base* a; struct ub_event_base* b;})x).b) -#define AS_EVENT(x) \ - (((union {struct ub_event* a; struct event* b;})x).b) -#define AS_UB_EVENT(x) \ - (((union {struct event* a; struct ub_event* b;})x).b) - -const char* ub_event_get_version() +#define AS_EVENT_BASE(x) ((struct event_base*)x) +#define AS_UB_EVENT_BASE(x) ((struct ub_event_base*)x) +#define AS_EVENT(x) ((struct event*)x) +#define AS_UB_EVENT(x) ((struct ub_event*)x) + +const char* ub_event_get_version(void) { return event_get_version(); } diff --git a/contrib/unbound/util/ub_event_pluggable.c b/contrib/unbound/util/ub_event_pluggable.c index 5c517555e71b..4a9451263b7c 100644 --- a/contrib/unbound/util/ub_event_pluggable.c +++ b/contrib/unbound/util/ub_event_pluggable.c @@ -144,12 +144,10 @@ struct my_event { struct event ev; }; -#define AS_MY_EVENT_BASE(x) \ - (((union {struct ub_event_base* a; struct my_event_base* b;})x).b) -#define AS_MY_EVENT(x) \ - (((union {struct ub_event* a; struct my_event* b;})x).b) +#define AS_MY_EVENT_BASE(x) ((struct my_event_base*)x) +#define AS_MY_EVENT(x) ((struct my_event*)x) -const char* ub_event_get_version() +const char* ub_event_get_version(void) { return "pluggable-event"PACKAGE_VERSION; } @@ -597,7 +595,7 @@ ub_event_add(struct ub_event* ev, struct timeval* tv) int ub_event_del(struct ub_event* ev) { - if (ev->magic == UB_EVENT_MAGIC) { + if (ev && ev->magic == UB_EVENT_MAGIC) { fptr_ok(ev->vmt != &default_event_vmt || ev->vmt->del == my_event_del); return (*ev->vmt->del)(ev); @@ -620,7 +618,7 @@ ub_timer_add(struct ub_event* ev, struct ub_event_base* base, int ub_timer_del(struct ub_event* ev) { - if (ev->magic == UB_EVENT_MAGIC) { + if (ev && ev->magic == UB_EVENT_MAGIC) { fptr_ok(ev->vmt != &default_event_vmt || ev->vmt->del_timer == my_timer_del); return (*ev->vmt->del_timer)(ev); @@ -642,7 +640,7 @@ ub_signal_add(struct ub_event* ev, struct timeval* tv) int ub_signal_del(struct ub_event* ev) { - if (ev->magic == UB_EVENT_MAGIC) { + if (ev && ev->magic == UB_EVENT_MAGIC) { fptr_ok(ev->vmt != &default_event_vmt || ev->vmt->del_signal == my_signal_del); return (*ev->vmt->del_signal)(ev); @@ -653,7 +651,7 @@ ub_signal_del(struct ub_event* ev) void ub_winsock_unregister_wsaevent(struct ub_event* ev) { - if (ev->magic == UB_EVENT_MAGIC) { + if (ev && ev->magic == UB_EVENT_MAGIC) { fptr_ok(ev->vmt != &default_event_vmt || ev->vmt->winsock_unregister_wsaevent == my_winsock_unregister_wsaevent); diff --git a/contrib/unbound/util/winsock_event.c b/contrib/unbound/util/winsock_event.c index 40b79821a478..9aad27edc0bc 100644 --- a/contrib/unbound/util/winsock_event.c +++ b/contrib/unbound/util/winsock_event.c @@ -262,8 +262,9 @@ static int handle_select(struct event_base* base, struct timeval* wait) break; /* sanity check */ } log_assert(numwait <= WSA_MAXIMUM_WAIT_EVENTS); - verbose(VERB_CLIENT, "winsock_event bmax=%d numwait=%d wait=%x " - "timeout=%d", base->max, numwait, (int)wait, (int)timeout); + verbose(VERB_CLIENT, "winsock_event bmax=%d numwait=%d wait=%s " + "timeout=%d", base->max, numwait, (wait?"<wait>":"<null>"), + (int)timeout); /* do the wait */ if(numwait == 0) { |