From b6f6a1ca110dc40074c63a30e86351aa4e9ddf71 Mon Sep 17 00:00:00 2001 From: Henry Rawas Date: Wed, 6 Jul 2011 13:34:04 -0700 Subject: [PATCH] ipv6 node --- lib/net_uv.js | 31 ++++++++++----------- src/tcp_wrap.cc | 46 ++++++++++++++++++++++++++++++++ test/simple/test-net-pingpong.js | 4 +-- 3 files changed, 64 insertions(+), 17 deletions(-) diff --git a/lib/net_uv.js b/lib/net_uv.js index d1f418c287..039ff70b57 100644 --- a/lib/net_uv.js +++ b/lib/net_uv.js @@ -321,7 +321,7 @@ function afterWrite(status, handle, req, buffer) { } -function connectip(self, port, ip) { +function connectip(self, port, ip, addressType) { self.remoteAddress = ip; self.remotePort = port; @@ -330,7 +330,11 @@ function connectip(self, port, ip) { assert.ok(self._connecting); - var connectReq = self._handle.connect(ip, port); + if (addressType == 6) { + var connectReq = self._handle.connect6(ip, port); + } else { + var connectReq = self._handle.connect(ip, port); + } if (connectReq) { connectReq.oncomplete = afterConnect; @@ -370,16 +374,12 @@ Socket.prototype.connect = function(port /* [host], [cb] */) { } else { timers.active(self); - if (addressType != 4) { - throw new Error("ipv6 addresses not yet supported by libuv"); - } - - connectip(self, port, ip || '127.0.0.1'); + connectip(self, port, ip || '127.0.0.1', ip ? addressType : 4); } }); } else { debug("connect: missing host"); - connectip(self, port, '127.0.0.1'); + connectip(self, port, '127.0.0.1', 4); } }; @@ -462,12 +462,16 @@ exports.Server = Server; function toPort(x) { return (x = Number(x)) >= 0 ? x : false; } -function listenip(self, ip, port) { +function listenip(self, ip, port, addressType) { var r = 0; if (ip && port) { debug("bind to " + ip); - r = self._handle.bind(ip, port); + if (addressType == 6) { + r = self._handle.bind6(ip, port); + } else { + r = self._handle.bind(ip, port); + } } if (r) { @@ -498,7 +502,7 @@ Server.prototype.listen = function() { } else if (typeof arguments[1] == 'undefined' || typeof arguments[1] == 'function') { // The first argument is the port, no IP given. - listenip(self, '0.0.0.0', port); + listenip(self, '0.0.0.0', port, 4); } else { // The first argument is the port, the second an IP @@ -506,10 +510,7 @@ Server.prototype.listen = function() { if (err) { self.emit('error', err); } else { - if (addressType != 4) { - throw new Error("ipv6 addresses not yet supported by libuv"); - } - listenip(self, ip || '0.0.0.0', port); + listenip(self, ip || '0.0.0.0', port, ip ? addressType : 4); } }); } diff --git a/src/tcp_wrap.cc b/src/tcp_wrap.cc index 2258e53fb6..125b880cf4 100644 --- a/src/tcp_wrap.cc +++ b/src/tcp_wrap.cc @@ -99,6 +99,8 @@ class TCPWrap { NODE_SET_PROTOTYPE_METHOD(t, "connect", Connect); NODE_SET_PROTOTYPE_METHOD(t, "shutdown", Shutdown); NODE_SET_PROTOTYPE_METHOD(t, "close", Close); + NODE_SET_PROTOTYPE_METHOD(t, "bind6", Bind6); + NODE_SET_PROTOTYPE_METHOD(t, "connect6", Connect6); constructor = Persistent::New(t->GetFunction()); @@ -168,6 +170,23 @@ class TCPWrap { return scope.Close(Integer::New(r)); } + static Handle Bind6(const Arguments& args) { + HandleScope scope; + + UNWRAP + + String::AsciiValue ip6_address(args[0]->ToString()); + int port = args[1]->Int32Value(); + + struct sockaddr_in6 address = uv_ip6_addr(*ip6_address, port); + int r = uv_tcp_bind6(&wrap->handle_, address); + + // Error starting the tcp. + if (r) SetErrno(uv_last_error().code); + + return scope.Close(Integer::New(r)); + } + static Handle Listen(const Arguments& args) { HandleScope scope; @@ -462,6 +481,33 @@ class TCPWrap { } } + static Handle Connect6(const Arguments& args) { + HandleScope scope; + + UNWRAP + + String::AsciiValue ip_address(args[0]->ToString()); + int port = args[1]->Int32Value(); + + struct sockaddr_in6 address = uv_ip6_addr(*ip_address, port); + + // I hate when people program C++ like it was C, and yet I do it too. + // I'm too lazy to come up with the perfect class hierarchy here. Let's + // just do some type munging. + ReqWrap* req_wrap = new ReqWrap((uv_handle_t*) &wrap->handle_, + (void*)AfterConnect); + + int r = uv_tcp_connect6(&req_wrap->req_, address); + + if (r) { + SetErrno(uv_last_error().code); + delete req_wrap; + return scope.Close(v8::Null()); + } else { + return scope.Close(req_wrap->object_); + } + } + static void AfterShutdown(uv_req_t* req, int status) { ReqWrap* req_wrap = (ReqWrap*) req->data; TCPWrap* wrap = (TCPWrap*) req->handle->data; diff --git a/test/simple/test-net-pingpong.js b/test/simple/test-net-pingpong.js index 6db4861d8e..98136df33d 100644 --- a/test/simple/test-net-pingpong.js +++ b/test/simple/test-net-pingpong.js @@ -131,17 +131,17 @@ function pingPongTest(port, host) { /* All are run at once, so run on different ports */ if (!process.useUV) { // these tests will not run yet with net_uv TODO: remove when net_uv supports dns - pingPongTest(20997, '::1'); pingPongTest('/tmp/pingpong.sock'); } pingPongTest(20988); pingPongTest(20989, 'localhost'); +pingPongTest(20997, '::1'); process.addListener('exit', function () { if (!process.useUV) { assert.equal(4, tests_run); } else { - assert.equal(2, tests_run); + assert.equal(3, tests_run); } console.log('done'); });