From 94cb32bc4624275e2dc5cd746f58ea202921208d Mon Sep 17 00:00:00 2001 From: Sofia Rodrigues Date: Tue, 21 Oct 2025 11:17:22 -0300 Subject: [PATCH] fix: ipv4 address encoding from libuv to lean (#10854) This PR fixes the IPv4 address encoding from libuv to lean --- src/runtime/uv/dns.cpp | 14 +++++++++++++- tests/lean/run/async_dns.lean | 26 ++++++++++++++++++++++++++ 2 files changed, 39 insertions(+), 1 deletion(-) diff --git a/src/runtime/uv/dns.cpp b/src/runtime/uv/dns.cpp index e72c5077fc..e1cea0349a 100644 --- a/src/runtime/uv/dns.cpp +++ b/src/runtime/uv/dns.cpp @@ -81,7 +81,19 @@ extern "C" LEAN_EXPORT lean_obj_res lean_uv_dns_get_info(b_obj_arg name, b_obj_a for (struct addrinfo* ai = res; ai != NULL; ai = ai->ai_next) { const struct sockaddr* sin_addr = (const struct sockaddr*)ai->ai_addr; - in_addr_storage* storage_addr = (in_addr_storage*)sin_addr->sa_data; + + in_addr_storage* storage_addr; + + if (sin_addr->sa_family == AF_INET) { + struct sockaddr_in* ipv4 = (struct sockaddr_in*)sin_addr; + storage_addr = (in_addr_storage*)&(ipv4->sin_addr); + } else if (sin_addr->sa_family == AF_INET6) { + struct sockaddr_in6* ipv6 = (struct sockaddr_in6*)sin_addr; + storage_addr = (in_addr_storage*)&(ipv6->sin6_addr); + } else { + continue; + } + lean_object* addr = lean_in_addr_storage_to_ip_addr((short)sin_addr->sa_family, storage_addr); arr = lean_array_push(arr, addr); } diff --git a/tests/lean/run/async_dns.lean b/tests/lean/run/async_dns.lean index c6c5dbf617..997d531ec4 100644 --- a/tests/lean/run/async_dns.lean +++ b/tests/lean/run/async_dns.lean @@ -31,6 +31,32 @@ def runDNSNoAscii : Async Unit := do unless infos.size > 0 do (throw <| IO.userError <| "No DNS results for google.com" : IO _) + let ipv4 := infos.filterMap (fun | .v4 e => some e | _ => none) + + if let some head := ipv4[0]? then + let parts : Vector UInt8 4 := head.octets + + let isValid := + -- Not in 0.0.0.0/8 (current network) + parts[0] != 0 && + -- Not in 10.0.0.0/8 (private) + parts[0] != 10 && + -- Not in 127.0.0.0/8 (loopback) + parts[0] != 127 && + -- Not in 169.254.0.0/16 (link-local) + !(parts[0] == 169 && parts[1] == 254) && + -- Not in 172.16.0.0/12 (private) + !(parts[0] == 172 && parts[1] >= 16 && parts[1] <= 31) && + -- Not in 192.168.0.0/16 (private) + !(parts[0] == 192 && parts[1] == 168) && + -- Not in 224.0.0.0/4 (multicast) + parts[0] < 224 && + -- Not 255.255.255.255 (broadcast) + !(parts[0] == 255 && parts[1] == 255 && parts[2] == 255 && parts[3] == 255) + + unless isValid do + throw <| IO.userError <| s!"Invalid IP address for google.com: {parts[0]}.{parts[1]}.{parts[2]}.{parts[3]}" + def runReverseDNS : Async Unit := do let result ← DNS.getNameInfo (.v4 ⟨.ofParts 8 8 8 8, 53⟩) assertBEq result.service "domain"