diff options
author | Maxim Yurchuk <maxim-yurchuk@ydb.tech> | 2024-10-20 00:06:50 +0300 |
---|---|---|
committer | GitHub <noreply@github.com> | 2024-10-20 00:06:50 +0300 |
commit | e0b481c6710337ae655271bbb80afe6ac81a5614 (patch) | |
tree | dba67dc017935800d0c3f8dc967e9522c5302bd2 /contrib/libs/c-ares/src/lib/ares_update_servers.c | |
parent | 07f2e60d02d95eab14a86a4b9469db1af7795001 (diff) | |
parent | f04ad7e5462f5910ef95f2efd15c509e539ae62d (diff) | |
download | ydb-e0b481c6710337ae655271bbb80afe6ac81a5614.tar.gz |
Merge pull request #10642 from ydb-platform/mergelibs-241019-1758
Library import 241019-1758
Diffstat (limited to 'contrib/libs/c-ares/src/lib/ares_update_servers.c')
-rw-r--r-- | contrib/libs/c-ares/src/lib/ares_update_servers.c | 593 |
1 files changed, 358 insertions, 235 deletions
diff --git a/contrib/libs/c-ares/src/lib/ares_update_servers.c b/contrib/libs/c-ares/src/lib/ares_update_servers.c index 639f79d815..70a9381499 100644 --- a/contrib/libs/c-ares/src/lib/ares_update_servers.c +++ b/contrib/libs/c-ares/src/lib/ares_update_servers.c @@ -39,6 +39,9 @@ #ifdef HAVE_NET_IF_H # include <net/if.h> #endif +#ifdef HAVE_STDINT_H +# include <stdint.h> +#endif #if defined(USE_WINSOCK) # if defined(HAVE_IPHLPAPI_H) @@ -61,8 +64,8 @@ typedef struct { unsigned int ll_scope; } ares_sconfig_t; -static ares_bool_t ares__addr_match(const struct ares_addr *addr1, - const struct ares_addr *addr2) +static ares_bool_t ares_addr_match(const struct ares_addr *addr1, + const struct ares_addr *addr2) { if (addr1 == NULL && addr2 == NULL) { return ARES_TRUE; /* LCOV_EXCL_LINE: DefensiveCoding */ @@ -90,9 +93,9 @@ static ares_bool_t ares__addr_match(const struct ares_addr *addr1, return ARES_FALSE; } -ares_bool_t ares__subnet_match(const struct ares_addr *addr, - const struct ares_addr *subnet, - unsigned char netmask) +ares_bool_t ares_subnet_match(const struct ares_addr *addr, + const struct ares_addr *subnet, + unsigned char netmask) { const unsigned char *addr_ptr; const unsigned char *subnet_ptr; @@ -144,7 +147,7 @@ ares_bool_t ares__subnet_match(const struct ares_addr *addr, return ARES_TRUE; } -ares_bool_t ares__addr_is_linklocal(const struct ares_addr *addr) +ares_bool_t ares_addr_is_linklocal(const struct ares_addr *addr) { struct ares_addr subnet; const unsigned char subnetaddr[16] = { 0xfe, 0x80, 0x00, 0x00, 0x00, 0x00, @@ -155,7 +158,7 @@ ares_bool_t ares__addr_is_linklocal(const struct ares_addr *addr) subnet.family = AF_INET6; memcpy(&subnet.addr.addr6, subnetaddr, 16); - return ares__subnet_match(addr, &subnet, 10); + return ares_subnet_match(addr, &subnet, 10); } static ares_bool_t ares_server_blacklisted(const struct ares_addr *addr) @@ -185,13 +188,60 @@ static ares_bool_t ares_server_blacklisted(const struct ares_addr *addr) struct ares_addr subnet; subnet.family = AF_INET6; memcpy(&subnet.addr.addr6, blacklist_v6[i].netbase, 16); - if (ares__subnet_match(addr, &subnet, blacklist_v6[i].netmask)) { + if (ares_subnet_match(addr, &subnet, blacklist_v6[i].netmask)) { return ARES_TRUE; } } return ARES_FALSE; } +static ares_status_t parse_nameserver_uri(ares_buf_t *buf, + ares_sconfig_t *sconfig) +{ + ares_uri_t *uri = NULL; + ares_status_t status = ARES_SUCCESS; + const char *port; + char *ll_scope; + char hoststr[256]; + size_t addrlen; + + status = ares_uri_parse_buf(&uri, buf); + if (status != ARES_SUCCESS) { + return status; + } + + if (!ares_streq("dns", ares_uri_get_scheme(uri))) { + status = ARES_EBADSTR; + goto done; + } + + ares_strcpy(hoststr, ares_uri_get_host(uri), sizeof(hoststr)); + ll_scope = strchr(hoststr, '%'); + if (ll_scope != NULL) { + *ll_scope = 0; + ll_scope++; + ares_strcpy(sconfig->ll_iface, ll_scope, sizeof(sconfig->ll_iface)); + } + + /* Convert ip address from string to network byte order */ + sconfig->addr.family = AF_UNSPEC; + if (ares_dns_pton(hoststr, &sconfig->addr, &addrlen) == NULL) { + status = ARES_EBADSTR; + goto done; + } + + sconfig->udp_port = ares_uri_get_port(uri); + sconfig->tcp_port = sconfig->udp_port; + port = ares_uri_get_query_key(uri, "tcpport"); + if (port != NULL) { + sconfig->tcp_port = (unsigned short)atoi(port); + } + +done: + ares_uri_destroy(uri); + return status; +} + /* Parse address and port in these formats, either ipv4 or ipv6 addresses * are allowed: * ipaddr @@ -211,7 +261,7 @@ static ares_bool_t ares_server_blacklisted(const struct ares_addr *addr) * Returns an error code on failure, else ARES_SUCCESS */ -static ares_status_t parse_nameserver(ares__buf_t *buf, ares_sconfig_t *sconfig) +static ares_status_t parse_nameserver(ares_buf_t *buf, ares_sconfig_t *sconfig) { ares_status_t status; char ipaddr[INET6_ADDRSTRLEN] = ""; @@ -220,57 +270,57 @@ static ares_status_t parse_nameserver(ares__buf_t *buf, ares_sconfig_t *sconfig) memset(sconfig, 0, sizeof(*sconfig)); /* Consume any leading whitespace */ - ares__buf_consume_whitespace(buf, ARES_TRUE); + ares_buf_consume_whitespace(buf, ARES_TRUE); /* pop off IP address. If it is in [ ] then it can be ipv4 or ipv6. If * not, ipv4 only */ - if (ares__buf_begins_with(buf, (const unsigned char *)"[", 1)) { + if (ares_buf_begins_with(buf, (const unsigned char *)"[", 1)) { /* Consume [ */ - ares__buf_consume(buf, 1); + ares_buf_consume(buf, 1); - ares__buf_tag(buf); + ares_buf_tag(buf); /* Consume until ] */ - if (ares__buf_consume_until_charset(buf, (const unsigned char *)"]", 1, - ARES_TRUE) == 0) { + if (ares_buf_consume_until_charset(buf, (const unsigned char *)"]", 1, + ARES_TRUE) == SIZE_MAX) { return ARES_EBADSTR; } - status = ares__buf_tag_fetch_string(buf, ipaddr, sizeof(ipaddr)); + status = ares_buf_tag_fetch_string(buf, ipaddr, sizeof(ipaddr)); if (status != ARES_SUCCESS) { return status; } /* Skip over ] */ - ares__buf_consume(buf, 1); + ares_buf_consume(buf, 1); } else { size_t offset; /* Not in [ ], see if '.' is in first 4 characters, if it is, then its ipv4, * otherwise treat as ipv6 */ - ares__buf_tag(buf); + ares_buf_tag(buf); - offset = ares__buf_consume_until_charset(buf, (const unsigned char *)".", 1, - ARES_TRUE); - ares__buf_tag_rollback(buf); - ares__buf_tag(buf); + offset = ares_buf_consume_until_charset(buf, (const unsigned char *)".", 1, + ARES_TRUE); + ares_buf_tag_rollback(buf); + ares_buf_tag(buf); if (offset > 0 && offset < 4) { /* IPv4 */ - if (ares__buf_consume_charset(buf, (const unsigned char *)"0123456789.", - 11) == 0) { + if (ares_buf_consume_charset(buf, (const unsigned char *)"0123456789.", + 11) == 0) { return ARES_EBADSTR; } } else { /* IPv6 */ const unsigned char ipv6_charset[] = "ABCDEFabcdef0123456789.:"; - if (ares__buf_consume_charset(buf, ipv6_charset, - sizeof(ipv6_charset) - 1) == 0) { + if (ares_buf_consume_charset(buf, ipv6_charset, + sizeof(ipv6_charset) - 1) == 0) { return ARES_EBADSTR; } } - status = ares__buf_tag_fetch_string(buf, ipaddr, sizeof(ipaddr)); + status = ares_buf_tag_fetch_string(buf, ipaddr, sizeof(ipaddr)); if (status != ARES_SUCCESS) { return status; } @@ -283,21 +333,21 @@ static ares_status_t parse_nameserver(ares__buf_t *buf, ares_sconfig_t *sconfig) } /* Pull off port */ - if (ares__buf_begins_with(buf, (const unsigned char *)":", 1)) { + if (ares_buf_begins_with(buf, (const unsigned char *)":", 1)) { char portstr[6]; /* Consume : */ - ares__buf_consume(buf, 1); + ares_buf_consume(buf, 1); - ares__buf_tag(buf); + ares_buf_tag(buf); /* Read numbers */ - if (ares__buf_consume_charset(buf, (const unsigned char *)"0123456789", - 10) == 0) { + if (ares_buf_consume_charset(buf, (const unsigned char *)"0123456789", + 10) == 0) { return ARES_EBADSTR; } - status = ares__buf_tag_fetch_string(buf, portstr, sizeof(portstr)); + status = ares_buf_tag_fetch_string(buf, portstr, sizeof(portstr)); if (status != ARES_SUCCESS) { return status; } @@ -307,22 +357,22 @@ static ares_status_t parse_nameserver(ares__buf_t *buf, ares_sconfig_t *sconfig) } /* Pull off interface modifier */ - if (ares__buf_begins_with(buf, (const unsigned char *)"%", 1)) { + if (ares_buf_begins_with(buf, (const unsigned char *)"%", 1)) { const unsigned char iface_charset[] = "ABCDEFGHIJKLMNOPQRSTUVWXYZ" "abcdefghijklmnopqrstuvwxyz" "0123456789.-_\\:{}"; /* Consume % */ - ares__buf_consume(buf, 1); + ares_buf_consume(buf, 1); - ares__buf_tag(buf); + ares_buf_tag(buf); - if (ares__buf_consume_charset(buf, iface_charset, - sizeof(iface_charset) - 1) == 0) { + if (ares_buf_consume_charset(buf, iface_charset, + sizeof(iface_charset) - 1) == 0) { return ARES_EBADSTR; } - status = ares__buf_tag_fetch_string(buf, sconfig->ll_iface, - sizeof(sconfig->ll_iface)); + status = ares_buf_tag_fetch_string(buf, sconfig->ll_iface, + sizeof(sconfig->ll_iface)); if (status != ARES_SUCCESS) { return status; } @@ -330,24 +380,29 @@ static ares_status_t parse_nameserver(ares__buf_t *buf, ares_sconfig_t *sconfig) /* Consume any trailing whitespace so we can bail out if there is something * after we didn't read */ - ares__buf_consume_whitespace(buf, ARES_TRUE); + ares_buf_consume_whitespace(buf, ARES_TRUE); - if (ares__buf_len(buf) != 0) { + if (ares_buf_len(buf) != 0) { return ARES_EBADSTR; } return ARES_SUCCESS; } -static ares_status_t ares__sconfig_linklocal(ares_sconfig_t *s, - const char *ll_iface) +static ares_status_t ares_sconfig_linklocal(const ares_channel_t *channel, + ares_sconfig_t *s, + const char *ll_iface) { unsigned int ll_scope = 0; + if (ares_str_isnum(ll_iface)) { char ifname[IF_NAMESIZE] = ""; ll_scope = (unsigned int)atoi(ll_iface); - if (ares__if_indextoname(ll_scope, ifname, sizeof(ifname)) == NULL) { + if (channel->sock_funcs.aif_indextoname == NULL || + channel->sock_funcs.aif_indextoname(ll_scope, ifname, sizeof(ifname), + channel->sock_func_cb_data) == + NULL) { DEBUGF(fprintf(stderr, "Interface %s for ipv6 Link Local not found\n", ll_iface)); return ARES_ENOTFOUND; @@ -357,7 +412,10 @@ static ares_status_t ares__sconfig_linklocal(ares_sconfig_t *s, return ARES_SUCCESS; } - ll_scope = ares__if_nametoindex(ll_iface); + if (channel->sock_funcs.aif_nametoindex != NULL) { + ll_scope = + channel->sock_funcs.aif_nametoindex(ll_iface, channel->sock_func_cb_data); + } if (ll_scope == 0) { DEBUGF(fprintf(stderr, "Interface %s for ipv6 Link Local not found\n", ll_iface)); @@ -368,11 +426,11 @@ static ares_status_t ares__sconfig_linklocal(ares_sconfig_t *s, return ARES_SUCCESS; } -ares_status_t ares__sconfig_append(ares__llist_t **sconfig, - const struct ares_addr *addr, - unsigned short udp_port, - unsigned short tcp_port, - const char *ll_iface) +ares_status_t ares_sconfig_append(const ares_channel_t *channel, + ares_llist_t **sconfig, + const struct ares_addr *addr, + unsigned short udp_port, + unsigned short tcp_port, const char *ll_iface) { ares_sconfig_t *s; ares_status_t status; @@ -392,7 +450,7 @@ ares_status_t ares__sconfig_append(ares__llist_t **sconfig, } if (*sconfig == NULL) { - *sconfig = ares__llist_create(ares_free); + *sconfig = ares_llist_create(ares_free); if (*sconfig == NULL) { status = ARES_ENOMEM; /* LCOV_EXCL_LINE: OutOfMemory */ goto fail; /* LCOV_EXCL_LINE: OutOfMemory */ @@ -405,13 +463,13 @@ ares_status_t ares__sconfig_append(ares__llist_t **sconfig, /* Handle link-local enumeration. If an interface is specified on a * non-link-local address, we'll simply end up ignoring that */ - if (ares__addr_is_linklocal(&s->addr)) { + if (ares_addr_is_linklocal(&s->addr)) { if (ares_strlen(ll_iface) == 0) { /* Silently ignore this entry, we require an interface */ status = ARES_SUCCESS; goto fail; } - status = ares__sconfig_linklocal(s, ll_iface); + status = ares_sconfig_linklocal(channel, s, ll_iface); /* Silently ignore this entry, we can't validate the interface */ if (status != ARES_SUCCESS) { status = ARES_SUCCESS; @@ -419,7 +477,7 @@ ares_status_t ares__sconfig_append(ares__llist_t **sconfig, } } - if (ares__llist_insert_last(*sconfig, s) == NULL) { + if (ares_llist_insert_last(*sconfig, s) == NULL) { status = ARES_ENOMEM; /* LCOV_EXCL_LINE: OutOfMemory */ goto fail; /* LCOV_EXCL_LINE: OutOfMemory */ } @@ -448,36 +506,43 @@ fail: * * Returns an error code on failure, else ARES_SUCCESS. */ -ares_status_t ares__sconfig_append_fromstr(ares__llist_t **sconfig, - const char *str, - ares_bool_t ignore_invalid) +ares_status_t ares_sconfig_append_fromstr(const ares_channel_t *channel, + ares_llist_t **sconfig, + const char *str, + ares_bool_t ignore_invalid) { - ares_status_t status = ARES_SUCCESS; - ares__buf_t *buf = NULL; - ares__llist_t *list = NULL; - ares__llist_node_t *node; + ares_status_t status = ARES_SUCCESS; + ares_buf_t *buf = NULL; + ares_array_t *list = NULL; + size_t num; + size_t i; /* On Windows, there may be more than one nameserver specified in the same * registry key, so we parse input as a space or comma separated list. */ - buf = ares__buf_create_const((const unsigned char *)str, ares_strlen(str)); + buf = ares_buf_create_const((const unsigned char *)str, ares_strlen(str)); if (buf == NULL) { status = ARES_ENOMEM; goto done; } - status = ares__buf_split(buf, (const unsigned char *)" ,", 2, - ARES_BUF_SPLIT_NONE, 0, &list); + status = ares_buf_split(buf, (const unsigned char *)" ,", 2, + ARES_BUF_SPLIT_NONE, 0, &list); if (status != ARES_SUCCESS) { goto done; } - for (node = ares__llist_node_first(list); node != NULL; - node = ares__llist_node_next(node)) { - ares__buf_t *entry = ares__llist_node_val(node); + num = ares_array_len(list); + for (i = 0; i < num; i++) { + ares_buf_t **bufptr = ares_array_at(list, i); + ares_buf_t *entry = *bufptr; ares_sconfig_t s; - status = parse_nameserver(entry, &s); + status = parse_nameserver_uri(entry, &s); + if (status != ARES_SUCCESS) { + status = parse_nameserver(entry, &s); + } + if (status != ARES_SUCCESS) { if (ignore_invalid) { continue; @@ -486,8 +551,8 @@ ares_status_t ares__sconfig_append_fromstr(ares__llist_t **sconfig, } } - status = ares__sconfig_append(sconfig, &s.addr, s.udp_port, s.tcp_port, - s.ll_iface); + status = ares_sconfig_append(channel, sconfig, &s.addr, s.udp_port, + s.tcp_port, s.ll_iface); if (status != ARES_SUCCESS) { goto done; /* LCOV_EXCL_LINE: OutOfMemory */ } @@ -496,14 +561,14 @@ ares_status_t ares__sconfig_append_fromstr(ares__llist_t **sconfig, status = ARES_SUCCESS; done: - ares__llist_destroy(list); - ares__buf_destroy(buf); + ares_array_destroy(list); + ares_buf_destroy(buf); return status; } -static unsigned short ares__sconfig_get_port(const ares_channel_t *channel, - const ares_sconfig_t *s, - ares_bool_t is_tcp) +static unsigned short ares_sconfig_get_port(const ares_channel_t *channel, + const ares_sconfig_t *s, + ares_bool_t is_tcp) { unsigned short port = is_tcp ? s->tcp_port : s->udp_port; @@ -518,24 +583,24 @@ static unsigned short ares__sconfig_get_port(const ares_channel_t *channel, return port; } -static ares__slist_node_t *ares__server_find(ares_channel_t *channel, - const ares_sconfig_t *s) +static ares_slist_node_t *ares_server_find(const ares_channel_t *channel, + const ares_sconfig_t *s) { - ares__slist_node_t *node; + ares_slist_node_t *node; - for (node = ares__slist_node_first(channel->servers); node != NULL; - node = ares__slist_node_next(node)) { - const ares_server_t *server = ares__slist_node_val(node); + for (node = ares_slist_node_first(channel->servers); node != NULL; + node = ares_slist_node_next(node)) { + const ares_server_t *server = ares_slist_node_val(node); - if (!ares__addr_match(&server->addr, &s->addr)) { + if (!ares_addr_match(&server->addr, &s->addr)) { continue; } - if (server->tcp_port != ares__sconfig_get_port(channel, s, ARES_TRUE)) { + if (server->tcp_port != ares_sconfig_get_port(channel, s, ARES_TRUE)) { continue; } - if (server->udp_port != ares__sconfig_get_port(channel, s, ARES_FALSE)) { + if (server->udp_port != ares_sconfig_get_port(channel, s, ARES_FALSE)) { continue; } @@ -544,28 +609,28 @@ static ares__slist_node_t *ares__server_find(ares_channel_t *channel, return NULL; } -static ares_bool_t ares__server_isdup(const ares_channel_t *channel, - ares__llist_node_t *s) +static ares_bool_t ares_server_isdup(const ares_channel_t *channel, + ares_llist_node_t *s) { /* Scan backwards to see if this is a duplicate */ - ares__llist_node_t *prev; - const ares_sconfig_t *server = ares__llist_node_val(s); + ares_llist_node_t *prev; + const ares_sconfig_t *server = ares_llist_node_val(s); - for (prev = ares__llist_node_prev(s); prev != NULL; - prev = ares__llist_node_prev(prev)) { - const ares_sconfig_t *p = ares__llist_node_val(prev); + for (prev = ares_llist_node_prev(s); prev != NULL; + prev = ares_llist_node_prev(prev)) { + const ares_sconfig_t *p = ares_llist_node_val(prev); - if (!ares__addr_match(&server->addr, &p->addr)) { + if (!ares_addr_match(&server->addr, &p->addr)) { continue; } - if (ares__sconfig_get_port(channel, server, ARES_TRUE) != - ares__sconfig_get_port(channel, p, ARES_TRUE)) { + if (ares_sconfig_get_port(channel, server, ARES_TRUE) != + ares_sconfig_get_port(channel, p, ARES_TRUE)) { continue; } - if (ares__sconfig_get_port(channel, server, ARES_FALSE) != - ares__sconfig_get_port(channel, p, ARES_FALSE)) { + if (ares_sconfig_get_port(channel, server, ARES_FALSE) != + ares_sconfig_get_port(channel, p, ARES_FALSE)) { continue; } @@ -575,9 +640,9 @@ static ares_bool_t ares__server_isdup(const ares_channel_t *channel, return ARES_FALSE; } -static ares_status_t ares__server_create(ares_channel_t *channel, - const ares_sconfig_t *sconfig, - size_t idx) +static ares_status_t ares_server_create(ares_channel_t *channel, + const ares_sconfig_t *sconfig, + size_t idx) { ares_status_t status; ares_server_t *server = ares_malloc_zero(sizeof(*server)); @@ -588,8 +653,8 @@ static ares_status_t ares__server_create(ares_channel_t *channel, server->idx = idx; server->channel = channel; - server->udp_port = ares__sconfig_get_port(channel, sconfig, ARES_FALSE); - server->tcp_port = ares__sconfig_get_port(channel, sconfig, ARES_TRUE); + server->udp_port = ares_sconfig_get_port(channel, sconfig, ARES_FALSE); + server->tcp_port = ares_sconfig_get_port(channel, sconfig, ARES_TRUE); server->addr.family = sconfig->addr.family; server->next_retry_time.sec = 0; server->next_retry_time.usec = 0; @@ -608,25 +673,13 @@ static ares_status_t ares__server_create(ares_channel_t *channel, server->ll_scope = sconfig->ll_scope; } - server->tcp_parser = ares__buf_create(); - if (server->tcp_parser == NULL) { - status = ARES_ENOMEM; /* LCOV_EXCL_LINE: OutOfMemory */ - goto done; /* LCOV_EXCL_LINE: OutOfMemory */ - } - - server->tcp_send = ares__buf_create(); - if (server->tcp_send == NULL) { - status = ARES_ENOMEM; /* LCOV_EXCL_LINE: OutOfMemory */ - goto done; /* LCOV_EXCL_LINE: OutOfMemory */ - } - - server->connections = ares__llist_create(NULL); + server->connections = ares_llist_create(NULL); if (server->connections == NULL) { status = ARES_ENOMEM; /* LCOV_EXCL_LINE: OutOfMemory */ goto done; /* LCOV_EXCL_LINE: OutOfMemory */ } - if (ares__slist_insert(channel->servers, server) == NULL) { + if (ares_slist_insert(channel->servers, server) == NULL) { status = ARES_ENOMEM; /* LCOV_EXCL_LINE: OutOfMemory */ goto done; /* LCOV_EXCL_LINE: OutOfMemory */ } @@ -635,31 +688,31 @@ static ares_status_t ares__server_create(ares_channel_t *channel, done: if (status != ARES_SUCCESS) { - ares__destroy_server(server); /* LCOV_EXCL_LINE: OutOfMemory */ + ares_destroy_server(server); /* LCOV_EXCL_LINE: OutOfMemory */ } return status; } -static ares_bool_t ares__server_in_newconfig(const ares_server_t *server, - ares__llist_t *srvlist) +static ares_bool_t ares_server_in_newconfig(const ares_server_t *server, + ares_llist_t *srvlist) { - ares__llist_node_t *node; + ares_llist_node_t *node; const ares_channel_t *channel = server->channel; - for (node = ares__llist_node_first(srvlist); node != NULL; - node = ares__llist_node_next(node)) { - const ares_sconfig_t *s = ares__llist_node_val(node); + for (node = ares_llist_node_first(srvlist); node != NULL; + node = ares_llist_node_next(node)) { + const ares_sconfig_t *s = ares_llist_node_val(node); - if (!ares__addr_match(&server->addr, &s->addr)) { + if (!ares_addr_match(&server->addr, &s->addr)) { continue; } - if (server->tcp_port != ares__sconfig_get_port(channel, s, ARES_TRUE)) { + if (server->tcp_port != ares_sconfig_get_port(channel, s, ARES_TRUE)) { continue; } - if (server->udp_port != ares__sconfig_get_port(channel, s, ARES_FALSE)) { + if (server->udp_port != ares_sconfig_get_port(channel, s, ARES_FALSE)) { continue; } @@ -669,19 +722,19 @@ static ares_bool_t ares__server_in_newconfig(const ares_server_t *server, return ARES_FALSE; } -static ares_bool_t ares__servers_remove_stale(ares_channel_t *channel, - ares__llist_t *srvlist) +static ares_bool_t ares_servers_remove_stale(ares_channel_t *channel, + ares_llist_t *srvlist) { - ares_bool_t stale_removed = ARES_FALSE; - ares__slist_node_t *snode = ares__slist_node_first(channel->servers); + ares_bool_t stale_removed = ARES_FALSE; + ares_slist_node_t *snode = ares_slist_node_first(channel->servers); while (snode != NULL) { - ares__slist_node_t *snext = ares__slist_node_next(snode); - const ares_server_t *server = ares__slist_node_val(snode); - if (!ares__server_in_newconfig(server, srvlist)) { + ares_slist_node_t *snext = ares_slist_node_next(snode); + const ares_server_t *server = ares_slist_node_val(snode); + if (!ares_server_in_newconfig(server, srvlist)) { /* This will clean up all server state via the destruction callback and * move any queries to new servers */ - ares__slist_node_destroy(snode); + ares_slist_node_destroy(snode); stale_removed = ARES_TRUE; } snode = snext; @@ -689,21 +742,21 @@ static ares_bool_t ares__servers_remove_stale(ares_channel_t *channel, return stale_removed; } -static void ares__servers_trim_single(ares_channel_t *channel) +static void ares_servers_trim_single(ares_channel_t *channel) { - while (ares__slist_len(channel->servers) > 1) { - ares__slist_node_destroy(ares__slist_node_last(channel->servers)); + while (ares_slist_len(channel->servers) > 1) { + ares_slist_node_destroy(ares_slist_node_last(channel->servers)); } } -ares_status_t ares__servers_update(ares_channel_t *channel, - ares__llist_t *server_list, - ares_bool_t user_specified) +ares_status_t ares_servers_update(ares_channel_t *channel, + ares_llist_t *server_list, + ares_bool_t user_specified) { - ares__llist_node_t *node; - size_t idx = 0; - ares_status_t status; - ares_bool_t list_changed = ARES_FALSE; + ares_llist_node_t *node; + size_t idx = 0; + ares_status_t status; + ares_bool_t list_changed = ARES_FALSE; if (channel == NULL) { return ARES_EFORMERR; /* LCOV_EXCL_LINE: DefensiveCoding */ @@ -714,19 +767,19 @@ ares_status_t ares__servers_update(ares_channel_t *channel, */ /* Add new entries */ - for (node = ares__llist_node_first(server_list); node != NULL; - node = ares__llist_node_next(node)) { - const ares_sconfig_t *sconfig = ares__llist_node_val(node); - ares__slist_node_t *snode; + for (node = ares_llist_node_first(server_list); node != NULL; + node = ares_llist_node_next(node)) { + const ares_sconfig_t *sconfig = ares_llist_node_val(node); + ares_slist_node_t *snode; /* If a server has already appeared in the list of new servers, skip it. */ - if (ares__server_isdup(channel, node)) { + if (ares_server_isdup(channel, node)) { continue; } - snode = ares__server_find(channel, sconfig); + snode = ares_server_find(channel, sconfig); if (snode != NULL) { - ares_server_t *server = ares__slist_node_val(snode); + ares_server_t *server = ares_slist_node_val(snode); /* Copy over link-local settings. Its possible some of this data has * changed, maybe ... */ @@ -740,10 +793,10 @@ ares_status_t ares__servers_update(ares_channel_t *channel, server->idx = idx; /* Index changed, reinsert node, doesn't require any memory * allocations so can't fail. */ - ares__slist_node_reinsert(snode); + ares_slist_node_reinsert(snode); } } else { - status = ares__server_create(channel, sconfig, idx); + status = ares_server_create(channel, sconfig, idx); if (status != ARES_SUCCESS) { goto done; } @@ -755,13 +808,13 @@ ares_status_t ares__servers_update(ares_channel_t *channel, } /* Remove any servers that don't exist in the current configuration */ - if (ares__servers_remove_stale(channel, server_list)) { + if (ares_servers_remove_stale(channel, server_list)) { list_changed = ARES_TRUE; } /* Trim to one server if ARES_FLAG_PRIMARY is set. */ if (channel->flags & ARES_FLAG_PRIMARY) { - ares__servers_trim_single(channel); + ares_servers_trim_single(channel); } if (user_specified) { @@ -771,7 +824,7 @@ ares_status_t ares__servers_update(ares_channel_t *channel, /* Clear any cached query results only if the server list changed */ if (list_changed) { - ares__qcache_flush(channel->qcache); + ares_qcache_flush(channel->qcache); } status = ARES_SUCCESS; @@ -781,15 +834,15 @@ done: } static ares_status_t - ares_addr_node_to_server_config_llist(const struct ares_addr_node *servers, - ares__llist_t **llist) + ares_addr_node_to_sconfig_llist(const struct ares_addr_node *servers, + ares_llist_t **llist) { const struct ares_addr_node *node; - ares__llist_t *s; + ares_llist_t *s; *llist = NULL; - s = ares__llist_create(ares_free); + s = ares_llist_create(ares_free); if (s == NULL) { goto fail; /* LCOV_EXCL_LINE: OutOfMemory */ } @@ -816,7 +869,7 @@ static ares_status_t sizeof(sconfig->addr.addr.addr6)); } - if (ares__llist_insert_last(s, sconfig) == NULL) { + if (ares_llist_insert_last(s, sconfig) == NULL) { ares_free(sconfig); /* LCOV_EXCL_LINE: OutOfMemory */ goto fail; /* LCOV_EXCL_LINE: OutOfMemory */ } @@ -827,20 +880,21 @@ static ares_status_t /* LCOV_EXCL_START: OutOfMemory */ fail: - ares__llist_destroy(s); + ares_llist_destroy(s); return ARES_ENOMEM; /* LCOV_EXCL_STOP */ } -static ares_status_t ares_addr_port_node_to_server_config_llist( - const struct ares_addr_port_node *servers, ares__llist_t **llist) +static ares_status_t + ares_addrpnode_to_sconfig_llist(const struct ares_addr_port_node *servers, + ares_llist_t **llist) { const struct ares_addr_port_node *node; - ares__llist_t *s; + ares_llist_t *s; *llist = NULL; - s = ares__llist_create(ares_free); + s = ares_llist_create(ares_free); if (s == NULL) { goto fail; /* LCOV_EXCL_LINE: OutOfMemory */ } @@ -870,7 +924,7 @@ static ares_status_t ares_addr_port_node_to_server_config_llist( sconfig->tcp_port = (unsigned short)node->tcp_port; sconfig->udp_port = (unsigned short)node->udp_port; - if (ares__llist_insert_last(s, sconfig) == NULL) { + if (ares_llist_insert_last(s, sconfig) == NULL) { ares_free(sconfig); /* LCOV_EXCL_LINE: OutOfMemory */ goto fail; /* LCOV_EXCL_LINE: OutOfMemory */ } @@ -881,21 +935,21 @@ static ares_status_t ares_addr_port_node_to_server_config_llist( /* LCOV_EXCL_START: OutOfMemory */ fail: - ares__llist_destroy(s); + ares_llist_destroy(s); return ARES_ENOMEM; /* LCOV_EXCL_STOP */ } -ares_status_t ares_in_addr_to_server_config_llist(const struct in_addr *servers, - size_t nservers, - ares__llist_t **llist) +ares_status_t ares_in_addr_to_sconfig_llist(const struct in_addr *servers, + size_t nservers, + ares_llist_t **llist) { - size_t i; - ares__llist_t *s; + size_t i; + ares_llist_t *s; *llist = NULL; - s = ares__llist_create(ares_free); + s = ares_llist_create(ares_free); if (s == NULL) { goto fail; /* LCOV_EXCL_LINE: OutOfMemory */ } @@ -912,7 +966,7 @@ ares_status_t ares_in_addr_to_server_config_llist(const struct in_addr *servers, memcpy(&sconfig->addr.addr.addr4, &servers[i], sizeof(sconfig->addr.addr.addr4)); - if (ares__llist_insert_last(s, sconfig) == NULL) { + if (ares_llist_insert_last(s, sconfig) == NULL) { goto fail; /* LCOV_EXCL_LINE: OutOfMemory */ } } @@ -922,21 +976,90 @@ ares_status_t ares_in_addr_to_server_config_llist(const struct in_addr *servers, /* LCOV_EXCL_START: OutOfMemory */ fail: - ares__llist_destroy(s); + ares_llist_destroy(s); return ARES_ENOMEM; /* LCOV_EXCL_STOP */ } +static ares_bool_t ares_server_use_uri(const ares_server_t *server) +{ + /* Currently only reason to use new format is if the ports for udp and tcp + * are different */ + if (server->tcp_port != server->udp_port) { + return ARES_TRUE; + } + return ARES_FALSE; +} + +static ares_status_t ares_get_server_addr_uri(const ares_server_t *server, + ares_buf_t *buf) +{ + ares_uri_t *uri = NULL; + ares_status_t status; + char addr[INET6_ADDRSTRLEN]; + + uri = ares_uri_create(); + if (uri == NULL) { + return ARES_ENOMEM; + } + + status = ares_uri_set_scheme(uri, "dns"); + if (status != ARES_SUCCESS) { + goto done; + } + + ares_inet_ntop(server->addr.family, &server->addr.addr, addr, sizeof(addr)); + + if (ares_strlen(server->ll_iface)) { + char addr_iface[256]; + + snprintf(addr_iface, sizeof(addr_iface), "%s%%%s", addr, server->ll_iface); + status = ares_uri_set_host(uri, addr_iface); + } else { + status = ares_uri_set_host(uri, addr); + } + + if (status != ARES_SUCCESS) { + goto done; + } + + status = ares_uri_set_port(uri, server->udp_port); + if (status != ARES_SUCCESS) { + goto done; + } + + if (server->udp_port != server->tcp_port) { + char port[6]; + snprintf(port, sizeof(port), "%d", server->tcp_port); + status = ares_uri_set_query_key(uri, "tcpport", port); + if (status != ARES_SUCCESS) { + goto done; + } + } + + status = ares_uri_write_buf(uri, buf); + if (status != ARES_SUCCESS) { + goto done; + } + +done: + ares_uri_destroy(uri); + return status; +} + /* Write out the details of a server to a buffer */ -ares_status_t ares_get_server_addr(const ares_server_t *server, - ares__buf_t *buf) +ares_status_t ares_get_server_addr(const ares_server_t *server, ares_buf_t *buf) { ares_status_t status; char addr[INET6_ADDRSTRLEN]; + if (ares_server_use_uri(server)) { + return ares_get_server_addr_uri(server, buf); + } + /* ipv4addr or [ipv6addr] */ if (server->addr.family == AF_INET6) { - status = ares__buf_append_byte(buf, '['); + status = ares_buf_append_byte(buf, '['); if (status != ARES_SUCCESS) { return status; /* LCOV_EXCL_LINE: OutOfMemory */ } @@ -944,37 +1067,37 @@ ares_status_t ares_get_server_addr(const ares_server_t *server, ares_inet_ntop(server->addr.family, &server->addr.addr, addr, sizeof(addr)); - status = ares__buf_append_str(buf, addr); + status = ares_buf_append_str(buf, addr); if (status != ARES_SUCCESS) { return status; /* LCOV_EXCL_LINE: OutOfMemory */ } if (server->addr.family == AF_INET6) { - status = ares__buf_append_byte(buf, ']'); + status = ares_buf_append_byte(buf, ']'); if (status != ARES_SUCCESS) { return status; /* LCOV_EXCL_LINE: OutOfMemory */ } } /* :port */ - status = ares__buf_append_byte(buf, ':'); + status = ares_buf_append_byte(buf, ':'); if (status != ARES_SUCCESS) { return status; /* LCOV_EXCL_LINE: OutOfMemory */ } - status = ares__buf_append_num_dec(buf, server->udp_port, 0); + status = ares_buf_append_num_dec(buf, server->udp_port, 0); if (status != ARES_SUCCESS) { return status; /* LCOV_EXCL_LINE: OutOfMemory */ } /* %iface */ if (ares_strlen(server->ll_iface)) { - status = ares__buf_append_byte(buf, '%'); + status = ares_buf_append_byte(buf, '%'); if (status != ARES_SUCCESS) { return status; /* LCOV_EXCL_LINE: OutOfMemory */ } - status = ares__buf_append_str(buf, server->ll_iface); + status = ares_buf_append_str(buf, server->ll_iface); if (status != ARES_SUCCESS) { return status; /* LCOV_EXCL_LINE: OutOfMemory */ } @@ -990,17 +1113,17 @@ int ares_get_servers(const ares_channel_t *channel, struct ares_addr_node *srvr_last = NULL; struct ares_addr_node *srvr_curr; ares_status_t status = ARES_SUCCESS; - ares__slist_node_t *node; + ares_slist_node_t *node; if (channel == NULL) { return ARES_ENODATA; } - ares__channel_lock(channel); + ares_channel_lock(channel); - for (node = ares__slist_node_first(channel->servers); node != NULL; - node = ares__slist_node_next(node)) { - const ares_server_t *server = ares__slist_node_val(node); + for (node = ares_slist_node_first(channel->servers); node != NULL; + node = ares_slist_node_next(node)) { + const ares_server_t *server = ares_slist_node_val(node); /* Allocate storage for this server node appending it to the list */ srvr_curr = ares_malloc_data(ARES_DATATYPE_ADDR_NODE); @@ -1033,7 +1156,7 @@ int ares_get_servers(const ares_channel_t *channel, *servers = srvr_head; - ares__channel_unlock(channel); + ares_channel_unlock(channel); return (int)status; } @@ -1045,17 +1168,17 @@ int ares_get_servers_ports(const ares_channel_t *channel, struct ares_addr_port_node *srvr_last = NULL; struct ares_addr_port_node *srvr_curr; ares_status_t status = ARES_SUCCESS; - ares__slist_node_t *node; + ares_slist_node_t *node; if (channel == NULL) { return ARES_ENODATA; } - ares__channel_lock(channel); + ares_channel_lock(channel); - for (node = ares__slist_node_first(channel->servers); node != NULL; - node = ares__slist_node_next(node)) { - const ares_server_t *server = ares__slist_node_val(node); + for (node = ares_slist_node_first(channel->servers); node != NULL; + node = ares_slist_node_next(node)) { + const ares_server_t *server = ares_slist_node_val(node); /* Allocate storage for this server node appending it to the list */ srvr_curr = ares_malloc_data(ARES_DATATYPE_ADDR_PORT_NODE); @@ -1091,30 +1214,30 @@ int ares_get_servers_ports(const ares_channel_t *channel, *servers = srvr_head; - ares__channel_unlock(channel); + ares_channel_unlock(channel); return (int)status; } int ares_set_servers(ares_channel_t *channel, const struct ares_addr_node *servers) { - ares__llist_t *slist; - ares_status_t status; + ares_llist_t *slist; + ares_status_t status; if (channel == NULL) { return ARES_ENODATA; } - status = ares_addr_node_to_server_config_llist(servers, &slist); + status = ares_addr_node_to_sconfig_llist(servers, &slist); if (status != ARES_SUCCESS) { return (int)status; } - ares__channel_lock(channel); - status = ares__servers_update(channel, slist, ARES_TRUE); - ares__channel_unlock(channel); + ares_channel_lock(channel); + status = ares_servers_update(channel, slist, ARES_TRUE); + ares_channel_unlock(channel); - ares__llist_destroy(slist); + ares_llist_destroy(slist); return (int)status; } @@ -1122,23 +1245,23 @@ int ares_set_servers(ares_channel_t *channel, int ares_set_servers_ports(ares_channel_t *channel, const struct ares_addr_port_node *servers) { - ares__llist_t *slist; - ares_status_t status; + ares_llist_t *slist; + ares_status_t status; if (channel == NULL) { return ARES_ENODATA; } - status = ares_addr_port_node_to_server_config_llist(servers, &slist); + status = ares_addrpnode_to_sconfig_llist(servers, &slist); if (status != ARES_SUCCESS) { return (int)status; } - ares__channel_lock(channel); - status = ares__servers_update(channel, slist, ARES_TRUE); - ares__channel_unlock(channel); + ares_channel_lock(channel); + status = ares_servers_update(channel, slist, ARES_TRUE); + ares_channel_unlock(channel); - ares__llist_destroy(slist); + ares_llist_destroy(slist); return (int)status; } @@ -1147,8 +1270,8 @@ int ares_set_servers_ports(ares_channel_t *channel, /* IPv6 addresses with ports require square brackets [fe80::1]:53 */ static ares_status_t set_servers_csv(ares_channel_t *channel, const char *_csv) { - ares_status_t status; - ares__llist_t *slist = NULL; + ares_status_t status; + ares_llist_t *slist = NULL; if (channel == NULL) { return ARES_ENODATA; @@ -1156,23 +1279,23 @@ static ares_status_t set_servers_csv(ares_channel_t *channel, const char *_csv) if (ares_strlen(_csv) == 0) { /* blank all servers */ - ares__channel_lock(channel); - status = ares__servers_update(channel, NULL, ARES_TRUE); - ares__channel_unlock(channel); + ares_channel_lock(channel); + status = ares_servers_update(channel, NULL, ARES_TRUE); + ares_channel_unlock(channel); return status; } - status = ares__sconfig_append_fromstr(&slist, _csv, ARES_FALSE); + status = ares_sconfig_append_fromstr(channel, &slist, _csv, ARES_FALSE); if (status != ARES_SUCCESS) { - ares__llist_destroy(slist); + ares_llist_destroy(slist); return status; } - ares__channel_lock(channel); - status = ares__servers_update(channel, slist, ARES_TRUE); - ares__channel_unlock(channel); + ares_channel_lock(channel); + status = ares_servers_update(channel, slist, ARES_TRUE); + ares_channel_unlock(channel); - ares__llist_destroy(slist); + ares_llist_destroy(slist); return status; } @@ -1190,24 +1313,24 @@ int ares_set_servers_ports_csv(ares_channel_t *channel, const char *_csv) char *ares_get_servers_csv(const ares_channel_t *channel) { - ares__buf_t *buf = NULL; - char *out = NULL; - ares__slist_node_t *node; + ares_buf_t *buf = NULL; + char *out = NULL; + ares_slist_node_t *node; - ares__channel_lock(channel); + ares_channel_lock(channel); - buf = ares__buf_create(); + buf = ares_buf_create(); if (buf == NULL) { goto done; /* LCOV_EXCL_LINE: OutOfMemory */ } - for (node = ares__slist_node_first(channel->servers); node != NULL; - node = ares__slist_node_next(node)) { + for (node = ares_slist_node_first(channel->servers); node != NULL; + node = ares_slist_node_next(node)) { ares_status_t status; - const ares_server_t *server = ares__slist_node_val(node); + const ares_server_t *server = ares_slist_node_val(node); - if (ares__buf_len(buf)) { - status = ares__buf_append_byte(buf, ','); + if (ares_buf_len(buf)) { + status = ares_buf_append_byte(buf, ','); if (status != ARES_SUCCESS) { goto done; /* LCOV_EXCL_LINE: OutOfMemory */ } @@ -1219,12 +1342,12 @@ char *ares_get_servers_csv(const ares_channel_t *channel) } } - out = ares__buf_finish_str(buf, NULL); + out = ares_buf_finish_str(buf, NULL); buf = NULL; done: - ares__channel_unlock(channel); - ares__buf_destroy(buf); + ares_channel_unlock(channel); + ares_buf_destroy(buf); return out; } |