summaryrefslogtreecommitdiff
path: root/src/cares_wrap.cc
diff options
context:
space:
mode:
Diffstat (limited to 'src/cares_wrap.cc')
-rw-r--r--src/cares_wrap.cc109
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"),