api: Add entrypoints to allow use of per-server ports
Add user-visible entrypoints ares_{get,set}_servers_ports(3), which take struct ares_addr_port_node rather than struct ares_addr_node. This structure includes a UDP and TCP port number; if this is set to zero, the channel-wide port values are used as before. Similarly, add a new ares_set_servers_ports_csv(3) entrypoint, which is analogous to ares_set_servers(3) except it doesn't ignore any specified port information; instead, any per-server specified port is used as both the UDP and TCP port for that server. The internal struct ares_addr is extended to hold the UDP/TCP ports, stored in network order, with the convention that a value of zero indicates that the channel-wide UDP/TCP port should be used. For the internal implementation of ares_dup(3), shift to use the _ports() version of the get/set functions, so port information is transferred correctly to the new channel. Update manpages, and add missing ares_set_servers_csv to the lists while we're at it
This commit is contained in:
parent
06d0f72e54
commit
7972adc5d7
|
@ -82,6 +82,7 @@ MANPAGES = ares_cancel.3 \
|
|||
ares_free_hostent.3 \
|
||||
ares_free_string.3 \
|
||||
ares_get_servers.3 \
|
||||
ares_get_servers_ports.3 \
|
||||
ares_gethostbyaddr.3 \
|
||||
ares_gethostbyname.3 \
|
||||
ares_gethostbyname_file.3 \
|
||||
|
@ -112,6 +113,8 @@ MANPAGES = ares_cancel.3 \
|
|||
ares_set_local_ip6.3 \
|
||||
ares_set_servers.3 \
|
||||
ares_set_servers_csv.3 \
|
||||
ares_set_servers_ports.3 \
|
||||
ares_set_servers_ports_csv.3 \
|
||||
ares_set_socket_callback.3 \
|
||||
ares_set_sortlist.3 \
|
||||
ares_strerror.3 \
|
||||
|
@ -131,6 +134,7 @@ HTMLPAGES = ares_cancel.html \
|
|||
ares_free_hostent.html \
|
||||
ares_free_string.html \
|
||||
ares_get_servers.html \
|
||||
ares_get_servers_ports.html \
|
||||
ares_gethostbyaddr.html \
|
||||
ares_gethostbyname.html \
|
||||
ares_gethostbyname_file.html \
|
||||
|
@ -160,6 +164,8 @@ HTMLPAGES = ares_cancel.html \
|
|||
ares_set_local_ip6.html \
|
||||
ares_set_servers.html \
|
||||
ares_set_servers_csv.html \
|
||||
ares_set_servers_ports.html \
|
||||
ares_set_servers_ports_csv.html \
|
||||
ares_set_socket_callback.html \
|
||||
ares_set_sortlist.html \
|
||||
ares_strerror.html \
|
||||
|
@ -179,6 +185,7 @@ PDFPAGES = ares_cancel.pdf \
|
|||
ares_free_hostent.pdf \
|
||||
ares_free_string.pdf \
|
||||
ares_get_servers.pdf \
|
||||
ares_get_servers_ports.pdf \
|
||||
ares_gethostbyaddr.pdf \
|
||||
ares_gethostbyname.pdf \
|
||||
ares_gethostbyname_file.pdf \
|
||||
|
@ -208,6 +215,8 @@ PDFPAGES = ares_cancel.pdf \
|
|||
ares_set_local_ip6.pdf \
|
||||
ares_set_servers.pdf \
|
||||
ares_set_servers_csv.pdf \
|
||||
ares_set_servers_ports.pdf \
|
||||
ares_set_servers_ports_csv.pdf \
|
||||
ares_set_socket_callback.pdf \
|
||||
ares_set_sortlist.pdf \
|
||||
ares_strerror.pdf \
|
||||
|
|
18
ares.h
18
ares.h
|
@ -563,7 +563,6 @@ CARES_EXTERN void ares_free_data(void *dataptr);
|
|||
|
||||
CARES_EXTERN const char *ares_strerror(int code);
|
||||
|
||||
/* TODO: Hold port here as well. */
|
||||
struct ares_addr_node {
|
||||
struct ares_addr_node *next;
|
||||
int family;
|
||||
|
@ -573,15 +572,32 @@ struct ares_addr_node {
|
|||
} addr;
|
||||
};
|
||||
|
||||
struct ares_addr_port_node {
|
||||
struct ares_addr_port_node *next;
|
||||
int family;
|
||||
union {
|
||||
struct in_addr addr4;
|
||||
struct ares_in6_addr addr6;
|
||||
} addr;
|
||||
int udp_port;
|
||||
int tcp_port;
|
||||
};
|
||||
|
||||
CARES_EXTERN int ares_set_servers(ares_channel channel,
|
||||
struct ares_addr_node *servers);
|
||||
CARES_EXTERN int ares_set_servers_ports(ares_channel channel,
|
||||
struct ares_addr_port_node *servers);
|
||||
|
||||
/* Incomming string format: host[:port][,host[:port]]... */
|
||||
CARES_EXTERN int ares_set_servers_csv(ares_channel channel,
|
||||
const char* servers);
|
||||
CARES_EXTERN int ares_set_servers_ports_csv(ares_channel channel,
|
||||
const char* servers);
|
||||
|
||||
CARES_EXTERN int ares_get_servers(ares_channel channel,
|
||||
struct ares_addr_node **servers);
|
||||
CARES_EXTERN int ares_get_servers_ports(ares_channel channel,
|
||||
struct ares_addr_port_node **servers);
|
||||
|
||||
CARES_EXTERN const char *ares_inet_ntop(int af, const void *src, char *dst,
|
||||
ares_socklen_t size);
|
||||
|
|
15
ares_data.c
15
ares_data.c
|
@ -92,6 +92,12 @@ void ares_free_data(void *dataptr)
|
|||
ares_free_data(ptr->data.addr_node.next);
|
||||
break;
|
||||
|
||||
case ARES_DATATYPE_ADDR_PORT_NODE:
|
||||
|
||||
if (ptr->data.addr_port_node.next)
|
||||
ares_free_data(ptr->data.addr_port_node.next);
|
||||
break;
|
||||
|
||||
case ARES_DATATYPE_NAPTR_REPLY:
|
||||
|
||||
if (ptr->data.naptr_reply.next)
|
||||
|
@ -169,6 +175,15 @@ void *ares_malloc_data(ares_datatype type)
|
|||
sizeof(ptr->data.addr_node.addrV6));
|
||||
break;
|
||||
|
||||
case ARES_DATATYPE_ADDR_PORT_NODE:
|
||||
ptr->data.addr_port_node.next = NULL;
|
||||
ptr->data.addr_port_node.family = 0;
|
||||
ptr->data.addr_port_node.udp_port = 0;
|
||||
ptr->data.addr_port_node.tcp_port = 0;
|
||||
memset(&ptr->data.addr_port_node.addrV6, 0,
|
||||
sizeof(ptr->data.addr_port_node.addrV6));
|
||||
break;
|
||||
|
||||
case ARES_DATATYPE_NAPTR_REPLY:
|
||||
ptr->data.naptr_reply.next = NULL;
|
||||
ptr->data.naptr_reply.flags = NULL;
|
||||
|
|
|
@ -28,6 +28,7 @@ typedef enum {
|
|||
ARES_DATATYPE_HOSTENT, /* struct hostent */
|
||||
ARES_DATATYPE_OPTIONS, /* struct ares_options */
|
||||
#endif
|
||||
ARES_DATATYPE_ADDR_PORT_NODE, /* struct ares_addr_port_node - introduced in 1.11.0 */
|
||||
ARES_DATATYPE_LAST /* not used - introduced in 1.7.0 */
|
||||
} ares_datatype;
|
||||
|
||||
|
@ -58,6 +59,7 @@ struct ares_data {
|
|||
struct ares_txt_reply txt_reply;
|
||||
struct ares_srv_reply srv_reply;
|
||||
struct ares_addr_node addr_node;
|
||||
struct ares_addr_port_node addr_port_node;
|
||||
struct ares_mx_reply mx_reply;
|
||||
struct ares_naptr_reply naptr_reply;
|
||||
struct ares_soa_reply soa_reply;
|
||||
|
|
|
@ -16,12 +16,13 @@
|
|||
.\"
|
||||
.TH ARES_GET_SERVERS 3 "5 March 2010"
|
||||
.SH NAME
|
||||
ares_get_servers \- Retrieve name servers from an initialized ares_channel
|
||||
ares_get_servers, ares_get_servers_ports \- Retrieve name servers from an initialized ares_channel
|
||||
.SH SYNOPSIS
|
||||
.nf
|
||||
.B #include <ares.h>
|
||||
.PP
|
||||
.B int ares_get_servers(ares_channel \fIchannel\fP, struct ares_addr_node **\fIservers\fP)
|
||||
.B int ares_get_servers_ports(ares_channel \fIchannel\fP, struct ares_addr_port_node **\fIservers\fP)
|
||||
.fi
|
||||
.SH DESCRIPTION
|
||||
The \fBares_get_servers(3)\fP function retrieves name servers configuration
|
||||
|
@ -32,8 +33,13 @@ as a linked list of ares_addr_node structs storing a pointer to the first
|
|||
node at the address specified by
|
||||
.IR servers .
|
||||
|
||||
The \fBares_get_servers_ports(3)\fP function also retrieves any per-server
|
||||
port information that may have been previously configured, returning a linked
|
||||
list of ares_addr_port structures.
|
||||
|
||||
Function caller may traverse the returned name server linked list, or may use
|
||||
it directly as suitable input for the \fBares_set_servers(3)\fP function, but
|
||||
it directly as suitable input for the \fBares_set_servers(3)\fP /
|
||||
\fBares_set_servers_ports(3)\fP functions, but
|
||||
shall not shrink or extend the list on its own.
|
||||
|
||||
Each node of the name server linked list is stored in memory dynamically
|
||||
|
@ -47,8 +53,7 @@ optmask \fBARES_OPT_SERVERS\fP functionally obsolete except for
|
|||
IPv4-only name server usage.
|
||||
|
||||
.SH RETURN VALUES
|
||||
.B ares_get_servers(3)
|
||||
may return any of the following values:
|
||||
This function may return any of the following values:
|
||||
.TP 15
|
||||
.B ARES_SUCCESS
|
||||
The name servers configuration was successfuly retrieved
|
||||
|
@ -57,7 +62,7 @@ The name servers configuration was successfuly retrieved
|
|||
The memory was exhausted
|
||||
.TP 15
|
||||
.B ARES_ENODATA
|
||||
The channel data identified by
|
||||
The channel data identified by
|
||||
.IR channel
|
||||
was invalid.
|
||||
.SH SEE ALSO
|
||||
|
@ -65,7 +70,8 @@ was invalid.
|
|||
.BR ares_init_options (3),
|
||||
.BR ares_save_options(3)
|
||||
.SH AVAILABILITY
|
||||
ares_get_servers(3) was added in c-ares 1.7.1
|
||||
\fBares_get_servers(3)\fP was added in c-ares 1.7.1;
|
||||
\fBares_get_servers_ports(3)\fP was added in c-ares 1.11.0.
|
||||
.SH AUTHOR
|
||||
Implementation of this function and associated library internals are based
|
||||
on code, comments and feedback provided in November and December of 2008 by
|
||||
|
|
|
@ -0,0 +1 @@
|
|||
.so man3/ares_get_servers.3
|
36
ares_init.c
36
ares_init.c
|
@ -263,8 +263,8 @@ int ares_init_options(ares_channel *channelptr, struct ares_options *options,
|
|||
int ares_dup(ares_channel *dest, ares_channel src)
|
||||
{
|
||||
struct ares_options opts;
|
||||
struct ares_addr_node *servers;
|
||||
int ipv6_nservers = 0;
|
||||
struct ares_addr_port_node *servers;
|
||||
int non_v4_default_port = 0;
|
||||
int i, rc;
|
||||
int optmask;
|
||||
|
||||
|
@ -297,22 +297,24 @@ int ares_dup(ares_channel *dest, ares_channel src)
|
|||
(*dest)->local_ip4 = src->local_ip4;
|
||||
memcpy((*dest)->local_ip6, src->local_ip6, sizeof(src->local_ip6));
|
||||
|
||||
/* Full name server cloning required when not all are IPv4 */
|
||||
/* Full name server cloning required if there is a non-IPv4, or non-default port, nameserver */
|
||||
for (i = 0; i < src->nservers; i++)
|
||||
{
|
||||
if (src->servers[i].addr.family != AF_INET) {
|
||||
ipv6_nservers++;
|
||||
if ((src->servers[i].addr.family != AF_INET) ||
|
||||
(src->servers[i].addr.udp_port != 0) ||
|
||||
(src->servers[i].addr.tcp_port != 0)) {
|
||||
non_v4_default_port++;
|
||||
break;
|
||||
}
|
||||
}
|
||||
if (ipv6_nservers) {
|
||||
rc = ares_get_servers(src, &servers);
|
||||
if (non_v4_default_port) {
|
||||
rc = ares_get_servers_ports(src, &servers);
|
||||
if (rc != ARES_SUCCESS) {
|
||||
ares_destroy(*dest);
|
||||
*dest = NULL;
|
||||
return rc;
|
||||
}
|
||||
rc = ares_set_servers(*dest, servers);
|
||||
rc = ares_set_servers_ports(*dest, servers);
|
||||
ares_free_data(servers);
|
||||
if (rc != ARES_SUCCESS) {
|
||||
ares_destroy(*dest);
|
||||
|
@ -359,11 +361,13 @@ int ares_save_options(ares_channel channel, struct ares_options *options,
|
|||
options->sock_state_cb = channel->sock_state_cb;
|
||||
options->sock_state_cb_data = channel->sock_state_cb_data;
|
||||
|
||||
/* Copy IPv4 servers */
|
||||
/* Copy IPv4 servers that use the default port */
|
||||
if (channel->nservers) {
|
||||
for (i = 0; i < channel->nservers; i++)
|
||||
{
|
||||
if (channel->servers[i].addr.family == AF_INET)
|
||||
if ((channel->servers[i].addr.family == AF_INET) &&
|
||||
(channel->servers[i].addr.udp_port == 0) &&
|
||||
(channel->servers[i].addr.tcp_port == 0))
|
||||
ipv4_nservers++;
|
||||
}
|
||||
if (ipv4_nservers) {
|
||||
|
@ -372,7 +376,9 @@ int ares_save_options(ares_channel channel, struct ares_options *options,
|
|||
return ARES_ENOMEM;
|
||||
for (i = j = 0; i < channel->nservers; i++)
|
||||
{
|
||||
if (channel->servers[i].addr.family == AF_INET)
|
||||
if ((channel->servers[i].addr.family == AF_INET) &&
|
||||
(channel->servers[i].addr.udp_port == 0) &&
|
||||
(channel->servers[i].addr.tcp_port == 0))
|
||||
memcpy(&options->servers[j++],
|
||||
&channel->servers[i].addr.addrV4,
|
||||
sizeof(channel->servers[i].addr.addrV4));
|
||||
|
@ -468,6 +474,8 @@ static int init_by_options(ares_channel channel,
|
|||
for (i = 0; i < options->nservers; i++)
|
||||
{
|
||||
channel->servers[i].addr.family = AF_INET;
|
||||
channel->servers[i].addr.udp_port = 0;
|
||||
channel->servers[i].addr.tcp_port = 0;
|
||||
memcpy(&channel->servers[i].addr.addrV4,
|
||||
&options->servers[i],
|
||||
sizeof(channel->servers[i].addr.addrV4));
|
||||
|
@ -1156,6 +1164,8 @@ static int init_by_resolv_conf(ares_channel channel)
|
|||
{
|
||||
servers[i].addr.addrV4.s_addr = htonl(def_nameservers[i]);
|
||||
servers[i].addr.family = AF_INET;
|
||||
servers[i].addr.udp_port = 0;
|
||||
servers[i].addr.tcp_port = 0;
|
||||
}
|
||||
status = ARES_EOF;
|
||||
|
||||
|
@ -1444,6 +1454,8 @@ static int init_by_defaults(ares_channel channel)
|
|||
}
|
||||
channel->servers[0].addr.family = AF_INET;
|
||||
channel->servers[0].addr.addrV4.s_addr = htonl(INADDR_LOOPBACK);
|
||||
channel->servers[0].addr.udp_port = 0;
|
||||
channel->servers[0].addr.tcp_port = 0;
|
||||
channel->nservers = 1;
|
||||
}
|
||||
|
||||
|
@ -1650,6 +1662,8 @@ static int config_nameserver(struct server_state **servers, int *nservers,
|
|||
|
||||
/* Store address data. */
|
||||
newserv[*nservers].addr.family = host.family;
|
||||
newserv[*nservers].addr.udp_port = 0;
|
||||
newserv[*nservers].addr.tcp_port = 0;
|
||||
if (host.family == AF_INET)
|
||||
memcpy(&newserv[*nservers].addr.addrV4, &host.addrV4,
|
||||
sizeof(host.addrV4));
|
||||
|
|
141
ares_options.c
141
ares_options.c
|
@ -83,6 +83,62 @@ int ares_get_servers(ares_channel channel,
|
|||
return status;
|
||||
}
|
||||
|
||||
int ares_get_servers_ports(ares_channel channel,
|
||||
struct ares_addr_port_node **servers)
|
||||
{
|
||||
struct ares_addr_port_node *srvr_head = NULL;
|
||||
struct ares_addr_port_node *srvr_last = NULL;
|
||||
struct ares_addr_port_node *srvr_curr;
|
||||
int status = ARES_SUCCESS;
|
||||
int i;
|
||||
|
||||
if (!channel)
|
||||
return ARES_ENODATA;
|
||||
|
||||
for (i = 0; i < channel->nservers; i++)
|
||||
{
|
||||
/* Allocate storage for this server node appending it to the list */
|
||||
srvr_curr = ares_malloc_data(ARES_DATATYPE_ADDR_PORT_NODE);
|
||||
if (!srvr_curr)
|
||||
{
|
||||
status = ARES_ENOMEM;
|
||||
break;
|
||||
}
|
||||
if (srvr_last)
|
||||
{
|
||||
srvr_last->next = srvr_curr;
|
||||
}
|
||||
else
|
||||
{
|
||||
srvr_head = srvr_curr;
|
||||
}
|
||||
srvr_last = srvr_curr;
|
||||
|
||||
/* Fill this server node data */
|
||||
srvr_curr->family = channel->servers[i].addr.family;
|
||||
srvr_curr->udp_port = ntohs((unsigned short)channel->servers[i].addr.udp_port);
|
||||
srvr_curr->tcp_port = ntohs((unsigned short)channel->servers[i].addr.tcp_port);
|
||||
if (srvr_curr->family == AF_INET)
|
||||
memcpy(&srvr_curr->addrV4, &channel->servers[i].addr.addrV4,
|
||||
sizeof(srvr_curr->addrV4));
|
||||
else
|
||||
memcpy(&srvr_curr->addrV6, &channel->servers[i].addr.addrV6,
|
||||
sizeof(srvr_curr->addrV6));
|
||||
}
|
||||
|
||||
if (status != ARES_SUCCESS)
|
||||
{
|
||||
if (srvr_head)
|
||||
{
|
||||
ares_free_data(srvr_head);
|
||||
srvr_head = NULL;
|
||||
}
|
||||
}
|
||||
|
||||
*servers = srvr_head;
|
||||
|
||||
return status;
|
||||
}
|
||||
|
||||
int ares_set_servers(ares_channel channel,
|
||||
struct ares_addr_node *servers)
|
||||
|
@ -117,6 +173,57 @@ int ares_set_servers(ares_channel channel,
|
|||
for (i = 0, srvr = servers; srvr; i++, srvr = srvr->next)
|
||||
{
|
||||
channel->servers[i].addr.family = srvr->family;
|
||||
channel->servers[i].addr.udp_port = 0;
|
||||
channel->servers[i].addr.tcp_port = 0;
|
||||
if (srvr->family == AF_INET)
|
||||
memcpy(&channel->servers[i].addr.addrV4, &srvr->addrV4,
|
||||
sizeof(srvr->addrV4));
|
||||
else
|
||||
memcpy(&channel->servers[i].addr.addrV6, &srvr->addrV6,
|
||||
sizeof(srvr->addrV6));
|
||||
}
|
||||
/* Initialize servers state remaining data */
|
||||
ares__init_servers_state(channel);
|
||||
}
|
||||
|
||||
return ARES_SUCCESS;
|
||||
}
|
||||
|
||||
int ares_set_servers_ports(ares_channel channel,
|
||||
struct ares_addr_port_node *servers)
|
||||
{
|
||||
struct ares_addr_port_node *srvr;
|
||||
int num_srvrs = 0;
|
||||
int i;
|
||||
|
||||
if (ares_library_initialized() != ARES_SUCCESS)
|
||||
return ARES_ENOTINITIALIZED; /* LCOV_EXCL_LINE: n/a on non-WinSock */
|
||||
|
||||
if (!channel)
|
||||
return ARES_ENODATA;
|
||||
|
||||
ares__destroy_servers_state(channel);
|
||||
|
||||
for (srvr = servers; srvr; srvr = srvr->next)
|
||||
{
|
||||
num_srvrs++;
|
||||
}
|
||||
|
||||
if (num_srvrs > 0)
|
||||
{
|
||||
/* Allocate storage for servers state */
|
||||
channel->servers = ares_malloc(num_srvrs * sizeof(struct server_state));
|
||||
if (!channel->servers)
|
||||
{
|
||||
return ARES_ENOMEM;
|
||||
}
|
||||
channel->nservers = num_srvrs;
|
||||
/* Fill servers state address data */
|
||||
for (i = 0, srvr = servers; srvr; i++, srvr = srvr->next)
|
||||
{
|
||||
channel->servers[i].addr.family = srvr->family;
|
||||
channel->servers[i].addr.udp_port = htons((unsigned short)srvr->udp_port);
|
||||
channel->servers[i].addr.tcp_port = htons((unsigned short)srvr->tcp_port);
|
||||
if (srvr->family == AF_INET)
|
||||
memcpy(&channel->servers[i].addr.addrV4, &srvr->addrV4,
|
||||
sizeof(srvr->addrV4));
|
||||
|
@ -133,8 +240,8 @@ int ares_set_servers(ares_channel channel,
|
|||
|
||||
/* Incomming string format: host[:port][,host[:port]]... */
|
||||
/* IPv6 addresses with ports require square brackets [fe80::1%lo0]:53 */
|
||||
int ares_set_servers_csv(ares_channel channel,
|
||||
const char* _csv)
|
||||
static int set_servers_csv(ares_channel channel,
|
||||
const char* _csv, int use_port)
|
||||
{
|
||||
size_t i;
|
||||
char* csv = NULL;
|
||||
|
@ -142,8 +249,8 @@ int ares_set_servers_csv(ares_channel channel,
|
|||
char* start_host;
|
||||
int cc = 0;
|
||||
int rv = ARES_SUCCESS;
|
||||
struct ares_addr_node *servers = NULL;
|
||||
struct ares_addr_node *last = NULL;
|
||||
struct ares_addr_port_node *servers = NULL;
|
||||
struct ares_addr_port_node *last = NULL;
|
||||
|
||||
if (ares_library_initialized() != ARES_SUCCESS)
|
||||
return ARES_ENOTINITIALIZED; /* LCOV_EXCL_LINE: n/a on non-WinSock */
|
||||
|
@ -182,9 +289,10 @@ int ares_set_servers_csv(ares_channel channel,
|
|||
else if (*ptr == ',') {
|
||||
char* pp = ptr - 1;
|
||||
char* p = ptr;
|
||||
int port = 0;
|
||||
struct in_addr in4;
|
||||
struct ares_in6_addr in6;
|
||||
struct ares_addr_node *s = NULL;
|
||||
struct ares_addr_port_node *s = NULL;
|
||||
|
||||
*ptr = 0; /* null terminate host:port string */
|
||||
/* Got an entry..see if the port was specified. */
|
||||
|
@ -213,7 +321,7 @@ int ares_set_servers_csv(ares_channel channel,
|
|||
if (*pp == ']')
|
||||
p++; /* move p before ':' */
|
||||
/* p will point to the start of the port */
|
||||
(void)strtol(p, NULL, 10);
|
||||
port = (int)strtol(p, NULL, 10);
|
||||
*pp = 0; /* null terminate host */
|
||||
}
|
||||
}
|
||||
|
@ -246,8 +354,8 @@ int ares_set_servers_csv(ares_channel channel,
|
|||
memcpy(&s->addr, &in4, sizeof(struct in_addr));
|
||||
}
|
||||
if (s) {
|
||||
/* TODO: Add port to ares_addr_node and assign it here. */
|
||||
|
||||
s->udp_port = use_port ? port: 0;
|
||||
s->tcp_port = s->udp_port;
|
||||
s->next = NULL;
|
||||
if (last) {
|
||||
last->next = s;
|
||||
|
@ -266,16 +374,29 @@ int ares_set_servers_csv(ares_channel channel,
|
|||
}
|
||||
}
|
||||
|
||||
rv = ares_set_servers(channel, servers);
|
||||
rv = ares_set_servers_ports(channel, servers);
|
||||
|
||||
out:
|
||||
if (csv)
|
||||
ares_free(csv);
|
||||
while (servers) {
|
||||
struct ares_addr_node *s = servers;
|
||||
struct ares_addr_port_node *s = servers;
|
||||
servers = servers->next;
|
||||
ares_free(s);
|
||||
}
|
||||
|
||||
return rv;
|
||||
}
|
||||
|
||||
int ares_set_servers_csv(ares_channel channel,
|
||||
const char* _csv)
|
||||
{
|
||||
return set_servers_csv(channel, _csv, FALSE);
|
||||
}
|
||||
|
||||
int ares_set_servers_ports_csv(ares_channel channel,
|
||||
const char* _csv)
|
||||
{
|
||||
return set_servers_csv(channel, _csv, TRUE);
|
||||
}
|
||||
|
||||
|
|
|
@ -123,6 +123,8 @@ struct ares_addr {
|
|||
struct in_addr addr4;
|
||||
struct ares_in6_addr addr6;
|
||||
} addr;
|
||||
int udp_port; /* stored in network order */
|
||||
int tcp_port; /* stored in network order */
|
||||
};
|
||||
#define addrV4 addr.addr4
|
||||
#define addrV6 addr.addr6
|
||||
|
@ -255,8 +257,8 @@ struct ares_channeldata {
|
|||
int tries;
|
||||
int ndots;
|
||||
int rotate; /* if true, all servers specified are used */
|
||||
int udp_port;
|
||||
int tcp_port;
|
||||
int udp_port; /* stored in network order */
|
||||
int tcp_port; /* stored in network order */
|
||||
int socket_send_buffer_size;
|
||||
int socket_receive_buffer_size;
|
||||
char **domains;
|
||||
|
|
|
@ -978,7 +978,11 @@ static int open_tcp_socket(ares_channel channel, struct server_state *server)
|
|||
salen = sizeof(saddr.sa4);
|
||||
memset(sa, 0, salen);
|
||||
saddr.sa4.sin_family = AF_INET;
|
||||
saddr.sa4.sin_port = aresx_sitous(channel->tcp_port);
|
||||
if (server->addr.tcp_port) {
|
||||
saddr.sa4.sin_port = aresx_sitous(server->addr.tcp_port);
|
||||
} else {
|
||||
saddr.sa4.sin_port = aresx_sitous(channel->tcp_port);
|
||||
}
|
||||
memcpy(&saddr.sa4.sin_addr, &server->addr.addrV4,
|
||||
sizeof(server->addr.addrV4));
|
||||
break;
|
||||
|
@ -987,7 +991,11 @@ static int open_tcp_socket(ares_channel channel, struct server_state *server)
|
|||
salen = sizeof(saddr.sa6);
|
||||
memset(sa, 0, salen);
|
||||
saddr.sa6.sin6_family = AF_INET6;
|
||||
saddr.sa6.sin6_port = aresx_sitous(channel->tcp_port);
|
||||
if (server->addr.tcp_port) {
|
||||
saddr.sa6.sin6_port = aresx_sitous(server->addr.tcp_port);
|
||||
} else {
|
||||
saddr.sa6.sin6_port = aresx_sitous(channel->tcp_port);
|
||||
}
|
||||
memcpy(&saddr.sa6.sin6_addr, &server->addr.addrV6,
|
||||
sizeof(server->addr.addrV6));
|
||||
break;
|
||||
|
@ -1070,7 +1078,11 @@ static int open_udp_socket(ares_channel channel, struct server_state *server)
|
|||
salen = sizeof(saddr.sa4);
|
||||
memset(sa, 0, salen);
|
||||
saddr.sa4.sin_family = AF_INET;
|
||||
saddr.sa4.sin_port = aresx_sitous(channel->udp_port);
|
||||
if (server->addr.udp_port) {
|
||||
saddr.sa4.sin_port = aresx_sitous(server->addr.udp_port);
|
||||
} else {
|
||||
saddr.sa4.sin_port = aresx_sitous(channel->udp_port);
|
||||
}
|
||||
memcpy(&saddr.sa4.sin_addr, &server->addr.addrV4,
|
||||
sizeof(server->addr.addrV4));
|
||||
break;
|
||||
|
@ -1079,7 +1091,11 @@ static int open_udp_socket(ares_channel channel, struct server_state *server)
|
|||
salen = sizeof(saddr.sa6);
|
||||
memset(sa, 0, salen);
|
||||
saddr.sa6.sin6_family = AF_INET6;
|
||||
saddr.sa6.sin6_port = aresx_sitous(channel->udp_port);
|
||||
if (server->addr.udp_port) {
|
||||
saddr.sa6.sin6_port = aresx_sitous(server->addr.udp_port);
|
||||
} else {
|
||||
saddr.sa6.sin6_port = aresx_sitous(channel->udp_port);
|
||||
}
|
||||
memcpy(&saddr.sa6.sin6_addr, &server->addr.addrV6,
|
||||
sizeof(server->addr.addrV6));
|
||||
break;
|
||||
|
|
|
@ -15,12 +15,13 @@
|
|||
.\"
|
||||
.TH ARES_SET_SERVERS 3 "5 March 2010"
|
||||
.SH NAME
|
||||
ares_set_servers \- Initialize an ares_channel name servers configuration
|
||||
ares_set_servers, ares_set_servers_ports \- Initialize an ares_channel name servers configuration
|
||||
.SH SYNOPSIS
|
||||
.nf
|
||||
.B #include <ares.h>
|
||||
.PP
|
||||
.B int ares_set_servers(ares_channel \fIchannel\fP, struct ares_addr_node *\fIservers\fP)
|
||||
.B int ares_set_servers_ports(ares_channel \fIchannel\fP, struct ares_addr_port_node *\fIservers\fP)
|
||||
.fi
|
||||
.SH DESCRIPTION
|
||||
The \fBares_set_servers(3)\fP function initializes name servers configuration
|
||||
|
@ -30,19 +31,25 @@ from a
|
|||
.IR servers
|
||||
pointer to a linked list of ares_addr_node structs holding name servers
|
||||
address data.
|
||||
|
||||
.PP
|
||||
The name server linked list pointer argument may be the result of a previous
|
||||
call to \fBares_get_servers(3)\fP or a linked list of ares_addr_node structs
|
||||
setup by other means.
|
||||
|
||||
call to \fBares_get_servers(3)\fP or a linked list of \fBares_addr_node\fP structs
|
||||
set up by other means.
|
||||
.PP
|
||||
The \fBares_set_servers(3)\fP function also allows the specification of UDP and
|
||||
TCP ports to be used for communication on a per-server basis. The provided
|
||||
linked list argument may be the result of a previous call to
|
||||
\fBares_get_servers_ports(3)\fP or a linked list of \fBares_addr_port_node\fP structs
|
||||
set up by other means.
|
||||
.PP
|
||||
This function replaces any potentially previously configured name servers
|
||||
with the ones given in the linked list. So, in order to configure a channel
|
||||
with more than one name server all the desired ones must be specified in a
|
||||
with more than one name server all the desired ones must be specified in a
|
||||
single list.
|
||||
|
||||
\fBares_set_servers(3)\fP does not take ownership of the linked list argument.
|
||||
.PP
|
||||
The function does not take ownership of the linked list argument.
|
||||
The caller is responsible for freeing the linked list when no longer needed.
|
||||
|
||||
.PP
|
||||
This function is capable of handling IPv4 and IPv6 name server
|
||||
addresses simultaneously, rendering \fBares_init_options(3)\fP with
|
||||
optmask \fBARES_OPT_SERVERS\fP functionally obsolete except for
|
||||
|
@ -71,7 +78,8 @@ c-ares library initialization not yet performed.
|
|||
.BR ares_init_options (3),
|
||||
.BR ares_dup(3)
|
||||
.SH AVAILABILITY
|
||||
ares_set_servers(3) was added in c-ares 1.7.1
|
||||
\fBares_set_servers(3)\fP was added in c-ares 1.7.1;
|
||||
\fBares_set_servers_ports(3)\fP was added in c-ares 1.11.0.
|
||||
.SH AUTHOR
|
||||
Implementation of this function and associated library internals are based
|
||||
on code, comments and feedback provided in November and December of 2008 by
|
||||
|
|
|
@ -15,26 +15,32 @@
|
|||
.\"
|
||||
.TH ARES_SET_SERVERS_CSV 3 "30 June 2010"
|
||||
.SH NAME
|
||||
ares_set_servers_csv \- Set list of DNS servers to be used.
|
||||
ares_set_servers_csv, ares_set_servers_ports_csv \- Set list of DNS servers to be used.
|
||||
.SH SYNOPSIS
|
||||
.nf
|
||||
.B #include <ares.h>
|
||||
.PP
|
||||
.B int ares_set_servers_csv(ares_channel \fIchannel\fP, const char* \fIservers\fP)
|
||||
.B int ares_set_servers_ports_csv(ares_channel \fIchannel\fP, const char* \fIservers\fP)
|
||||
.fi
|
||||
.SH DESCRIPTION
|
||||
The \fBares_set_servers_csv\fP function sets the list of DNS servers
|
||||
that ARES will query. The format of the servers option is:
|
||||
The \fBares_set_servers_csv\fP and \fBares_set_servers_ports_csv\fPfunctions set
|
||||
the list of DNS servers that ARES will query. The format of the servers option is:
|
||||
|
||||
host[:port][,host[:port]]...
|
||||
|
||||
For example:
|
||||
|
||||
192.168.1.100,192.168.1.101,3.4.5.6
|
||||
.PP
|
||||
The \fBares_set_servers_csv\fP function will ignore any port values specified in
|
||||
the input string, whereare the \fBares_set_servers_ports_csv\fP function will
|
||||
apply any specified port values as the UDP and TCP port to be used for that
|
||||
particular nameserver.
|
||||
|
||||
.SH RETURN VALUES
|
||||
.B ares_set_servers_csv(3)
|
||||
may return any of the following values:
|
||||
This function may return any of the following values:
|
||||
.TP 15
|
||||
.B ARES_SUCCESS
|
||||
The name servers configuration was successfuly initialized.
|
||||
|
@ -51,10 +57,8 @@ was invalid.
|
|||
c-ares library initialization not yet performed.
|
||||
.SH SEE ALSO
|
||||
.BR ares_set_servers (3)
|
||||
.SH NOTES
|
||||
The port option is currently ignored by c-ares internals
|
||||
and the standard port is always used.
|
||||
|
||||
This function was added in c-ares 1.7.2
|
||||
.SH AVAILABILITY
|
||||
\fBares_set_servers_csv\fP was added in c-ares 1.7.2;
|
||||
\fBares_set_servers_ports_csv\fP was added in c-ares 1.11.0.
|
||||
.SH AUTHOR
|
||||
Ben Greear
|
||||
|
|
|
@ -0,0 +1 @@
|
|||
.so man3/ares_set_servers.3
|
|
@ -0,0 +1 @@
|
|||
.so man3/ares_set_servers_csv.3
|
Loading…
Reference in New Issue