| ... | ... | @@ -6,10 +6,11 @@ const is_windows = native_os == .windows; |
| 6 | 6 | const windows = std.os.windows; |
| 7 | 7 | |
| 8 | 8 | const std = @import("../std.zig"); |
| 9 | const Io = std.Io; |
| 10 | const net = std.Io.net; |
| 9 | 11 | const Allocator = std.mem.Allocator; |
| 10 | 12 | const assert = std.debug.assert; |
| 11 | 13 | const posix = std.posix; |
| 12 | | const Io = std.Io; |
| 13 | 14 | const ResetEvent = std.Thread.ResetEvent; |
| 14 | 15 | |
| 15 | 16 | /// Thread-safe. |
| ... | ... | @@ -1692,9 +1693,9 @@ fn select(userdata: ?*anyopaque, futures: []const *Io.AnyFuture) usize { |
| 1692 | 1693 | |
| 1693 | 1694 | fn netListenIpPosix( |
| 1694 | 1695 | userdata: ?*anyopaque, |
| 1695 | | address: Io.net.IpAddress, |
| 1696 | | options: Io.net.IpAddress.ListenOptions, |
| 1697 | | ) Io.net.IpAddress.ListenError!Io.net.Server { |
| 1696 | address: net.IpAddress, |
| 1697 | options: net.IpAddress.ListenOptions, |
| 1698 | ) net.IpAddress.ListenError!net.Server { |
| 1698 | 1699 | const pool: *Pool = @ptrCast(@alignCast(userdata)); |
| 1699 | 1700 | const family = posixAddressFamily(&address); |
| 1700 | 1701 | const socket_fd = try openSocketPosix(pool, family, .{ |
| ... | ... | @@ -1734,10 +1735,10 @@ fn netListenIpPosix( |
| 1734 | 1735 | |
| 1735 | 1736 | fn netListenUnix( |
| 1736 | 1737 | userdata: ?*anyopaque, |
| 1737 | | address: *const Io.net.UnixAddress, |
| 1738 | | options: Io.net.UnixAddress.ListenOptions, |
| 1739 | | ) Io.net.UnixAddress.ListenError!Io.net.Socket.Handle { |
| 1740 | | if (!Io.net.has_unix_sockets) return error.AddressFamilyUnsupported; |
| 1738 | address: *const net.UnixAddress, |
| 1739 | options: net.UnixAddress.ListenOptions, |
| 1740 | ) net.UnixAddress.ListenError!net.Socket.Handle { |
| 1741 | if (!net.has_unix_sockets) return error.AddressFamilyUnsupported; |
| 1741 | 1742 | const pool: *Pool = @ptrCast(@alignCast(userdata)); |
| 1742 | 1743 | const socket_fd = openSocketPosix(pool, posix.AF.UNIX, .{ .mode = .stream }) catch |err| switch (err) { |
| 1743 | 1744 | error.ProtocolUnsupportedBySystem => return error.AddressFamilyUnsupported, |
| ... | ... | @@ -1903,9 +1904,9 @@ fn setSocketOption(pool: *Pool, fd: posix.fd_t, level: i32, opt_name: u32, optio |
| 1903 | 1904 | |
| 1904 | 1905 | fn netConnectIpPosix( |
| 1905 | 1906 | userdata: ?*anyopaque, |
| 1906 | | address: *const Io.net.IpAddress, |
| 1907 | | options: Io.net.IpAddress.ConnectOptions, |
| 1908 | | ) Io.net.IpAddress.ConnectError!Io.net.Stream { |
| 1907 | address: *const net.IpAddress, |
| 1908 | options: net.IpAddress.ConnectOptions, |
| 1909 | ) net.IpAddress.ConnectError!net.Stream { |
| 1909 | 1910 | if (options.timeout != .none) @panic("TODO"); |
| 1910 | 1911 | const pool: *Pool = @ptrCast(@alignCast(userdata)); |
| 1911 | 1912 | const family = posixAddressFamily(address); |
| ... | ... | @@ -1926,9 +1927,9 @@ fn netConnectIpPosix( |
| 1926 | 1927 | |
| 1927 | 1928 | fn netConnectUnix( |
| 1928 | 1929 | userdata: ?*anyopaque, |
| 1929 | | address: *const Io.net.UnixAddress, |
| 1930 | | ) Io.net.UnixAddress.ConnectError!Io.net.Socket.Handle { |
| 1931 | | if (!Io.net.has_unix_sockets) return error.AddressFamilyUnsupported; |
| 1930 | address: *const net.UnixAddress, |
| 1931 | ) net.UnixAddress.ConnectError!net.Socket.Handle { |
| 1932 | if (!net.has_unix_sockets) return error.AddressFamilyUnsupported; |
| 1932 | 1933 | const pool: *Pool = @ptrCast(@alignCast(userdata)); |
| 1933 | 1934 | const socket_fd = try openSocketPosix(pool, posix.AF.UNIX, .{ .mode = .stream }); |
| 1934 | 1935 | errdefer posix.close(socket_fd); |
| ... | ... | @@ -1940,9 +1941,9 @@ fn netConnectUnix( |
| 1940 | 1941 | |
| 1941 | 1942 | fn netBindIpPosix( |
| 1942 | 1943 | userdata: ?*anyopaque, |
| 1943 | | address: *const Io.net.IpAddress, |
| 1944 | | options: Io.net.IpAddress.BindOptions, |
| 1945 | | ) Io.net.IpAddress.BindError!Io.net.Socket { |
| 1944 | address: *const net.IpAddress, |
| 1945 | options: net.IpAddress.BindOptions, |
| 1946 | ) net.IpAddress.BindError!net.Socket { |
| 1946 | 1947 | const pool: *Pool = @ptrCast(@alignCast(userdata)); |
| 1947 | 1948 | const family = posixAddressFamily(address); |
| 1948 | 1949 | const socket_fd = try openSocketPosix(pool, family, options); |
| ... | ... | @@ -1957,7 +1958,7 @@ fn netBindIpPosix( |
| 1957 | 1958 | }; |
| 1958 | 1959 | } |
| 1959 | 1960 | |
| 1960 | | fn openSocketPosix(pool: *Pool, family: posix.sa_family_t, options: Io.net.IpAddress.BindOptions) !posix.socket_t { |
| 1961 | fn openSocketPosix(pool: *Pool, family: posix.sa_family_t, options: net.IpAddress.BindOptions) !posix.socket_t { |
| 1961 | 1962 | const mode = posixSocketMode(options.mode); |
| 1962 | 1963 | const protocol = posixProtocol(options.protocol); |
| 1963 | 1964 | const socket_fd = while (true) { |
| ... | ... | @@ -2003,7 +2004,7 @@ fn openSocketPosix(pool: *Pool, family: posix.sa_family_t, options: Io.net.IpAdd |
| 2003 | 2004 | const socket_flags_unsupported = builtin.os.tag.isDarwin() or native_os == .haiku; // 💩💩 |
| 2004 | 2005 | const have_accept4 = !socket_flags_unsupported; |
| 2005 | 2006 | |
| 2006 | | fn netAcceptPosix(userdata: ?*anyopaque, listen_fd: Io.net.Socket.Handle) Io.net.Server.AcceptError!Io.net.Stream { |
| 2007 | fn netAcceptPosix(userdata: ?*anyopaque, listen_fd: net.Socket.Handle) net.Server.AcceptError!net.Stream { |
| 2007 | 2008 | const pool: *Pool = @ptrCast(@alignCast(userdata)); |
| 2008 | 2009 | var storage: PosixAddress = undefined; |
| 2009 | 2010 | var addr_len: posix.socklen_t = @sizeOf(PosixAddress); |
| ... | ... | @@ -2050,7 +2051,7 @@ fn netAcceptPosix(userdata: ?*anyopaque, listen_fd: Io.net.Socket.Handle) Io.net |
| 2050 | 2051 | } }; |
| 2051 | 2052 | } |
| 2052 | 2053 | |
| 2053 | | fn netReadPosix(userdata: ?*anyopaque, fd: Io.net.Socket.Handle, data: [][]u8) Io.net.Stream.Reader.Error!usize { |
| 2054 | fn netReadPosix(userdata: ?*anyopaque, fd: net.Socket.Handle, data: [][]u8) net.Stream.Reader.Error!usize { |
| 2054 | 2055 | const pool: *Pool = @ptrCast(@alignCast(userdata)); |
| 2055 | 2056 | |
| 2056 | 2057 | var iovecs_buffer: [max_iovecs_len]posix.iovec = undefined; |
| ... | ... | @@ -2113,10 +2114,10 @@ const have_sendmmsg = builtin.os.tag == .linux; |
| 2113 | 2114 | |
| 2114 | 2115 | fn netSend( |
| 2115 | 2116 | userdata: ?*anyopaque, |
| 2116 | | handle: Io.net.Socket.Handle, |
| 2117 | | messages: []Io.net.OutgoingMessage, |
| 2118 | | flags: Io.net.SendFlags, |
| 2119 | | ) struct { ?Io.net.Socket.SendError, usize } { |
| 2117 | handle: net.Socket.Handle, |
| 2118 | messages: []net.OutgoingMessage, |
| 2119 | flags: net.SendFlags, |
| 2120 | ) struct { ?net.Socket.SendError, usize } { |
| 2120 | 2121 | const pool: *Pool = @ptrCast(@alignCast(userdata)); |
| 2121 | 2122 | |
| 2122 | 2123 | const posix_flags: u32 = |
| ... | ... | @@ -2141,10 +2142,10 @@ fn netSend( |
| 2141 | 2142 | |
| 2142 | 2143 | fn netSendOne( |
| 2143 | 2144 | pool: *Pool, |
| 2144 | | handle: Io.net.Socket.Handle, |
| 2145 | | message: *Io.net.OutgoingMessage, |
| 2145 | handle: net.Socket.Handle, |
| 2146 | message: *net.OutgoingMessage, |
| 2146 | 2147 | flags: u32, |
| 2147 | | ) Io.net.Socket.SendError!void { |
| 2148 | ) net.Socket.SendError!void { |
| 2148 | 2149 | var addr: PosixAddress = undefined; |
| 2149 | 2150 | var iovec: posix.iovec = .{ .base = @constCast(message.data_ptr), .len = message.data_len }; |
| 2150 | 2151 | const msg: posix.msghdr = .{ |
| ... | ... | @@ -2225,10 +2226,10 @@ fn netSendOne( |
| 2225 | 2226 | |
| 2226 | 2227 | fn netSendMany( |
| 2227 | 2228 | pool: *Pool, |
| 2228 | | handle: Io.net.Socket.Handle, |
| 2229 | | messages: []Io.net.OutgoingMessage, |
| 2229 | handle: net.Socket.Handle, |
| 2230 | messages: []net.OutgoingMessage, |
| 2230 | 2231 | flags: u32, |
| 2231 | | ) Io.net.Socket.SendError!usize { |
| 2232 | ) net.Socket.SendError!usize { |
| 2232 | 2233 | var msg_buffer: [64]std.os.linux.mmsghdr = undefined; |
| 2233 | 2234 | var addr_buffer: [msg_buffer.len]PosixAddress = undefined; |
| 2234 | 2235 | var iovecs_buffer: [msg_buffer.len]posix.iovec = undefined; |
| ... | ... | @@ -2292,12 +2293,12 @@ fn netSendMany( |
| 2292 | 2293 | |
| 2293 | 2294 | fn netReceive( |
| 2294 | 2295 | userdata: ?*anyopaque, |
| 2295 | | handle: Io.net.Socket.Handle, |
| 2296 | | message_buffer: []Io.net.IncomingMessage, |
| 2296 | handle: net.Socket.Handle, |
| 2297 | message_buffer: []net.IncomingMessage, |
| 2297 | 2298 | data_buffer: []u8, |
| 2298 | | flags: Io.net.ReceiveFlags, |
| 2299 | flags: net.ReceiveFlags, |
| 2299 | 2300 | timeout: Io.Timeout, |
| 2300 | | ) struct { ?Io.net.Socket.ReceiveTimeoutError, usize } { |
| 2301 | ) struct { ?net.Socket.ReceiveTimeoutError, usize } { |
| 2301 | 2302 | const pool: *Pool = @ptrCast(@alignCast(userdata)); |
| 2302 | 2303 | |
| 2303 | 2304 | // recvmmsg is useless, here's why: |
| ... | ... | @@ -2418,11 +2419,11 @@ fn netReceive( |
| 2418 | 2419 | |
| 2419 | 2420 | fn netWritePosix( |
| 2420 | 2421 | userdata: ?*anyopaque, |
| 2421 | | fd: Io.net.Socket.Handle, |
| 2422 | fd: net.Socket.Handle, |
| 2422 | 2423 | header: []const u8, |
| 2423 | 2424 | data: []const []const u8, |
| 2424 | 2425 | splat: usize, |
| 2425 | | ) Io.net.Stream.Writer.Error!usize { |
| 2426 | ) net.Stream.Writer.Error!usize { |
| 2426 | 2427 | const pool: *Pool = @ptrCast(@alignCast(userdata)); |
| 2427 | 2428 | try pool.checkCancel(); |
| 2428 | 2429 | |
| ... | ... | @@ -2476,7 +2477,7 @@ fn addBuf(v: []posix.iovec_const, i: *@FieldType(posix.msghdr_const, "iovlen"), |
| 2476 | 2477 | i.* += 1; |
| 2477 | 2478 | } |
| 2478 | 2479 | |
| 2479 | | fn netClose(userdata: ?*anyopaque, handle: Io.net.Socket.Handle) void { |
| 2480 | fn netClose(userdata: ?*anyopaque, handle: net.Socket.Handle) void { |
| 2480 | 2481 | const pool: *Pool = @ptrCast(@alignCast(userdata)); |
| 2481 | 2482 | _ = pool; |
| 2482 | 2483 | switch (native_os) { |
| ... | ... | @@ -2487,8 +2488,8 @@ fn netClose(userdata: ?*anyopaque, handle: Io.net.Socket.Handle) void { |
| 2487 | 2488 | |
| 2488 | 2489 | fn netInterfaceNameResolve( |
| 2489 | 2490 | userdata: ?*anyopaque, |
| 2490 | | name: *const Io.net.Interface.Name, |
| 2491 | | ) Io.net.Interface.Name.ResolveError!Io.net.Interface { |
| 2491 | name: *const net.Interface.Name, |
| 2492 | ) net.Interface.Name.ResolveError!net.Interface { |
| 2492 | 2493 | const pool: *Pool = @ptrCast(@alignCast(userdata)); |
| 2493 | 2494 | |
| 2494 | 2495 | if (native_os == .linux) { |
| ... | ... | @@ -2542,7 +2543,7 @@ fn netInterfaceNameResolve( |
| 2542 | 2543 | @panic("unimplemented"); |
| 2543 | 2544 | } |
| 2544 | 2545 | |
| 2545 | | fn netInterfaceName(userdata: ?*anyopaque, interface: Io.net.Interface) Io.net.Interface.NameError!Io.net.Interface.Name { |
| 2546 | fn netInterfaceName(userdata: ?*anyopaque, interface: net.Interface) net.Interface.NameError!net.Interface.Name { |
| 2546 | 2547 | const pool: *Pool = @ptrCast(@alignCast(userdata)); |
| 2547 | 2548 | try pool.checkCancel(); |
| 2548 | 2549 | |
| ... | ... | @@ -2573,14 +2574,14 @@ const UnixAddress = extern union { |
| 2573 | 2574 | un: posix.sockaddr.un, |
| 2574 | 2575 | }; |
| 2575 | 2576 | |
| 2576 | | fn posixAddressFamily(a: *const Io.net.IpAddress) posix.sa_family_t { |
| 2577 | fn posixAddressFamily(a: *const net.IpAddress) posix.sa_family_t { |
| 2577 | 2578 | return switch (a.*) { |
| 2578 | 2579 | .ip4 => posix.AF.INET, |
| 2579 | 2580 | .ip6 => posix.AF.INET6, |
| 2580 | 2581 | }; |
| 2581 | 2582 | } |
| 2582 | 2583 | |
| 2583 | | fn addressFromPosix(posix_address: *PosixAddress) Io.net.IpAddress { |
| 2584 | fn addressFromPosix(posix_address: *PosixAddress) net.IpAddress { |
| 2584 | 2585 | return switch (posix_address.any.family) { |
| 2585 | 2586 | posix.AF.INET => .{ .ip4 = address4FromPosix(&posix_address.in) }, |
| 2586 | 2587 | posix.AF.INET6 => .{ .ip6 = address6FromPosix(&posix_address.in6) }, |
| ... | ... | @@ -2588,7 +2589,7 @@ fn addressFromPosix(posix_address: *PosixAddress) Io.net.IpAddress { |
| 2588 | 2589 | }; |
| 2589 | 2590 | } |
| 2590 | 2591 | |
| 2591 | | fn addressToPosix(a: *const Io.net.IpAddress, storage: *PosixAddress) posix.socklen_t { |
| 2592 | fn addressToPosix(a: *const net.IpAddress, storage: *PosixAddress) posix.socklen_t { |
| 2592 | 2593 | return switch (a.*) { |
| 2593 | 2594 | .ip4 => |ip4| { |
| 2594 | 2595 | storage.in = address4ToPosix(ip4); |
| ... | ... | @@ -2601,21 +2602,21 @@ fn addressToPosix(a: *const Io.net.IpAddress, storage: *PosixAddress) posix.sock |
| 2601 | 2602 | }; |
| 2602 | 2603 | } |
| 2603 | 2604 | |
| 2604 | | fn addressUnixToPosix(a: *const Io.net.UnixAddress, storage: *UnixAddress) posix.socklen_t { |
| 2605 | fn addressUnixToPosix(a: *const net.UnixAddress, storage: *UnixAddress) posix.socklen_t { |
| 2605 | 2606 | @memcpy(storage.un.path[0..a.path.len], a.path); |
| 2606 | 2607 | storage.un.family = posix.AF.UNIX; |
| 2607 | 2608 | storage.un.path[a.path.len] = 0; |
| 2608 | 2609 | return @sizeOf(posix.sockaddr.un); |
| 2609 | 2610 | } |
| 2610 | 2611 | |
| 2611 | | fn address4FromPosix(in: *posix.sockaddr.in) Io.net.Ip4Address { |
| 2612 | fn address4FromPosix(in: *posix.sockaddr.in) net.Ip4Address { |
| 2612 | 2613 | return .{ |
| 2613 | 2614 | .port = std.mem.bigToNative(u16, in.port), |
| 2614 | 2615 | .bytes = @bitCast(in.addr), |
| 2615 | 2616 | }; |
| 2616 | 2617 | } |
| 2617 | 2618 | |
| 2618 | | fn address6FromPosix(in6: *posix.sockaddr.in6) Io.net.Ip6Address { |
| 2619 | fn address6FromPosix(in6: *posix.sockaddr.in6) net.Ip6Address { |
| 2619 | 2620 | return .{ |
| 2620 | 2621 | .port = std.mem.bigToNative(u16, in6.port), |
| 2621 | 2622 | .bytes = in6.addr, |
| ... | ... | @@ -2624,14 +2625,14 @@ fn address6FromPosix(in6: *posix.sockaddr.in6) Io.net.Ip6Address { |
| 2624 | 2625 | }; |
| 2625 | 2626 | } |
| 2626 | 2627 | |
| 2627 | | fn address4ToPosix(a: Io.net.Ip4Address) posix.sockaddr.in { |
| 2628 | fn address4ToPosix(a: net.Ip4Address) posix.sockaddr.in { |
| 2628 | 2629 | return .{ |
| 2629 | 2630 | .port = std.mem.nativeToBig(u16, a.port), |
| 2630 | 2631 | .addr = @bitCast(a.bytes), |
| 2631 | 2632 | }; |
| 2632 | 2633 | } |
| 2633 | 2634 | |
| 2634 | | fn address6ToPosix(a: *const Io.net.Ip6Address) posix.sockaddr.in6 { |
| 2635 | fn address6ToPosix(a: *const net.Ip6Address) posix.sockaddr.in6 { |
| 2635 | 2636 | return .{ |
| 2636 | 2637 | .port = std.mem.nativeToBig(u16, a.port), |
| 2637 | 2638 | .flowinfo = a.flow, |
| ... | ... | @@ -2647,7 +2648,7 @@ fn errnoBug(err: posix.E) Io.UnexpectedError { |
| 2647 | 2648 | } |
| 2648 | 2649 | } |
| 2649 | 2650 | |
| 2650 | | fn posixSocketMode(mode: Io.net.Socket.Mode) u32 { |
| 2651 | fn posixSocketMode(mode: net.Socket.Mode) u32 { |
| 2651 | 2652 | return switch (mode) { |
| 2652 | 2653 | .stream => posix.SOCK.STREAM, |
| 2653 | 2654 | .dgram => posix.SOCK.DGRAM, |
| ... | ... | @@ -2657,7 +2658,7 @@ fn posixSocketMode(mode: Io.net.Socket.Mode) u32 { |
| 2657 | 2658 | }; |
| 2658 | 2659 | } |
| 2659 | 2660 | |
| 2660 | | fn posixProtocol(protocol: ?Io.net.Protocol) u32 { |
| 2661 | fn posixProtocol(protocol: ?net.Protocol) u32 { |
| 2661 | 2662 | return @intFromEnum(protocol orelse return 0); |
| 2662 | 2663 | } |
| 2663 | 2664 | |