Repository navigation
Conversation
normalize_endpoint_url() swaps 0.0.0.0 for one reachable address so clients get a usable endpoint URL, but asyncua listens on the endpoint host, so the server ended up listening on that one address only. Keep the normalized URL as the advertised endpoint and set socket_address to 0.0.0.0 so the listener covers every interface. Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com> Claude-Session: https://claude.ai/code/session_015ZahKj3kRaL9bQVSUQSHjK
Returns ("0.0.0.0", port) for an opc.tcp://0.0.0.0 endpoint and None otherwise; server.py uses it as the asyncua socket address.
Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
Claude-Session: https://claude.ai/code/session_015ZahKj3kRaL9bQVSUQSHjK
Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com> Claude-Session: https://claude.ai/code/session_015ZahKj3kRaL9bQVSUQSHjK
Covers bind_address_for(), the listening socket after a real asyncua start, and TCP connections on loopback and a non-loopback address. Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com> Claude-Session: https://claude.ai/code/session_015ZahKj3kRaL9bQVSUQSHjK
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment
Add this suggestion to a batch that can be applied as a single commit.This suggestion is invalid because no changes were made to the code.Suggestions cannot be applied while the pull request is closed.Suggestions cannot be applied while viewing a subset of changes.Only one suggestion per line can be applied in a batch.Add this suggestion to a batch that can be applied as a single commit.Applying suggestions on deleted lines is not supported.You must change the existing code in this line in order to create a valid suggestion.Outdated suggestions cannot be applied.This suggestion has been applied or marked resolved.Suggestions cannot be applied from pending reviews.Suggestions cannot be applied on multi-line comments.Suggestions cannot be applied while the pull request is queued to merge.Suggestion cannot be applied right now. Please check back later.
Summary
Fixes #210: with the OPC-UA server set to "All interfaces (0.0.0.0)", the runtime listens on a single interface only.
normalize_endpoint_url()replaces0.0.0.0with one reachable address (get_local_ip(), the default-route address) so clients get a usable endpoint URL. asyncua listens on the endpoint host, so the listener ended up bound to that one address: other LANs, loopback and Docker interfaces were not reachable (on the reporter's host, only the modem WAN address was).The fix keeps the normalized URL as the advertised endpoint and sets asyncua's
Server.socket_addressto("0.0.0.0", port)when the configured endpoint is0.0.0.0, so the server listens on every interface. asyncua's discovery already rewrites the endpoint URL to the address each client connected to (match_discovery_source_ip, on by default), so clients on any interface are told an address they can reach. Endpoints with a specific host are unchanged.Not in this PR: the issue comment about retrying when an interface has no address yet at startup, and
::(IPv6 any) endpoints.Ticket
External contribution, no RTOP ticket. Closes #210.
How it was tested
tests/pytest/plugins/opcua/test_endpoint_bind.py(10 tests):bind_address_for()cases;OpcuaServerManager._setup_server()plus a real asyncua start, checking the listening socket is0.0.0.0for an all-interfaces endpoint and the given host otherwise; and a TCP connection on loopback and on a non-loopback address while the endpoint advertises the non-loopback one.server.pychange, the two all-interfaces tests fail: the socket is bound to the advertised address only and the loopback connection is refused. With it, all 10 pass.test_string_types.py,test_read_status.py,test_endpoint_bind.py) passes locally: 36 passed.tests/pytest/plugins/opcuadirectory: 47 failed / 264 passed ondevelopmentbefore the change, 47 failed / 274 passed after; the 47 failures are the same tests (pre-existing, e.g. the test project'sopcua.jsonis format_version 0).Client: sessions opened on both127.0.0.1and the host's LAN address against an all-interfaces server; each client was given the endpoint URL of the address it used.Checklist
bash scripts/run-pytest.shpasses: not run as a whole; the OPC-UA results are above. The opcua directory is red ondevelopmentbefore this change.pre-commit runclean: the new test file passes black, isort, ruff and ruff-format.server.pyandopcua_endpoints_config.pyare not black-formatted ondevelopment, so they were not reformatted here; the change adds no new ruff findings. pylint was not run..claude/review-guidelines.md): Python plugin only, no IPC or scan-cycle change, new behaviour covered by pytest, type hints on the new function.Contributor License Agreement
🤖 Generated with Claude Code
https://claude.ai/code/session_015ZahKj3kRaL9bQVSUQSHjK