Skip to content

Commit 528bedf

Browse files
authored
Use musl implementation of gethostbyname/gethostbyaddr functions. NFC (#21067)
Instead of implementing these directly in JS, we now implement a much lower level lookup function and rely on musl for all the higher level stuff. `gethostbyname` bottoms out in `_emscripten_lookup_name` and `gethostbyaddr` bottomrs out in `getnameinfo`
1 parent 12b814a commit 528bedf

15 files changed

+60
-69
lines changed

src/library.js

Lines changed: 5 additions & 51 deletions
Original file line numberDiff line numberDiff line change
@@ -1824,57 +1824,11 @@ addToLibrary({
18241824
}
18251825
},
18261826

1827-
// note: lots of leaking here!
1828-
gethostbyaddr__deps: ['$DNS', '$getHostByName', '$inetNtop4', '$setErrNo'],
1829-
gethostbyaddr__proxy: 'sync',
1830-
gethostbyaddr: (addr, addrlen, type) => {
1831-
if (type !== {{{ cDefs.AF_INET }}}) {
1832-
setErrNo({{{ cDefs.EAFNOSUPPORT }}});
1833-
// TODO: set h_errno
1834-
return null;
1835-
}
1836-
addr = {{{ makeGetValue('addr', '0', 'i32') }}}; // addr is in_addr
1837-
var host = inetNtop4(addr);
1838-
var lookup = DNS.lookup_addr(host);
1839-
if (lookup) {
1840-
host = lookup;
1841-
}
1842-
return getHostByName(host);
1843-
},
1844-
1845-
gethostbyname__deps: ['$getHostByName'],
1846-
gethostbyname__proxy: 'sync',
1847-
gethostbyname: (name) => getHostByName(UTF8ToString(name)),
1848-
1849-
$getHostByName__deps: ['malloc', '$stringToNewUTF8', '$DNS', '$inetPton4'],
1850-
$getHostByName: (name) => {
1851-
// generate hostent
1852-
var ret = _malloc({{{ C_STRUCTS.hostent.__size__ }}}); // XXX possibly leaked, as are others here
1853-
var nameBuf = stringToNewUTF8(name);
1854-
{{{ makeSetValue('ret', C_STRUCTS.hostent.h_name, 'nameBuf', POINTER_TYPE) }}};
1855-
var aliasesBuf = _malloc(4);
1856-
{{{ makeSetValue('aliasesBuf', '0', '0', POINTER_TYPE) }}};
1857-
{{{ makeSetValue('ret', C_STRUCTS.hostent.h_aliases, 'aliasesBuf', 'i8**') }}};
1858-
var afinet = {{{ cDefs.AF_INET }}};
1859-
{{{ makeSetValue('ret', C_STRUCTS.hostent.h_addrtype, 'afinet', 'i32') }}};
1860-
{{{ makeSetValue('ret', C_STRUCTS.hostent.h_length, '4', 'i32') }}};
1861-
var addrListBuf = _malloc(12);
1862-
{{{ makeSetValue('addrListBuf', '0', 'addrListBuf+8', POINTER_TYPE) }}};
1863-
{{{ makeSetValue('addrListBuf', '4', '0', POINTER_TYPE) }}};
1864-
{{{ makeSetValue('addrListBuf', '8', 'inetPton4(DNS.lookup_name(name))', 'i32') }}};
1865-
{{{ makeSetValue('ret', C_STRUCTS.hostent.h_addr_list, 'addrListBuf', 'i8**') }}};
1866-
return ret;
1867-
},
1868-
1869-
gethostbyname_r__deps: ['gethostbyname', 'memcpy', 'free'],
1870-
gethostbyname_r__proxy: 'sync',
1871-
gethostbyname_r: (name, ret, buf, buflen, out, err) => {
1872-
var data = _gethostbyname(name);
1873-
_memcpy(ret, data, {{{ C_STRUCTS.hostent.__size__ }}});
1874-
_free(data);
1875-
{{{ makeSetValue('err', '0', '0', 'i32') }}};
1876-
{{{ makeSetValue('out', '0', 'ret', '*') }}};
1877-
return 0;
1827+
_emscripten_lookup_name__deps: ['$UTF8ToString', '$DNS', '$inetPton4'],
1828+
_emscripten_lookup_name: (name) => {
1829+
// uint32_t _emscripten_lookup_name(const char *name);
1830+
var nameString = UTF8ToString(name);
1831+
return inetPton4(DNS.lookup_name(nameString));
18781832
},
18791833

18801834
getaddrinfo__deps: ['$Sockets', '$DNS', '$inetPton4', '$inetNtop4', '$inetPton6', '$inetNtop6', '$writeSockaddr', 'malloc', 'htonl'],

src/library_sigs.js

Lines changed: 1 addition & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -323,6 +323,7 @@ sigs = {
323323
_emscripten_fs_load_embedded_files__sig: 'vp',
324324
_emscripten_get_now_is_monotonic__sig: 'i',
325325
_emscripten_get_progname__sig: 'vpi',
326+
_emscripten_lookup_name__sig: 'ip',
326327
_emscripten_notify_mailbox_postmessage__sig: 'vppp',
327328
_emscripten_push_main_loop_blocker__sig: 'vppp',
328329
_emscripten_push_uncounted_main_loop_blocker__sig: 'vppp',
@@ -966,9 +967,6 @@ sigs = {
966967
filledEllipseRGBA__sig: 'ipiiiiiiii',
967968
getaddrinfo__sig: 'ipppp',
968969
getentropy__sig: 'ipp',
969-
gethostbyaddr__sig: 'ppii',
970-
gethostbyname__sig: 'pp',
971-
gethostbyname_r__sig: 'ipppppp',
972970
getnameinfo__sig: 'ipipipii',
973971
getprotobyname__sig: 'pp',
974972
getprotobynumber__sig: 'pi',

system/lib/libc/emscripten_internal.h

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -146,6 +146,8 @@ void __resumeException(void* exn);
146146
void __cxa_call_unexpected(void* exn);
147147
void llvm_eh_typeid_for(void* exn);
148148

149+
uint32_t _emscripten_lookup_name(const char *name);
150+
149151
#ifdef __cplusplus
150152
}
151153
#endif

system/lib/libc/lookup_name.c

Lines changed: 34 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,34 @@
1+
// Emscripten-specific version of musl/src/network/lookup_name.c
2+
3+
#include <assert.h>
4+
#include <string.h>
5+
#include "musl/src/network/lookup.h"
6+
#include "emscripten_internal.h"
7+
8+
int __lookup_name(struct address buf[static MAXADDRS], char canon[static 256], const char *name, int family, int flags)
9+
{
10+
/* We currently only support the callsite in gethostbyname2_r which
11+
* passes AI_CANONNAME. Remove this assertion when if we ever expand
12+
* this support. */
13+
assert(flags == AI_CANONNAME);
14+
15+
if (family != AF_INET) {
16+
return EAI_SYSTEM;
17+
}
18+
19+
/* This hunk is a duplicated from musl/src/network/lookup_name.c */
20+
*canon = 0;
21+
if (name) {
22+
/* reject empty name and check len so it fits into temp bufs */
23+
size_t l = strnlen(name, 255);
24+
if (l-1 >= 254)
25+
return EAI_NONAME;
26+
memcpy(canon, name, l+1);
27+
}
28+
29+
/* We only support a single address */
30+
uint32_t addr = _emscripten_lookup_name(name);
31+
memset(&buf[0], 0, sizeof(buf[0]));
32+
memcpy(&buf[0].addr, &addr, sizeof(addr));
33+
return 1;
34+
}
Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1 +1 @@
1-
8429
1+
8422
Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1 +1 @@
1-
23103
1+
23089
Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1 +1 @@
1-
7256
1+
7251
Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1 +1 @@
1-
19727
1+
19713

test/other/test_support_errno.c

Lines changed: 5 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -8,12 +8,13 @@
88
#include <stdio.h>
99
#include <errno.h>
1010
#include <string.h>
11-
#include <sys/types.h>
12-
#include <netdb.h>
11+
#include <emscripten/em_asm.h>
12+
#include <emscripten/em_js.h>
13+
14+
EM_JS_DEPS(test, "$setErrNo");
1315

1416
int main() {
15-
void* rtn = gethostbyaddr(NULL, 0, 0);
16-
printf("rtn : %p\n", rtn);
17+
EM_ASM(setErrNo(5));
1718
printf("errno : %d\n", errno);
1819
printf("strerror: %s\n", strerror(errno));
1920
return 0;

test/other/test_support_errno.out

Lines changed: 0 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1,3 +1,2 @@
1-
rtn : 0
21
errno : 5
32
strerror: Address family not supported by protocol
Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1,3 +1,3 @@
1-
rtn : 0
1+
failed to set errno from JS
22
errno : 0
33
strerror: No error information
Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1 +1 @@
1-
58284
1+
58265
Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1 +1 @@
1-
57140
1+
57121

test/test_other.py

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -11918,7 +11918,7 @@ def test_default_to_cxx(self):
1191811918
'minimal': (['-sMINIMAL_RUNTIME', '-sSUPPORT_ERRNO'],),
1191911919
})
1192011920
def test_support_errno(self, args):
11921-
self.emcc_args += args
11921+
self.emcc_args += args + ['-sEXPORTED_FUNCTIONS=_main,___errno_location']
1192211922

1192311923
self.do_other_test('test_support_errno.c')
1192411924
size_default = os.path.getsize('test_support_errno.js')

tools/system_libs.py

Lines changed: 5 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -29,6 +29,8 @@
2929
'listen.c', 'accept.c', 'getsockname.c', 'getpeername.c', 'send.c',
3030
'recv.c', 'sendto.c', 'recvfrom.c', 'sendmsg.c', 'recvmsg.c',
3131
'getsockopt.c', 'setsockopt.c', 'freeaddrinfo.c',
32+
'gethostbyaddr.c', 'gethostbyaddr_r.c', 'gethostbyname.c',
33+
'gethostbyname_r.c', 'gethostbyname2.c', 'gethostbyname2_r.c',
3234
'in6addr_any.c', 'in6addr_loopback.c', 'accept4.c']
3335

3436
# Experimental: Setting EMCC_USE_NINJA will cause system libraries to get built with ninja rather
@@ -1064,12 +1066,12 @@ def get_files(self):
10641066
ignore += [
10651067
'memcpy.c', 'memset.c', 'memmove.c', 'getaddrinfo.c', 'getnameinfo.c',
10661068
'res_query.c', 'res_querydomain.c',
1067-
'proto.c', 'gethostbyaddr.c', 'gethostbyaddr_r.c', 'gethostbyname.c',
1068-
'gethostbyname2_r.c', 'gethostbyname_r.c', 'gethostbyname2.c',
1069+
'proto.c',
10691070
'syscall.c', 'popen.c', 'pclose.c',
10701071
'getgrouplist.c', 'initgroups.c', 'wordexp.c', 'timer_create.c',
10711072
'getentropy.c',
10721073
'getauxval.c',
1074+
'lookup_name.c',
10731075
# 'process' exclusion
10741076
'fork.c', 'vfork.c', 'posix_spawn.c', 'posix_spawnp.c', 'execve.c', 'waitid.c', 'system.c',
10751077
'_Fork.c',
@@ -1258,6 +1260,7 @@ def get_files(self):
12581260
'mktime.c',
12591261
'tzset.c',
12601262
'kill.c',
1263+
'lookup_name.c',
12611264
'pthread_sigmask.c',
12621265
'raise.c',
12631266
'sigaction.c',

0 commit comments

Comments
 (0)