Function resolve [src]

Prototype

pub fn resolve(buf: []const u8, port: u16) IPv6ResolveError!Ip6Address

Parameters

buf: []const u8port: u16

Possible Errors

AccessDenied SocketError

Permission to create a socket of the specified type and/or pro‐tocol is denied.

AddressFamilyNotSupported SocketError

The implementation does not support the specified address family.

FileSystem IoCtl_SIOCGIFINDEX_Error
Incomplete IPParseError
InterfaceNotFound IoCtl_SIOCGIFINDEX_Error
InvalidCharacter IPParseError
InvalidEnd IPParseError
InvalidIpv4Mapping IPv6ParseError
NameTooLong IPv6InterfaceError
Overflow IPParseError
ProcessFdQuotaExceeded SocketError

The per-process limit on the number of open file descriptors has been reached.

ProtocolFamilyNotAvailable SocketError

Unknown protocol, or protocol family not available.

ProtocolNotSupported SocketError

The protocol type or the specified protocol is not supported within this domain.

SocketTypeNotSupported SocketError

The socket type is not supported by the protocol.

SystemFdQuotaExceeded SocketError

The system-wide limit on the total number of open files has been reached.

SystemResources SocketError

Insufficient memory is available. The socket cannot be created until sufficient resources are freed.

Unexpected UnexpectedError

The Operating System returned an undocumented error code.

This error is in theory not possible, but it would be better to handle this error than to invoke undefined behavior.

When this error code is observed, it usually means the Zig Standard Library needs a small patch to add the error code to the error set for the respective function.

Source

pub fn resolve(buf: []const u8, port: u16) IPv6ResolveError!Ip6Address { // TODO: Unify the implementations of resolveIp6 and parseIp6. var result = Ip6Address{ .sa = posix.sockaddr.in6{ .scope_id = 0, .port = mem.nativeToBig(u16, port), .flowinfo = 0, .addr = undefined, }, }; var ip_slice: *[16]u8 = result.sa.addr[0..]; var tail: [16]u8 = undefined; var x: u16 = 0; var saw_any_digits = false; var index: u8 = 0; var abbrv = false; var scope_id = false; var scope_id_value: [posix.IFNAMESIZE - 1]u8 = undefined; var scope_id_index: usize = 0; for (buf, 0..) |c, i| { if (scope_id) { // Handling of percent-encoding should be for an URI library. if ((c >= '0' and c <= '9') or (c >= 'A' and c <= 'Z') or (c >= 'a' and c <= 'z') or (c == '-') or (c == '.') or (c == '_') or (c == '~')) { if (scope_id_index >= scope_id_value.len) { return error.Overflow; } scope_id_value[scope_id_index] = c; scope_id_index += 1; } else { return error.InvalidCharacter; } } else if (c == ':') { if (!saw_any_digits) { if (abbrv) return error.InvalidCharacter; // ':::' if (i != 0) abbrv = true; @memset(ip_slice[index..], 0); ip_slice = tail[0..]; index = 0; continue; } if (index == 14) { return error.InvalidEnd; } ip_slice[index] = @as(u8, @truncate(x >> 8)); index += 1; ip_slice[index] = @as(u8, @truncate(x)); index += 1; x = 0; saw_any_digits = false; } else if (c == '%') { if (!saw_any_digits) { return error.InvalidCharacter; } scope_id = true; saw_any_digits = false; } else if (c == '.') { if (!abbrv or ip_slice[0] != 0xff or ip_slice[1] != 0xff) { // must start with '::ffff:' return error.InvalidIpv4Mapping; } const start_index = mem.lastIndexOfScalar(u8, buf[0..i], ':').? + 1; const addr = (Ip4Address.parse(buf[start_index..], 0) catch { return error.InvalidIpv4Mapping; }).sa.addr; ip_slice = result.sa.addr[0..]; ip_slice[10] = 0xff; ip_slice[11] = 0xff; const ptr = mem.sliceAsBytes(@as(*const [1]u32, &addr)[0..]); ip_slice[12] = ptr[0]; ip_slice[13] = ptr[1]; ip_slice[14] = ptr[2]; ip_slice[15] = ptr[3]; return result; } else { const digit = try std.fmt.charToDigit(c, 16); { const ov = @mulWithOverflow(x, 16); if (ov[1] != 0) return error.Overflow; x = ov[0]; } { const ov = @addWithOverflow(x, digit); if (ov[1] != 0) return error.Overflow; x = ov[0]; } saw_any_digits = true; } } if (!saw_any_digits and !abbrv) { return error.Incomplete; } if (scope_id and scope_id_index == 0) { return error.Incomplete; } var resolved_scope_id: u32 = 0; if (scope_id_index > 0) { const scope_id_str = scope_id_value[0..scope_id_index]; resolved_scope_id = std.fmt.parseInt(u32, scope_id_str, 10) catch |err| blk: { if (err != error.InvalidCharacter) return err; break :blk try if_nametoindex(scope_id_str); }; } result.sa.scope_id = resolved_scope_id; if (index == 14) { ip_slice[14] = @as(u8, @truncate(x >> 8)); ip_slice[15] = @as(u8, @truncate(x)); return result; } else { ip_slice[index] = @as(u8, @truncate(x >> 8)); index += 1; ip_slice[index] = @as(u8, @truncate(x)); index += 1; @memcpy(result.sa.addr[16 - index ..][0..index], ip_slice[0..index]); return result; } }