api: Add ares_set_sortlist(3) entrypoint

Allow explicit configuration of the channel's sortlist, by
specifying a string in the same format as the equivalent
/etc/resolv.conf option.

This allows library users to perform the same configuration
that is available via /etc/resolv.conf, but without needing
to change that file.
This commit is contained in:
David Drysdale 2015-12-29 17:31:34 +00:00
parent f1bcfa1122
commit 06d0f72e54
4 changed files with 102 additions and 22 deletions

View File

@ -113,6 +113,7 @@ MANPAGES = ares_cancel.3 \
ares_set_servers.3 \
ares_set_servers_csv.3 \
ares_set_socket_callback.3 \
ares_set_sortlist.3 \
ares_strerror.3 \
ares_timeout.3 \
ares_version.3 \
@ -160,6 +161,7 @@ HTMLPAGES = ares_cancel.html \
ares_set_servers.html \
ares_set_servers_csv.html \
ares_set_socket_callback.html \
ares_set_sortlist.html \
ares_strerror.html \
ares_timeout.html \
ares_version.html \
@ -207,6 +209,7 @@ PDFPAGES = ares_cancel.pdf \
ares_set_servers.pdf \
ares_set_servers_csv.pdf \
ares_set_socket_callback.pdf \
ares_set_sortlist.pdf \
ares_strerror.pdf \
ares_timeout.pdf \
ares_version.pdf \

3
ares.h
View File

