From 28a2260812ec9f9416524634453f8ff306411417 Mon Sep 17 00:00:00 2001 From: Brad House Date: Fri, 13 Sep 2024 15:37:44 -0400 Subject: [PATCH] ares_get_servers_csv() output in uri format when needed --- src/lib/ares_update_servers.c | 71 ++++++++++++++++++++++++++++++++++- 1 file changed, 70 insertions(+), 1 deletion(-) diff --git a/src/lib/ares_update_servers.c b/src/lib/ares_update_servers.c index 2a04ac2411..43f841860b 100644 --- a/src/lib/ares_update_servers.c +++ b/src/lib/ares_update_servers.c @@ -228,7 +228,7 @@ static ares_status_t parse_nameserver_uri(ares_buf_t *buf, ares_sconfig_t *sconf sconfig->tcp_port = sconfig->udp_port; port = ares_uri_get_query_key(uri, "tcpport"); if (port != NULL) { - sconfig->tcp_port = atoi(port); + sconfig->tcp_port = (unsigned short)atoi(port); } done: @@ -963,12 +963,81 @@ ares_status_t ares_in_addr_to_sconfig_llist(const struct in_addr *servers, /* 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[INET6_ADDRSTRLEN + 17]; + + 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 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, '[');