11
11
#include "py/mperrno.h"
12
12
#include "py/runtime.h"
13
13
#include "shared-bindings/socketpool/SocketPool.h"
14
+ #include "common-hal/socketpool/__init__.h"
15
+ #include "common-hal/wifi/__init__.h"
14
16
#if CIRCUITPY_SSL
15
17
#include "shared-bindings/ssl/SSLSocket.h"
16
18
#include "shared-module/ssl/SSLSocket.h"
25
27
#include "components/lwip/lwip/src/include/lwip/netdb.h"
26
28
#include "components/vfs/include/esp_vfs_eventfd.h"
27
29
30
+ void socketpool_resolve_host_or_throw (int family , int type , const char * hostname , struct sockaddr_storage * addr , int port ) {
31
+ struct addrinfo * result_i ;
32
+ const struct addrinfo hints = {
33
+ .ai_family = family ,
34
+ .ai_socktype = type ,
35
+ };
36
+ int error = socketpool_getaddrinfo_common (hostname , port , & hints , & result_i );
37
+ if (error != 0 || result_i == NULL ) {
38
+ common_hal_socketpool_socketpool_raise_gaierror_noname ();
39
+ }
40
+ memcpy (addr , result_i -> ai_addr , sizeof (struct sockaddr_storage ));
41
+ lwip_freeaddrinfo (result_i );
42
+ }
43
+
44
+ static void resolve_host_or_throw (socketpool_socket_obj_t * self , const char * hostname , struct sockaddr_storage * addr , int port ) {
45
+ socketpool_resolve_host_or_throw (self -> family , self -> type , hostname , addr , port );
46
+ }
47
+
28
48
StackType_t socket_select_stack [2 * configMINIMAL_STACK_SIZE ];
29
49
30
50
/* Socket state table:
@@ -175,7 +195,7 @@ static bool _socketpool_socket(socketpool_socketpool_obj_t *self,
175
195
if (family == SOCKETPOOL_AF_INET ) {
176
196
addr_family = AF_INET ;
177
197
ipproto = IPPROTO_IP ;
178
- #if LWIP_IPV6
198
+ #if CIRCUITPY_SOCKETPOOL_IPV6
179
199
} else { // INET6
180
200
addr_family = AF_INET6 ;
181
201
ipproto = IPPROTO_IPV6 ;
@@ -230,8 +250,14 @@ bool socketpool_socket(socketpool_socketpool_obj_t *self,
230
250
231
251
socketpool_socket_obj_t * common_hal_socketpool_socket (socketpool_socketpool_obj_t * self ,
232
252
socketpool_socketpool_addressfamily_t family , socketpool_socketpool_sock_t type , int proto ) {
233
- if (family != SOCKETPOOL_AF_INET ) {
234
- mp_raise_NotImplementedError (MP_ERROR_TEXT ("Only IPv4 sockets supported" ));
253
+ switch (family ) {
254
+ #if CIRCUITPY_SOCKETPOOL_IPV6
255
+ case SOCKETPOOL_AF_INET6 :
256
+ #endif
257
+ case SOCKETPOOL_AF_INET :
258
+ break ;
259
+ default :
260
+ mp_raise_NotImplementedError (MP_ERROR_TEXT ("Unsupported socket type" ));
235
261
}
236
262
237
263
socketpool_socket_obj_t * sock = m_new_obj_with_finaliser (socketpool_socket_obj_t );
@@ -244,9 +270,9 @@ socketpool_socket_obj_t *common_hal_socketpool_socket(socketpool_socketpool_obj_
244
270
return sock ;
245
271
}
246
272
247
- int socketpool_socket_accept (socketpool_socket_obj_t * self , uint8_t * ip , uint32_t * port , socketpool_socket_obj_t * accepted ) {
248
- struct sockaddr_in accept_addr ;
249
- socklen_t socklen = sizeof (accept_addr );
273
+ int socketpool_socket_accept (socketpool_socket_obj_t * self , mp_obj_t * peer_out , socketpool_socket_obj_t * accepted ) {
274
+ struct sockaddr_storage peer_addr ;
275
+ socklen_t socklen = sizeof (peer_addr );
250
276
int newsoc = -1 ;
251
277
bool timed_out = false;
252
278
uint64_t start_ticks = supervisor_ticks_ms64 ();
@@ -257,20 +283,17 @@ int socketpool_socket_accept(socketpool_socket_obj_t *self, uint8_t *ip, uint32_
257
283
timed_out = supervisor_ticks_ms64 () - start_ticks >= self -> timeout_ms ;
258
284
}
259
285
RUN_BACKGROUND_TASKS ;
260
- newsoc = lwip_accept (self -> num , (struct sockaddr * )& accept_addr , & socklen );
286
+ newsoc = lwip_accept (self -> num , (struct sockaddr * )& peer_addr , & socklen );
261
287
// In non-blocking mode, fail instead of timing out
262
288
if (newsoc == -1 && (self -> timeout_ms == 0 || mp_hal_is_interrupted ())) {
263
289
return - MP_EAGAIN ;
264
290
}
265
291
}
266
292
267
- if (!timed_out ) {
268
- // harmless on failure but avoiding memcpy is faster
269
- memcpy ((void * )ip , (void * )& accept_addr .sin_addr .s_addr , sizeof (accept_addr .sin_addr .s_addr ));
270
- * port = accept_addr .sin_port ;
271
- } else {
293
+ if (timed_out ) {
272
294
return - ETIMEDOUT ;
273
295
}
296
+
274
297
if (newsoc < 0 ) {
275
298
return - MP_EBADF ;
276
299
}
@@ -295,13 +318,16 @@ int socketpool_socket_accept(socketpool_socket_obj_t *self, uint8_t *ip, uint32_
295
318
accepted -> type = self -> type ;
296
319
}
297
320
321
+ if (peer_out ) {
322
+ * peer_out = sockaddr_to_tuple (& peer_addr );
323
+ }
324
+
298
325
return newsoc ;
299
326
}
300
327
301
- socketpool_socket_obj_t * common_hal_socketpool_socket_accept (socketpool_socket_obj_t * self ,
302
- uint8_t * ip , uint32_t * port ) {
328
+ socketpool_socket_obj_t * common_hal_socketpool_socket_accept (socketpool_socket_obj_t * self , mp_obj_t * peer_out ) {
303
329
socketpool_socket_obj_t * sock = m_new_obj_with_finaliser (socketpool_socket_obj_t );
304
- int newsoc = socketpool_socket_accept (self , ip , port , NULL );
330
+ int newsoc = socketpool_socket_accept (self , peer_out , NULL );
305
331
306
332
if (newsoc > 0 ) {
307
333
// Create the socket
@@ -321,20 +347,35 @@ socketpool_socket_obj_t *common_hal_socketpool_socket_accept(socketpool_socket_o
321
347
322
348
size_t common_hal_socketpool_socket_bind (socketpool_socket_obj_t * self ,
323
349
const char * host , size_t hostlen , uint32_t port ) {
324
- struct sockaddr_in bind_addr ;
350
+ struct sockaddr_storage bind_addr ;
325
351
const char * broadcast = "<broadcast>" ;
326
- uint32_t ip ;
327
- if (hostlen == 0 ) {
328
- ip = IPADDR_ANY ;
329
- } else if (hostlen == strlen (broadcast ) &&
330
- memcmp (host , broadcast , strlen (broadcast )) == 0 ) {
331
- ip = IPADDR_BROADCAST ;
332
- } else {
333
- ip = inet_addr (host );
352
+
353
+ bind_addr .ss_family = self -> family ;
354
+
355
+ #if CIRCUITPY_SOCKETPOOL_IPV6
356
+ if (self -> family == AF_INET6 ) {
357
+ struct sockaddr_in6 * addr6 = (void * )& bind_addr ;
358
+ addr6 -> sin6_port = htons (port );
359
+ // no ipv6 broadcast
360
+ if (hostlen == 0 ) {
361
+ memset (& addr6 -> sin6_addr , 0 , sizeof (addr6 -> sin6_addr ));
362
+ } else {
363
+ socketpool_resolve_host_or_throw (self -> family , self -> type , host , & bind_addr , port );
364
+ }
365
+ } else
366
+ #endif
367
+ {
368
+ struct sockaddr_in * addr4 = (void * )& bind_addr ;
369
+ addr4 -> sin_port = htons (port );
370
+ if (hostlen == 0 ) {
371
+ addr4 -> sin_addr .s_addr = IPADDR_ANY ;
372
+ } else if (hostlen == strlen (broadcast ) &&
373
+ memcmp (host , broadcast , strlen (broadcast )) == 0 ) {
374
+ addr4 -> sin_addr .s_addr = IPADDR_BROADCAST ;
375
+ } else {
376
+ socketpool_resolve_host_or_throw (self -> family , self -> type , host , & bind_addr , port );
377
+ }
334
378
}
335
- bind_addr .sin_addr .s_addr = ip ;
336
- bind_addr .sin_family = AF_INET ;
337
- bind_addr .sin_port = htons (port );
338
379
339
380
int result = lwip_bind (self -> num , (struct sockaddr * )& bind_addr , sizeof (bind_addr ));
340
381
if (result == 0 ) {
@@ -376,34 +417,16 @@ void common_hal_socketpool_socket_close(socketpool_socket_obj_t *self) {
376
417
377
418
void common_hal_socketpool_socket_connect (socketpool_socket_obj_t * self ,
378
419
const char * host , size_t hostlen , uint32_t port ) {
379
- const struct addrinfo hints = {
380
- .ai_family = AF_INET ,
381
- .ai_socktype = SOCK_STREAM ,
382
- };
383
- struct addrinfo * result_i ;
384
- int error = lwip_getaddrinfo (host , NULL , & hints , & result_i );
385
- if (error != 0 || result_i == NULL ) {
386
- common_hal_socketpool_socketpool_raise_gaierror_noname ();
387
- }
388
-
389
- // Set parameters
390
- struct sockaddr_in dest_addr ;
391
- #pragma GCC diagnostic push
392
- #pragma GCC diagnostic ignored "-Wcast-align"
393
- dest_addr .sin_addr .s_addr = ((struct sockaddr_in * )result_i -> ai_addr )-> sin_addr .s_addr ;
394
- #pragma GCC diagnostic pop
395
- lwip_freeaddrinfo (result_i );
396
-
397
- dest_addr .sin_family = AF_INET ;
398
- dest_addr .sin_port = htons (port );
420
+ struct sockaddr_storage addr ;
421
+ resolve_host_or_throw (self , host , & addr , port );
399
422
400
423
// Replace above with function call -----
401
424
402
425
// Emulate SO_CONTIMEO, which is not implemented by lwip.
403
426
// All our sockets are non-blocking, so we check the timeout ourselves.
404
427
405
428
int result = -1 ;
406
- result = lwip_connect (self -> num , (struct sockaddr * )& dest_addr , sizeof ( struct sockaddr_in ) );
429
+ result = lwip_connect (self -> num , (struct sockaddr * )& addr , addr . s2_len );
407
430
408
431
if (result == 0 ) {
409
432
// Connected immediately.
@@ -483,9 +506,9 @@ bool common_hal_socketpool_socket_listen(socketpool_socket_obj_t *self, int back
483
506
}
484
507
485
508
mp_uint_t common_hal_socketpool_socket_recvfrom_into (socketpool_socket_obj_t * self ,
486
- uint8_t * buf , uint32_t len , uint8_t * ip , uint32_t * port ) {
509
+ uint8_t * buf , uint32_t len , mp_obj_t * source_out ) {
487
510
488
- struct sockaddr_in source_addr ;
511
+ struct sockaddr_storage source_addr ;
489
512
socklen_t socklen = sizeof (source_addr );
490
513
491
514
// LWIP Socket
@@ -507,10 +530,7 @@ mp_uint_t common_hal_socketpool_socket_recvfrom_into(socketpool_socket_obj_t *se
507
530
}
508
531
}
509
532
510
- if (!timed_out ) {
511
- memcpy ((void * )ip , (void * )& source_addr .sin_addr .s_addr , sizeof (source_addr .sin_addr .s_addr ));
512
- * port = htons (source_addr .sin_port );
513
- } else {
533
+ if (timed_out ) {
514
534
mp_raise_OSError (ETIMEDOUT );
515
535
}
516
536
@@ -519,6 +539,10 @@ mp_uint_t common_hal_socketpool_socket_recvfrom_into(socketpool_socket_obj_t *se
519
539
return 0 ;
520
540
}
521
541
542
+ if (source_out ) {
543
+ * source_out = sockaddr_to_tuple (& source_addr );
544
+ }
545
+
522
546
return received ;
523
547
}
524
548
@@ -605,29 +629,10 @@ mp_uint_t common_hal_socketpool_socket_send(socketpool_socket_obj_t *self, const
605
629
mp_uint_t common_hal_socketpool_socket_sendto (socketpool_socket_obj_t * self ,
606
630
const char * host , size_t hostlen , uint32_t port , const uint8_t * buf , uint32_t len ) {
607
631
608
- // Set parameters
609
- const struct addrinfo hints = {
610
- .ai_family = AF_INET ,
611
- .ai_socktype = SOCK_STREAM ,
612
- };
613
- struct addrinfo * result_i ;
614
- int error = lwip_getaddrinfo (host , NULL , & hints , & result_i );
615
- if (error != 0 || result_i == NULL ) {
616
- common_hal_socketpool_socketpool_raise_gaierror_noname ();
617
- }
618
-
619
- // Set parameters
620
- struct sockaddr_in dest_addr ;
621
- #pragma GCC diagnostic push
622
- #pragma GCC diagnostic ignored "-Wcast-align"
623
- dest_addr .sin_addr .s_addr = ((struct sockaddr_in * )result_i -> ai_addr )-> sin_addr .s_addr ;
624
- #pragma GCC diagnostic pop
625
- lwip_freeaddrinfo (result_i );
626
-
627
- dest_addr .sin_family = AF_INET ;
628
- dest_addr .sin_port = htons (port );
632
+ struct sockaddr_storage addr ;
633
+ resolve_host_or_throw (self , host , & addr , port );
629
634
630
- int bytes_sent = lwip_sendto (self -> num , buf , len , 0 , (struct sockaddr * )& dest_addr , sizeof ( dest_addr ) );
635
+ int bytes_sent = lwip_sendto (self -> num , buf , len , 0 , (struct sockaddr * )& addr , addr . s2_len );
631
636
if (bytes_sent < 0 ) {
632
637
mp_raise_BrokenPipeError ();
633
638
return 0 ;
0 commit comments