adafruit / circuitpython

CircuitPython - a Python implementation for teaching coding with microcontrollers
https://circuitpython.org
Other
4.06k stars 1.2k forks source link

ESP socket safemode #8365

Open bill88t opened 1 year ago

bill88t commented 1 year ago

CircuitPython version

Adafruit CircuitPython 9.0.0-alpha.1-25-g000d22f25 on 2023-08-30; VCC-GND YD-ESP32-S3 (N16R8) with ESP32S3

Code/REPL

import wifi
from socketpool import SocketPool

pool = SocketPool(wifi.radio)
_socket = pool.socket(pool.AF_INET, pool.SOCK_STREAM)
_socket.bind(("0.0.0.0", 20))
_socket.bind(("0.0.0.0", 21))

print("Accepting 1")
_socket.listen(5)
a = _socket.accept()
print("Accepting 2")
b = _socket.accept()
print("Accepted 2")

_socket.close()
print("ok")

Behavior

Connect on p20 with telnet telnet: Unable to connect to remote host: Connection refused Connect on p21 with telnet board safemodes 50% of the time, if you ^C and retry the telnet connection it crashes 100% though telnet: Unable to connect to remote host: Connection refused

Description

No response

Additional information

No response

bill88t commented 1 year ago

Got backtrace:

? 0x420968c6:0x3fceaf60 0x420976a1:0x3fceaf80 0x420992f6:0x3fceafb0 0x4209e32a:0x3fceb020 0x420a1fee:0x3fceb050 0x42093d91:0x3fceb070
0x420968c6: tcp_pcb_num_cal at /home/bill88t/git/circuitpython/ports/espressif/esp-idf/components/lwip/lwip/src/core/tcp.c:1875
0x420976a1: tcp_pcb_num_cal at /home/bill88t/git/circuitpython/ports/espressif/esp-idf/components/lwip/lwip/src/core/tcp.c:1888
 (inlined by) tcp_alloc at /home/bill88t/git/circuitpython/ports/espressif/esp-idf/components/lwip/lwip/src/core/tcp.c:1896
0x420992f6: tcp_listen_input at /home/bill88t/git/circuitpython/ports/espressif/esp-idf/components/lwip/lwip/src/core/tcp_in.c:663
 (inlined by) tcp_input at /home/bill88t/git/circuitpython/ports/espressif/esp-idf/components/lwip/lwip/src/core/tcp_in.c:380
0x4209e32a: ip4_input at /home/bill88t/git/circuitpython/ports/espressif/esp-idf/components/lwip/lwip/src/core/ipv4/ip4.c:803
0x420a1fee: ethernet_input at /home/bill88t/git/circuitpython/ports/espressif/esp-idf/components/lwip/lwip/src/netif/ethernet.c:186
0x42093d91: tcpip_thread_handle_msg at /home/bill88t/git/circuitpython/ports/espressif/esp-idf/components/lwip/lwip/src/api/tcpip.c:180
 (inlined by) tcpip_thread at /home/bill88t/git/circuitpython/ports/espressif/esp-idf/components/lwip/lwip/src/api/tcpip.c:154

I will try to debug it.

bill88t commented 1 year ago

This is not something I can do much with. I think blocking .bind() on an already bound socket is the only way around this.

jepler commented 1 year ago

On standard Python, the 2nd bind call is an exception, because a socket can only be bound to one address:

>>> s.bind(("0.0.0.0", 20000))
>>> s.bind(("0.0.0.0", 20001))
Traceback (most recent call last):
  File "<stdin>", line 1, in <module>
OSError: [Errno 22] Invalid argument
bill88t commented 1 year ago

Can I go ahead and implement the bind lock?

If a bind goes thorough, set the lock at true. If the lock is true, raise OSError(22) on another bind.

bill88t commented 5 months ago

With the new bind logic this no longer produces a safemode but just irregular behavior.