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
pull/34/head
David Drysdale 9 years ago
parent 06d0f72e54
commit 7972adc5d7
  1. 9
      Makefile.inc
  2. 18
      ares.h
  3. 15
      ares_data.c
  4. 2
      ares_data.h
  5. 16
      ares_get_servers.3
  6. 1
      ares_get_servers_ports.3
  7. 36
      ares_init.c
  8. 141
      ares_options.c
  9. 6
      ares_private.h
  10. 16
      ares_process.c
  11. 26
      ares_set_servers.3
  12. 22
      ares_set_servers_csv.3
  13. 1
      ares_set_servers_ports.3
  14. 1
      ares_set_servers_ports_csv.3

@ -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 \

@ -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);

@ -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
@ -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

@ -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));

@ -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;
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;
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;
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;
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
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…
Cancel
Save