@@ -284,19 +284,6 @@ STATIC err_t _lwip_tcp_recv(void *arg, struct tcp_pcb *tcpb, struct pbuf *p, err
284284 return ERR_OK ;
285285}
286286
287- STATIC uint8_t lwip_dns_returned ;
288- STATIC uint8_t lwip_dns_result [4 ];
289-
290- // Callback for incoming DNS requests. Just set our results.
291- STATIC void _lwip_dns_incoming (const char * name , ip_addr_t * addr , void * callback_arg ) {
292- if (addr != NULL ) {
293- lwip_dns_returned = 1 ;
294- memcpy (lwip_dns_result , addr , sizeof (lwip_dns_result ));
295- } else {
296- lwip_dns_returned = 2 ;
297- }
298- }
299-
300287/*******************************************************************************/
301288// Functions for socket send/recieve operations. Socket send/recv and friends call
302289// these to do the work.
@@ -999,41 +986,59 @@ STATIC mp_obj_t mod_lwip_callback() {
999986}
1000987MP_DEFINE_CONST_FUN_OBJ_0 (mod_lwip_callback_obj , mod_lwip_callback );
1001988
989+ typedef struct _getaddrinfo_state_t {
990+ volatile int status ;
991+ volatile ip_addr_t ipaddr ;
992+ } getaddrinfo_state_t ;
993+
994+ // Callback for incoming DNS requests.
995+ STATIC void lwip_getaddrinfo_cb (const char * name , ip_addr_t * ipaddr , void * arg ) {
996+ getaddrinfo_state_t * state = arg ;
997+ if (ipaddr != NULL ) {
998+ state -> status = 1 ;
999+ state -> ipaddr = * ipaddr ;
1000+ } else {
1001+ // error
1002+ state -> status = -2 ;
1003+ }
1004+ }
1005+
10021006// lwip.getaddrinfo
10031007STATIC mp_obj_t lwip_getaddrinfo (mp_obj_t host_in , mp_obj_t port_in ) {
10041008 mp_uint_t hlen ;
10051009 const char * host = mp_obj_str_get_data (host_in , & hlen );
10061010 mp_int_t port = mp_obj_get_int (port_in );
10071011
1008- ip_addr_t result ;
1009- lwip_dns_returned = 0 ;
1012+ getaddrinfo_state_t state ;
1013+ state . status = 0 ;
10101014
1011- switch (dns_gethostbyname (host , & result , _lwip_dns_incoming , NULL )) {
1012- case ERR_OK : {
1013- break ;
1014- }
1015- case ERR_INPROGRESS : {
1016- while (!lwip_dns_returned ) {
1015+ err_t ret = dns_gethostbyname (host , (ip_addr_t * )& state .ipaddr , lwip_getaddrinfo_cb , & state );
1016+ switch (ret ) {
1017+ case ERR_OK :
1018+ // cached
1019+ state .status = 1 ;
1020+ break ;
1021+ case ERR_INPROGRESS :
1022+ while (state .status == 0 ) {
10171023 poll_sockets ();
10181024 }
1019- if (lwip_dns_returned == 2 ) {
1020- nlr_raise (mp_obj_new_exception_arg1 (& mp_type_OSError , MP_OBJ_NEW_SMALL_INT (ENOENT )));
1021- }
10221025 break ;
1023- }
1024- default : {
1025- nlr_raise (mp_obj_new_exception_arg1 (& mp_type_OSError , MP_OBJ_NEW_SMALL_INT (ENOENT )));
1026- }
1026+ default :
1027+ state .status = ret ;
1028+ }
1029+
1030+ if (state .status < 0 ) {
1031+ // TODO: CPython raises gaierror, we raise with native lwIP negative error
1032+ // values, to differentiate from normal errno's at least in such way.
1033+ nlr_raise (mp_obj_new_exception_arg1 (& mp_type_OSError , MP_OBJ_NEW_SMALL_INT (state .status )));
10271034 }
10281035
1029- uint8_t out_ip [NETUTILS_IPV4ADDR_BUFSIZE ];
1030- memcpy (out_ip , lwip_dns_result , sizeof (lwip_dns_result ));
10311036 mp_obj_tuple_t * tuple = mp_obj_new_tuple (5 , NULL );
10321037 tuple -> items [0 ] = MP_OBJ_NEW_SMALL_INT (MOD_NETWORK_AF_INET );
10331038 tuple -> items [1 ] = MP_OBJ_NEW_SMALL_INT (MOD_NETWORK_SOCK_STREAM );
10341039 tuple -> items [2 ] = MP_OBJ_NEW_SMALL_INT (0 );
10351040 tuple -> items [3 ] = MP_OBJ_NEW_QSTR (MP_QSTR_ );
1036- tuple -> items [4 ] = netutils_format_inet_addr (out_ip , port , NETUTILS_BIG );
1041+ tuple -> items [4 ] = netutils_format_inet_addr (( uint8_t * ) & state . ipaddr , port , NETUTILS_BIG );
10371042 return mp_obj_new_list (1 , (mp_obj_t * )& tuple );
10381043}
10391044STATIC MP_DEFINE_CONST_FUN_OBJ_2 (lwip_getaddrinfo_obj , lwip_getaddrinfo );
0 commit comments