Use AF_INET sockets instead of always AF_INET6
You can get AF_INET6 still, it's just not the only choice.
This commit is contained in:
parent
fdae14070c
commit
b9106b0ecd
69
lib/net.js
69
lib/net.js
@ -39,7 +39,7 @@ var setNoDelay = binding.setNoDelay;
|
|||||||
var socketError = binding.socketError;
|
var socketError = binding.socketError;
|
||||||
var getsockname = binding.getsockname;
|
var getsockname = binding.getsockname;
|
||||||
var getaddrinfo = binding.getaddrinfo;
|
var getaddrinfo = binding.getaddrinfo;
|
||||||
var needsLookup = binding.needsLookup;
|
var isIP = binding.isIP;
|
||||||
var errnoException = binding.errnoException;
|
var errnoException = binding.errnoException;
|
||||||
var EINPROGRESS = binding.EINPROGRESS;
|
var EINPROGRESS = binding.EINPROGRESS;
|
||||||
var ENOENT = binding.ENOENT;
|
var ENOENT = binding.ENOENT;
|
||||||
@ -422,6 +422,7 @@ Stream.prototype.write = function (data, encoding) {
|
|||||||
Stream.prototype._writeOut = function (data, encoding) {
|
Stream.prototype._writeOut = function (data, encoding) {
|
||||||
if (!this.writable) throw new Error('Stream is not writable');
|
if (!this.writable) throw new Error('Stream is not writable');
|
||||||
|
|
||||||
|
if (data.length == 0) return true;
|
||||||
|
|
||||||
var buffer, off, len;
|
var buffer, off, len;
|
||||||
var bytesWritten, charsWritten;
|
var bytesWritten, charsWritten;
|
||||||
@ -566,6 +567,8 @@ function doConnect (socket, port, host) {
|
|||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
debug('connecting to ' + host + ' : ' + port);
|
||||||
|
|
||||||
// Don't start the read watcher until connection is established
|
// Don't start the read watcher until connection is established
|
||||||
socket._readWatcher.set(socket.fd, true, false);
|
socket._readWatcher.set(socket.fd, true, false);
|
||||||
|
|
||||||
@ -607,13 +610,13 @@ Stream.prototype.connect = function () {
|
|||||||
var port = parseInt(arguments[0]);
|
var port = parseInt(arguments[0]);
|
||||||
|
|
||||||
if (port >= 0) {
|
if (port >= 0) {
|
||||||
self.fd = socket('tcp');
|
|
||||||
//debug('new fd = ' + self.fd);
|
//debug('new fd = ' + self.fd);
|
||||||
self.type = 'tcp';
|
|
||||||
// TODO dns resolution on arguments[1]
|
// TODO dns resolution on arguments[1]
|
||||||
var port = arguments[0];
|
var port = arguments[0];
|
||||||
self._resolving = true;
|
self._resolving = true;
|
||||||
lookupDomainName(arguments[1], function (ip) {
|
lookupDomainName(arguments[1], function (ip, isV4) {
|
||||||
|
self.type = isV4 ? 'tcp4' : 'tcp6';
|
||||||
|
self.fd = socket(self.type);
|
||||||
self._resolving = false;
|
self._resolving = false;
|
||||||
doConnect(self, port, ip);
|
doConnect(self, port, ip);
|
||||||
});
|
});
|
||||||
@ -729,8 +732,8 @@ function Server (listener) {
|
|||||||
if (!peerInfo) return;
|
if (!peerInfo) return;
|
||||||
|
|
||||||
var s = new Stream(peerInfo.fd);
|
var s = new Stream(peerInfo.fd);
|
||||||
s.remoteAddress = peerInfo.remoteAddress;
|
s.remoteAddress = peerInfo.address;
|
||||||
s.remotePort = peerInfo.remotePort;
|
s.remotePort = peerInfo.port;
|
||||||
s.type = self.type;
|
s.type = self.type;
|
||||||
s.server = self;
|
s.server = self;
|
||||||
s.resume();
|
s.resume();
|
||||||
@ -750,25 +753,27 @@ exports.createServer = function (listener) {
|
|||||||
return new Server(listener);
|
return new Server(listener);
|
||||||
};
|
};
|
||||||
|
|
||||||
/* This function does both an ipv4 and ipv6 look up.
|
// This function does both an ipv4 and ipv6 look up.
|
||||||
* It first tries the ipv4 look up, if that fails, then it does the ipv6.
|
// It first tries the ipv4 look up, if that fails, then it does the ipv6.
|
||||||
*/
|
// callback(dn, isV4
|
||||||
function lookupDomainName (dn, callback) {
|
function lookupDomainName (dn, callback) {
|
||||||
if (!needsLookup(dn)) {
|
var kind = isIP(dn);
|
||||||
|
debug('kind = ' + kind);
|
||||||
|
if (kind) {
|
||||||
// Always wait until the next tick this is so people can do
|
// Always wait until the next tick this is so people can do
|
||||||
//
|
//
|
||||||
// server.listen(8000);
|
// server.listen(8000);
|
||||||
// server.addListener('listening', fn);
|
// server.addListener('listening', fn);
|
||||||
//
|
//
|
||||||
// Marginally slower, but a lot fewer WTFs.
|
// Marginally slower, but a lot fewer WTFs.
|
||||||
process.nextTick(function () { callback(dn); })
|
process.nextTick(function () { callback(dn, kind == 4 ? true : false); })
|
||||||
} else {
|
} else {
|
||||||
debug("getaddrinfo 4 " + dn);
|
debug("getaddrinfo 4 " + dn);
|
||||||
getaddrinfo(dn, 4, function (r4) {
|
getaddrinfo(dn, 4, function (r4) {
|
||||||
if (r4 instanceof Error) throw r4;
|
if (r4 instanceof Error) throw r4;
|
||||||
if (r4.length > 0) {
|
if (r4.length > 0) {
|
||||||
debug("getaddrinfo 4 found " + r4);
|
debug("getaddrinfo 4 found " + r4);
|
||||||
callback(r4[0]);
|
callback(r4[0], true);
|
||||||
} else {
|
} else {
|
||||||
debug("getaddrinfo 6 " + dn);
|
debug("getaddrinfo 6 " + dn);
|
||||||
getaddrinfo(dn, 6, function (r6) {
|
getaddrinfo(dn, 6, function (r6) {
|
||||||
@ -777,7 +782,7 @@ function lookupDomainName (dn, callback) {
|
|||||||
throw new Error("No address associated with hostname " + dn);
|
throw new Error("No address associated with hostname " + dn);
|
||||||
}
|
}
|
||||||
debug("getaddrinfo 6 found " + r6);
|
debug("getaddrinfo 6 found " + r6);
|
||||||
callback(r6[0]);
|
callback(r6[0], false);
|
||||||
});
|
});
|
||||||
}
|
}
|
||||||
});
|
});
|
||||||
@ -797,13 +802,6 @@ Server.prototype.listen = function () {
|
|||||||
var self = this;
|
var self = this;
|
||||||
if (self.fd) throw new Error('Server already opened');
|
if (self.fd) throw new Error('Server already opened');
|
||||||
|
|
||||||
function doListen () {
|
|
||||||
listen(self.fd, 128);
|
|
||||||
self.watcher.set(self.fd, true, false);
|
|
||||||
self.watcher.start();
|
|
||||||
self.emit("listening");
|
|
||||||
}
|
|
||||||
|
|
||||||
if (typeof(arguments[0]) == 'string') {
|
if (typeof(arguments[0]) == 'string') {
|
||||||
// the first argument specifies a path
|
// the first argument specifies a path
|
||||||
self.fd = socket('unix');
|
self.fd = socket('unix');
|
||||||
@ -815,7 +813,7 @@ Server.prototype.listen = function () {
|
|||||||
if (err) {
|
if (err) {
|
||||||
if (err.errno == ENOENT) {
|
if (err.errno == ENOENT) {
|
||||||
bind(self.fd, path);
|
bind(self.fd, path);
|
||||||
doListen();
|
self._doListen();
|
||||||
} else {
|
} else {
|
||||||
throw r;
|
throw r;
|
||||||
}
|
}
|
||||||
@ -828,30 +826,41 @@ Server.prototype.listen = function () {
|
|||||||
throw err;
|
throw err;
|
||||||
} else {
|
} else {
|
||||||
bind(self.fd, path);
|
bind(self.fd, path);
|
||||||
doListen();
|
self._doListen();
|
||||||
}
|
}
|
||||||
});
|
});
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
});
|
});
|
||||||
} else if (!arguments[0]) {
|
} else if (!arguments[1]) {
|
||||||
// Don't bind(). OS will assign a port with INADDR_ANY.
|
// Don't bind(). OS will assign a port with INADDR_ANY.
|
||||||
// The port can be found with server.address()
|
// The port can be found with server.address()
|
||||||
self.fd = socket('tcp');
|
self.type = 'tcp4';
|
||||||
self.type = 'tcp';
|
self.fd = socket(self.type);
|
||||||
doListen();
|
bind(self.fd, arguments[0]);
|
||||||
|
process.nextTick(function () {
|
||||||
|
self._doListen();
|
||||||
|
});
|
||||||
} else {
|
} else {
|
||||||
// the first argument is the port, the second an IP
|
// the first argument is the port, the second an IP
|
||||||
self.fd = socket('tcp');
|
|
||||||
self.type = 'tcp';
|
|
||||||
var port = arguments[0];
|
var port = arguments[0];
|
||||||
lookupDomainName(arguments[1], function (ip) {
|
lookupDomainName(arguments[1], function (ip, isV4) {
|
||||||
|
self.type = isV4 ? 'tcp4' : 'tcp6';
|
||||||
|
self.fd = socket(self.type);
|
||||||
bind(self.fd, port, ip);
|
bind(self.fd, port, ip);
|
||||||
doListen();
|
self._doListen();
|
||||||
});
|
});
|
||||||
}
|
}
|
||||||
};
|
};
|
||||||
|
|
||||||
|
Server.prototype._doListen = function () {
|
||||||
|
listen(this.fd, 128);
|
||||||
|
this.watcher.set(this.fd, true, false);
|
||||||
|
this.watcher.start();
|
||||||
|
this.emit("listening");
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
Server.prototype.address = function () {
|
Server.prototype.address = function () {
|
||||||
return getsockname(this.fd);
|
return getsockname(this.fd);
|
||||||
|
163
src/node_net2.cc
163
src/node_net2.cc
@ -38,8 +38,6 @@ static Persistent<String> errno_symbol;
|
|||||||
static Persistent<String> syscall_symbol;
|
static Persistent<String> syscall_symbol;
|
||||||
|
|
||||||
static Persistent<String> fd_symbol;
|
static Persistent<String> fd_symbol;
|
||||||
static Persistent<String> remote_address_symbol;
|
|
||||||
static Persistent<String> remote_port_symbol;
|
|
||||||
static Persistent<String> address_symbol;
|
static Persistent<String> address_symbol;
|
||||||
static Persistent<String> port_symbol;
|
static Persistent<String> port_symbol;
|
||||||
static Persistent<String> type_symbol;
|
static Persistent<String> type_symbol;
|
||||||
@ -467,20 +465,27 @@ static Handle<Value> Socket(const Arguments& args) {
|
|||||||
HandleScope scope;
|
HandleScope scope;
|
||||||
|
|
||||||
// default to TCP
|
// default to TCP
|
||||||
int domain = PF_INET6;
|
int domain = PF_INET;
|
||||||
int type = SOCK_STREAM;
|
int type = SOCK_STREAM;
|
||||||
|
|
||||||
if (args[0]->IsString()) {
|
if (args[0]->IsString()) {
|
||||||
String::Utf8Value t(args[0]->ToString());
|
String::Utf8Value t(args[0]->ToString());
|
||||||
|
// FIXME optimize this cascade.
|
||||||
if (0 == strcasecmp(*t, "TCP")) {
|
if (0 == strcasecmp(*t, "TCP")) {
|
||||||
|
domain = PF_INET;
|
||||||
|
type = SOCK_STREAM;
|
||||||
|
} else if (0 == strcasecmp(*t, "TCP4")) {
|
||||||
|
domain = PF_INET;
|
||||||
|
type = SOCK_STREAM;
|
||||||
|
} else if (0 == strcasecmp(*t, "TCP6")) {
|
||||||
domain = PF_INET6;
|
domain = PF_INET6;
|
||||||
type = SOCK_STREAM;
|
type = SOCK_STREAM;
|
||||||
|
} else if (0 == strcasecmp(*t, "UNIX")) {
|
||||||
|
domain = PF_UNIX;
|
||||||
|
type = SOCK_STREAM;
|
||||||
} else if (0 == strcasecmp(*t, "UDP")) {
|
} else if (0 == strcasecmp(*t, "UDP")) {
|
||||||
domain = PF_INET6;
|
domain = PF_INET6;
|
||||||
type = SOCK_DGRAM;
|
type = SOCK_DGRAM;
|
||||||
} else if (0 == strcasecmp(*t, "UNIX")) {
|
|
||||||
domain = PF_UNIX;
|
|
||||||
type = SOCK_STREAM;
|
|
||||||
} else {
|
} else {
|
||||||
return ThrowException(Exception::Error(
|
return ThrowException(Exception::Error(
|
||||||
String::New("Unknown socket type.")));
|
String::New("Unknown socket type.")));
|
||||||
@ -505,13 +510,14 @@ static Handle<Value> Socket(const Arguments& args) {
|
|||||||
// (yes this is all to avoid one small heap alloc)
|
// (yes this is all to avoid one small heap alloc)
|
||||||
static struct sockaddr *addr;
|
static struct sockaddr *addr;
|
||||||
static socklen_t addrlen;
|
static socklen_t addrlen;
|
||||||
static struct sockaddr_un un;
|
|
||||||
static struct sockaddr_in6 in6;
|
|
||||||
static inline Handle<Value> ParseAddressArgs(Handle<Value> first,
|
static inline Handle<Value> ParseAddressArgs(Handle<Value> first,
|
||||||
Handle<Value> second,
|
Handle<Value> second,
|
||||||
struct in6_addr default_addr
|
bool is_bind) {
|
||||||
) {
|
static struct sockaddr_un un;
|
||||||
if (first->IsString() && second->IsUndefined()) {
|
static struct sockaddr_in in;
|
||||||
|
static struct sockaddr_in6 in6;
|
||||||
|
|
||||||
|
if (first->IsString() && !second->IsString()) {
|
||||||
// UNIX
|
// UNIX
|
||||||
String::Utf8Value path(first->ToString());
|
String::Utf8Value path(first->ToString());
|
||||||
|
|
||||||
@ -528,36 +534,32 @@ static inline Handle<Value> ParseAddressArgs(Handle<Value> first,
|
|||||||
|
|
||||||
} else {
|
} else {
|
||||||
// TCP or UDP
|
// TCP or UDP
|
||||||
int port = first->Int32Value();
|
memset(&in, 0, sizeof in);
|
||||||
memset(&in6, 0, sizeof in6);
|
memset(&in6, 0, sizeof in6);
|
||||||
|
|
||||||
|
int port = first->Int32Value();
|
||||||
|
in.sin_port = in6.sin6_port = htons(port);
|
||||||
|
in.sin_family = AF_INET;
|
||||||
|
in6.sin6_family = AF_INET6;
|
||||||
|
|
||||||
|
bool is_ipv4 = true;
|
||||||
|
|
||||||
if (!second->IsString()) {
|
if (!second->IsString()) {
|
||||||
in6.sin6_addr = default_addr;
|
in.sin_addr.s_addr = htonl(is_bind ? INADDR_ANY : INADDR_LOOPBACK);
|
||||||
|
in6.sin6_addr = is_bind ? in6addr_any : in6addr_loopback;
|
||||||
} else {
|
} else {
|
||||||
String::Utf8Value ip(second->ToString());
|
String::Utf8Value ip(second->ToString());
|
||||||
|
|
||||||
char ipv6[255] = "::FFFF:";
|
if (inet_pton(AF_INET, *ip, &(in.sin_addr)) <= 0) {
|
||||||
|
is_ipv4 = false;
|
||||||
if (inet_pton(AF_INET, *ip, &(in6.sin6_addr)) > 0) {
|
if (inet_pton(AF_INET6, *ip, &(in6.sin6_addr)) <= 0) {
|
||||||
// If this is an IPv4 address then we need to change it
|
return ErrnoException(errno, "inet_pton", "Invalid IP Address");
|
||||||
// to the IPv4-mapped-on-IPv6 format which looks like
|
}
|
||||||
// ::FFFF:<IPv4 address>
|
|
||||||
// For more information see "Address Format" ipv6(7) and
|
|
||||||
// "BUGS" in inet_pton(3)
|
|
||||||
strcat(ipv6, *ip);
|
|
||||||
} else {
|
|
||||||
strcpy(ipv6, *ip);
|
|
||||||
}
|
|
||||||
|
|
||||||
if (inet_pton(AF_INET6, ipv6, &(in6.sin6_addr)) <= 0) {
|
|
||||||
return ErrnoException(errno, "inet_pton", "Invalid IP Address");
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
in6.sin6_family = AF_INET6;
|
addr = is_ipv4 ? (struct sockaddr*)&in : (struct sockaddr*)&in6;
|
||||||
in6.sin6_port = htons(port);
|
addrlen = is_ipv4 ? sizeof in : sizeof in6;
|
||||||
|
|
||||||
addr = (struct sockaddr*)&in6;
|
|
||||||
addrlen = sizeof in6;
|
|
||||||
}
|
}
|
||||||
return Handle<Value>();
|
return Handle<Value>();
|
||||||
}
|
}
|
||||||
@ -578,7 +580,7 @@ static Handle<Value> Bind(const Arguments& args) {
|
|||||||
|
|
||||||
FD_ARG(args[0])
|
FD_ARG(args[0])
|
||||||
|
|
||||||
Handle<Value> error = ParseAddressArgs(args[1], args[2], in6addr_any);
|
Handle<Value> error = ParseAddressArgs(args[1], args[2], true);
|
||||||
if (!error.IsEmpty()) return ThrowException(error);
|
if (!error.IsEmpty()) return ThrowException(error);
|
||||||
|
|
||||||
int flags = 1;
|
int flags = 1;
|
||||||
@ -658,7 +660,7 @@ static Handle<Value> Connect(const Arguments& args) {
|
|||||||
|
|
||||||
FD_ARG(args[0])
|
FD_ARG(args[0])
|
||||||
|
|
||||||
Handle<Value> error = ParseAddressArgs(args[1], args[2], in6addr_loopback);
|
Handle<Value> error = ParseAddressArgs(args[1], args[2], false);
|
||||||
if (!error.IsEmpty()) return ThrowException(error);
|
if (!error.IsEmpty()) return ThrowException(error);
|
||||||
|
|
||||||
int r = connect(fd, addr, addrlen);
|
int r = connect(fd, addr, addrlen);
|
||||||
@ -671,6 +673,31 @@ static Handle<Value> Connect(const Arguments& args) {
|
|||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
|
#define ADDRESS_TO_JS(info, address_storage) \
|
||||||
|
do { \
|
||||||
|
char ip[INET6_ADDRSTRLEN]; \
|
||||||
|
int port; \
|
||||||
|
struct sockaddr_in *a4; \
|
||||||
|
struct sockaddr_in6 *a6; \
|
||||||
|
switch ((address_storage).ss_family) { \
|
||||||
|
case AF_INET6: \
|
||||||
|
a6 = (struct sockaddr_in6*)&(address_storage); \
|
||||||
|
inet_ntop(AF_INET6, &(a6->sin6_addr), ip, INET6_ADDRSTRLEN); \
|
||||||
|
port = ntohs(a6->sin6_port); \
|
||||||
|
(info)->Set(address_symbol, String::New(ip)); \
|
||||||
|
(info)->Set(port_symbol, Integer::New(port)); \
|
||||||
|
break; \
|
||||||
|
case AF_INET: \
|
||||||
|
a4 = (struct sockaddr_in*)&(address_storage); \
|
||||||
|
inet_ntop(AF_INET, &(a4->sin_addr), ip, INET6_ADDRSTRLEN); \
|
||||||
|
port = ntohs(a4->sin_port); \
|
||||||
|
(info)->Set(address_symbol, String::New(ip)); \
|
||||||
|
(info)->Set(port_symbol, Integer::New(port)); \
|
||||||
|
break; \
|
||||||
|
} \
|
||||||
|
} while (0)
|
||||||
|
|
||||||
|
|
||||||
static Handle<Value> GetSockName(const Arguments& args) {
|
static Handle<Value> GetSockName(const Arguments& args) {
|
||||||
HandleScope scope;
|
HandleScope scope;
|
||||||
|
|
||||||
@ -687,17 +714,7 @@ static Handle<Value> GetSockName(const Arguments& args) {
|
|||||||
|
|
||||||
Local<Object> info = Object::New();
|
Local<Object> info = Object::New();
|
||||||
|
|
||||||
if (address_storage.ss_family == AF_INET6) {
|
ADDRESS_TO_JS(info, address_storage);
|
||||||
struct sockaddr_in6 *a = (struct sockaddr_in6*)&address_storage;
|
|
||||||
|
|
||||||
char ip[INET6_ADDRSTRLEN];
|
|
||||||
inet_ntop(AF_INET6, &(a->sin6_addr), ip, INET6_ADDRSTRLEN);
|
|
||||||
|
|
||||||
int port = ntohs(a->sin6_port);
|
|
||||||
|
|
||||||
info->Set(address_symbol, String::New(ip));
|
|
||||||
info->Set(port_symbol, Integer::New(port));
|
|
||||||
}
|
|
||||||
|
|
||||||
return scope.Close(info);
|
return scope.Close(info);
|
||||||
}
|
}
|
||||||
@ -719,17 +736,7 @@ static Handle<Value> GetPeerName(const Arguments& args) {
|
|||||||
|
|
||||||
Local<Object> info = Object::New();
|
Local<Object> info = Object::New();
|
||||||
|
|
||||||
if (address_storage.ss_family == AF_INET6) {
|
ADDRESS_TO_JS(info, address_storage);
|
||||||
struct sockaddr_in6 *a = (struct sockaddr_in6*)&address_storage;
|
|
||||||
|
|
||||||
char ip[INET6_ADDRSTRLEN];
|
|
||||||
inet_ntop(AF_INET6, &(a->sin6_addr), ip, INET6_ADDRSTRLEN);
|
|
||||||
|
|
||||||
int port = ntohs(a->sin6_port);
|
|
||||||
|
|
||||||
info->Set(remote_address_symbol, String::New(ip));
|
|
||||||
info->Set(remote_port_symbol, Integer::New(port));
|
|
||||||
}
|
|
||||||
|
|
||||||
return scope.Close(info);
|
return scope.Close(info);
|
||||||
}
|
}
|
||||||
@ -753,8 +760,8 @@ static Handle<Value> Listen(const Arguments& args) {
|
|||||||
// var peerInfo = t.accept(server_fd);
|
// var peerInfo = t.accept(server_fd);
|
||||||
//
|
//
|
||||||
// peerInfo.fd
|
// peerInfo.fd
|
||||||
// peerInfo.remoteAddress
|
// peerInfo.address
|
||||||
// peerInfo.remotePort
|
// peerInfo.port
|
||||||
//
|
//
|
||||||
// Returns a new nonblocking socket fd. If the listen queue is empty the
|
// Returns a new nonblocking socket fd. If the listen queue is empty the
|
||||||
// function returns null (wait for server_fd to become readable and try
|
// function returns null (wait for server_fd to become readable and try
|
||||||
@ -784,17 +791,7 @@ static Handle<Value> Accept(const Arguments& args) {
|
|||||||
|
|
||||||
peer_info->Set(fd_symbol, Integer::New(peer_fd));
|
peer_info->Set(fd_symbol, Integer::New(peer_fd));
|
||||||
|
|
||||||
if (address_storage.ss_family == AF_INET6) {
|
ADDRESS_TO_JS(peer_info, address_storage);
|
||||||
struct sockaddr_in6 *a = (struct sockaddr_in6*)&address_storage;
|
|
||||||
|
|
||||||
char ip[INET6_ADDRSTRLEN];
|
|
||||||
inet_ntop(AF_INET6, &(a->sin6_addr), ip, INET6_ADDRSTRLEN);
|
|
||||||
|
|
||||||
int port = ntohs(a->sin6_port);
|
|
||||||
|
|
||||||
peer_info->Set(remote_address_symbol, String::New(ip));
|
|
||||||
peer_info->Set(remote_port_symbol, Integer::New(port));
|
|
||||||
}
|
|
||||||
|
|
||||||
return scope.Close(peer_info);
|
return scope.Close(peer_info);
|
||||||
}
|
}
|
||||||
@ -1226,28 +1223,28 @@ static Handle<Value> GetAddrInfo(const Arguments& args) {
|
|||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
static Handle<Value> NeedsLookup(const Arguments& args) {
|
static Handle<Value> IsIP(const Arguments& args) {
|
||||||
HandleScope scope;
|
HandleScope scope;
|
||||||
|
|
||||||
if (args[0]->IsNull() || args[0]->IsUndefined()) return False();
|
if (!args[0]->IsString()) {
|
||||||
|
return scope.Close(Integer::New(4));
|
||||||
|
}
|
||||||
|
|
||||||
String::Utf8Value s(args[0]->ToString());
|
String::Utf8Value s(args[0]->ToString());
|
||||||
|
|
||||||
// avoiding buffer overflows in the following strcat
|
// avoiding buffer overflows in the following strcat
|
||||||
// 2001:0db8:85a3:08d3:1319:8a2e:0370:7334
|
// 2001:0db8:85a3:08d3:1319:8a2e:0370:7334
|
||||||
// 39 = max ipv6 address.
|
// 39 = max ipv6 address.
|
||||||
if (s.length() > INET6_ADDRSTRLEN) return True();
|
if (s.length() > INET6_ADDRSTRLEN) {
|
||||||
|
return scope.Close(Integer::New(0));
|
||||||
|
}
|
||||||
|
|
||||||
struct sockaddr_in6 a;
|
struct sockaddr_in6 a;
|
||||||
|
|
||||||
if (inet_pton(AF_INET, *s, &(a.sin6_addr)) > 0) return False();
|
if (inet_pton(AF_INET, *s, &(a.sin6_addr)) > 0) return scope.Close(Integer::New(4));
|
||||||
if (inet_pton(AF_INET6, *s, &(a.sin6_addr)) > 0) return False();
|
if (inet_pton(AF_INET6, *s, &(a.sin6_addr)) > 0) return scope.Close(Integer::New(6));
|
||||||
|
|
||||||
char ipv6[255] = "::FFFF:";
|
return scope.Close(Integer::New(0));
|
||||||
strcat(ipv6, *s);
|
|
||||||
if (inet_pton(AF_INET6, ipv6, &(a.sin6_addr)) > 0) return False();
|
|
||||||
|
|
||||||
return True();
|
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
@ -1291,7 +1288,7 @@ void InitNet2(Handle<Object> target) {
|
|||||||
NODE_SET_METHOD(target, "getsockname", GetSockName);
|
NODE_SET_METHOD(target, "getsockname", GetSockName);
|
||||||
NODE_SET_METHOD(target, "getpeername", GetPeerName);
|
NODE_SET_METHOD(target, "getpeername", GetPeerName);
|
||||||
NODE_SET_METHOD(target, "getaddrinfo", GetAddrInfo);
|
NODE_SET_METHOD(target, "getaddrinfo", GetAddrInfo);
|
||||||
NODE_SET_METHOD(target, "needsLookup", NeedsLookup);
|
NODE_SET_METHOD(target, "isIP", IsIP);
|
||||||
NODE_SET_METHOD(target, "errnoException", CreateErrnoException);
|
NODE_SET_METHOD(target, "errnoException", CreateErrnoException);
|
||||||
|
|
||||||
target->Set(String::NewSymbol("ENOENT"), Integer::New(ENOENT));
|
target->Set(String::NewSymbol("ENOENT"), Integer::New(ENOENT));
|
||||||
@ -1305,8 +1302,6 @@ void InitNet2(Handle<Object> target) {
|
|||||||
errno_symbol = NODE_PSYMBOL("errno");
|
errno_symbol = NODE_PSYMBOL("errno");
|
||||||
syscall_symbol = NODE_PSYMBOL("syscall");
|
syscall_symbol = NODE_PSYMBOL("syscall");
|
||||||
fd_symbol = NODE_PSYMBOL("fd");
|
fd_symbol = NODE_PSYMBOL("fd");
|
||||||
remote_address_symbol = NODE_PSYMBOL("remoteAddress");
|
|
||||||
remote_port_symbol = NODE_PSYMBOL("remotePort");
|
|
||||||
address_symbol = NODE_PSYMBOL("address");
|
address_symbol = NODE_PSYMBOL("address");
|
||||||
port_symbol = NODE_PSYMBOL("port");
|
port_symbol = NODE_PSYMBOL("port");
|
||||||
}
|
}
|
||||||
|
@ -11,10 +11,12 @@ function pingPongTest (port, host, on_complete) {
|
|||||||
var server = net.createServer(function (socket) {
|
var server = net.createServer(function (socket) {
|
||||||
assert.equal(true, socket.remoteAddress !== null);
|
assert.equal(true, socket.remoteAddress !== null);
|
||||||
assert.equal(true, socket.remoteAddress !== undefined);
|
assert.equal(true, socket.remoteAddress !== undefined);
|
||||||
if (host === "127.0.0.1")
|
if (host === "127.0.0.1" || host === "localhost" || !host) {
|
||||||
assert.equal(socket.remoteAddress, "127.0.0.1");
|
assert.equal(socket.remoteAddress, "127.0.0.1");
|
||||||
else if (host == null)
|
} else {
|
||||||
|
puts('host = ' + host + ', remoteAddress = ' + socket.remoteAddress);
|
||||||
assert.equal(socket.remoteAddress, "::1");
|
assert.equal(socket.remoteAddress, "::1");
|
||||||
|
}
|
||||||
|
|
||||||
socket.setEncoding("utf8");
|
socket.setEncoding("utf8");
|
||||||
socket.setNoDelay();
|
socket.setNoDelay();
|
||||||
|
Loading…
x
Reference in New Issue
Block a user