From ca5022b8f10c95d834678108adcd12f1c907016e Mon Sep 17 00:00:00 2001 From: Ben Noordhuis Date: Thu, 14 Mar 2013 15:13:58 +0100 Subject: [PATCH] net: improve arbitrary tcp socket support Consider this example: // fd 3 is a bound tcp socket var s = net.createServer(cb); s.listen({ fd: 3 }); console.log(s.address()); // prints null This commit makes net.Server#address() print the actual address. Ditto for non-listen sockets; properties like net.Socket#localAddress and net.Socket#remoteAddress now return the correct value. Fixes #5009. --- lib/net.js | 41 +++++++++++++++++++++-------------------- src/tcp_wrap.cc | 10 ++++++++++ 2 files changed, 31 insertions(+), 20 deletions(-) diff --git a/lib/net.js b/lib/net.js index c58af2a5667..6174b40eac5 100644 --- a/lib/net.js +++ b/lib/net.js @@ -42,6 +42,15 @@ function createTCP() { } +function createHandle(fd) { + var tty = process.binding('tty_wrap'); + var type = tty.guessHandleType(fd); + if (type === 'PIPE') return createPipe(); + if (type === 'TCP') return createTCP(); + throw new TypeError('Unsupported fd type: ' + type); +} + + var debug; if (process.env.NODE_DEBUG && /net/.test(process.env.NODE_DEBUG)) { var pid = process.pid; @@ -144,7 +153,7 @@ function Socket(options) { if (options.handle) { this._handle = options.handle; // private } else if (typeof options.fd !== 'undefined') { - this._handle = createPipe(); + this._handle = createHandle(options.fd); this._handle.open(options.fd); this.readable = options.readable !== false; this.writable = options.writable !== false; @@ -930,26 +939,18 @@ var createServerHandle = exports._createServerHandle = var handle; if (typeof fd === 'number' && fd >= 0) { - var tty_wrap = process.binding('tty_wrap'); - var type = tty_wrap.guessHandleType(fd); - switch (type) { - case 'PIPE': - case 'TCP': - debug('listen pipe fd=' + fd); - // create a PipeWrap - handle = createPipe(); - handle.open(fd); - handle.readable = true; - handle.writable = true; - break; - - default: - // Not a fd we can listen on. This will trigger an error. - debug('listen invalid fd=' + fd + ' type=' + type); - process._errno = 'EINVAL'; // hack, callers expect that errno is set - handle = null; - break; + try { + handle = createHandle(fd); } + catch (e) { + // Not a fd we can listen on. This will trigger an error. + debug('listen invalid fd=' + fd + ': ' + e.message); + process._errno = 'EINVAL'; // hack, callers expect that errno is set + return null; + } + handle.open(fd); + handle.readable = true; + handle.writable = true; return handle; } else if (port == -1 && addressType == -1) { diff --git a/src/tcp_wrap.cc b/src/tcp_wrap.cc index 4c55f2eff50..b48f8acd701 100644 --- a/src/tcp_wrap.cc +++ b/src/tcp_wrap.cc @@ -104,6 +104,7 @@ void TCPWrap::Initialize(Handle target) { NODE_SET_PROTOTYPE_METHOD(t, "writeUtf8String", StreamWrap::WriteUtf8String); NODE_SET_PROTOTYPE_METHOD(t, "writeUcs2String", StreamWrap::WriteUcs2String); + NODE_SET_PROTOTYPE_METHOD(t, "open", Open); NODE_SET_PROTOTYPE_METHOD(t, "bind", Bind); NODE_SET_PROTOTYPE_METHOD(t, "listen", Listen); NODE_SET_PROTOTYPE_METHOD(t, "connect", Connect); @@ -256,6 +257,15 @@ Handle TCPWrap::SetSimultaneousAccepts(const Arguments& args) { #endif +Handle TCPWrap::Open(const Arguments& args) { + HandleScope scope; + UNWRAP(TCPWrap) + int fd = args[0]->IntegerValue(); + uv_tcp_open(&wrap->handle_, fd); + return Null(); +} + + Handle TCPWrap::Bind(const Arguments& args) { HandleScope scope;