| ... | ... | @@ -14,6 +14,19 @@ pub const has_unix_sockets = @hasDecl(os.sockaddr, "un") and |
| 14 | 14 | (builtin.target.os.tag != .windows or |
| 15 | 15 | builtin.os.version_range.windows.isAtLeast(.win10_rs4) orelse false); |
| 16 | 16 | |
| 17 | pub const IPParseError = error{ |
| 18 | Overflow, |
| 19 | InvalidEnd, |
| 20 | InvalidCharacter, |
| 21 | Incomplete, |
| 22 | }; |
| 23 | |
| 24 | pub const IPv4ParseError = IPParseError || error{NonCanonical}; |
| 25 | |
| 26 | pub const IPv6ParseError = IPParseError || error{InvalidIpv4Mapping}; |
| 27 | pub const IPv6InterfaceError = os.SocketError || os.IoCtl_SIOCGIFINDEX_Error || error{NameTooLong}; |
| 28 | pub const IPv6ResolveError = IPv6ParseError || IPv6InterfaceError; |
| 29 | |
| 17 | 30 | pub const Address = extern union { |
| 18 | 31 | any: os.sockaddr, |
| 19 | 32 | in: Ip4Address, |
| ... | ... | @@ -77,15 +90,15 @@ pub const Address = extern union { |
| 77 | 90 | } |
| 78 | 91 | } |
| 79 | 92 | |
| 80 | | pub fn parseIp6(buf: []const u8, port: u16) !Address { |
| 93 | pub fn parseIp6(buf: []const u8, port: u16) IPv6ParseError!Address { |
| 81 | 94 | return Address{ .in6 = try Ip6Address.parse(buf, port) }; |
| 82 | 95 | } |
| 83 | 96 | |
| 84 | | pub fn resolveIp6(buf: []const u8, port: u16) !Address { |
| 97 | pub fn resolveIp6(buf: []const u8, port: u16) IPv6ResolveError!Address { |
| 85 | 98 | return Address{ .in6 = try Ip6Address.resolve(buf, port) }; |
| 86 | 99 | } |
| 87 | 100 | |
| 88 | | pub fn parseIp4(buf: []const u8, port: u16) !Address { |
| 101 | pub fn parseIp4(buf: []const u8, port: u16) IPv4ParseError!Address { |
| 89 | 102 | return Address{ .in = try Ip4Address.parse(buf, port) }; |
| 90 | 103 | } |
| 91 | 104 | |
| ... | ... | @@ -198,7 +211,7 @@ pub const Address = extern union { |
| 198 | 211 | pub const Ip4Address = extern struct { |
| 199 | 212 | sa: os.sockaddr.in, |
| 200 | 213 | |
| 201 | | pub fn parse(buf: []const u8, port: u16) !Ip4Address { |
| 214 | pub fn parse(buf: []const u8, port: u16) IPv4ParseError!Ip4Address { |
| 202 | 215 | var result = Ip4Address{ |
| 203 | 216 | .sa = .{ |
| 204 | 217 | .port = mem.nativeToBig(u16, port), |
| ... | ... | @@ -307,7 +320,7 @@ pub const Ip6Address = extern struct { |
| 307 | 320 | /// Parse a given IPv6 address string into an Address. |
| 308 | 321 | /// Assumes the Scope ID of the address is fully numeric. |
| 309 | 322 | /// For non-numeric addresses, see `resolveIp6`. |
| 310 | | pub fn parse(buf: []const u8, port: u16) !Ip6Address { |
| 323 | pub fn parse(buf: []const u8, port: u16) IPv6ParseError!Ip6Address { |
| 311 | 324 | var result = Ip6Address{ |
| 312 | 325 | .sa = os.sockaddr.in6{ |
| 313 | 326 | .scope_id = 0, |
| ... | ... | @@ -424,7 +437,7 @@ pub const Ip6Address = extern struct { |
| 424 | 437 | } |
| 425 | 438 | } |
| 426 | 439 | |
| 427 | | pub fn resolve(buf: []const u8, port: u16) !Ip6Address { |
| 440 | pub fn resolve(buf: []const u8, port: u16) IPv6ResolveError!Ip6Address { |
| 428 | 441 | // TODO: Unify the implementations of resolveIp6 and parseIp6. |
| 429 | 442 | var result = Ip6Address{ |
| 430 | 443 | .sa = os.sockaddr.in6{ |
| ... | ... | @@ -659,7 +672,7 @@ pub fn connectUnixSocket(path: []const u8) !Stream { |
| 659 | 672 | }; |
| 660 | 673 | } |
| 661 | 674 | |
| 662 | | fn if_nametoindex(name: []const u8) !u32 { |
| 675 | fn if_nametoindex(name: []const u8) IPv6InterfaceError!u32 { |
| 663 | 676 | if (builtin.target.os.tag == .linux) { |
| 664 | 677 | var ifr: os.ifreq = undefined; |
| 665 | 678 | const sockfd = try os.socket(os.AF.UNIX, os.SOCK.DGRAM | os.SOCK.CLOEXEC, 0); |