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:
parent
fd68000c12
commit
efa786da4e
|
@ -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;
|
||||||
}
|
}
|
||||||
|
|
|
@ -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
|
||||||
|
|
Loading…
Reference in New Issue