@ -344,6 +344,9 @@ CARES_EXTERN void ares_set_socket_callback(ares_channel channel,
ares_sock_create_callback callback,
void *user_data);
CARES_EXTERN int ares_set_sortlist(ares_channel channel,
const char *sortstr);
CARES_EXTERN void ares_send(ares_channel channel,
const unsigned char *qbuf,
int qlen,

View File

@ -80,17 +80,17 @@ static int set_options(ares_channel channel, const char *str);
static const char *try_option(const char *p, const char *q, const char *opt);
static int init_id_key(rc4_key* key,int key_data_len);
#if !defined(WIN32) && !defined(WATT32) && \
!defined(ANDROID) && !defined(__ANDROID__) && !defined(CARES_USE_LIBRESOLV)
static int config_sortlist(struct apattern **sortlist, int *nsort,
const char *str);
static int sortlist_alloc(struct apattern **sortlist, int *nsort,
struct apattern *pat);
static int ip_addr(const char *s, ssize_t len, struct in_addr *addr);
static void natural_mask(struct apattern *pat);
#if !defined(WIN32) && !defined(WATT32) && \
!defined(ANDROID) && !defined(__ANDROID__) && !defined(CARES_USE_LIBRESOLV)
static int config_domain(ares_channel channel, char *str);
static int config_lookup(ares_channel channel, const char *str,
const char *bindch, const char *filech);
static int config_sortlist(struct apattern **sortlist, int *nsort,
const char *str);
static char *try_config(char *s, const char *opt, char scc);
#endif
@ -1664,9 +1664,8 @@ static int config_nameserver(struct server_state **servers, int *nservers,
return ARES_SUCCESS;
}
#endif /* !WATT32 */
#if !defined(WIN32) && !defined(ANDROID) && !defined(__ANDROID__) && \
!defined(CARES_USE_LIBRESOLV)
static int config_sortlist(struct apattern **sortlist, int *nsort,
const char *str)
{
@ -1756,8 +1755,6 @@ static int config_sortlist(struct apattern **sortlist, int *nsort,
return ARES_SUCCESS;
}
#endif /* !WIN32 & !ANDROID & !__ANDROID__ */
#endif /* !WATT32 */
static int set_search(ares_channel channel, const char *str)
{
@ -1927,19 +1924,7 @@ static char *try_config(char *s, const char *opt, char scc)
/* return pointer to option value */
return p;
}
static int sortlist_alloc(struct apattern **sortlist, int *nsort,
struct apattern *pat)
{
struct apattern *newsort;
newsort = ares_realloc(*sortlist, (*nsort + 1) * sizeof(struct apattern));
if (!newsort)
return 0;
newsort[*nsort] = *pat;
*sortlist = newsort;
(*nsort)++;
return 1;
}
#endif /* !WIN32 & !WATT32 & !ANDROID & !__ANDROID__ */
static int ip_addr(const char *ipbuf, ssize_t len, struct in_addr *addr)
{
@ -1973,7 +1958,19 @@ static void natural_mask(struct apattern *pat)
else
pat->mask.addr4.s_addr = htonl(IN_CLASSC_NET);
}
#endif /* !WIN32 & !WATT32 & !ANDROID & !__ANDROID__ */
static int sortlist_alloc(struct apattern **sortlist, int *nsort,
struct apattern *pat)
{
struct apattern *newsort;
newsort = ares_realloc(*sortlist, (*nsort + 1) * sizeof(struct apattern));
if (!newsort)
return 0;
newsort[*nsort] = *pat;
*sortlist = newsort;
(*nsort)++;
return 1;
}
/* initialize an rc4 key. If possible a cryptographically secure random key
is generated using a suitable function (for example win32's RtlGenRandom as
@ -2074,6 +2071,25 @@ void ares_set_socket_callback(ares_channel channel,
channel->sock_create_cb_data = data;
}
int ares_set_sortlist(ares_channel channel, const char *sortstr)
{
int nsort = 0;
struct apattern *sortlist = NULL;
int status;
if (!channel)
return ARES_ENODATA;
status = config_sortlist(&sortlist, &nsort, sortstr);
if (status == ARES_SUCCESS && sortlist) {
if (channel->sortlist)
ares_free(channel->sortlist);
channel->sortlist = sortlist;
channel->nsort = nsort;
}
return status;
}
void ares__init_servers_state(ares_channel channel)
{
struct server_state *server;

58
ares_set_sortlist.3 Normal file
View File

@ -0,0 +1,58 @@
.\"
.\" Permission to use, copy, modify, and distribute this
.\" software and its documentation for any purpose and without
.\" fee is hereby granted, provided that the above copyright
.\" notice appear in all copies and that both that copyright
.\" notice and this permission notice appear in supporting
.\" documentation, and that the name of M.I.T. not be used in
.\" advertising or publicity pertaining to distribution of the
.\" software without specific, written prior permission.
.\" M.I.T. makes no representations about the suitability of
.\" this software for any purpose. It is provided "as is"
.\" without express or implied warranty.
.\"
.TH ARES_SET_SORTLIST 3 "23 November 2015"
.SH NAME
ares_set_sortlist \- Initialize an ares_channel sortlist configuration
.SH SYNOPSIS
.nf
.B #include <ares.h>
.PP
.B int ares_set_sortlist(ares_channel \fIchannel\fP, const char *\fIsortstr\fP)
.fi
.SH DESCRIPTION
The \fBares_set_sortlist(3)\fP function initializes an address sortlist configuration
for the channel data identified by
.IR channel ,
so that addresses returned by \fBares_gethostbyname(3)\fP are sorted according to the
sortlist. The provided
.IR sortstr
string that holds a space separated list of IP-address-netmask pairs. The
netmask is optional but follows the address after a slash if present. For example,
"130.155.160.0/255.255.240.0 130.155.0.0".
This function replaces any potentially previously configured address sortlist
with the ones given in the configuration string.
.SH RETURN VALUES
.B ares_set_sortlist(3)
may return any of the following values:
.TP 15
.B ARES_SUCCESS
The sortlist configuration was successfuly initialized.
.TP 15
.B ARES_ENOMEM
The process's available memory was exhausted.
.TP 15
.B ARES_ENODATA
The channel data identified by
.IR channel
was invalid.
.TP 15
.B ARES_ENOTINITIALIZED
c-ares library initialization not yet performed.
.SH SEE ALSO
.BR ares_init_options (3),
.BR ares_dup(3)
.SH AVAILABILITY
ares_set_sortlist(3) was added in c-ares 1.11.0