Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Only allows one TLS connection at a time #134

Open
askpatrickw opened this issue Apr 15, 2021 · 8 comments
Open

Only allows one TLS connection at a time #134

askpatrickw opened this issue Apr 15, 2021 · 8 comments

Comments

@askpatrickw
Copy link

In release 3.5.3 a change was made:
"Only allow one TLS connection at a time. Nina FW doesn't work well with multiple."

This broke the Azure_IOT workflow where you use HTTP to determiner your Iot Hub and then connect to it over MQTT.
adafruit/Adafruit_CircuitPython_AzureIoT#31 (comment)

There was a workaround for that library, but I wanted to document the issue.

@justmobilize
Copy link
Collaborator

@tannewt do you remember (almost 4 years ago), why this was removed?

Testing, using:

from digitalio import DigitalInOut
import board
import os

import adafruit_connection_manager
from adafruit_esp32spi import adafruit_esp32spi

esp32_cs = DigitalInOut(board.D13)
esp32_ready = DigitalInOut(board.D11)
esp32_reset = DigitalInOut(board.D12)

spi = board.SPI()
esp = adafruit_esp32spi.ESP_SPIcontrol(spi, esp32_cs, esp32_ready, esp32_reset)

# Get WiFi details, ensure these are setup in settings.toml
ssid = os.getenv("WIFI_SSID")
password = os.getenv("WIFI_PASSWORD")

print(f"\nConnecting to {ssid}...")
esp.connect(ssid, password)
print("connected")

pool = adafruit_connection_manager.get_radio_socketpool(esp)
ssl_context = adafruit_connection_manager.get_radio_ssl_context(esp)

connection_manager = adafruit_connection_manager.get_connection_manager(pool)
socket_1 = connection_manager.get_socket("io.adafruit.com", 443, "https:", is_ssl=True, ssl_context=ssl_context)
socket_2 = connection_manager.get_socket("www.adafruit.com", 443, "https:", is_ssl=True, ssl_context=ssl_context)

I get:

>>> socket_1 = connection_manager.get_socket("io.adafruit.com", 443, "https:", is_ssl=True, ssl_context=ssl_context)
>>> socket_2 = connection_manager.get_socket("www.adafruit.com", 443, "https:", is_ssl=True, ssl_context=ssl_context)
Traceback (most recent call last):
  File "<stdin>", line 1, in <module>
  File "adafruit_connection_manager.py", line 332, in get_socket
  File "adafruit_connection_manager.py", line 244, in _get_connected_socket
  File "adafruit_connection_manager.py", line 61, in connect
  File "adafruit_esp32spi/adafruit_esp32spi_socketpool.py", line 114, in connect
  File "adafruit_esp32spi/adafruit_esp32spi.py", line 836, in socket_connect
  File "adafruit_esp32spi/adafruit_esp32spi.py", line 721, in socket_open
OSError: 23

If I comment out the code to only allow 1 I get:

>>> socket_1 = connection_manager.get_socket("io.adafruit.com", 443, "https:", is_ssl=True, ssl_context=ssl_context)
>>> socket_2 = connection_manager.get_socket("www.adafruit.com", 443, "https:", is_ssl=True, ssl_context=ssl_context)
Traceback (most recent call last):
  File "<stdin>", line 1, in <module>
  File "adafruit_connection_manager.py", line 332, in get_socket
  File "adafruit_connection_manager.py", line 244, in _get_connected_socket
  File "adafruit_connection_manager.py", line 61, in connect
  File "/lib/adafruit_esp32spi/adafruit_esp32spi_socketpool.py", line 114, in connect
  File "/lib/adafruit_esp32spi/adafruit_esp32spi.py", line 836, in socket_connect
  File "/lib/adafruit_esp32spi/adafruit_esp32spi.py", line 732, in socket_open
  File "/lib/adafruit_esp32spi/adafruit_esp32spi.py", line 341, in _send_command_get_response
  File "/lib/adafruit_esp32spi/adafruit_esp32spi.py", line 311, in _wait_response_cmd
  File "/lib/adafruit_esp32spi/adafruit_esp32spi.py", line 293, in _check_data
BrokenPipeError: Expected 01 but got 00

cc @dhalbert

@dhalbert
Copy link
Contributor

dhalbert commented May 24, 2024

I found a discussion in the forums that includes @tannewt that is at the same time as the 3.5.3 release: https://forums.adafruit.com/viewtopic.php?p=836698

@anecdata
Copy link
Member

anecdata commented May 24, 2024

I think this† has been noted before, but I can't find it:

secure_socks = []
for sock_num, _ in enumerate(HOSTS):
    secure_socks.append(
        ssl_context.wrap_socket(
            pool.socket(pool.AF_INET, pool.SOCK_STREAM),
            server_hostname=HOSTS[sock_num]
        )
    )

with debug=2, results in:

*** Get socket
	Parameter #0 length is 1
