@ -228,56 +228,11 @@ static Local<Array> HostentToNames(struct hostent* host) {
}
}
static const char * AresErrnoString ( int errorno ) {
switch ( errorno ) {
# define ERRNO_CASE(e) case ARES_##e: return #e;
ERRNO_CASE ( SUCCESS )
ERRNO_CASE ( ENODATA )
ERRNO_CASE ( EFORMERR )
ERRNO_CASE ( ESERVFAIL )
ERRNO_CASE ( ENOTFOUND )
ERRNO_CASE ( ENOTIMP )
ERRNO_CASE ( EREFUSED )
ERRNO_CASE ( EBADQUERY )
ERRNO_CASE ( EBADNAME )
ERRNO_CASE ( EBADFAMILY )
ERRNO_CASE ( EBADRESP )
ERRNO_CASE ( ECONNREFUSED )
ERRNO_CASE ( ETIMEOUT )
ERRNO_CASE ( EOF )
ERRNO_CASE ( EFILE )
ERRNO_CASE ( ENOMEM )
ERRNO_CASE ( EDESTRUCTION )
ERRNO_CASE ( EBADSTR )
ERRNO_CASE ( EBADFLAGS )
ERRNO_CASE ( ENONAME )
ERRNO_CASE ( EBADHINTS )
ERRNO_CASE ( ENOTINITIALIZED )
ERRNO_CASE ( ELOADIPHLPAPI )
ERRNO_CASE ( EADDRGETNETWORKPARAMS )
ERRNO_CASE ( ECANCELLED )
# undef ERRNO_CASE
default :
assert ( 0 & & " Unhandled c-ares error " ) ;
return " (UNKNOWN) " ;
}
}
static void SetAresErrno ( int errorno ) {
HandleScope scope ( node_isolate ) ;
Local < Value > key = String : : NewSymbol ( " _errno " ) ;
Local < Value > value = String : : NewSymbol ( AresErrnoString ( errorno ) ) ;
Local < Object > process = PersistentToLocal ( process_p ) ;
process - > Set ( key , value ) ;
}
class QueryWrap {
class QueryWrap {
public :
public :
QueryWrap ( ) {
QueryWrap ( Local < Object > req_wrap_obj ) {
HandleScope scope ( node_isolate ) ;
HandleScope scope ( node_isolate ) ;
persistent ( ) . Reset ( node_isolate , Object : : New ( ) ) ;
persistent ( ) . Reset ( node_isolate , req_wrap_obj ) ;
}
}
virtual ~ QueryWrap ( ) {
virtual ~ QueryWrap ( ) {
@ -355,10 +310,10 @@ class QueryWrap {
void ParseError ( int status ) {
void ParseError ( int status ) {
assert ( status ! = ARES_SUCCESS ) ;
assert ( status ! = ARES_SUCCESS ) ;
SetAresErrno ( status ) ;
HandleScope scope ( node_isolate ) ;
HandleScope scope ( node_isolate ) ;
Local < Value > argv [ 1 ] = { Integer : : New ( - 1 , node_isolate ) } ;
Local < Value > argv [ ] = {
Integer : : New ( status , node_isolate )
} ;
MakeCallback ( object ( ) , oncomplete_sym , ARRAY_SIZE ( argv ) , argv ) ;
MakeCallback ( object ( ) , oncomplete_sym , ARRAY_SIZE ( argv ) , argv ) ;
}
}
@ -378,6 +333,9 @@ class QueryWrap {
class QueryAWrap : public QueryWrap {
class QueryAWrap : public QueryWrap {
public :
public :
QueryAWrap ( Local < Object > req_wrap_obj ) : QueryWrap ( req_wrap_obj ) {
}
int Send ( const char * name ) {
int Send ( const char * name ) {
ares_query ( ares_channel , name , ns_c_in , ns_t_a , Callback , GetQueryArg ( ) ) ;
ares_query ( ares_channel , name , ns_c_in , ns_t_a , Callback , GetQueryArg ( ) ) ;
return 0 ;
return 0 ;
@ -405,6 +363,9 @@ class QueryAWrap: public QueryWrap {
class QueryAaaaWrap : public QueryWrap {
class QueryAaaaWrap : public QueryWrap {
public :
public :
QueryAaaaWrap ( Local < Object > req_wrap_obj ) : QueryWrap ( req_wrap_obj ) {
}
int Send ( const char * name ) {
int Send ( const char * name ) {
ares_query ( ares_channel ,
ares_query ( ares_channel ,
name ,
name ,
@ -437,6 +398,9 @@ class QueryAaaaWrap: public QueryWrap {
class QueryCnameWrap : public QueryWrap {
class QueryCnameWrap : public QueryWrap {
public :
public :
QueryCnameWrap ( Local < Object > req_wrap_obj ) : QueryWrap ( req_wrap_obj ) {
}
int Send ( const char * name ) {
int Send ( const char * name ) {
ares_query ( ares_channel ,
ares_query ( ares_channel ,
name ,
name ,
@ -472,6 +436,9 @@ class QueryCnameWrap: public QueryWrap {
class QueryMxWrap : public QueryWrap {
class QueryMxWrap : public QueryWrap {
public :
public :
QueryMxWrap ( Local < Object > req_wrap_obj ) : QueryWrap ( req_wrap_obj ) {
}
int Send ( const char * name ) {
int Send ( const char * name ) {
ares_query ( ares_channel , name , ns_c_in , ns_t_mx , Callback , GetQueryArg ( ) ) ;
ares_query ( ares_channel , name , ns_c_in , ns_t_mx , Callback , GetQueryArg ( ) ) ;
return 0 ;
return 0 ;
@ -511,6 +478,9 @@ class QueryMxWrap: public QueryWrap {
class QueryNsWrap : public QueryWrap {
class QueryNsWrap : public QueryWrap {
public :
public :
QueryNsWrap ( Local < Object > req_wrap_obj ) : QueryWrap ( req_wrap_obj ) {
}
int Send ( const char * name ) {
int Send ( const char * name ) {
ares_query ( ares_channel , name , ns_c_in , ns_t_ns , Callback , GetQueryArg ( ) ) ;
ares_query ( ares_channel , name , ns_c_in , ns_t_ns , Callback , GetQueryArg ( ) ) ;
return 0 ;
return 0 ;
@ -536,6 +506,9 @@ class QueryNsWrap: public QueryWrap {
class QueryTxtWrap : public QueryWrap {
class QueryTxtWrap : public QueryWrap {
public :
public :
QueryTxtWrap ( Local < Object > req_wrap_obj ) : QueryWrap ( req_wrap_obj ) {
}
int Send ( const char * name ) {
int Send ( const char * name ) {
ares_query ( ares_channel , name , ns_c_in , ns_t_txt , Callback , GetQueryArg ( ) ) ;
ares_query ( ares_channel , name , ns_c_in , ns_t_txt , Callback , GetQueryArg ( ) ) ;
return 0 ;
return 0 ;
@ -568,6 +541,9 @@ class QueryTxtWrap: public QueryWrap {
class QuerySrvWrap : public QueryWrap {
class QuerySrvWrap : public QueryWrap {
public :
public :
QuerySrvWrap ( Local < Object > req_wrap_obj ) : QueryWrap ( req_wrap_obj ) {
}
int Send ( const char * name ) {
int Send ( const char * name ) {
ares_query ( ares_channel ,
ares_query ( ares_channel ,
name ,
name ,
@ -617,6 +593,9 @@ class QuerySrvWrap: public QueryWrap {
class QueryNaptrWrap : public QueryWrap {
class QueryNaptrWrap : public QueryWrap {
public :
public :
QueryNaptrWrap ( Local < Object > req_wrap_obj ) : QueryWrap ( req_wrap_obj ) {
}
int Send ( const char * name ) {
int Send ( const char * name ) {
ares_query ( ares_channel ,
ares_query ( ares_channel ,
name ,
name ,
@ -679,18 +658,21 @@ class QueryNaptrWrap: public QueryWrap {
class GetHostByAddrWrap : public QueryWrap {
class GetHostByAddrWrap : public QueryWrap {
public :
public :
GetHostByAddrWrap ( Local < Object > req_wrap_obj ) : QueryWrap ( req_wrap_obj ) {
}
int Send ( const char * name ) {
int Send ( const char * name ) {
int length , family ;
int length , family ;
char address_buffer [ sizeof ( struct in6_addr ) ] ;
char address_buffer [ sizeof ( struct in6_addr ) ] ;
if ( uv_inet_pton ( AF_INET , name , & address_buffer ) . code = = UV_OK ) {
if ( uv_inet_pton ( AF_INET , name , & address_buffer ) = = 0 ) {
length = sizeof ( struct in_addr ) ;
length = sizeof ( struct in_addr ) ;
family = AF_INET ;
family = AF_INET ;
} else if ( uv_inet_pton ( AF_INET6 , name , & address_buffer ) . code = = UV_OK ) {
} else if ( uv_inet_pton ( AF_INET6 , name , & address_buffer ) = = 0 ) {
length = sizeof ( struct in6_addr ) ;
length = sizeof ( struct in6_addr ) ;
family = AF_INET6 ;
family = AF_INET6 ;
} else {
} else {
return ARES_ENOTIMP ;
return UV_EINVAL ; // So errnoException() reports a proper error.
}
}
ares_gethostbyaddr ( ares_channel ,
ares_gethostbyaddr ( ares_channel ,
@ -713,6 +695,9 @@ class GetHostByAddrWrap: public QueryWrap {
class GetHostByNameWrap : public QueryWrap {
class GetHostByNameWrap : public QueryWrap {
public :
public :
GetHostByNameWrap ( Local < Object > req_wrap_obj ) : QueryWrap ( req_wrap_obj ) {
}
int Send ( const char * name , int family ) {
int Send ( const char * name , int family ) {
ares_gethostbyname ( ares_channel , name , family , Callback , GetQueryArg ( ) ) ;
ares_gethostbyname ( ares_channel , name , family , Callback , GetQueryArg ( ) ) ;
return 0 ;
return 0 ;
@ -735,26 +720,27 @@ static void Query(const FunctionCallbackInfo<Value>& args) {
HandleScope scope ( node_isolate ) ;
HandleScope scope ( node_isolate ) ;
assert ( ! args . IsConstructCall ( ) ) ;
assert ( ! args . IsConstructCall ( ) ) ;
assert ( args . Length ( ) > = 2 ) ;
assert ( args [ 0 ] - > IsObject ( ) ) ;
assert ( args [ 1 ] - > IsFunction ( ) ) ;
assert ( args [ 1 ] - > IsString ( ) ) ;
assert ( args [ 2 ] - > IsFunction ( ) ) ;
Wrap * wrap = new Wrap ( ) ;
Local < Object > req_wrap_obj = args [ 0 ] . As < Object > ( ) ;
wrap - > SetOnComplete ( args [ 1 ] ) ;
Local < String > string = args [ 1 ] . As < String > ( ) ;
Local < Function > callback = args [ 2 ] . As < Function > ( ) ;
Wrap * wrap = new Wrap ( req_wrap_obj ) ;
wrap - > SetOnComplete ( callback ) ;
// We must cache the wrap's js object here, because cares might make the
// We must cache the wrap's js object here, because cares might make the
// callback from the wrap->Send stack. This will destroy the wrap's internal
// callback from the wrap->Send stack. This will destroy the wrap's internal
// object reference, causing wrap->object() to return an empty handle.
// object reference, causing wrap->object() to return an empty handle.
Local < Object > object = Local < Object > : : New ( node_isolate , wrap - > persistent ( ) ) ;
Local < Object > object = Local < Object > : : New ( node_isolate , wrap - > persistent ( ) ) ;
String : : Utf8Value name ( args [ 0 ] ) ;
String : : Utf8Value name ( string ) ;
int err = wrap - > Send ( * name ) ;
if ( err ) delete wrap ;
int r = wrap - > Send ( * name ) ;
args . GetReturnValue ( ) . Set ( err ) ;
if ( r ) {
SetAresErrno ( r ) ;
delete wrap ;
} else {
args . GetReturnValue ( ) . Set ( object ) ;
}
}
}
@ -763,27 +749,29 @@ static void QueryWithFamily(const FunctionCallbackInfo<Value>& args) {
HandleScope scope ( node_isolate ) ;
HandleScope scope ( node_isolate ) ;
assert ( ! args . IsConstructCall ( ) ) ;
assert ( ! args . IsConstructCall ( ) ) ;
assert ( args . Length ( ) > = 3 ) ;
assert ( args [ 0 ] - > IsObject ( ) ) ;
assert ( args [ 2 ] - > IsFunction ( ) ) ;
assert ( args [ 1 ] - > IsString ( ) ) ;
assert ( args [ 2 ] - > IsInt32 ( ) ) ;
assert ( args [ 3 ] - > IsFunction ( ) ) ;
Local < Object > req_wrap_obj = args [ 0 ] . As < Object > ( ) ;
Local < String > string = args [ 1 ] . As < String > ( ) ;
int family = args [ 2 ] - > Int32Value ( ) ;
Local < Function > callback = args [ 3 ] . As < Function > ( ) ;
Wrap * wrap = new Wrap ( ) ;
Wrap * wrap = new Wrap ( req_wrap_obj ) ;
wrap - > SetOnComplete ( args [ 2 ] ) ;
wrap - > SetOnComplete ( callback ) ;
// We must cache the wrap's js object here, because cares might make the
// We must cache the wrap's js object here, because cares might make the
// callback from the wrap->Send stack. This will destroy the wrap's internal
// callback from the wrap->Send stack. This will destroy the wrap's internal
// object reference, causing wrap->object() to return an empty handle.
// object reference, causing wrap->object() to return an empty handle.
Local < Object > object = Local < Object > : : New ( node_isolate , wrap - > persistent ( ) ) ;
Local < Object > object = Local < Object > : : New ( node_isolate , wrap - > persistent ( ) ) ;
String : : Utf8Value name ( args [ 0 ] ) ;
String : : Utf8Value name ( string ) ;
int family = args [ 1 ] - > Int32Value ( ) ;
int err = wrap - > Send ( * name , family ) ;
if ( err ) delete wrap ;
int r = wrap - > Send ( * name , family ) ;
args . GetReturnValue ( ) . Set ( err ) ;
if ( r ) {
SetAresErrno ( r ) ;
delete wrap ;
} else {
args . GetReturnValue ( ) . Set ( object ) ;
}
}
}
@ -792,13 +780,12 @@ void AfterGetAddrInfo(uv_getaddrinfo_t* req, int status, struct addrinfo* res) {
GetAddrInfoReqWrap * req_wrap = ( GetAddrInfoReqWrap * ) req - > data ;
GetAddrInfoReqWrap * req_wrap = ( GetAddrInfoReqWrap * ) req - > data ;
Local < Value > argv [ 1 ] ;
Local < Value > argv [ ] = {
Integer : : New ( status , node_isolate ) ,
Null ( node_isolate )
} ;
if ( status ) {
if ( status = = 0 ) {
// Error
SetErrno ( uv_last_error ( uv_default_loop ( ) ) ) ;
argv [ 0 ] = Null ( node_isolate ) ;
} else {
// Success
// Success
struct addrinfo * address ;
struct addrinfo * address ;
int n = 0 ;
int n = 0 ;
@ -826,11 +813,11 @@ void AfterGetAddrInfo(uv_getaddrinfo_t* req, int status, struct addrinfo* res) {
if ( address - > ai_family = = AF_INET ) {
if ( address - > ai_family = = AF_INET ) {
// Juggle pointers
// Juggle pointers
addr = ( char * ) & ( ( struct sockaddr_in * ) address - > ai_addr ) - > sin_addr ;
addr = ( char * ) & ( ( struct sockaddr_in * ) address - > ai_addr ) - > sin_addr ;
uv_err_ t err = uv_inet_ntop ( address - > ai_family ,
in t err = uv_inet_ntop ( address - > ai_family ,
addr ,
addr ,
ip ,
ip ,
INET6_ADDRSTRLEN ) ;
INET6_ADDRSTRLEN ) ;
if ( err . code ! = UV_OK )
if ( err )
continue ;
continue ;
// Create JavaScript string
// Create JavaScript string
@ -852,11 +839,11 @@ void AfterGetAddrInfo(uv_getaddrinfo_t* req, int status, struct addrinfo* res) {
if ( address - > ai_family = = AF_INET6 ) {
if ( address - > ai_family = = AF_INET6 ) {
// Juggle pointers
// Juggle pointers
addr = ( char * ) & ( ( struct sockaddr_in6 * ) address - > ai_addr ) - > sin6_addr ;
addr = ( char * ) & ( ( struct sockaddr_in6 * ) address - > ai_addr ) - > sin6_addr ;
uv_err_ t err = uv_inet_ntop ( address - > ai_family ,
in t err = uv_inet_ntop ( address - > ai_family ,
addr ,
addr ,
ip ,
ip ,
INET6_ADDRSTRLEN ) ;
INET6_ADDRSTRLEN ) ;
if ( err . code ! = UV_OK )
if ( err )
continue ;
continue ;
// Create JavaScript string
// Create JavaScript string
@ -870,7 +857,7 @@ void AfterGetAddrInfo(uv_getaddrinfo_t* req, int status, struct addrinfo* res) {
}
}
argv [ 0 ] = results ;
argv [ 1 ] = results ;
}
}
uv_freeaddrinfo ( res ) ;
uv_freeaddrinfo ( res ) ;
@ -889,9 +876,9 @@ static void IsIP(const FunctionCallbackInfo<Value>& args) {
char address_buffer [ sizeof ( struct in6_addr ) ] ;
char address_buffer [ sizeof ( struct in6_addr ) ] ;
int rc = 0 ;
int rc = 0 ;
if ( uv_inet_pton ( AF_INET , * ip , & address_buffer ) . code = = UV_OK )
if ( uv_inet_pton ( AF_INET , * ip , & address_buffer ) = = 0 )
rc = 4 ;
rc = 4 ;
else if ( uv_inet_pton ( AF_INET6 , * ip , & address_buffer ) . code = = UV_OK )
else if ( uv_inet_pton ( AF_INET6 , * ip , & address_buffer ) = = 0 )
rc = 6 ;
rc = 6 ;
args . GetReturnValue ( ) . Set ( rc ) ;
args . GetReturnValue ( ) . Set ( rc ) ;
@ -901,42 +888,45 @@ static void IsIP(const FunctionCallbackInfo<Value>& args) {
static void GetAddrInfo ( const FunctionCallbackInfo < Value > & args ) {
static void GetAddrInfo ( const FunctionCallbackInfo < Value > & args ) {
HandleScope scope ( node_isolate ) ;
HandleScope scope ( node_isolate ) ;
String : : Utf8Value hostname ( args [ 0 ] ) ;
assert ( args [ 0 ] - > IsObject ( ) ) ;
assert ( args [ 1 ] - > IsString ( ) ) ;
int fam = AF_UNSPEC ;
assert ( args [ 2 ] - > IsInt32 ( ) ) ;
if ( args [ 1 ] - > IsInt32 ( ) ) {
Local < Object > req_wrap_obj = args [ 0 ] . As < Object > ( ) ;
switch ( args [ 1 ] - > Int32Value ( ) ) {
String : : Utf8Value hostname ( args [ 1 ] ) ;
case 6 :
fam = AF_INET6 ;
int family ;
break ;
switch ( args [ 2 ] - > Int32Value ( ) ) {
case 0 :
case 4 :
family = AF_UNSPEC ;
fam = AF_INET ;
break ;
break ;
case 4 :
}
family = AF_INET ;
break ;
case 6 :
family = AF_INET6 ;
break ;
default :
assert ( 0 & & " bad address family " ) ;
abort ( ) ;
}
}
GetAddrInfoReqWrap * req_wrap = new GetAddrInfoReqWrap ( ) ;
GetAddrInfoReqWrap * req_wrap = new GetAddrInfoReqWrap ( req_wrap_obj ) ;
struct addrinfo hints ;
struct addrinfo hints ;
memset ( & hints , 0 , sizeof ( struct addrinfo ) ) ;
memset ( & hints , 0 , sizeof ( struct addrinfo ) ) ;
hints . ai_family = fam ;
hints . ai_family = family ;
hints . ai_socktype = SOCK_STREAM ;
hints . ai_socktype = SOCK_STREAM ;
int r = uv_getaddrinfo ( uv_default_loop ( ) ,
int er r = uv_getaddrinfo ( uv_default_loop ( ) ,
& req_wrap - > req_ ,
& req_wrap - > req_ ,
AfterGetAddrInfo ,
AfterGetAddrInfo ,
* hostname ,
* hostname ,
NULL ,
NULL ,
& hints ) ;
& hints ) ;
req_wrap - > Dispatched ( ) ;
req_wrap - > Dispatched ( ) ;
if ( err ) delete req_wrap ;
if ( r ) {
args . GetReturnValue ( ) . Set ( err ) ;
SetErrno ( uv_last_error ( uv_default_loop ( ) ) ) ;
delete req_wrap ;
} else {
args . GetReturnValue ( ) . Set ( req_wrap - > persistent ( ) ) ;
}
}
}
@ -956,8 +946,8 @@ static void GetServers(const FunctionCallbackInfo<Value>& args) {
char ip [ INET6_ADDRSTRLEN ] ;
char ip [ INET6_ADDRSTRLEN ] ;
const void * caddr = static_cast < const void * > ( & cur - > addr ) ;
const void * caddr = static_cast < const void * > ( & cur - > addr ) ;
uv_err_ t err = uv_inet_ntop ( cur - > family , caddr , ip , sizeof ( ip ) ) ;
in t err = uv_inet_ntop ( cur - > family , caddr , ip , sizeof ( ip ) ) ;
assert ( err . code = = UV_OK ) ;
assert ( err = = 0 ) ;
Local < String > addr = String : : New ( ip ) ;
Local < String > addr = String : : New ( ip ) ;
server_array - > Set ( i , addr ) ;
server_array - > Set ( i , addr ) ;
@ -986,7 +976,7 @@ static void SetServers(const FunctionCallbackInfo<Value>& args) {
ares_addr_node * servers = new ares_addr_node [ len ] ;
ares_addr_node * servers = new ares_addr_node [ len ] ;
ares_addr_node * last = NULL ;
ares_addr_node * last = NULL ;
uv_err_t uv_ret ;
int err ;
for ( uint32_t i = 0 ; i < len ; i + + ) {
for ( uint32_t i = 0 ; i < len ; i + + ) {
assert ( arr - > Get ( i ) - > IsArray ( ) ) ;
assert ( arr - > Get ( i ) - > IsArray ( ) ) ;
@ -1004,18 +994,18 @@ static void SetServers(const FunctionCallbackInfo<Value>& args) {
switch ( fam ) {
switch ( fam ) {
case 4 :
case 4 :
cur - > family = AF_INET ;
cur - > family = AF_INET ;
uv_ret = uv_inet_pton ( AF_INET , * ip , & cur - > addr ) ;
err = uv_inet_pton ( AF_INET , * ip , & cur - > addr ) ;
break ;
break ;
case 6 :
case 6 :
cur - > family = AF_INET6 ;
cur - > family = AF_INET6 ;
uv_ret = uv_inet_pton ( AF_INET6 , * ip , & cur - > addr ) ;
err = uv_inet_pton ( AF_INET6 , * ip , & cur - > addr ) ;
break ;
break ;
default :
default :
assert ( 0 & & " Bad address family. " ) ;
assert ( 0 & & " Bad address family. " ) ;
abort ( ) ;
abort ( ) ;
}
}
if ( uv_ret . code ! = UV_OK )
if ( err )
break ;
break ;
cur - > next = NULL ;
cur - > next = NULL ;
@ -1026,16 +1016,14 @@ static void SetServers(const FunctionCallbackInfo<Value>& args) {
last = cur ;
last = cur ;
}
}
int r ;
if ( err = = 0 )
err = ares_set_servers ( ares_channel , & servers [ 0 ] ) ;
if ( uv_ret . code = = UV_OK )
r = ares_set_servers ( ares_channel , & servers [ 0 ] ) ;
else
else
r = ARES_EBADSTR ;
err = ARES_EBADSTR ;
delete [ ] servers ;
delete [ ] servers ;
args . GetReturnValue ( ) . Set ( r ) ;
args . GetReturnValue ( ) . Set ( er r) ;
}
}