Skip to content

Commit 314c764

Browse files
committed
fix: IPv6 TCP connection support
Three bugs prevented native IPv6 TCP connections from working: 1. TcpListenerConnection::serve_listener() assigned the remote peer address as the connection's local address (tcp_listener.rs). For IPv4-mapped addresses this was harmless, but for native IPv6 it produced an invalid local address. Fixed by capturing the listener's actual local address before the accept loop. 2. build_via_received() serialized IPv6 addresses without brackets in the Via received= parameter (connection.rs), producing received=2001:db8::1 instead of received=[2001:db8::1]. When rsip re-parsed this, it misinterpreted colons as port separators. 3. serve_connection() silently discarded the Result from serve_loop() (transport_layer.rs), making transport errors invisible. The error is now logged at warn level. Tested with production Ribbon SBC traffic over TCP/IPv6. All three fixes are required for native IPv6 TCP to work end-to-end. Relates to #94 (similar parser failures in on_received_message).
1 parent 0f40684 commit 314c764

3 files changed

Lines changed: 14 additions & 6 deletions

File tree

src/transport/connection.rs

Lines changed: 5 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -347,9 +347,13 @@ impl SipConnection {
347347
typed_via.params.push(Param::Transport(transport));
348348
}
349349

350+
let received_str = match addr {
351+
SocketAddr::V6(_) => format!("[{}]", received.host),
352+
_ => received.host.to_string(),
353+
};
350354
*via = typed_via
351355
.with_param(Param::Received(rsip::param::Received::new(
352-
received.host.to_string(),
356+
received_str,
353357
)))
354358
.with_param(Param::Other(
355359
rsip::param::OtherParam::new("rport"),

src/transport/tcp_listener.rs

Lines changed: 5 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -36,6 +36,10 @@ impl TcpListenerConnection {
3636
transport_layer_inner: TransportLayerInnerRef,
3737
) -> Result<()> {
3838
let listener = TcpListener::bind(self.inner.local_addr.get_socketaddr()?).await?;
39+
let listener_local_addr = SipAddr {
40+
r#type: Some(rsip::transport::Transport::Tcp),
41+
addr: listener.local_addr().unwrap().into(),
42+
};
3943
tokio::spawn(async move {
4044
loop {
4145
let (stream, remote_addr) = match listener.accept().await {
@@ -49,10 +53,7 @@ impl TcpListenerConnection {
4953
debug!(remote = %remote_addr, "tcp connection rejected by whitelist");
5054
continue;
5155
}
52-
let local_addr = SipAddr {
53-
r#type: Some(rsip::transport::Transport::Tcp),
54-
addr: remote_addr.into(),
55-
};
56+
let local_addr = listener_local_addr.clone();
5657
let tcp_connection = match TcpConnection::from_stream(
5758
stream,
5859
local_addr.clone(),

src/transport/transport_layer.rs

Lines changed: 4 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -431,9 +431,12 @@ impl TransportLayerInner {
431431
}
432432
select! {
433433
_ = sub_token.cancelled() => { }
434-
_ = async {
434+
result = async {
435435
transport.serve_loop(sender_clone.clone()).await
436436
} => {
437+
if let Err(e) = result {
438+
warn!(addr=%transport.get_addr(), error = %e, "serve_loop error");
439+
}
437440
}
438441
}
439442
info!(addr=%transport.get_addr(), "transport serve_loop exited");

0 commit comments

Comments
 (0)