Skip to content

HTTPS clone URL

Subversion checkout URL

You can clone with HTTPS or Subversion.

Download ZIP

Loading…

expose ares_get_servers in cares_wrap #3132

Closed
wants to merge 1 commit into from

2 participants

@tjfontaine
Owner

This exposes ares_get_servers as cares_wrap.getServers which passes to a callback an array of IPs that ares is currently using for resolution.

It's callback based with an eye towards #3018 where ares would be initialized on the thread pool during platform initialization only to retrieve relevant platform information and then be immediately disposed.

@bnoordhuis bnoordhuis commented on the diff
src/cares_wrap.cc
((17 lines not shown))
+ assert(r == ARES_SUCCESS);
+
+ cur = servers;
+ i = 0;
+
+ while (cur != NULL) {
+ uv_inet_ntop(cur->family, (const void *) &cur->addr, ip, sizeof(ip));
+
+ Local<String> addr = String::New(ip);
+ server_array->Set(Integer::New(i), addr);
+
+ i++;
+ cur = cur->next;
+ }
+
+ callback->Call(Context::GetCurrent()->Global(), 1, argv);

If it's a synchronous function, you don't have to make a callback, just return the result. Callbacks are supposed to run on the next tick of the event loop anyway.

@tjfontaine Owner

Right, but if/when the pure js dns implementation happens, then ares would only be initialized (on the thread pool) when needing to get this information and then disposed. So I designed it this way so I could use it in the module now and not change the consuming code if/when #3018 is merged.

Okay, fair enough. Can you add a JS shim that defers the callback to the next tick?

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
@tjfontaine tjfontaine closed this
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Commits on Apr 18, 2012
  1. @tjfontaine
This page is out of date. Refresh to see the latest.
Showing with 39 additions and 0 deletions.
  1. +35 −0 src/cares_wrap.cc
  2. +4 −0 test/simple/test-c-ares.js
View
35 src/cares_wrap.cc
@@ -65,6 +65,7 @@ using v8::Object;
using v8::Persistent;
using v8::String;
using v8::Value;
+using v8::Undefined;
typedef class ReqWrap<uv_getaddrinfo_t> GetAddrInfoReqWrap;
@@ -727,6 +728,39 @@ static Handle<Value> GetAddrInfo(const Arguments& args) {
}
}
+static Handle<Value> GetServers(const Arguments &args) {
+ HandleScope scope;
+ int r, i;
+ struct ares_addr_node *servers = NULL, *cur = NULL;
+ char ip[INET6_ADDRSTRLEN];
+
+ Local<Array> server_array = Array::New();
+ Local<Function> callback = Local<Function>::Cast(args[0]);
+ Local<Value> argv[1];
+
+ argv[0] = server_array;
+
+ r = ares_get_servers(ares_channel, &servers);
+ assert(r == ARES_SUCCESS);
+
+ cur = servers;
+ i = 0;
+
+ while (cur != NULL) {
+ uv_inet_ntop(cur->family, (const void *) &cur->addr, ip, sizeof(ip));
+
+ Local<String> addr = String::New(ip);
+ server_array->Set(Integer::New(i), addr);
+
+ i++;
+ cur = cur->next;
+ }
+
+ callback->Call(Context::GetCurrent()->Global(), 1, argv);

If it's a synchronous function, you don't have to make a callback, just return the result. Callbacks are supposed to run on the next tick of the event loop anyway.

@tjfontaine Owner

Right, but if/when the pure js dns implementation happens, then ares would only be initialized (on the thread pool) when needing to get this information and then disposed. So I designed it this way so I could use it in the module now and not change the consuming code if/when #3018 is merged.

Okay, fair enough. Can you add a JS shim that defers the callback to the next tick?

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
+
+ ares_free_data(servers);
+ return Undefined();
+}
static void Initialize(Handle<Object> target) {
HandleScope scope;
@@ -750,6 +784,7 @@ static void Initialize(Handle<Object> target) {
NODE_SET_METHOD(target, "getHostByName", QueryWithFamily<GetHostByNameWrap>);
NODE_SET_METHOD(target, "getaddrinfo", GetAddrInfo);
+ NODE_SET_METHOD(target, "getServers", GetServers);
target->Set(String::NewSymbol("AF_INET"), Integer::New(AF_INET));
target->Set(String::NewSymbol("AF_INET6"), Integer::New(AF_INET6));
View
4 test/simple/test-c-ares.js
@@ -51,3 +51,7 @@ if (process.platform != 'win32') {
assert.ok(Array.isArray(domains));
});
}
+
+process.binding('cares_wrap').getServers(function(servers) {
+ assert.ok(Array.isArray(servers));
+});
Something went wrong with that request. Please try again.