Skip to content
This repository has been archived by the owner on Apr 22, 2023. It is now read-only.

Commit

Permalink
Browse files Browse the repository at this point in the history
Add binding to uv_getaddrinfo
  • Loading branch information
ry committed Oct 20, 2011
1 parent 95d530f commit be2320d
Show file tree
Hide file tree
Showing 2 changed files with 130 additions and 8 deletions.
106 changes: 106 additions & 0 deletions src/cares_wrap.cc
Expand Up @@ -21,8 +21,11 @@

#include <assert.h>
#include <node.h>
#include <req_wrap.h>
#include <uv.h>

#include <string.h>

#if defined(__OpenBSD__) || defined(__MINGW32__) || defined(_MSC_VER)
# include <nameser.h>
#else
Expand Down Expand Up @@ -63,6 +66,9 @@ using v8::Persistent;
using v8::String;
using v8::Value;


typedef class ReqWrap<uv_getaddrinfo_t> GetAddrInfoReqWrap;

static Persistent<String> oncomplete_sym;

static ares_channel ares_channel;
Expand Down Expand Up @@ -592,6 +598,104 @@ static Handle<Value> QueryWithFamily(const Arguments& args) {
}


void AfterGetAddrInfo(uv_getaddrinfo_t* req, int status, struct addrinfo* res) {
HandleScope scope;

GetAddrInfoReqWrap* req_wrap = (GetAddrInfoReqWrap*) req->data;

Local<Value> argv[1];

if (status) {
// Error
SetErrno(uv_last_error(uv_default_loop()));
argv[0] = Local<Value>::New(Null());
} else {
// Success
struct addrinfo *address;
int n = 0;

// Count the number of responses.
for (address = res; address; address = address->ai_next) {
n++;
}

// Create the response array.
Local<Array> results = Array::New(n);

char ip[INET6_ADDRSTRLEN];
const char *addr;

n = 0;

// Iterate over the responses again this time creating javascript
// strings for each IP and filling the results array.
address = res;
while (address) {
assert(address->ai_socktype == SOCK_STREAM);
assert(address->ai_family == AF_INET || address->ai_family == AF_INET6);

// Juggle pointers
addr = (address->ai_family == AF_INET ?
(char*) &((struct sockaddr_in*) address->ai_addr)->sin_addr :
(char*) &((struct sockaddr_in6*) address->ai_addr)->sin6_addr);
const char* c = inet_ntop(address->ai_family, addr, ip, INET6_ADDRSTRLEN);

// Create JavaScript string
Local<String> s = String::New(c);
results->Set(n, s);

// Increment
n++;
address = address->ai_next;
}

argv[0] = results;
}

uv_freeaddrinfo(res);

// Make the callback into JavaScript
MakeCallback(req_wrap->object_, "oncomplete", 1, argv);

delete req_wrap;
}


static Handle<Value> GetAddrInfo(const Arguments& args) {
HandleScope scope;

String::Utf8Value hostname(args[0]->ToString());

int fam = AF_INET;
if (args[1]->IsInt32() && args[1]->Int32Value() == 6) {
fam = AF_INET6;
}

GetAddrInfoReqWrap* req_wrap = new GetAddrInfoReqWrap();

struct addrinfo hints;
memset(&hints, 0, sizeof(struct addrinfo));
hints.ai_family = fam;
hints.ai_socktype = SOCK_STREAM;

int r = uv_getaddrinfo(uv_default_loop(),
&req_wrap->req_,
AfterGetAddrInfo,
*hostname,
NULL,
&hints);
req_wrap->Dispatched();

if (r) {
SetErrno(uv_last_error(uv_default_loop()));
delete req_wrap;
return scope.Close(v8::Null());
} else {
return scope.Close(req_wrap->object_);
}
}


static void Initialize(Handle<Object> target) {
HandleScope scope;
int r;
Expand All @@ -613,6 +717,8 @@ static void Initialize(Handle<Object> target) {
NODE_SET_METHOD(target, "getHostByAddr", Query<GetHostByAddrWrap>);
NODE_SET_METHOD(target, "getHostByName", QueryWithFamily<GetHostByNameWrap>);

NODE_SET_METHOD(target, "getaddrinfo", GetAddrInfo);

target->Set(String::NewSymbol("AF_INET"), Integer::New(AF_INET));
target->Set(String::NewSymbol("AF_INET6"), Integer::New(AF_INET6));
target->Set(String::NewSymbol("AF_UNSPEC"), Integer::New(AF_UNSPEC));
Expand Down
32 changes: 24 additions & 8 deletions test/internet/test-dns.js
Expand Up @@ -21,7 +21,7 @@

var assert = require('assert'),
dns = require('dns'),
net = require('net_uv'),
net = require('net'),
isIP = net.isIP,
isIPv4 = net.isIPv4,
isIPv6 = net.isIPv6;
Expand Down Expand Up @@ -57,13 +57,6 @@ function TEST(f) {
}


process.on('exit', function() {
console.log(completed + ' tests completed');
assert.equal(running, false);
assert.strictEqual(expected, completed);
});


function checkWrap(req) {
assert.ok(typeof req === 'object');
}
Expand Down Expand Up @@ -386,3 +379,26 @@ TEST(function test_lookup_localhost_ipv4(done) {
checkWrap(req);
}); */


var getaddrinfoCallbackCalled = false;

console.log("looking up nodejs.org...");
var req = process.binding('cares_wrap').getaddrinfo('nodejs.org');

req.oncomplete = function(domains) {
console.log("nodejs.org = ", domains);
assert.ok(Array.isArray(domains));
assert.ok(domains.length >= 1);
assert.ok(typeof domains[0] == 'string');
getaddrinfoCallbackCalled = true;
};



process.on('exit', function() {
console.log(completed + ' tests completed');
assert.equal(running, false);
assert.strictEqual(expected, completed);
assert.ok(getaddrinfoCallbackCalled);
});

0 comments on commit be2320d

Please sign in to comment.