From df9fdb1861fa4598c6fea48080522a5d44469024 Mon Sep 17 00:00:00 2001 From: Pierre Tachoire Date: Thu, 23 Jan 2025 16:38:05 +0100 Subject: [PATCH] std.net.listen: no REUSEPORT with unix socket On Linux, set REUSEPORT option on an unix socket returns a EOPNOTSUPP error. See https://github.com/torvalds/linux/commit/5b0af621c3f6ef9261cf6067812f2fd9943acb4b --- lib/std/net.zig | 2 +- lib/std/net/test.zig | 15 +++++++++++++++ 2 files changed, 16 insertions(+), 1 deletion(-) diff --git a/lib/std/net.zig b/lib/std/net.zig index 10e1beb622..3c956c8c2e 100644 --- a/lib/std/net.zig +++ b/lib/std/net.zig @@ -248,7 +248,7 @@ pub const Address = extern union { posix.SO.REUSEADDR, &mem.toBytes(@as(c_int, 1)), ); - if (@hasDecl(posix.SO, "REUSEPORT")) { + if (@hasDecl(posix.SO, "REUSEPORT") and address.any.family != posix.AF.UNIX) { try posix.setsockopt( sockfd, posix.SOL.SOCKET, diff --git a/lib/std/net/test.zig b/lib/std/net/test.zig index 3e316c5456..81b540b917 100644 --- a/lib/std/net/test.zig +++ b/lib/std/net/test.zig @@ -296,6 +296,21 @@ test "listen on a unix socket, send bytes, receive bytes" { try testing.expectEqualSlices(u8, "Hello world!", buf[0..n]); } +test "listen on a unix socket with reuse_port option" { + if (!net.has_unix_sockets) return error.SkipZigTest; + // Windows doesn't implement reuse port option. + if (builtin.os.tag == .windows) return error.SkipZigTest; + + const socket_path = try generateFileName("socket.unix"); + defer testing.allocator.free(socket_path); + + const socket_addr = try net.Address.initUnix(socket_path); + defer std.fs.cwd().deleteFile(socket_path) catch {}; + + var server = try socket_addr.listen(.{ .reuse_port = true }); + server.deinit(); +} + fn generateFileName(base_name: []const u8) ![]const u8 { const random_bytes_count = 12; const sub_path_len = comptime std.fs.base64_encoder.calcSize(random_bytes_count);