diff options
Diffstat (limited to 'src/cares_wrap.cc')
-rw-r--r-- | src/cares_wrap.cc | 109 |
1 files changed, 109 insertions, 0 deletions
diff --git a/src/cares_wrap.cc b/src/cares_wrap.cc index d9b4e1884..8cca4214b 100644 --- a/src/cares_wrap.cc +++ b/src/cares_wrap.cc @@ -939,6 +939,111 @@ static Handle<Value> GetAddrInfo(const Arguments& args) { } +static Handle<Value> GetServers(const Arguments& args) { + HandleScope scope(node_isolate); + + Local<Array> server_array = Array::New(); + + ares_addr_node* servers; + + int r = ares_get_servers(ares_channel, &servers); + assert(r == ARES_SUCCESS); + + ares_addr_node* cur = servers; + + for (int i = 0; cur != NULL; ++i, cur = cur->next) { + char ip[INET6_ADDRSTRLEN]; + + const void* caddr = static_cast<const void*>(&cur->addr); + uv_err_t err = uv_inet_ntop(cur->family, caddr, ip, sizeof(ip)); + assert(err.code == UV_OK); + + Local<String> addr = String::New(ip); + server_array->Set(i, addr); + } + + ares_free_data(servers); + + return scope.Close(server_array); +} + + +static Handle<Value> SetServers(const Arguments& args) { + HandleScope scope(node_isolate); + + assert(args[0]->IsArray()); + + Local<Array> arr = Local<Array>::Cast(args[0]); + + uint32_t len = arr->Length(); + + if (len == 0) { + int rv = ares_set_servers(ares_channel, NULL); + return scope.Close(Integer::New(rv)); + } + + ares_addr_node* servers = new ares_addr_node[len]; + ares_addr_node* last = NULL; + + uv_err_t uv_ret; + + for (uint32_t i = 0; i < len; i++) { + assert(arr->Get(i)->IsArray()); + + Local<Array> elm = Local<Array>::Cast(arr->Get(i)); + + assert(elm->Get(0)->Int32Value()); + assert(elm->Get(1)->IsString()); + + int fam = elm->Get(0)->Int32Value(); + String::Utf8Value ip(elm->Get(1)); + + ares_addr_node* cur = &servers[i]; + + switch (fam) { + case 4: + cur->family = AF_INET; + uv_ret = uv_inet_pton(AF_INET, *ip, &cur->addr); + break; + case 6: + cur->family = AF_INET6; + uv_ret = uv_inet_pton(AF_INET6, *ip, &cur->addr); + break; + } + + if (uv_ret.code != UV_OK) + break; + + cur->next = NULL; + + if (last != NULL) + last->next = cur; + + last = cur; + } + + int r; + + if (uv_ret.code == UV_OK) + r = ares_set_servers(ares_channel, &servers[0]); + else + r = ARES_EBADSTR; + + delete[] servers; + + return scope.Close(Integer::New(r)); +} + + +static Handle<Value> StrError(const Arguments& args) { + HandleScope scope; + + int r = args[0]->Int32Value(); + + return scope.Close(String::New(ares_strerror(r))); +} + + static void Initialize(Handle<Object> target) { HandleScope scope(node_isolate); int r; @@ -976,6 +1081,10 @@ static void Initialize(Handle<Object> target) { NODE_SET_METHOD(target, "getaddrinfo", GetAddrInfo); NODE_SET_METHOD(target, "isIP", IsIP); + NODE_SET_METHOD(target, "strerror", StrError); + NODE_SET_METHOD(target, "getServers", GetServers); + NODE_SET_METHOD(target, "setServers", SetServers); + target->Set(String::NewSymbol("AF_INET"), Integer::New(AF_INET, node_isolate)); target->Set(String::NewSymbol("AF_INET6"), |