Skip to content

fix(sdk): allow hostnames in server address configuration#2923

Open
felixfaisal wants to merge 9 commits intoapache:masterfrom
felixfaisal:dev
Open

fix(sdk): allow hostnames in server address configuration#2923
felixfaisal wants to merge 9 commits intoapache:masterfrom
felixfaisal:dev

Conversation

@felixfaisal
Copy link
Copy Markdown

Which issue does this PR close?

Closes #2882

Rationale

Server address validation previously required a literal socket address, preventing the use of DNS hostnames. This change allows hostnames (e.g., localhost:8080) in addition to IP addresses.

What changed?

Server address validation previously relied on SocketAddr parsing, which only accepts literal IP addresses and rejected DNS hostnames (e.g., localhost:8080). This prevented using hostnames when configuring client connections.

Validation now uses ToSocketAddrs, which performs address resolution and returns the list of socket addresses for a given host. TcpStream::connect(...) already performs this resolution internally and attempts to connect to each resolved address.

Local Execution

  • Passed
  • Pre-commit hooks ran

AI Usage

If AI tools were used, please answer:

  1. Which tools? ChatGPT free version
  2. Scope of usage? Write documentations like comments
  3. How did you verify the generated code works correctly?
  • I built the code using cargo build
  • I ran the unit tests under TCPConfigBuilder and added an additional unit test, also modifying another
  • I then ran the server and ran the examples
  1. Can you explain every line of the code if asked? Yup

Signed-off-by: Faisal Ahmed <faisalahmedfarooq46@gmail.com>
Signed-off-by: Faisal Ahmed <faisalahmedfarooq46@gmail.com>
@codecov
Copy link
Copy Markdown

codecov bot commented Mar 15, 2026

Codecov Report

❌ Patch coverage is 97.95918% with 4 lines in your changes missing coverage. Please review.
✅ Project coverage is 71.81%. Comparing base (411a697) to head (ee78d09).

Files with missing lines Patch % Lines
...ebsocket_config/websocket_client_config_builder.rs 0.00% 3 Missing ⚠️
core/common/src/utils/net.rs 99.44% 0 Missing and 1 partial ⚠️
Additional details and impacted files
@@             Coverage Diff              @@
##             master    #2923      +/-   ##
============================================
+ Coverage     71.74%   71.81%   +0.06%     
  Complexity      943      943              
============================================
  Files          1121     1122       +1     
  Lines         93800    93976     +176     
  Branches      71124    71313     +189     
============================================
+ Hits          67301    67485     +184     
+ Misses        23863    23839      -24     
- Partials       2636     2652      +16     
Components Coverage Δ
Rust Core 72.42% <97.95%> (+0.06%) ⬆️
Java SDK 62.30% <ø> (ø)
C# SDK 67.43% <ø> (-0.21%) ⬇️
Python SDK 81.43% <ø> (ø)
Node SDK 91.53% <ø> (+0.21%) ⬆️
Go SDK 38.68% <ø> (ø)
Files with missing lines Coverage Δ
...figuration/tcp_config/tcp_client_config_builder.rs 68.04% <100.00%> (+2.44%) ⬆️
core/common/src/utils/net.rs 99.44% <99.44%> (ø)
...ebsocket_config/websocket_client_config_builder.rs 0.00% <0.00%> (ø)

... and 26 files with indirect coverage changes

🚀 New features to boost your workflow:
  • ❄️ Test Analytics: Detect flaky tests, report on failures, and find test suite problems.
  • 📦 JS Bundle Analysis: Save yourself from yourself by tracking and limiting bundle sizes in JS merges.

Copy link
Copy Markdown
Contributor

@hubcio hubcio left a comment

Choose a reason for hiding this comment

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

hey, thanks for the pr! the intent is solid but there's a fundamental issue with the approach.

to_socket_addrs() calls getaddrinfo() under the hood, which is a synchronous blocking dns lookup. doing this inside build() means config construction now requires network access and can block the thread for seconds if dns is slow. config builders hould be pure/deterministic - th quic builder already gets this right by doing zero address validation in build(). we cannot accept this resolution.

validate the format only (valid host:port structure, port is a valid u16) and leave actual dns resolution to connect time. TcpStream::connect already does resolution internally anyway.

@hubcio
Copy link
Copy Markdown
Contributor

hubcio commented Mar 21, 2026

hello @felixfaisal do you plan to continue?

@felixfaisal
Copy link
Copy Markdown
Author

hello @felixfaisal do you plan to continue?

