Commit c4f97d3365
Changed files (8)
lib
std
lib/std/c/linux.zig
@@ -31,6 +31,7 @@ pub const MAP = struct {
pub const FAILED = @intToPtr(*c_void, maxInt(usize));
};
pub const MMAP2_UNIT = linux.MMAP2_UNIT;
+pub const MSG = linux.MSG;
pub const NAME_MAX = linux.NAME_MAX;
pub const O = linux.O;
pub const PATH_MAX = linux.PATH_MAX;
@@ -54,6 +55,7 @@ pub const STDIN_FILENO = linux.STDIN_FILENO;
pub const STDOUT_FILENO = linux.STDOUT_FILENO;
pub const SYS = linux.SYS;
pub const Sigaction = linux.Sigaction;
+pub const TCP = linux.TCP;
pub const VDSO = linux.VDSO;
pub const W = linux.W;
pub const W_OK = linux.W_OK;
lib/std/c/windows.zig
@@ -204,7 +204,9 @@ pub const in_addr = u32;
pub const addrinfo = ws2_32.addrinfo;
pub const AF = ws2_32.AF;
+pub const MSG = ws2_32.MSG;
pub const SOCK = ws2_32.SOCK;
+pub const TCP = ws2_32.TCP;
pub const IPPROTO = ws2_32.IPPROTO;
pub const BTHPROTO_RFCOMM = ws2_32.BTHPROTO_RFCOMM;
@@ -214,7 +216,6 @@ pub const POLL = ws2_32.POLL;
pub const SOL = ws2_32.SOL;
pub const SO = ws2_32.SO;
pub const PVD_CONFIG = ws2_32.PVD_CONFIG;
-pub const TCP_NODELAY = ws2_32.TCP_NODELAY;
pub const O = struct {
pub const RDONLY = 0o0;
lib/std/os/windows/ws2_32.zig
@@ -442,27 +442,33 @@ pub const PROTECTION_LEVEL_EDGERESTRICTED = 20;
pub const PROTECTION_LEVEL_RESTRICTED = 30;
pub const INET_ADDRSTRLEN = 22;
pub const INET6_ADDRSTRLEN = 65;
-pub const TCP_OFFLOAD_NO_PREFERENCE = 0;
-pub const TCP_OFFLOAD_NOT_PREFERRED = 1;
-pub const TCP_OFFLOAD_PREFERRED = 2;
-pub const TCP_EXPEDITED_1122 = 2;
-pub const TCP_KEEPALIVE = 3;
-pub const TCP_MAXSEG = 4;
-pub const TCP_MAXRT = 5;
-pub const TCP_STDURG = 6;
-pub const TCP_NOURG = 7;
-pub const TCP_ATMARK = 8;
-pub const TCP_NOSYNRETRIES = 9;
-pub const TCP_TIMESTAMPS = 10;
-pub const TCP_OFFLOAD_PREFERENCE = 11;
-pub const TCP_CONGESTION_ALGORITHM = 12;
-pub const TCP_DELAY_FIN_ACK = 13;
-pub const TCP_MAXRTMS = 14;
-pub const TCP_FASTOPEN = 15;
-pub const TCP_KEEPCNT = 16;
-pub const TCP_KEEPINTVL = 17;
-pub const TCP_FAIL_CONNECT_ON_ICMP_ERROR = 18;
-pub const TCP_ICMP_ERROR_INFO = 19;
+
+pub const TCP = struct {
+ pub const NODELAY = 1;
+ pub const EXPEDITED_1122 = 2;
+ pub const OFFLOAD_NO_PREFERENCE = 0;
+ pub const OFFLOAD_NOT_PREFERRED = 1;
+ pub const OFFLOAD_PREFERRED = 2;
+ pub const KEEPALIVE = 3;
+ pub const MAXSEG = 4;
+ pub const MAXRT = 5;
+ pub const STDURG = 6;
+ pub const NOURG = 7;
+ pub const ATMARK = 8;
+ pub const NOSYNRETRIES = 9;
+ pub const TIMESTAMPS = 10;
+ pub const OFFLOAD_PREFERENCE = 11;
+ pub const CONGESTION_ALGORITHM = 12;
+ pub const DELAY_FIN_ACK = 13;
+ pub const MAXRTMS = 14;
+ pub const FASTOPEN = 15;
+ pub const KEEPCNT = 16;
+ pub const KEEPINTVL = 17;
+ pub const FAIL_CONNECT_ON_ICMP_ERROR = 18;
+ pub const ICMP_ERROR_INFO = 19;
+ pub const BSDURGENT = 28672;
+};
+
pub const UDP_SEND_MSG_SIZE = 2;
pub const UDP_RECV_MAX_COALESCED_SIZE = 3;
pub const UDP_COALESCED_INFO = 3;
@@ -578,7 +584,6 @@ pub const SO = struct {
};
pub const WSK_SO_BASE = 16384;
-pub const TCP_NODELAY = 1;
pub const IOC_UNIX = 0;
pub const IOC_WS2 = 134217728;
pub const IOC_PROTOCOL = 268435456;
@@ -846,7 +851,6 @@ pub const POLL = struct {
pub const NVAL = 4;
};
-pub const TCP_BSDURGENT = 28672;
pub const TF_DISCONNECT = 1;
pub const TF_REUSE_SOCKET = 2;
pub const TF_WRITE_BEHIND = 4;
lib/std/os/linux.zig
@@ -2007,6 +2007,82 @@ pub const SOCK = struct {
pub const NONBLOCK = if (is_mips) 0o200 else 0o4000;
};
+pub const TCP = struct {
+ /// Turn off Nagle's algorithm
+ pub const NODELAY = 1;
+ /// Limit MSS
+ pub const MAXSEG = 2;
+ /// Never send partially complete segments.
+ pub const CORK = 3;
+ /// Start keeplives after this period, in seconds
+ pub const KEEPIDLE = 4;
+ /// Interval between keepalives
+ pub const KEEPINTVL = 5;
+ /// Number of keepalives before death
+ pub const KEEPCNT = 6;
+ /// Number of SYN retransmits
+ pub const SYNCNT = 7;
+ /// Life time of orphaned FIN-WAIT-2 state
+ pub const LINGER2 = 8;
+ /// Wake up listener only when data arrive
+ pub const DEFER_ACCEPT = 9;
+ /// Bound advertised window
+ pub const WINDOW_CLAMP = 10;
+ /// Information about this connection.
+ pub const INFO = 11;
+ /// Block/reenable quick acks
+ pub const QUICKACK = 12;
+ /// Congestion control algorithm
+ pub const CONGESTION = 13;
+ /// TCP MD5 Signature (RFC2385)
+ pub const MD5SIG = 14;
+ /// Use linear timeouts for thin streams
+ pub const THIN_LINEAR_TIMEOUTS = 16;
+ /// Fast retrans. after 1 dupack
+ pub const THIN_DUPACK = 17;
+ /// How long for loss retry before timeout
+ pub const USER_TIMEOUT = 18;
+ /// TCP sock is under repair right now
+ pub const REPAIR = 19;
+ pub const REPAIR_QUEUE = 20;
+ pub const QUEUE_SEQ = 21;
+ pub const REPAIR_OPTIONS = 22;
+ /// Enable FastOpen on listeners
+ pub const FASTOPEN = 23;
+ pub const TIMESTAMP = 24;
+ /// limit number of unsent bytes in write queue
+ pub const NOTSENT_LOWAT = 25;
+ /// Get Congestion Control (optional) info
+ pub const CC_INFO = 26;
+ /// Record SYN headers for new connections
+ pub const SAVE_SYN = 27;
+ /// Get SYN headers recorded for connection
+ pub const SAVED_SYN = 28;
+ /// Get/set window parameters
+ pub const REPAIR_WINDOW = 29;
+ /// Attempt FastOpen with connect
+ pub const FASTOPEN_CONNECT = 30;
+ /// Attach a ULP to a TCP connection
+ pub const ULP = 31;
+ /// TCP MD5 Signature with extensions
+ pub const MD5SIG_EXT = 32;
+ /// Set the key for Fast Open (cookie)
+ pub const FASTOPEN_KEY = 33;
+ /// Enable TFO without a TFO cookie
+ pub const FASTOPEN_NO_COOKIE = 34;
+ pub const ZEROCOPY_RECEIVE = 35;
+ /// Notify bytes available to read as a cmsg on read
+ pub const INQ = 36;
+ pub const CM_INQ = INQ;
+ /// delay outgoing packets by XX usec
+ pub const TX_DELAY = 37;
+
+ pub const REPAIR_ON = 1;
+ pub const REPAIR_OFF = 0;
+ /// Turn off without window probes
+ pub const REPAIR_OFF_NO_WP = -1;
+};
+
pub const PF = struct {
pub const UNSPEC = 0;
pub const LOCAL = 1;
@@ -3606,80 +3682,6 @@ pub const RR = struct {
pub const AAAA = 28;
};
-/// Turn off Nagle's algorithm
-pub const TCP_NODELAY = 1;
-/// Limit MSS
-pub const TCP_MAXSEG = 2;
-/// Never send partially complete segments.
-pub const TCP_CORK = 3;
-/// Start keeplives after this period, in seconds
-pub const TCP_KEEPIDLE = 4;
-/// Interval between keepalives
-pub const TCP_KEEPINTVL = 5;
-/// Number of keepalives before death
-pub const TCP_KEEPCNT = 6;
-/// Number of SYN retransmits
-pub const TCP_SYNCNT = 7;
-/// Life time of orphaned FIN-WAIT-2 state
-pub const TCP_LINGER2 = 8;
-/// Wake up listener only when data arrive
-pub const TCP_DEFER_ACCEPT = 9;
-/// Bound advertised window
-pub const TCP_WINDOW_CLAMP = 10;
-/// Information about this connection.
-pub const TCP_INFO = 11;
-/// Block/reenable quick acks
-pub const TCP_QUICKACK = 12;
-/// Congestion control algorithm
-pub const TCP_CONGESTION = 13;
-/// TCP MD5 Signature (RFC2385)
-pub const TCP_MD5SIG = 14;
-/// Use linear timeouts for thin streams
-pub const TCP_THIN_LINEAR_TIMEOUTS = 16;
-/// Fast retrans. after 1 dupack
-pub const TCP_THIN_DUPACK = 17;
-/// How long for loss retry before timeout
-pub const TCP_USER_TIMEOUT = 18;
-/// TCP sock is under repair right now
-pub const TCP_REPAIR = 19;
-pub const TCP_REPAIR_QUEUE = 20;
-pub const TCP_QUEUE_SEQ = 21;
-pub const TCP_REPAIR_OPTIONS = 22;
-/// Enable FastOpen on listeners
-pub const TCP_FASTOPEN = 23;
-pub const TCP_TIMESTAMP = 24;
-/// limit number of unsent bytes in write queue
-pub const TCP_NOTSENT_LOWAT = 25;
-/// Get Congestion Control (optional) info
-pub const TCP_CC_INFO = 26;
-/// Record SYN headers for new connections
-pub const TCP_SAVE_SYN = 27;
-/// Get SYN headers recorded for connection
-pub const TCP_SAVED_SYN = 28;
-/// Get/set window parameters
-pub const TCP_REPAIR_WINDOW = 29;
-/// Attempt FastOpen with connect
-pub const TCP_FASTOPEN_CONNECT = 30;
-/// Attach a ULP to a TCP connection
-pub const TCP_ULP = 31;
-/// TCP MD5 Signature with extensions
-pub const TCP_MD5SIG_EXT = 32;
-/// Set the key for Fast Open (cookie)
-pub const TCP_FASTOPEN_KEY = 33;
-/// Enable TFO without a TFO cookie
-pub const TCP_FASTOPEN_NO_COOKIE = 34;
-pub const TCP_ZEROCOPY_RECEIVE = 35;
-/// Notify bytes available to read as a cmsg on read
-pub const TCP_INQ = 36;
-pub const TCP_CM_INQ = TCP_INQ;
-/// delay outgoing packets by XX usec
-pub const TCP_TX_DELAY = 37;
-
-pub const TCP_REPAIR_ON = 1;
-pub const TCP_REPAIR_OFF = 0;
-/// Turn off without window probes
-pub const TCP_REPAIR_OFF_NO_WP = -1;
-
pub const tcp_repair_opt = extern struct {
opt_code: u32,
opt_val: u32,
lib/std/x/net/tcp.zig
@@ -195,7 +195,7 @@ pub const Client = struct {
pub fn setNoDelay(self: Client, enabled: bool) !void {
if (@hasDecl(os.TCP, "NODELAY")) {
const bytes = mem.asBytes(&@as(usize, @boolToInt(enabled)));
- return self.socket.setOption(os.IPPROTO.TCP, os.TCP_NODELAY, bytes);
+ return self.socket.setOption(os.IPPROTO.TCP, os.TCP.NODELAY, bytes);
}
return error.UnsupportedSocketOption;
}
@@ -204,7 +204,7 @@ pub const Client = struct {
/// `error.UnsupportedSocketOption` if the host does not support TCP Quick ACK.
pub fn setQuickACK(self: Client, enabled: bool) !void {
if (@hasDecl(os.TCP, "QUICKACK")) {
- return self.socket.setOption(os.IPPROTO.TCP, os.TCP_QUICKACK, mem.asBytes(&@as(u32, @boolToInt(enabled))));
+ return self.socket.setOption(os.IPPROTO.TCP, os.TCP.QUICKACK, mem.asBytes(&@as(u32, @boolToInt(enabled))));
}
return error.UnsupportedSocketOption;
}
@@ -305,7 +305,7 @@ pub const Listener = struct {
/// support TCP Fast Open.
pub fn setFastOpen(self: Listener, enabled: bool) !void {
if (@hasDecl(os.TCP, "FASTOPEN")) {
- return self.socket.setOption(os.IPPROTO.TCP, os.TCP_FASTOPEN, mem.asBytes(&@as(u32, @boolToInt(enabled))));
+ return self.socket.setOption(os.IPPROTO.TCP, os.TCP.FASTOPEN, mem.asBytes(&@as(u32, @boolToInt(enabled))));
}
return error.UnsupportedSocketOption;
}
lib/std/x/os/net.zig
@@ -11,16 +11,20 @@ const have_ifnamesize = @hasDecl(os.system, "IFNAMESIZE");
/// Resolves a network interface name into a scope/zone ID. It returns
/// an error if either resolution fails, or if the interface name is
/// too long.
-pub fn resolveScopeID(name: []const u8) !u32 {
+pub fn resolveScopeId(name: []const u8) !u32 {
if (have_ifnamesize) {
- if (name.len >= os.IFNAMESIZE - 1) return error.NameTooLong;
+ if (name.len >= os.IFNAMESIZE) return error.NameTooLong;
if (native_os.tag == .windows) {
- var interface_name: [os.IFNAMESIZE]u8 = undefined;
+ var interface_name: [os.IFNAMESIZE:0]u8 = undefined;
mem.copy(u8, &interface_name, name);
interface_name[name.len] = 0;
- return os.windows.ws2_32.if_nametoindex(@ptrCast([*:0]const u8, &interface_name));
+ const rc = os.windows.ws2_32.if_nametoindex(@ptrCast([*:0]const u8, &interface_name));
+ if (rc == 0) {
+ return error.InterfaceNotFound;
+ }
+ return rc;
}
const fd = try os.socket(os.AF.UNIX, os.SOCK.DGRAM, 0);
@@ -35,7 +39,7 @@ pub fn resolveScopeID(name: []const u8) !u32 {
return @bitCast(u32, f.ifru.ivalue);
}
- return error.Unsupported;
+ return error.InterfaceNotFound;
}
/// An IPv4 address comprised of 4 bytes.
@@ -403,7 +407,8 @@ pub const IPv6 = extern struct {
/// address.
pub const ParseError = error{
MalformedV4Mapping,
- BadScopeID,
+ InterfaceNotFound,
+ UnknownScopeId,
} || IPv4.ParseError;
/// Parses an arbitrary IPv6 address, including link-local addresses.
@@ -412,12 +417,15 @@ pub const IPv6 = extern struct {
const ip_slice = buf[0..index];
const scope_id_slice = buf[index + 1 ..];
- if (scope_id_slice.len == 0) return error.BadScopeID;
+ if (scope_id_slice.len == 0) return error.UnknownScopeId;
const scope_id: u32 = switch (scope_id_slice[0]) {
'0'...'9' => fmt.parseInt(u32, scope_id_slice, 10),
- else => resolveScopeID(scope_id_slice),
- } catch return error.BadScopeID;
+ else => resolveScopeId(scope_id_slice) catch |err| switch (err) {
+ error.InterfaceNotFound => return error.InterfaceNotFound,
+ else => err,
+ },
+ } catch return error.UnknownScopeId;
return parseWithScopeID(ip_slice, scope_id);
}
@@ -568,6 +576,11 @@ test "ipv6: parse & format addresses with scope ids" {
};
for (inputs) |input, i| {
- try testing.expectFmt(outputs[i], "{}", .{try IPv6.parse(input)});
+ const parsed = IPv6.parse(input) catch |err| switch (err) {
+ error.InterfaceNotFound => continue,
+ else => return err,
+ };
+
+ try testing.expectFmt(outputs[i], "{}", .{parsed});
}
}
lib/std/x/os/socket_windows.zig
@@ -11,7 +11,7 @@ pub fn Mixin(comptime Socket: type) type {
return struct {
/// Open a new socket.
pub fn init(domain: u32, socket_type: u32, protocol: u32, flags: std.enums.EnumFieldStruct(Socket.InitFlags, bool, false)) !Socket {
- var raw_flags: u32 = 0;
+ var raw_flags: u32 = ws2_32.WSA_FLAG_OVERLAPPED;
const set = std.EnumSet(Socket.InitFlags).init(flags);
if (set.contains(.close_on_exec)) raw_flags |= ws2_32.WSA_FLAG_NO_HANDLE_INHERIT;
lib/std/os.zig
@@ -115,6 +115,7 @@ pub const SYS = system.SYS;
pub const Sigaction = system.Sigaction;
pub const Stat = system.Stat;
pub const TCSA = system.TCSA;
+pub const TCP = system.TCP;
pub const VDSO = system.VDSO;
pub const W = system.W;
pub const addrinfo = system.addrinfo;