summaryrefslogtreecommitdiffstatshomepage
path: root/extmod
diff options
context:
space:
mode:
Diffstat (limited to 'extmod')
-rw-r--r--extmod/modlwip.c67
1 files changed, 36 insertions, 31 deletions
diff --git a/extmod/modlwip.c b/extmod/modlwip.c
index 4f29a5723b..89c8867d7d 100644
--- a/extmod/modlwip.c
+++ b/extmod/modlwip.c
@@ -284,19 +284,6 @@ STATIC err_t _lwip_tcp_recv(void *arg, struct tcp_pcb *tcpb, struct pbuf *p, err
return ERR_OK;
}
-STATIC uint8_t lwip_dns_returned;
-STATIC uint8_t lwip_dns_result[4];
-
-// Callback for incoming DNS requests. Just set our results.
-STATIC void _lwip_dns_incoming(const char *name, ip_addr_t *addr, void *callback_arg) {
- if (addr != NULL) {
- lwip_dns_returned = 1;
- memcpy(lwip_dns_result, addr, sizeof(lwip_dns_result));
- } else {
- lwip_dns_returned = 2;
- }
-}
-
/*******************************************************************************/
// Functions for socket send/recieve operations. Socket send/recv and friends call
// these to do the work.
@@ -999,41 +986,59 @@ STATIC mp_obj_t mod_lwip_callback() {
}
MP_DEFINE_CONST_FUN_OBJ_0(mod_lwip_callback_obj, mod_lwip_callback);
+typedef struct _getaddrinfo_state_t {
+ volatile int status;
+ volatile ip_addr_t ipaddr;
+} getaddrinfo_state_t;
+
+// Callback for incoming DNS requests.
+STATIC void lwip_getaddrinfo_cb(const char *name, ip_addr_t *ipaddr, void *arg) {
+ getaddrinfo_state_t *state = arg;
+ if (ipaddr != NULL) {
+ state->status = 1;
+ state->ipaddr = *ipaddr;
+ } else {
+ // error
+ state->status = -2;
+ }
+}
+
// lwip.getaddrinfo
STATIC mp_obj_t lwip_getaddrinfo(mp_obj_t host_in, mp_obj_t port_in) {
mp_uint_t hlen;
const char *host = mp_obj_str_get_data(host_in, &hlen);
mp_int_t port = mp_obj_get_int(port_in);
- ip_addr_t result;
- lwip_dns_returned = 0;
+ getaddrinfo_state_t state;
+ state.status = 0;
- switch (dns_gethostbyname(host, &result, _lwip_dns_incoming, NULL)) {
- case ERR_OK: {
- break;
- }
- case ERR_INPROGRESS: {
- while(!lwip_dns_returned) {
+ err_t ret = dns_gethostbyname(host, (ip_addr_t*)&state.ipaddr, lwip_getaddrinfo_cb, &state);
+ switch (ret) {
+ case ERR_OK:
+ // cached
+ state.status = 1;
+ break;
+ case ERR_INPROGRESS:
+ while (state.status == 0) {
poll_sockets();
}
- if (lwip_dns_returned == 2) {
- nlr_raise(mp_obj_new_exception_arg1(&mp_type_OSError, MP_OBJ_NEW_SMALL_INT(ENOENT)));
- }
break;
- }
- default: {
- nlr_raise(mp_obj_new_exception_arg1(&mp_type_OSError, MP_OBJ_NEW_SMALL_INT(ENOENT)));
- }
+ default:
+ state.status = ret;
+ }
+
+ if (state.status < 0) {
+ // TODO: CPython raises gaierror, we raise with native lwIP negative error
+ // values, to differentiate from normal errno's at least in such way.
+ nlr_raise(mp_obj_new_exception_arg1(&mp_type_OSError, MP_OBJ_NEW_SMALL_INT(state.status)));
}
- uint8_t out_ip[NETUTILS_IPV4ADDR_BUFSIZE];
- memcpy(out_ip, lwip_dns_result, sizeof(lwip_dns_result));
mp_obj_tuple_t *tuple = mp_obj_new_tuple(5, NULL);
tuple->items[0] = MP_OBJ_NEW_SMALL_INT(MOD_NETWORK_AF_INET);
tuple->items[1] = MP_OBJ_NEW_SMALL_INT(MOD_NETWORK_SOCK_STREAM);
tuple->items[2] = MP_OBJ_NEW_SMALL_INT(0);
tuple->items[3] = MP_OBJ_NEW_QSTR(MP_QSTR_);
- tuple->items[4] = netutils_format_inet_addr(out_ip, port, NETUTILS_BIG);
+ tuple->items[4] = netutils_format_inet_addr((uint8_t*)&state.ipaddr, port, NETUTILS_BIG);
return mp_obj_new_list(1, (mp_obj_t*)&tuple);
}
STATIC MP_DEFINE_CONST_FUN_OBJ_2(lwip_getaddrinfo_obj, lwip_getaddrinfo);