net.dns: don't calloc a single int

Removes yet another unchecked allocation point in our C libraries.

While here, fix potential reference leaks on error paths

Also while here, remove some stale documentation.  There can be as many
DNS requests in flight as LwIP has room for in its table
(DNS_TABLE_SIZE, which defaults to 4).
This commit is contained in:
Nathaniel Wesley Filardo 2020-04-06 12:19:38 +01:00 committed by Marcel Stör
parent fd68000c12
commit efa786da4e
2 changed files with 21 additions and 21 deletions

View File

@ -857,12 +857,19 @@ static void net_dns_static_cb(const char *name, ip_addr_t *ipaddr, void *callbac
if (ipaddr != NULL) if (ipaddr != NULL)
addr = *ipaddr; addr = *ipaddr;
else addr.addr = 0xFFFFFFFF; else addr.addr = 0xFFFFFFFF;
int cb_ref = ((int*)callback_arg)[0]; int cb_ref = (int)callback_arg;
free(callback_arg);
lua_State *L = lua_getstate(); lua_State *L = lua_getstate();
/*
* Move reference from registry to stack before the call could possibly
* longjmp us out of here.
*/
lua_rawgeti(L, LUA_REGISTRYINDEX, cb_ref); lua_rawgeti(L, LUA_REGISTRYINDEX, cb_ref);
luaL_unref(L, LUA_REGISTRYINDEX, cb_ref);
// XXX I have no idea why the API insists on a `nil` here, but it does.
lua_pushnil(L); lua_pushnil(L);
if (addr.addr != 0xFFFFFFFF) { if (addr.addr != 0xFFFFFFFF) {
char iptmp[20]; char iptmp[20];
size_t ipl = sprintf(iptmp, IPSTR, IP2STR(&addr.addr)); size_t ipl = sprintf(iptmp, IPSTR, IP2STR(&addr.addr));
@ -871,8 +878,6 @@ static void net_dns_static_cb(const char *name, ip_addr_t *ipaddr, void *callbac
lua_pushnil(L); lua_pushnil(L);
} }
lua_call(L, 2, 0); lua_call(L, 2, 0);
luaL_unref(L, LUA_REGISTRYINDEX, cb_ref);
} }
// Lua: net.dns.resolve( domain, function(sk, ip) ) // Lua: net.dns.resolve( domain, function(sk, ip) )
@ -883,25 +888,25 @@ static int net_dns_static( lua_State* L ) {
return luaL_error(L, "wrong domain"); return luaL_error(L, "wrong domain");
} }
/* Register callback with registry */
luaL_checkanyfunction(L, 2); luaL_checkanyfunction(L, 2);
lua_pushvalue(L, 2); // copy argument (func) to the top of stack lua_pushvalue(L, 2);
int cbref = luaL_ref(L, LUA_REGISTRYINDEX); int cbref = luaL_ref(L, LUA_REGISTRYINDEX);
if (cbref == LUA_NOREF) {
return luaL_error(L, "wrong callback");
}
int *cbref_ptr = calloc(1, sizeof(int));
cbref_ptr[0] = cbref;
ip_addr_t addr; ip_addr_t addr;
err_t err = dns_gethostbyname(domain, &addr, net_dns_static_cb, cbref_ptr);
_Static_assert(sizeof(void *) >= sizeof(typeof(cbref)),
"Can't upcast int to ptr");
err_t err = dns_gethostbyname(domain, &addr, net_dns_static_cb, (void *)cbref);
if (err == ERR_OK) { if (err == ERR_OK) {
net_dns_static_cb(domain, &addr, cbref_ptr); net_dns_static_cb(domain, &addr, (void *)cbref);
return 0; return 0;
} else if (err == ERR_INPROGRESS) { } else if (err == ERR_INPROGRESS) {
return 0; return 0;
} else { } else {
int e = lwip_lua_checkerr(L, err); /* Bail out! Unhook callback from registry, first */
free(cbref_ptr); luaL_unref(L, LUA_REGISTRYINDEX, cbref);
return e; return lwip_lua_checkerr(L, err);
} }
return 0; return 0;
} }

View File

@ -597,13 +597,8 @@ Resolve a hostname to an IP address. Doesn't require a socket like [`net.socket.
- `host` hostname to resolve - `host` hostname to resolve
- `function(sk, ip)` callback called when the name was resolved. `sk` is always `nil` - `function(sk, ip)` callback called when the name was resolved. `sk` is always `nil`
There is at most one callback for all `net.dns.resolve()` requests at any time;
all resolution results are sent to the most recent callback specified at time
of receipt! If multiple DNS callbacks are needed, associate them with separate
sockets using [`net.socket:dns()`](#netsocketdns).
#### Returns #### Returns
`nil` `nil` but may raise errors for severe network stack issues (e.g., out of DNS query table slots)
#### Example #### Example
```lua ```lua