diff options
author | Anthony Pesch <inolen@gmail.com> | 2013-08-11 01:54:19 -0700 |
---|---|---|
committer | Anthony Pesch <inolen@gmail.com> | 2013-08-29 01:45:38 -0700 |
commit | 54537559f334a916739f8c3f31e94597ad471219 (patch) | |
tree | e6d7bc7cc960521cb5e6d0e4faf5909353904004 /src | |
parent | ffd0f62f997d4ff774a62da65ad2fdbba4b0ab3e (diff) |
- minor refactoring to new address translation functions to support better "raw" functionality
- moved test_inet* tests into sockets test suite
Diffstat (limited to 'src')
-rw-r--r-- | src/library.js | 242 |
1 files changed, 139 insertions, 103 deletions
diff --git a/src/library.js b/src/library.js index 3ba2f56b..3f488034 100644 --- a/src/library.js +++ b/src/library.js @@ -6876,7 +6876,6 @@ LibraryManager.library = { // ========================================================================== // arpa/inet.h // ========================================================================== - htonl: function(value) { return ((value & 0xff) << 24) + ((value & 0xff00) << 8) + ((value & 0xff0000) >>> 8) + ((value & 0xff000000) >>> 24); @@ -6887,75 +6886,43 @@ LibraryManager.library = { ntohl: 'htonl', ntohs: 'htons', - // http://pubs.opengroup.org/onlinepubs/9699919799/functions/inet_ntop.html - inet_ntop__deps: ['__setErrNo', '$ERRNO_CODES', 'inet_ntop4', 'inet_ntop6'], - inet_ntop: function(af, src, dst, size) { - switch (af) { - case {{{ cDefine('AF_INET') }}}: - return _inet_ntop4(src, dst, size); - case {{{ cDefine('AF_INET6') }}}: - return _inet_ntop6(src, dst, size); - default: - ___setErrNo(ERRNO_CODES.EAFNOSUPPORT); - return 0; - } - }, - inet_pton__deps: ['__setErrNo', '$ERRNO_CODES', 'inet_pton4', 'inet_pton6'], - inet_pton: function(af, src, dst) { - switch (af) { - case {{{ cDefine('AF_INET') }}}: - return _inet_pton4(src, dst); - case {{{ cDefine('AF_INET6') }}}: - return _inet_pton6(src, dst); - default: - ___setErrNo(ERRNO_CODES.EAFNOSUPPORT); - return -1; - } - }, + // old ipv4 only functions + inet_addr__deps: ['_inet_pton4_raw'], inet_addr: function(ptr) { - var b = Pointer_stringify(ptr).split("."); - if (b.length !== 4) return -1; // we return -1 for error, and otherwise a uint32. this helps inet_pton differentiate - return (Number(b[0]) | (Number(b[1]) << 8) | (Number(b[2]) << 16) | (Number(b[3]) << 24)) >>> 0; - }, - _inet_aton_raw: function(str) { - var b = str.split("."); - return (Number(b[0]) | (Number(b[1]) << 8) | (Number(b[2]) << 16) | (Number(b[3]) << 24)) >>> 0; - }, - _inet_ntoa_raw: function(addr) { - return (addr & 0xff) + '.' + ((addr >> 8) & 0xff) + '.' + ((addr >> 16) & 0xff) + '.' + ((addr >> 24) & 0xff) + var addr = __inet_pton4_raw(Pointer_stringify(ptr)); + if (addr === null) { + return -1; + } + return addr; }, - inet_ntoa__deps: ['_inet_ntoa_raw'], + inet_ntoa__deps: ['_inet_ntop4_raw'], inet_ntoa: function(in_addr) { if (!_inet_ntoa.buffer) { _inet_ntoa.buffer = _malloc(1024); } - var addr = getValue(in_addr, 'i32'); - var str = __inet_ntoa_raw(addr); + var addr = {{{ makeGetValue('in_addr', '0', 'i32') }}}; + var str = __inet_ntop4_raw(addr); writeStringToMemory(str.substr(0, 1024), _inet_ntoa.buffer); return _inet_ntoa.buffer; }, - inet_aton__deps: ['inet_addr'], + inet_aton__deps: ['_inet_pton4_raw'], inet_aton: function(cp, inp) { - var addr = _inet_addr(cp); - setValue(inp, addr, 'i32'); - if (addr < 0) return 0; - return 1; - }, - - inet_ntop4__deps: ['__setErrNo', '$ERRNO_CODES', '_inet_ntoa_raw'], - inet_ntop4: function(src, dst, size) { - var str = __inet_ntoa_raw(getValue(src, 'i32')); - if (str.length+1 > size) { - ___setErrNo(ERRNO_CODES.ENOSPC); + var addr = __inet_pton4_raw(Pointer_stringify(cp)); + if (addr === null) { return 0; } - writeStringToMemory(str, dst); - return dst; + {{{ makeSetValue('inp', '0', 'addr', 'i32') }}} + return 1; }, - inet_ntop6__deps: ['__setErrNo', '$ERRNO_CODES', 'inet_ntop6_raw'], - inet_ntop6: function(src, dst, size) { - var str = _inet_ntop6_raw(src); + // new ipv4 / ipv6 functions + _inet_ntop4_raw: function(addr) { + return (addr & 0xff) + '.' + ((addr >> 8) & 0xff) + '.' + ((addr >> 16) & 0xff) + '.' + ((addr >> 24) & 0xff) + }, + _inet_ntop4__deps: ['__setErrNo', '$ERRNO_CODES', '_inet_ntop4_raw'], + _inet_ntop4: function(src, dst, size) { + var addr = {{{ makeGetValue('src', '0', 'i32') }}}; + var str = __inet_ntop4_raw(addr); if (str.length+1 > size) { ___setErrNo(ERRNO_CODES.ENOSPC); return 0; @@ -6963,9 +6930,8 @@ LibraryManager.library = { writeStringToMemory(str, dst); return dst; }, - inet_ntop6_raw__deps: ['ntohs'], - inet_ntop6_raw: function(src) { - + _inet_ntop6_raw__deps: ['ntohs', '_inet_ntop4_raw'], + _inet_ntop6_raw: function(ints) { // ref: http://www.ietf.org/rfc/rfc2373.txt - section 2.5.4 // Format for IPv4 compatible and mapped 128-bit IPv6 Addresses // 128-bits are split into eight 16-bit words @@ -6980,7 +6946,6 @@ LibraryManager.library = { // +--------------------------------------+----+---------------------+ // |0000..............................0000|FFFF| IPv4 ADDRESS | (mapped) // +--------------------------------------+----+---------------------+ - var str = ""; var word = 0; var longest = 0; @@ -6988,27 +6953,37 @@ LibraryManager.library = { var zstart = 0; var len = 0; var i = 0; + var parts = [ + ints[0] & 0xffff, + (ints[0] >> 16), + ints[1] & 0xffff, + (ints[1] >> 16), + ints[2] & 0xffff, + (ints[2] >> 16), + ints[3] & 0xffff, + (ints[3] >> 16) + ]; // Handle IPv4-compatible, IPv4-mapped, loopback and any/unspecified addresses var hasipv4 = true; var v4part = ""; // check if the 10 high-order bytes are all zeros (first 5 words) - for (i = 0; i < 10; i++) { - if ({{{ makeGetValue('src', 'i', 'i8') }}} !== 0) { hasipv4 = false; break; } + for (i = 0; i < 5; i++) { + if (parts[i] !== 0) { hasipv4 = false; break; } } if (hasipv4) { // low-order 32-bits store an IPv4 address (bytes 13 to 16) (last 2 words) - v4part = __inet_ntoa_raw({{{ makeGetValue('src', '12', 'i32') }}}); + v4part = __inet_ntop4_raw(parts[6] | (parts[7] << 16)); // IPv4-mapped IPv6 address if 16-bit value (bytes 11 and 12) == 0xFFFF (6th word) - if ({{{ makeGetValue('src', '10', 'i16') }}} === -1) { + if (parts[5] === -1) { str = "::ffff:"; str += v4part; return str; } // IPv4-compatible IPv6 address if 16-bit value (bytes 11 and 12) == 0x0000 (6th word) - if ({{{ makeGetValue('src', '10', 'i16') }}} === 0) { + if (parts[5] === 0) { str = "::"; //special case IPv6 addresses if(v4part === "0.0.0.0") v4part = ""; // any/unspecified address @@ -7022,7 +6997,7 @@ LibraryManager.library = { // first run to find the longest contiguous zero words for (word = 0; word < 8; word++) { - if ({{{ makeGetValue('src', 'word*2', 'i16') }}} === 0) { + if (parts[word] === 0) { if (word - lastzero > 1) { len = 0; } @@ -7038,7 +7013,7 @@ LibraryManager.library = { for (word = 0; word < 8; word++) { if (longest > 1) { // compress contiguous zeros - to produce "::" - if ({{{ makeGetValue('src', 'word*2', 'i16') }}} === 0 && word >= zstart && word < (zstart + longest) ) { + if (parts[word] === 0 && word >= zstart && word < (zstart + longest) ) { if (word === zstart) { str += ":"; if (zstart === 0) str += ":"; //leading zeros case @@ -7047,54 +7022,86 @@ LibraryManager.library = { } } // converts 16-bit words from big-endian to little-endian before converting to hex string - str += Number(_ntohs({{{ makeGetValue('src', 'word*2', 'i16') }}} & 0xffff)).toString(16); + str += Number(_ntohs(parts[word] & 0xffff)).toString(16); str += word < 7 ? ":" : ""; } return str; }, - - inet_pton4__deps: ['inet_addr'], - inet_pton4: function(src, dst) { - var ret = _inet_addr(src); - if (ret === -1 || isNaN(ret)) return 0; - setValue(dst, ret, 'i32'); - return 1; + _inet_ntop6__deps: ['__setErrNo', '$ERRNO_CODES', '_inet_ntop6_raw'], + _inet_ntop6: function(src, dst, size) { + var addr = [ + {{{ makeGetValue('src', '0', 'i32') }}}, {{{ makeGetValue('src', '4', 'i32') }}}, + {{{ makeGetValue('src', '8', 'i32') }}}, {{{ makeGetValue('src', '12', 'i32') }}} + ]; + var str = __inet_ntop6_raw(addr); + if (str.length+1 > size) { + ___setErrNo(ERRNO_CODES.ENOSPC); + return 0; + } + writeStringToMemory(str, dst); + return dst; }, - - inet_pton6__deps: ['inet_pton6_raw'], - inet_pton6: function(src, dst) { - return _inet_pton6_raw(Pointer_stringify(src), dst); + inet_ntop__deps: ['__setErrNo', '$ERRNO_CODES', '_inet_ntop4', '_inet_ntop6'], + inet_ntop: function(af, src, dst, size) { + // http://pubs.opengroup.org/onlinepubs/9699919799/functions/inet_ntop.html + switch (af) { + case {{{ cDefine('AF_INET') }}}: + return __inet_ntop4(src, dst, size); + case {{{ cDefine('AF_INET6') }}}: + return __inet_ntop6(src, dst, size); + default: + ___setErrNo(ERRNO_CODES.EAFNOSUPPORT); + return 0; + } }, - inet_pton6_raw__deps: ['htons'], - inet_pton6_raw: function(addr, dst) { + _inet_pton4_raw: function(str) { + var b = str.split('.'); + for (var i = 0; i < 4; i++) { + var tmp = Number(b[i]); + if (isNaN(tmp)) return null; + b[i] = tmp; + } + return (b[0] | (b[1] << 8) | (b[2] << 16) | (b[3] << 24)) >>> 0; + }, + _inet_pton4__deps: ['_inet_pton4_raw'], + _inet_pton4: function(src, dst) { + var ret = __inet_pton4_raw(Pointer_stringify(src)); + if (ret === null) { + return 0; + } + {{{ makeSetValue('dst', '0', 'ret', 'i32') }}} + return 1; + }, + _inet_pton6_raw__deps: ['htons'], + _inet_pton6_raw: function(str) { var words; var w, offset, z, i; /* http://home.deds.nl/~aeron/regex/ */ var valid6regx = /^((?=.*::)(?!.*::.+::)(::)?([\dA-F]{1,4}:(:|\b)|){5}|([\dA-F]{1,4}:){6})((([\dA-F]{1,4}((?!\3)::|:\b|$))|(?!\2\3)){2}|(((2[0-4]|1\d|[1-9])?\d|25[0-5])\.?\b){4})$/i - if (!valid6regx.test(addr)) { - return 0; + var parts = []; + if (!valid6regx.test(str)) { + return null; } - if (addr === "::") { - for (i=0; i < 4; i++) {{{ makeSetValue('dst', 'i*4', '0', 'i32') }}}; - return 1; + if (str === "::") { + return [0, 0, 0, 0, 0, 0, 0, 0]; } // Z placeholder to keep track of zeros when splitting the string on ":" - if (addr.indexOf("::") === 0) { - addr = addr.replace("::", "Z:"); // leading zeros case + if (str.indexOf("::") === 0) { + str = str.replace("::", "Z:"); // leading zeros case } else { - addr = addr.replace("::", ":Z:"); + str = str.replace("::", ":Z:"); } - if (addr.indexOf(".") > 0) { - // parse IPv4 embedded address - addr = addr.replace(new RegExp('[.]', 'g'), ":"); - words = addr.split(":"); + if (str.indexOf(".") > 0) { + // parse IPv4 embedded stress + str = str.replace(new RegExp('[.]', 'g'), ":"); + words = str.split(":"); words[words.length-4] = parseInt(words[words.length-4]) + parseInt(words[words.length-3])*256; words[words.length-3] = parseInt(words[words.length-2]) + parseInt(words[words.length-1])*256; words = words.slice(0, words.length-2); } else { - words = addr.split(":"); + words = str.split(":"); } offset = 0; z = 0; @@ -7103,20 +7110,49 @@ LibraryManager.library = { if (words[w] === 'Z') { // compressed zeros - write appropriate number of zero words for (z = 0; z < (8 - words.length+1); z++) { - {{{ makeSetValue('dst', '(w+z)*2', '0', 'i16') }}}; + parts[w+z] = 0; } offset = z-1; } else { // parse hex to field to 16-bit value and write it in network byte-order - {{{ makeSetValue('dst', '(w+offset)*2', '_htons(parseInt(words[w],16))', 'i16') }}}; + parts[w+offset] = _htons(parseInt(words[w],16)); } } else { // parsed IPv4 words - {{{ makeSetValue('dst', '(w+offset)*2', 'words[w]', 'i16') }}}; + parts[w+offset] = words[w]; } } + return [ + (parts[1] << 16) | parts[0], + (parts[3] << 16) | parts[2], + (parts[5] << 16) | parts[4], + (parts[7] << 16) | parts[6] + ]; + }, + _inet_pton6__deps: ['_inet_pton6_raw'], + _inet_pton6: function(src, dst) { + var ints = __inet_pton6_raw(Pointer_stringify(src)); + if (ints === null) { + return 0; + } + for (var i = 0; i < 4; i++) { + {{{ makeSetValue('dst', 'i*4', 'ints[i]', 'i32') }}}; + } return 1; }, + inet_pton__deps: ['__setErrNo', '$ERRNO_CODES', '_inet_pton4', '_inet_pton6'], + inet_pton: function(af, src, dst) { + // http://pubs.opengroup.org/onlinepubs/9699919799/functions/inet_pton.html + switch (af) { + case {{{ cDefine('AF_INET') }}}: + return __inet_pton4(src, dst); + case {{{ cDefine('AF_INET6') }}}: + return __inet_pton6(src, dst); + default: + ___setErrNo(ERRNO_CODES.EAFNOSUPPORT); + return -1; + } + }, // netinet/in.h @@ -7390,7 +7426,7 @@ LibraryManager.library = { // Stub: connection-oriented sockets are not supported yet. }, - bind__deps: ['$FS', '$Sockets', '_inet_ntoa_raw', 'ntohs', 'mkport'], + bind__deps: ['$FS', '$Sockets', '_inet_ntop4_raw', 'ntohs', 'mkport'], bind: function(fd, addr, addrlen) { var info = FS.getStream(fd); if (!info) return -1; @@ -7402,7 +7438,7 @@ LibraryManager.library = { info.port = _mkport(); } info.addr = Sockets.localAddr; // 10.0.0.254 - info.host = __inet_ntoa_raw(info.addr); + info.host = __inet_ntop4_raw(info.addr); info.close = function() { Sockets.portmap[info.port] = undefined; } @@ -7411,7 +7447,7 @@ LibraryManager.library = { info.bound = true; }, - sendmsg__deps: ['$FS', '$Sockets', 'bind', '_inet_ntoa_raw', 'ntohs'], + sendmsg__deps: ['$FS', '$Sockets', 'bind', '_inet_ntop4_raw', 'ntohs'], sendmsg: function(fd, msg, flags) { var info = FS.getStream(fd); if (!info) return -1; @@ -7425,7 +7461,7 @@ LibraryManager.library = { var port = _ntohs(getValue(name + Sockets.sockaddr_in_layout.sin_port, 'i16')); var addr = getValue(name + Sockets.sockaddr_in_layout.sin_addr, 'i32'); var connection = Sockets.connections[addr]; - // var host = __inet_ntoa_raw(addr); + // var host = __inet_ntop4_raw(addr); if (!(connection && connection.connected)) { ___setErrNo(ERRNO_CODES.EWOULDBLOCK); @@ -7632,14 +7668,14 @@ LibraryManager.library = { return stream.fd; }, - connect__deps: ['$FS', '$Sockets', '_inet_ntoa_raw', 'ntohs', 'gethostbyname'], + connect__deps: ['$FS', '$Sockets', '_inet_ntop4_raw', 'ntohs', 'gethostbyname'], connect: function(fd, addr, addrlen) { var info = FS.getStream(fd); if (!info) return -1; info.connected = true; info.addr = getValue(addr + Sockets.sockaddr_in_layout.sin_addr, 'i32'); info.port = _htons(getValue(addr + Sockets.sockaddr_in_layout.sin_port, 'i16')); - info.host = __inet_ntoa_raw(info.addr); + info.host = __inet_ntop4_raw(info.addr); // Support 'fake' ips from gethostbyname var parts = info.host.split('.'); if (parts[0] == '172' && parts[1] == '29') { |