store proper ip strings in new ip2l cache
All checks were successful
Generic zig build / build (push) Successful in 1m22s
Generic zig build / deploy (push) Successful in 13s

This commit is contained in:
Emil Lerch 2026-01-08 20:38:17 -08:00
parent a79094efdc
commit e8e31b25e8
Signed by: lobo
GPG key ID: A7B62D657EF764F8
2 changed files with 33 additions and 14 deletions

View file

@ -232,13 +232,14 @@ pub const Cache = struct {
const lat = try std.fmt.parseFloat(f64, lat_str);
const lon = try std.fmt.parseFloat(f64, lon_str);
// Parse IP to u128
const addr = try std.net.Address.parseIp(ip_str, 0);
const ip_u128: u128 = switch (addr.any.family) {
std.posix.AF.INET => @as(u128, @intCast(std.mem.readInt(u32, @ptrCast(&addr.in.sa.addr), .big))),
std.posix.AF.INET6 => std.mem.readInt(u128, @ptrCast(&addr.in6.sa.addr), .big),
else => return error.InvalidIpFamily,
};
// Try parsing as IP address first, fall back to u128
const ip_u128 = if (std.net.Address.parseIp(ip_str, 0)) |addr| blk: {
break :blk switch (addr.any.family) {
std.posix.AF.INET => @as(u128, @intCast(std.mem.readInt(u32, @ptrCast(&addr.in.sa.addr), .big))),
std.posix.AF.INET6 => std.mem.readInt(u128, @ptrCast(&addr.in6.sa.addr), .big),
else => return error.InvalidIpFamily,
};
} else |_| try std.fmt.parseInt(u128, ip_str, 10);
const name_copy = try allocator.dupe(u8, name);
return .{
@ -255,7 +256,7 @@ pub const Cache = struct {
return self.entries.get(ip);
}
pub fn put(self: *Cache, ip: u128, _: u8, loc: Location) !void {
pub fn put(self: *Cache, ip: u128, family: u8, loc: Location) !void {
const name_copy = try self.allocator.dupe(u8, loc.name);
try self.entries.put(ip, .{
.allocator = self.allocator,
@ -267,8 +268,25 @@ pub const Cache = struct {
if (self.file) |file| {
try file.seekFromEnd(0);
// Format IP as string for file
var buf: [39]u8 = undefined;
const ip_str = try std.fmt.bufPrint(&buf, "{}", .{ip});
var buf: [64]u8 = undefined;
const ip_str = if (family == 4)
try std.fmt.bufPrint(&buf, "{}.{}.{}.{}", .{
@as(u8, @truncate(ip >> 24)),
@as(u8, @truncate(ip >> 16)),
@as(u8, @truncate(ip >> 8)),
@as(u8, @truncate(ip)),
})
else
try std.fmt.bufPrint(&buf, "{x:0>4}:{x:0>4}:{x:0>4}:{x:0>4}:{x:0>4}:{x:0>4}:{x:0>4}:{x:0>4}", .{
@as(u16, @truncate(ip >> 112)),
@as(u16, @truncate(ip >> 96)),
@as(u16, @truncate(ip >> 80)),
@as(u16, @truncate(ip >> 64)),
@as(u16, @truncate(ip >> 48)),
@as(u16, @truncate(ip >> 32)),
@as(u16, @truncate(ip >> 16)),
@as(u16, @truncate(ip)),
});
const line = try std.fmt.allocPrint(self.allocator, "{s},{d},{d},{s}\n", .{
ip_str,
loc.coords.latitude,
@ -323,7 +341,7 @@ test "parseCacheLine: missing fields" {
test "parseCacheLine: invalid IP" {
const allocator = std.testing.allocator;
const line = "not.an.ip,37.5,-122.5,Test";
try std.testing.expectError(error.InvalidIPAddressFormat, Cache.parseCacheLine(allocator, line));
try std.testing.expectError(error.InvalidCharacter, Cache.parseCacheLine(allocator, line));
}
test "parseCacheLine: invalid latitude" {

View file

@ -134,9 +134,10 @@ pub const Resolver = struct {
return error.LocationNotFound;
}
// Format IP address
const ip_str = try std.fmt.allocPrint(self.allocator, "{any}", .{addr_list.addrs[0].any});
defer self.allocator.free(ip_str);
// Format IP address using std.net.Address.format
const addr = addr_list.addrs[0];
var buf: [64]u8 = undefined;
const ip_str = try std.fmt.bufPrint(&buf, "{f}", .{addr});
return self.resolveIP(ip_str);
}