Hey @hubcio Sorry for not paying attention here, I was a bit caught up this week, I plan to address the comments and update the logic by tonight or late tomorrow. I mostly agree with your review and will do the changes.

Signed-off-by: Faisal Ahmed <faisalahmedfarooq46@gmail.com>
@felixfaisal felixfaisal requested a review from hubcio March 23, 2026 04:36
@felixfaisal felixfaisal changed the title fix(client): allow hostnames in server address configuration fix(rust): allow hostnames in server address configuration Mar 23, 2026
"".to_string(),
))?;

if host.is_empty() {
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.

currently only empty host and bare colons are rejected, but any other characters pass - e.g. "!!!:8080" is accepted. would be good to add basic hostname character validation per RFC 952/1123 (alphanumeric, hyphens, dots) to catch obviously invalid addresses at config time rather than deferring everything to DNS resolution at connect time.

Copy link
Copy Markdown
Author

Choose a reason for hiding this comment

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

Created a separate function, to check if valid IPv4 address and if not check if valid hostname, added a couple of unit tests using claude. ✅
I was thinking if i should use regex or not, and ultimately decided to do it this way.

@hubcio hubcio changed the title fix(rust): allow hostnames in server address configuration fix(sdk): allow hostnames in server address configuration Mar 26, 2026
@hubcio
Copy link
Copy Markdown
Contributor

hubcio commented Mar 26, 2026

@felixfaisal both of these comments are not fixed. do you plan do to so?

felixfaisal and others added 2 commits March 27, 2026 13:49
@felixfaisal felixfaisal requested a review from hubcio March 27, 2026 13:36
@@ -105,11 +104,7 @@ impl TcpClientConfigBuilder {
/// Builds the TCP client configuration.
pub fn build(self) -> Result<TcpClientConfig, IggyError> {
let addr = self.config.server_address.trim();
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.

build() validates the trimmed addr but returns self.config with the original untrimmed server_address. if someone passes " localhost:8090 ", validation passes but TcpStream::connect later gets the whitespace-padded string. same issue in websocket_client_config_builder.rs.

fix: self.config.server_address = self.config.server_address.trim().to_string(); before validating.

Copy link
Copy Markdown
Author

Choose a reason for hiding this comment

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

Updated ✅

/// - Bare IPv6 without brackets (e.g. `::1:8080`) — ambiguous due to colons
/// - Missing port (e.g. `localhost`)
/// - Invalid port (e.g. `localhost:abc`, `localhost:65536`)
pub fn parse_server_address(addr: &str) -> Result<(), IggyError> {
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.

the function name says "parse" but it returns Result<(), IggyError> - it validates, it doesn't parse anything. validate_server_address would be more accurate for a public API, or return a structured type like (host, port) to make the parse useful.

Copy link
Copy Markdown
Author

Choose a reason for hiding this comment

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

Updated to validate_server_address

addr.to_string(),
"".to_string(),
))?;
let ipv6_str = &rest[0..close];
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.

&rest[0..close] - the 0.. is redundant, &rest[..close] is idiomatic.

Copy link
Copy Markdown
Author

Choose a reason for hiding this comment

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

Updated ✅

TcpClientReconnectionConfig, Topic, TopicDetails, TopicPermissions, TransportEndpoints,
TransportProtocol, UserId, UserStatus, Validatable, WebSocketClientConfig,
WebSocketClientConfigBuilder, WebSocketClientReconnectionConfig, defaults, locking,
parse_server_address,
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.

parse_server_address is a low-level validation utility. the builders already call it internally, so SDK consumers rarely need it directly. consider keeping it importable from iggy_common without putting it in the prelude - prelude is for iggy users.

Copy link
Copy Markdown
Author

Choose a reason for hiding this comment

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

Updated ✅

pub(crate) mod duration;
pub(crate) mod expiry;
pub(crate) mod hash;
pub mod net;
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.

pub mod net but the sibling modules are pub(crate). since only parse_server_address is re-exported in lib.rs, this could be pub(crate) mod net to match the pattern.

Copy link
Copy Markdown
Author

Choose a reason for hiding this comment

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

Updated ✅

  - Rename function to better reflect its purpose (validation only, not parsing)
  - Make net module private and only export validate_server_address publicly
  - Update config builders to normalize and validate server addresses
  - Remove duplicate address validation from examples

Signed-off-by: Faisal Ahmed <faisalahmedfarooq46@gmail.com>
@felixfaisal felixfaisal requested a review from hubcio March 28, 2026 11:34
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.

Rust SDK: Support DNS addresses in client

2 participants