aboutsummaryrefslogtreecommitdiff
path: root/src
diff options
context:
space:
mode:
authorFraser Adams <fraser.adams@blueyonder.co.uk>2013-11-09 16:57:12 +0000
committerFraser Adams <fraser.adams@blueyonder.co.uk>2013-11-09 16:57:12 +0000
commitea7053a084760b5dac25c4a8aa1345ad2ac79ed6 (patch)
treeb59dfc7cef0c6dff0a63ba1b374ffcc71119f358 /src
parente0268fa1035a718341c53921eee9318d4a8033cd (diff)
Provided an implementation for gai_strerror and gave getaddrinfo sensible default behaviour when hints is set to NULL. Ideally getaddrinfo should supply multiple addrinfo values when hints is NULL or ai_family is set to AF_UNSPEC but this is a somewhat more complex proposition
Diffstat (limited to 'src')
-rw-r--r--src/library.js56
-rw-r--r--src/struct_info.json6
2 files changed, 56 insertions, 6 deletions
diff --git a/src/library.js b/src/library.js
index 31f531e9..2e017d0a 100644
--- a/src/library.js
+++ b/src/library.js
@@ -7433,6 +7433,9 @@ LibraryManager.library = {
getaddrinfo__deps: ['$Sockets', '$DNS', '_inet_pton4_raw', '_inet_ntop4_raw', '_inet_pton6_raw', '_inet_ntop6_raw', '_write_sockaddr', 'htonl'],
getaddrinfo: function(node, service, hint, out) {
+ // Note getaddrinfo currently only returns a single addrinfo with ai_next defaulting to NULL. When NULL
+ // hints are specified or ai_family set to AF_UNSPEC or ai_socktype or ai_protocol set to 0 then we
+ // really should provide a linked list of suitable addrinfo values.
var addrs = [];
var canon = null;
var addr = 0;
@@ -7487,6 +7490,15 @@ LibraryManager.library = {
type = proto === {{{ cDefine('IPPROTO_UDP') }}} ? {{{ cDefine('SOCK_DGRAM') }}} : {{{ cDefine('SOCK_STREAM') }}};
}
+ // If type or proto are set to zero in hints we should really be returning multiple addrinfo values, but for
+ // now default to a TCP STREAM socket so we can at least return a sensible addrinfo given NULL hints.
+ if (proto === 0) {
+ proto = {{{ cDefine('IPPROTO_TCP') }}};
+ }
+ if (type === 0) {
+ type = {{{ cDefine('SOCK_STREAM') }}};
+ }
+
if (!node && !service) {
return {{{ cDefine('EAI_NONAME') }}};
}
@@ -7494,14 +7506,14 @@ LibraryManager.library = {
{{{ cDefine('AI_NUMERICSERV') }}}|{{{ cDefine('AI_V4MAPPED') }}}|{{{ cDefine('AI_ALL') }}}|{{{ cDefine('AI_ADDRCONFIG') }}})) {
return {{{ cDefine('EAI_BADFLAGS') }}};
}
- if (({{{ makeGetValue('hint', C_STRUCTS.addrinfo.ai_flags, 'i32') }}} & {{{ cDefine('AI_CANONNAME') }}}) && !node) {
+ if (hint != 0 && ({{{ makeGetValue('hint', C_STRUCTS.addrinfo.ai_flags, 'i32') }}} & {{{ cDefine('AI_CANONNAME') }}}) && !node) {
return {{{ cDefine('EAI_BADFLAGS') }}};
}
if (flags & {{{ cDefine('AI_ADDRCONFIG') }}}) {
// TODO
return {{{ cDefine('EAI_NONAME') }}};
}
- if (type !== {{{ cDefine('SOCK_STREAM') }}} && type !== {{{ cDefine('SOCK_DGRAM') }}}) {
+ if (type !== 0 && type !== {{{ cDefine('SOCK_STREAM') }}} && type !== {{{ cDefine('SOCK_DGRAM') }}}) {
return {{{ cDefine('EAI_SOCKTYPE') }}};
}
if (family !== {{{ cDefine('AF_UNSPEC') }}} && family !== {{{ cDefine('AF_INET') }}} && family !== {{{ cDefine('AF_INET6') }}}) {
@@ -7631,12 +7643,46 @@ LibraryManager.library = {
return 0;
},
+ // Can't use a literal for GAI_ERRNO_MESSAGES as the keys are negative values.
+ $GAI_ERRNO_MESSAGES: {},
+ gai_strerror__deps: ['$GAI_ERRNO_MESSAGES'],
gai_strerror: function(val) {
- if (!_gai_strerror.error) {
- _gai_strerror.error = allocate(intArrayFromString("unknown error"), 'i8', ALLOC_NORMAL);
+ var buflen = 256;
+
+ // On first call to gai_strerror we initialise the buffer and populate the error messages.
+ if (!_gai_strerror.buffer) {
+ _gai_strerror.buffer = _malloc(buflen);
+
+ GAI_ERRNO_MESSAGES['0'] = 'Success';
+ GAI_ERRNO_MESSAGES['' + {{{ cDefine('EAI_BADFLAGS') }}}] = 'Invalid value for \'ai_flags\' field';
+ GAI_ERRNO_MESSAGES['' + {{{ cDefine('EAI_NONAME') }}}] = 'NAME or SERVICE is unknown';
+ GAI_ERRNO_MESSAGES['' + {{{ cDefine('EAI_AGAIN') }}}] = 'Temporary failure in name resolution';
+ GAI_ERRNO_MESSAGES['' + {{{ cDefine('EAI_FAIL') }}}] = 'Non-recoverable failure in name res';
+ GAI_ERRNO_MESSAGES['' + {{{ cDefine('EAI_FAMILY') }}}] = '\'ai_family\' not supported';
+ GAI_ERRNO_MESSAGES['' + {{{ cDefine('EAI_SOCKTYPE') }}}] = '\'ai_socktype\' not supported';
+ GAI_ERRNO_MESSAGES['' + {{{ cDefine('EAI_SERVICE') }}}] = 'SERVICE not supported for \'ai_socktype\'';
+ GAI_ERRNO_MESSAGES['' + {{{ cDefine('EAI_MEMORY') }}}] = 'Memory allocation failure';
+ GAI_ERRNO_MESSAGES['' + {{{ cDefine('EAI_SYSTEM') }}}] = 'System error returned in \'errno\'';
+ GAI_ERRNO_MESSAGES['' + {{{ cDefine('EAI_OVERFLOW') }}}] = 'Argument buffer overflow';
+ }
+
+ var msg = 'Unknown error';
+
+ if (val in GAI_ERRNO_MESSAGES) {
+ if (GAI_ERRNO_MESSAGES[val].length > buflen - 1) {
+ msg = 'Message too long'; // EMSGSIZE message. This should never occur given the GAI_ERRNO_MESSAGES above.
+ } else {
+ msg = GAI_ERRNO_MESSAGES[val];
+ }
+ }
+
+ for (var i = 0; i < msg.length; i++) {
+ {{{ makeSetValue('_gai_strerror.buffer', 'i', 'msg.charCodeAt(i)', 'i8') }}}
}
- return _gai_strerror.error;
+ {{{ makeSetValue('_gai_strerror.buffer', 'i', 0, 'i8') }}}
+
+ return _gai_strerror.buffer;
},
// ==========================================================================
diff --git a/src/struct_info.json b/src/struct_info.json
index 5b4726e8..2943104c 100644
--- a/src/struct_info.json
+++ b/src/struct_info.json
@@ -290,7 +290,11 @@
"AI_CANONNAME",
"AI_PASSIVE",
"NI_NAMEREQD",
- "EAI_NONAME",
+ "EAI_NONAME",
+ "EAI_AGAIN",
+ "EAI_FAIL",
+ "EAI_MEMORY",
+ "EAI_SYSTEM",
"EAI_SOCKTYPE",
"EAI_BADFLAGS"
],