@ -83,6 +83,62 @@ int ares_get_servers(ares_channel channel,
return status ;
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 ,
int ares_set_servers ( ares_channel channel ,
struct ares_addr_node * servers )
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 )
for ( i = 0 , srvr = servers ; srvr ; i + + , srvr = srvr - > next )
{
{
channel - > servers [ i ] . addr . family = srvr - > family ;
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 )
if ( srvr - > family = = AF_INET )
memcpy ( & channel - > servers [ i ] . addr . addrV4 , & srvr - > addrV4 ,
memcpy ( & channel - > servers [ i ] . addr . addrV4 , & srvr - > addrV4 ,
sizeof ( srvr - > addrV4 ) ) ;
sizeof ( srvr - > addrV4 ) ) ;
@ -133,8 +240,8 @@ int ares_set_servers(ares_channel channel,
/* Incomming string format: host[:port][,host[:port]]... */
/* Incomming string format: host[:port][,host[:port]]... */
/* IPv6 addresses with ports require square brackets [fe80::1%lo0]:53 */
/* IPv6 addresses with ports require square brackets [fe80::1%lo0]:53 */
int ares_ set_servers_csv( ares_channel channel ,
static int set_servers_csv ( ares_channel channel ,
const char * _csv )
const char * _csv , int use_port )
{
{
size_t i ;
size_t i ;
char * csv = NULL ;
char * csv = NULL ;
@ -142,8 +249,8 @@ int ares_set_servers_csv(ares_channel channel,
char * start_host ;
char * start_host ;
int cc = 0 ;
int cc = 0 ;
int rv = ARES_SUCCESS ;
int rv = ARES_SUCCESS ;
struct ares_addr_node * servers = NULL ;
struct ares_addr_port_ node * servers = NULL ;
struct ares_addr_node * last = NULL ;
struct ares_addr_port_ node * last = NULL ;
if ( ares_library_initialized ( ) ! = ARES_SUCCESS )
if ( ares_library_initialized ( ) ! = ARES_SUCCESS )
return ARES_ENOTINITIALIZED ; /* LCOV_EXCL_LINE: n/a on non-WinSock */
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 = = ' , ' ) {
else if ( * ptr = = ' , ' ) {
char * pp = ptr - 1 ;
char * pp = ptr - 1 ;
char * p = ptr ;
char * p = ptr ;
int port = 0 ;
struct in_addr in4 ;
struct in_addr in4 ;
struct ares_in6_addr in6 ;
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 */
* ptr = 0 ; /* null terminate host:port string */
/* Got an entry..see if the port was specified. */
/* Got an entry..see if the port was specified. */
@ -213,7 +321,7 @@ int ares_set_servers_csv(ares_channel channel,
if ( * pp = = ' ] ' )
if ( * pp = = ' ] ' )
p + + ; /* move p before ':' */
p + + ; /* move p before ':' */
/* p will point to the start of the port */
/* 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 */
* 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 ) ) ;
memcpy ( & s - > addr , & in4 , sizeof ( struct in_addr ) ) ;
}
}
if ( s ) {
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 ;
s - > next = NULL ;
if ( last ) {
if ( last ) {
last - > next = s ;
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 :
out :
if ( csv )
if ( csv )
ares_free ( csv ) ;
ares_free ( csv ) ;
while ( servers ) {
while ( servers ) {
struct ares_addr_node * s = servers ;
struct ares_addr_port_ node * s = servers ;
servers = servers - > next ;
servers = servers - > next ;
ares_free ( s ) ;
ares_free ( s ) ;
}
}
return rv ;
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 ) ;
}