Skip to content

Commit 0ee06ca

Browse files
committed
Net Module: Fixes in source.rs - rewrote UDP implementation and a few other fixes
1 parent d421137 commit 0ee06ca

File tree

1 file changed

+116
-13
lines changed

1 file changed

+116
-13
lines changed

src/rust/lib_ccxr/src/net/source.rs

Lines changed: 116 additions & 13 deletions
Original file line numberDiff line numberDiff line change
@@ -160,33 +160,136 @@ impl RecvSource {
160160
address,
161161
port,
162162
} => {
163-
let address = address
164-
.map(|x| {
165-
for s in (x, 0).to_socket_addrs().unwrap() {
166-
if let SocketAddr::V4(sv4) = s {
167-
return *sv4.ip();
163+
// Handle address resolution - match C behavior more closely
164+
let address = address.map(|x| {
165+
// First try to parse as direct IP address
166+
if let Ok(ip) = x.parse::<Ipv4Addr>() {
167+
return ip;
168+
}
169+
170+
// Handle localhost specifically
171+
if x == "localhost" {
172+
return Ipv4Addr::LOCALHOST;
173+
}
174+
175+
// Try DNS resolution with more lenient approach
176+
match (x, 0).to_socket_addrs() {
177+
Ok(addrs) => {
178+
for s in addrs {
179+
match s {
180+
SocketAddr::V4(sv4) => return *sv4.ip(),
181+
SocketAddr::V6(sv6) => {
182+
// Convert IPv6 localhost to IPv4
183+
if sv6.ip().is_loopback() {
184+
return Ipv4Addr::LOCALHOST;
185+
}
186+
// Try IPv4-mapped IPv6
187+
if let Some(ipv4) = sv6.ip().to_ipv4_mapped() {
188+
return ipv4;
189+
}
190+
}
191+
}
168192
}
193+
// If we get here, no suitable address was found
194+
fatal!(cause = ExitCause::Failure; "Could not resolve udp address to IPv4")
195+
},
196+
Err(_) => {
197+
fatal!(cause = ExitCause::Failure; "Could not resolve udp address")
169198
}
170-
fatal!(cause = ExitCause::Failure; "Could not resolve udp address")
171-
})
172-
.unwrap_or(Ipv4Addr::UNSPECIFIED);
199+
}
200+
}).unwrap_or(Ipv4Addr::UNSPECIFIED);
173201

202+
// Handle source resolution - don't try to resolve hostnames with ports
174203
let source = source.map(|x| {
175-
for s in (x, 0).to_socket_addrs().unwrap() {
176-
if let SocketAddr::V4(sv4) = s {
177-
return *sv4.ip();
204+
// Check if this looks like hostname:port format (which is invalid for source)
205+
if x.contains(':') {
206+
info!(
207+
"Warning: Source '{}' contains port - this should be hostname only\n",
208+
x
209+
);
210+
// Try to extract just the hostname part
211+
if let Some(hostname) = x.split(':').next() {
212+
info!("Extracting hostname '{}' from '{}'\n", hostname, x);
213+
return resolve_hostname_to_ipv4(hostname);
178214
}
179215
}
180-
fatal!(cause = ExitCause::Failure; "Could not resolve udp source")
216+
217+
resolve_hostname_to_ipv4(x)
181218
});
182219

220+
// Helper function to resolve hostname to IPv4
221+
fn resolve_hostname_to_ipv4(hostname: &str) -> Ipv4Addr {
222+
// First try to parse as direct IP address
223+
if let Ok(ip) = hostname.parse::<Ipv4Addr>() {
224+
info!("Source address: {}\n", ip);
225+
return ip;
226+
}
227+
228+
// Handle localhost specifically
229+
if hostname == "localhost" {
230+
info!("Source address: {}\n", Ipv4Addr::LOCALHOST);
231+
return Ipv4Addr::LOCALHOST;
232+
}
233+
234+
// Try DNS resolution
235+
match (hostname, 0).to_socket_addrs() {
236+
Ok(addrs) => {
237+
for s in addrs {
238+
info!("Resolved address: {}\n", s);
239+
match s {
240+
SocketAddr::V4(sv4) => {
241+
info!("Source address: {}\n", sv4.ip());
242+
return *sv4.ip();
243+
}
244+
SocketAddr::V6(sv6) => {
245+
// Convert IPv6 localhost to IPv4
246+
if sv6.ip().is_loopback() {
247+
info!(
248+
"Source address: {} (converted from IPv6)\n",
249+
Ipv4Addr::LOCALHOST
250+
);
251+
return Ipv4Addr::LOCALHOST;
252+
}
253+
// Try IPv4-mapped IPv6
254+
if let Some(ipv4) = sv6.ip().to_ipv4_mapped() {
255+
info!(
256+
"Source address: {} (converted from IPv6)\n",
257+
ipv4
258+
);
259+
return ipv4;
260+
}
261+
}
262+
}
263+
}
264+
// If we get here, no suitable address was found
265+
info!(
266+
"Warning: Only IPv6 addresses found for {}, but IPv4 required\n",
267+
hostname
268+
);
269+
fatal!(cause = ExitCause::Failure; "Could not resolve udp source to IPv4")
270+
}
271+
Err(e) => {
272+
info!("DNS resolution failed for {}: {}\n", hostname, e);
273+
fatal!(cause = ExitCause::Failure; "Could not resolve udp source")
274+
}
275+
}
276+
}
277+
278+
info!(
279+
"Source: {}\n",
280+
source
281+
.map(|s| s.to_string())
282+
.unwrap_or_else(|| "None".to_string())
283+
);
284+
info!("Source port: {}\n", port);
285+
183286
let socket = Socket::new(Domain::IPV4, Type::DGRAM, None).unwrap_or_else(
184287
|_| fatal!(cause = ExitCause::Failure; "Socket creation error"),
185288
);
186289

187290
if address.is_multicast() {
188291
socket.set_reuse_address(true).unwrap_or_else(|_| {
189-
info!("Cannot not set reuse address\n");
292+
info!("Cannot set reuse address\n");
190293
});
191294
}
192295

0 commit comments

Comments
 (0)