Skip to content

Experimental support for IPv6#7671

Open
achamayou wants to merge 10 commits intomainfrom
ipv6_experiment
Open

Experimental support for IPv6#7671
achamayou wants to merge 10 commits intomainfrom
ipv6_experiment

Conversation

@achamayou
Copy link
Copy Markdown
Member

@achamayou
Copy link
Copy Markdown
Member Author

@copilot build, run the tests, summarize failures and take them into account to apply a tentative fix.

Copy link
Copy Markdown
Contributor

Copilot AI commented Mar 11, 2026

@achamayou I've opened a new pull request, #7732, to work on those changes. Once the pull request is ready, I'll request review from you.

Co-authored-by: copilot-swe-agent[bot] <198982749+Copilot@users.noreply.github.com>
Co-authored-by: achamayou <4016369+achamayou@users.noreply.github.com>
@achamayou achamayou marked this pull request as ready for review March 11, 2026 16:19
@achamayou achamayou requested a review from a team as a code owner March 11, 2026 16:19
Copilot AI review requested due to automatic review settings March 11, 2026 16:19
Copy link
Copy Markdown
Contributor

Copilot AI left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Pull request overview

This PR adds initial end-to-end coverage for IPv6 loopback usage in the test suite, and updates host/node networking code paths to better handle IPv6 addresses (notably in TCP connection setup and certificate SAN generation).

Changes:

  • Add an e2e test that starts a network with RPC interfaces bound to ::1 and exercises common endpoints.
  • Adjust test infra to avoid binding the IPv4-only “client interface” used for partition simulation when the node RPC host is IPv6.
  • Improve IPv6 handling in node certificate SAN construction and in host TCP client socket creation.

Reviewed changes

Copilot reviewed 5 out of 5 changed files in this pull request and generated 2 comments.

Show a summary per file
File Description
tests/infra/node.py Skips node_client_host binding when RPC host is IPv6 to avoid incompatible partition-simulation client interface.
tests/e2e_logging.py Registers a new common_ipv6 sub-test using the logging sample app.
tests/e2e_common_endpoints.py Adds run_ipv6() which forces nodes to bind to ::1 (skipping if IPv6 loopback is unavailable).
src/node/node_state.h Strips brackets from IPv6 hosts when constructing default SANs; updates IPv6-related comment in is_ip().
src/host/tcp.h Defers client socket creation to use the resolved address family (IPv4 vs IPv6).
Comments suppressed due to low confidence (1)

src/node/node_state.h:2347

  • The is_ip() heuristic does not correctly detect general IPv6 literals: it only returns true when the final ':' component is purely numeric, so valid IPv6 addresses ending with hex letters (eg "2001:db8::a") will be treated as DNS names. This can produce incorrect SAN types in generated node certificates and break TLS validation when connecting by IP. Consider replacing this heuristic with a real IPv4/IPv6 parse (eg inet_pton / uv_inet_pton) after stripping brackets (and any zone ID if present).
    bool is_ip(const std::string_view& hostname)
    {
      // IP address components are purely numeric. DNS names may be largely
      // numeric, but at least the final component (TLD) must not be
      // all-numeric. So this distinguishes "1.2.3.4" (an IP address) from
      // "1.2.3.c4m" (a DNS name). "1.2.3." is invalid for either, and will
      // throw. Handles IPv6 by splitting on ':' after splitting on '.'.
      const auto final_component =
        ccf::nonstd::split(ccf::nonstd::split(hostname, ".").back(), ":")
          .back();
      if (final_component.empty())
      {
        throw std::runtime_error(fmt::format(
          "{} has a trailing period, is not a valid hostname", hostname));
      }

      return std::ranges::all_of(
        final_component, [](char c) { return c >= '0' && c <= '9'; });

You can also share your feedback on Copilot code review. Take the survey.

Comment thread src/host/tcp.h
Comment thread src/host/tcp.h
Copilot AI and others added 2 commits April 16, 2026 21:42
Copy link
Copy Markdown
Contributor

Copilot AI commented Apr 16, 2026

@copilot build, run the tests, summarize failures and take them into account to apply a tentative fix.

Done in 1ae1a18.

I ran local checks and reviewed CI failures:

  • Local build currently fails in this environment with fatal error: 'uv.h' file not found in src/tasks/task_system.cpp (pre-existing environment/dependency issue).
  • CI failure logs (run 22936601579) showed common_ipv6 failing to start node 0, causing e2e_logging and e2e_logging_http2 failures.

Tentative fix applied in src/host/tcp.h:

  • avoid repeated uv_tcp_open on already-open handles during reconnect attempts,
  • apply TCP_USER_TIMEOUT on client-bind sockets too,
  • close pre-libuv sockets on error paths to avoid leaks.

Comment thread src/host/tcp.h Outdated

#include <netinet/in.h>
#include <optional>
#ifndef _WIN32
Copy link
Copy Markdown
Member Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

@copilot we don't support WIN32, please remove this include guard.

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Done in 05af854: removed the _WIN32 include guard around <unistd.h> in src/host/tcp.h.

Comment thread src/host/tcp.h Outdated
// This is best-effort cleanup on an existing failure path: we only log
// close() errors (including EINTR). We intentionally do not retry
// close(), since retrying may close a reused fd.
#ifdef _WIN32
Copy link
Copy Markdown
Member Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Drop all WIN32 include guards, we don't want them.

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Done in 262f563: removed the remaining _WIN32 guards in src/host/tcp.h (timeout and socket-close paths).

@achamayou
Copy link
Copy Markdown
Member Author

@copilot add to the description of the PR mermaid flowcharts that show the connection flow before and after your changes.

Agent-Logs-Url: https://github.com/microsoft/CCF/sessions/0cf0011c-18a2-4003-951c-55a903a0b6a5

Co-authored-by: achamayou <4016369+achamayou@users.noreply.github.com>
@achamayou
Copy link
Copy Markdown
Member Author

@copilot add to the description of the PR mermaid flowcharts that show the connection flow before and after your changes.

Agent-Logs-Url: https://github.com/microsoft/CCF/sessions/2caf1046-8ae3-4198-98b2-d97b68196b3f

Co-authored-by: achamayou <4016369+achamayou@users.noreply.github.com>
Copy link
Copy Markdown
Contributor

Copilot AI commented Apr 17, 2026

@copilot add to the description of the PR mermaid flowcharts that show the connection flow before and after your changes.

Updated the PR description with Mermaid flowcharts showing the connection flow before and after the TCP IPv6 retry/timeout changes (update pushed with 262f563).

@copilot add to the description of the PR mermaid flowcharts that show the connection flow before and after your changes.

Updated the PR description with Mermaid flowcharts showing the connection flow before and after the TCP IPv6 retry/timeout changes (update pushed with 262f563).

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

Successfully merging this pull request may close these issues.

3 participants