-
-
Notifications
You must be signed in to change notification settings - Fork 8.3k
extmod/asyncio/stream.py: Add ipv6 support to start_server(). #17311
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
base: master
Are you sure you want to change the base?
Conversation
Codecov ReportAll modified and coverable lines are covered by tests ✅
Additional details and impacted files@@ Coverage Diff @@
## master #17311 +/- ##
=======================================
Coverage 98.54% 98.54%
=======================================
Files 169 169
Lines 21898 21898
=======================================
Hits 21579 21579
Misses 319 319 ☔ View full report in Codecov by Sentry. 🚀 New features to boost your workflow:
|
3443947
to
56e8e68
Compare
Code size report:
|
56e8e68
to
6227c48
Compare
Enhance network interface discovery in test framework: - Add get_host_ipv6() function to determine host IPv6 address - Update test template to include IPv6 address lookup - Add helper method for IPv6 IP address retrieval from network interfaces - Support modern interface address format (ifconfig with address type) Signed-off-by: Andrew Leech <andrew.leech@planetinnovation.com.au>
Ensures that the underlying socket is opened with the correct protocol as parsed by getaddrinfo(). Signed-off-by: Andrew Leech <andrew.leech@planetinnovation.com.au>
6227c48
to
3b17ecc
Compare
@@ -180,11 +180,11 @@ async def start_server(cb, host, port, backlog=5, ssl=None): | |||
import socket | |||
|
|||
# Create and bind server socket. | |||
host = socket.getaddrinfo(host, port)[0] # TODO this is blocking! | |||
s = socket.socket() | |||
addr_info = socket.getaddrinfo(host, port)[0] # TODO this is blocking! |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
It would be possible to add the family
argument to start_server()
and pass it through to getaddrinfo()
here. Then you could force it to use IPv6 (or IPv4). But maybe that's a separate PR?
|
||
try: | ||
# Check if IPv6 is supported | ||
socket.socket(socket.AF_INET6, socket.SOCK_STREAM) |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
This detection won't work. All ports based on bare-metal lwIP will let this pass even if they don't have IPv6 enabled.
I don't know if it's possible to detect IPv6??
print("SKIP") | ||
raise SystemExit | ||
|
||
PORT = 8001 # Different from other tests to avoid conflicts |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
I don't think this needs to use a different port, 8000 should be fine.
|
||
async def handle_connection(reader, writer): | ||
# Test that peername exists | ||
peer = writer.get_extra_info("peername") |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
The peer
variable is unused. I don't think you need to call this function at all.
|
||
data = await reader.read(100) | ||
print("read:", data) | ||
assert data == message, "Data mismatch" |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Don't need this assert, the .exp will test the data is correct.
|
||
try: | ||
# Check if IPv6 is supported | ||
socket.socket(socket.AF_INET6, socket.SOCK_STREAM) |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
As above, this detection won't work.
try: | ||
# Connect with IPv6 client | ||
print("connect to ipv6 server") | ||
reader, writer = await asyncio.open_connection("::", PORT) |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
For this to work requires loopback mode in the TCP/IP driver. That's fine on unix, but it'll fail on most bare-metal ports.
# Read response | ||
data = await reader.read(100) | ||
print("read:", data) | ||
assert data == test_msg, "Data mismatch" |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Assert not needed.
@@ -79,19 +79,59 @@ def globals(**gs): | |||
print("SET {{}} = {{!r}}".format(g, gs[g])) | |||
multitest.flush() | |||
@staticmethod | |||
def get_network_ip(): | |||
def _get_ip_from_ifconfig(_nic, ipv6=False): | |||
# Helper to get IP address from an interface object using appropriate format |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
This comment doesn't add much, and I'm confused what "appropriate format" means?
pass | ||
|
||
# Find active network interface | ||
try: |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
The code below is very hard to understand. Why so many try/except's?
Summary
I'm starting to use ipv6 more with micropython devices as their discoverability can actually be much better on a local network, without worrying about needing to manually configure (ipv4) ip addresses.
To that end, this PR adds support to start_server() to automatically use the parsed protocol, ie setting
socket.AF_INET
orsocket.AF_INET6
on the socket as parsed bygetaddrinfo()
When adding unit tests for this change, I found the multi-test runner was missing support for ipv6 ip address detection, so that's been added as well (in a separate commit)
The ip address detection in multi-test runner has also been updated to use the newer / preferred
network.ipconfig("addr4")
style interface by default, falling back to ipconfig if needed.Testing
Unit tests are included which check ipv6 support in both
net_hosted
style test andmult_net
tests.Without the change to
extmod/asyncio/stream.py
the tests fails withOSError: 97
Trade-offs and Alternatives