From edbd75213d5f1619eef33b12c8287babb6869c93 Mon Sep 17 00:00:00 2001 From: zzstoatzz Date: Fri, 3 Apr 2026 13:06:58 -0500 Subject: [PATCH] fix netListenIp: sync syscalls for bind/listen (kernel <6.11) MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit IORING_OP_BIND and IORING_OP_LISTEN require kernel 6.11+. Our server is on 6.8 — the kernel returns EINVAL for unknown opcodes, surfacing as error.Unexpected. Use direct linux.bind()/linux.listen() syscalls instead (instant, non-blocking — same approach as getsockname). IORING_OP_ACCEPT (5.5), IORING_OP_CONNECT (5.5), IORING_OP_SOCKET (5.19), and IORING_OP_SENDMSG/RECVMSG/READV (5.3-5.6) all work fine. Co-Authored-By: Claude Opus 4.6 --- patches/uring-networking.patch | 97 +++++++++++++--------------------- 1 file changed, 36 insertions(+), 61 deletions(-) diff --git a/patches/uring-networking.patch b/patches/uring-networking.patch index 0eab1d1..8807b72 100644 --- a/patches/uring-networking.patch +++ b/patches/uring-networking.patch @@ -23,7 +23,7 @@ .netWriteFile = netWriteFileUnavailable, .netClose = netClose, .netShutdown = netShutdown, -@@ -4953,28 +4953,83 @@ +@@ -4953,28 +4953,102 @@ }; } @@ -52,8 +52,27 @@ + } + var storage: PosixAddress = undefined; + var addr_len = addressToPosix(address, &storage); -+ try ev.bind(&maybe_sync.cancel_region, socket_fd, &storage.any, addr_len); -+ try ev.listen(&maybe_sync.cancel_region, socket_fd, options.kernel_backlog); ++ // bind + listen: sync syscalls (IORING_OP_BIND/LISTEN require kernel 6.11+) ++ switch (linux.errno(linux.bind(socket_fd, &storage.any, addr_len))) { ++ .SUCCESS => {}, ++ .ADDRINUSE => return error.AddressInUse, ++ .AFNOSUPPORT => return error.AddressFamilyUnsupported, ++ .ADDRNOTAVAIL => return error.AddressUnavailable, ++ .BADF => |err| return errnoBug(err), ++ .INVAL => |err| return errnoBug(err), ++ .NOTSOCK => |err| return errnoBug(err), ++ .FAULT => |err| return errnoBug(err), ++ .NOMEM => return error.SystemResources, ++ else => |err| return unexpectedErrno(err), ++ } ++ switch (linux.errno(linux.listen(socket_fd, options.kernel_backlog))) { ++ .SUCCESS => {}, ++ .ADDRINUSE => return error.AddressInUse, ++ .BADF => |err| return errnoBug(err), ++ .NOTSOCK => |err| return errnoBug(err), ++ .OPNOTSUPP => |err| return errnoBug(err), ++ else => |err| return unexpectedErrno(err), ++ } + try ev.getsockname(try maybe_sync.enterSync(ev), socket_fd, &storage.any, &addr_len); + return .{ .handle = socket_fd, .address = addressFromPosix(&storage) }; } @@ -117,7 +136,7 @@ } fn netBindIp( -@@ -4996,16 +5051,26 @@ +@@ -4996,16 +5070,26 @@ return .{ .handle = socket_fd, .address = addressFromPosix(&storage) }; } @@ -149,7 +168,7 @@ } fn netListenUnixUnavailable( -@@ -5039,20 +5104,96 @@ +@@ -5039,18 +5123,94 @@ return error.OperationUnsupported; } @@ -178,8 +197,8 @@ + ev.netSendOne(handle, message, posix_flags) catch |err| return .{ err, i }; + } + return .{ null, messages.len }; - } - ++} ++ +fn netSendOne( + ev: *Evented, + handle: net.Socket.Handle, @@ -247,12 +266,10 @@ + else => |err| return unexpectedErrno(err), + } + } -+} -+ + } + fn netReceive( - ev: *Evented, - cancel_region: *CancelRegion, -@@ -5142,19 +5283,67 @@ +@@ -5142,19 +5302,67 @@ } } @@ -326,7 +343,7 @@ userdata: ?*anyopaque, handle: net.Socket.Handle, header: []const u8, -@@ -5162,12 +5351,94 @@ +@@ -5162,12 +5370,94 @@ splat: usize, ) net.Stream.Writer.Error!usize { const ev: *Evented = @ptrCast(@alignCast(userdata)); @@ -427,52 +444,12 @@ } fn netWriteFileUnavailable( -@@ -5303,11 +5574,100 @@ - .ADDRNOTAVAIL => return error.AddressUnavailable, - .FAULT => |err| return errnoBug(err), // invalid `addr` pointer - .NOMEM => return error.SystemResources, -+ else => |err| return unexpectedErrno(err), -+ } -+ } -+} -+ -+fn listen( -+ ev: *Evented, -+ cancel_region: *CancelRegion, -+ socket_fd: fd_t, -+ backlog: u31, -+) !void { -+ while (true) { -+ const thread = try cancel_region.awaitIoUring(); -+ thread.enqueue().* = .{ -+ .opcode = .LISTEN, -+ .flags = 0, -+ .ioprio = 0, -+ .fd = socket_fd, -+ .off = 0, -+ .addr = 0, -+ .len = backlog, -+ .rw_flags = 0, -+ .user_data = @intFromPtr(cancel_region.fiber), -+ .buf_index = 0, -+ .personality = 0, -+ .splice_fd_in = 0, -+ .addr3 = 0, -+ .resv = 0, -+ }; -+ ev.yield(null, .nothing); -+ switch (cancel_region.errno()) { -+ .SUCCESS => return, -+ .INTR, .CANCELED => {}, -+ .ADDRINUSE => return error.AddressInUse, -+ .BADF => |err| return errnoBug(err), -+ .NOTSOCK => |err| return errnoBug(err), -+ .OPNOTSUPP => |err| return errnoBug(err), +@@ -5306,6 +5596,58 @@ else => |err| return unexpectedErrno(err), } } - } - ++} ++ +fn connect( + ev: *Evented, + cancel_region: *CancelRegion, @@ -504,7 +481,7 @@ + .INTR, .CANCELED => {}, + .ADDRNOTAVAIL => return error.AddressUnavailable, + .AFNOSUPPORT => return error.AddressFamilyUnsupported, -+ .AGAIN, .INPROGRESS => return, // non-blocking / TCP fast open ++ .AGAIN, .INPROGRESS => return, + .ALREADY => return error.ConnectionPending, + .BADF => |err| return errnoBug(err), + .CONNREFUSED => return error.ConnectionRefused, @@ -523,8 +500,6 @@ + else => |err| return unexpectedErrno(err), + } + } -+} -+ + } + fn chdir(sync: *CancelRegion.Sync, path: [*:0]const u8) ChdirError!void { - while (true) { - try sync.cancel_region.await(.nothing); -- 2.51.2