Repository navigation
Conversation
The http://, https:// and redis:// naming services cut the host at the first colon, so an address such as `[::1]:8765` failed with "No port after colon" and a channel initialized with a load balancer could not select any server. Keep the bracketed address as the host and turn it into an endpoint directly, since there is nothing to resolve.
Contributor
There was a problem hiding this comment.
Warning
Copilot couldn't run its full agentic review because it didn't start before the timeout. Make sure your repository has a runner available, or add a copilot-code-review.yml file specifying one with the runs-on attribute. See the docs for more details.
Copilot review overview
5 open issues
In C++ code, prefer including<cstring>and usingstd::strchr/std::memcpyto avoid reliance… · New Use consistent capitalization for the acronym “IPv6” in comments and log messages (currently… · New Use consistent capitalization for the acronym “IPv6” in comments and log messages (currently… · New Use consistent capitalization for the acronym “IPv6” in comments and log messages (currently… · New The test reusesserversacross multipleGetServerscalls without explicitly clearing it, which… · New
What changed in this PR
Fixes DomainNamingService failing to parse bracketed IPv6 endpoints (e.g. [::1]:8765) so load-balanced channels can successfully select servers when initialized with IPv6 addresses.
Changes:
- Update
DomainNamingService::GetServersto treat bracketed hosts as IPv6 addresses and parse them viabutil::str2endpoint(skipping DNS). - Add a unit test suite covering valid/invalid bracketed IPv6 forms, including ports, default port, and paths.
| File | Description |
|---|---|
| test/brpc_naming_service_unittest.cpp | Adds test coverage for bracketed IPv6 address parsing in DomainNamingService. |
| src/brpc/policy/domain_naming_service.cpp | Fixes host/port parsing for bracketed IPv6 endpoints and bypasses DNS resolution for direct addresses. |
Review effort: Lite
| #include "butil/build_config.h" // OS_MACOSX | ||
| #include <netdb.h> // gethostbyname_r | ||
| #include <stdlib.h> // strtol | ||
| #include <string.h> // strchr, memcpy |
Comment on lines
+49
to
+50
| // IPv6 address such as `[::1]:8080'. Keep the brackets, which | ||
| // butil::str2endpoint() expects. |
| if (close == nullptr || | ||
| static_cast<size_t>(close - dns_name) + 1 >= sizeof(buf) || | ||
| (close[1] != '\0' && close[1] != ':' && close[1] != '/')) { | ||
| LOG(ERROR) << "Invalid ipv6 address in `" << dns_name << '\''; |
| // An address, not a name: nothing to resolve. | ||
| butil::EndPoint point; | ||
| if (butil::str2endpoint(buf, port, &point) != 0) { | ||
| LOG(ERROR) << "Invalid ipv6 address in `" << dns_name << '\''; |
Comment on lines
+170
to
+191
|
|
||
| ASSERT_EQ(0, dns.GetServers("[::1]:1234", &servers)); | ||
| ASSERT_EQ(1u, servers.size()); | ||
| ASSERT_STREQ("[::1]:1234", butil::endpoint2str(servers[0].addr).c_str()); | ||
|
|
||
| ASSERT_EQ(0, dns.GetServers("[fdbd:dc03:ff:501:b783:830f:f0f5:aa6a]:2280", &servers)); | ||
| ASSERT_EQ(1u, servers.size()); | ||
| ASSERT_STREQ("[fdbd:dc03:ff:501:b783:830f:f0f5:aa6a]:2280", | ||
| butil::endpoint2str(servers[0].addr).c_str()); | ||
|
|
||
| ASSERT_EQ(0, dns.GetServers("[::1]:1234/useless1/useless2", &servers)); | ||
| ASSERT_EQ(1u, servers.size()); | ||
| ASSERT_STREQ("[::1]:1234", butil::endpoint2str(servers[0].addr).c_str()); | ||
|
|
||
| ASSERT_EQ(0, dns.GetServers("[::1]", &servers)); | ||
| ASSERT_EQ(1u, servers.size()); | ||
| ASSERT_STREQ("[::1]:80", butil::endpoint2str(servers[0].addr).c_str()); | ||
|
|
||
| ASSERT_EQ(-1, dns.GetServers("[::1", &servers)); | ||
| ASSERT_EQ(-1, dns.GetServers("[::1]:", &servers)); | ||
| ASSERT_EQ(-1, dns.GetServers("[::1]1234", &servers)); | ||
| ASSERT_EQ(-1, dns.GetServers("[::1]:99999", &servers)); |
Copilot stopped reviewing on behalf of
wwbmmm due to an error
November 13, 2026 09:49
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.

What problem does this PR solve?
Issue Number: resolve #2283
Problem Summary:
A channel initialized with a load balancer and an IPv6 address in an
http://URL never finds a server. With a brpc server listening on[::1]:8765,Init("http://[::1]:8765", "rr", &options)returns 0, but every call then fails with[E61]Fail to select server from http://[::1]:8765 lb=rr, and the naming service logsNo port after colon in '[::1]:8765'.Initwith the same URL and no load balancer succeeds, because the single-server path already parses bracketed addresses.DomainNamingService::GetServers(registered forhttp,httpsandredis) copies the host up to the first:, so for[::1]:8765the host is[and the port parse fails. The address from the issue,[fdbd:dc03:ff:501:b783:830f:f0f5:aa6a]:2280, fails the same way.What is changed and the side effects?
Changed:
When the name starts with
[, the host runs to the matching]. After it only:port, a/pathor the end of the string is accepted, and the port is parsed as before. The bracketed address goes straight tobutil::str2endpoint, the parser the single-server path uses, without a DNS lookup. That does not depend on-dns_support_ipv6, since there is no name to resolve. Host names and IPv4 addresses take the same path as before.NamingServiceTest.domain_with_ipv6_addresscovers an address with a port, the address from the issue, a trailing path, the default port, and five malformed forms (missing], empty port, garbage after], port out of range, not an address). Without the change it fails at the first assertion withWhich is: -1and the sameNo port after colonlog.I tested in Docker on Ubuntu 22.04 (gcc 11.4, CMake build with
BUILD_UNIT_TESTS=ON). All 14 tests inbrpc_naming_service_unittestpass with the change. Without it, the other 13 pass and the new one fails. A small client and server program on[::1]:8765getsOKfrom/healththrough"rr"with the change, and the E61 error above without it.domain_naming_service.cppalso compiles with the CI warning flags plus-Werrorunder gcc 11.4 and clang 14. I did not run the Make or Bazel builds or the rest of the test suite, and I did not test on macOS.Side effects:
Performance effects: none. A bracketed address skips the DNS lookup it could never pass anyway.
Breaking backward compatibility: no. A name that starts with
[could not be resolved before.Check List: