}
-function connectip(self, port, ip) {
+function connectip(self, port, ip, addressType) {
self.remoteAddress = ip;
self.remotePort = port;
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;
} 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);
}
};
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) {
} 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
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);
}
});
}
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<Function>::New(t->GetFunction());
return scope.Close(Integer::New(r));
}
+ static Handle<Value> 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<Value> Listen(const Arguments& args) {
HandleScope scope;
}
}
+ static Handle<Value> 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;
/* 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');
});