Read 1:  [bytearray(b'\x00')]
Allocated socket #0
*** Get socket
	Parameter #0 length is 1
Read 1:  [bytearray(b'\x00')]
Allocated socket #0

†Seems to be allocating the same socket? That socket number is coming from NINA.

If we change the code to use the created secure socket (connect, write, read) before allocating the second one, we get further since a new socket number is allocated, but still OSError: 23 (on connect() to the 2nd secure socket):

*** Get socket
	Parameter #0 length is 1
Read 1:  [bytearray(b'\x01')]
Allocated socket #1
=========================
Connecting to remote socket...
*** Socket connect mode 2
*** Open socket to www.adafruit.com 443 2
Traceback (most recent call last):
  File "code.py", line 37, in <module>
  File "adafruit_connection_manager.py", line 69, in connect
  File "adafruit_esp32spi/adafruit_esp32spi_socketpool.py", line 142, in connect
  File "adafruit_esp32spi/adafruit_esp32spi.py", line 836, in socket_connect
  File "adafruit_esp32spi/adafruit_esp32spi.py", line 721, in socket_open
OSError: 23

@tannewt
Copy link
Member

tannewt commented May 24, 2024

I don't remember. Sorry!

@dhalbert
Copy link
Contributor

Given this testing, I'm not sure this can be fixed now. We can revisit after adafruit/nina-fw#62 is done. In the meantime, I'll merge #207.

@justmobilize
Copy link
Collaborator

I think this has been noted before, but I can't find it:

secure_socks = []
for sock_num, _ in enumerate(HOSTS):
    secure_socks.append(
        ssl_context.wrap_socket(
            pool.socket(pool.AF_INET, pool.SOCK_STREAM),
            server_hostname=HOSTS[sock_num]
        )
    )

results in (debug=2):

*** Get socket
	Parameter #0 length is 1
Read 1:  [bytearray(b'\x00')]
Allocated socket #0
*** Get socket
	Parameter #0 length is 1
Read 1:  [bytearray(b'\x00')]
Allocated socket #0

Seems to be allocating the same socket? That socket number is coming from NINA.

If we change the code to use the created secure socket (connect, write, read) before allocating the second one, we get further since a new socket number is allocated, but still OSError: 23 (on connect() to the 2nd secure socket):

*** Get socket
	Parameter #0 length is 1
Read 1:  [bytearray(b'\x01')]
Allocated socket #1
=========================
Connecting to remote socket...
*** Socket connect mode 2
*** Open socket to www.adafruit.com 443 2
Traceback (most recent call last):
  File "code.py", line 37, in <module>
  File "adafruit_connection_manager.py", line 69, in connect
  File "adafruit_esp32spi/adafruit_esp32spi_socketpool.py", line 142, in connect
  File "adafruit_esp32spi/adafruit_esp32spi.py", line 836, in socket_connect
  File "adafruit_esp32spi/adafruit_esp32spi.py", line 721, in socket_open
OSError: 23

I think this has been noted before, but I can't find it:

secure_socks = []
for sock_num, _ in enumerate(HOSTS):
    secure_socks.append(
        ssl_context.wrap_socket(
            pool.socket(pool.AF_INET, pool.SOCK_STREAM),
            server_hostname=HOSTS[sock_num]
        )
    )

results in (debug=2):

*** Get socket
	Parameter #0 length is 1
Read 1:  [bytearray(b'\x00')]
Allocated socket #0
*** Get socket
	Parameter #0 length is 1
Read 1:  [bytearray(b'\x00')]
Allocated socket #0

Seems to be allocating the same socket? That socket number is coming from NINA.

If we change the code to use the created secure socket (connect, write, read) before allocating the second one, we get further since a new socket number is allocated, but still OSError: 23 (on connect() to the 2nd secure socket):

*** Get socket
	Parameter #0 length is 1
Read 1:  [bytearray(b'\x01')]
Allocated socket #1
=========================
Connecting to remote socket...
*** Socket connect mode 2
*** Open socket to www.adafruit.com 443 2
Traceback (most recent call last):
  File "code.py", line 37, in <module>
  File "adafruit_connection_manager.py", line 69, in connect
  File "adafruit_esp32spi/adafruit_esp32spi_socketpool.py", line 142, in connect
  File "adafruit_esp32spi/adafruit_esp32spi.py", line 836, in socket_connect
  File "adafruit_esp32spi/adafruit_esp32spi.py", line 721, in socket_open
OSError: 23

A assume in this case HOSTS are two very different hosts?

@justmobilize
Copy link
Collaborator

Given this testing, I'm not sure this can be fixed now. We can revisit after adafruit/nina-fw#62 is done. In the meantime, I'll merge #207.

This was going to be my suggestion

@anecdata
Copy link
Member

anecdata commented May 24, 2024

assume in this case HOSTS are two very different hosts?

@justmobilize I used the same two Adafruit hosts (subdomains) that you did

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
None yet
Projects
None yet
Development

No branches or pull requests

5 participants