authorgravatar for pierre@lightpanda.ioPierre Tachoire <pierre@lightpanda.io> 2025-01-23 16:38:05+01:00
committergravatar for alex@alexrp.comAlex Rønne Petersen <alex@alexrp.com> 2025-01-26 18:40:34+01:00
logdf9fdb1861fa4598c6fea48080522a5d44469024
tree96ade330f855d2c04f9ef13038144d7692f289b7
parentdf1cd62720138122a9389d78df5187af7c577e24

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

2 files changed, 16 insertions(+), 1 deletions(-)

lib/std/net.zig+1-1
...@@ -248,7 +248,7 @@ pub const Address = extern union {...@@ -248,7 +248,7 @@ pub const Address = extern union {
248 posix.SO.REUSEADDR,248 posix.SO.REUSEADDR,
249 &mem.toBytes(@as(c_int, 1)),249 &mem.toBytes(@as(c_int, 1)),
250 );250 );
251 if (@hasDecl(posix.SO, "REUSEPORT")) {251 if (@hasDecl(posix.SO, "REUSEPORT") and address.any.family != posix.AF.UNIX) {
252 try posix.setsockopt(252 try posix.setsockopt(
253 sockfd,253 sockfd,
254 posix.SOL.SOCKET,254 posix.SOL.SOCKET,
lib/std/net/test.zig+15
...@@ -296,6 +296,21 @@ test "listen on a unix socket, send bytes, receive bytes" {...@@ -296,6 +296,21 @@ test "listen on a unix socket, send bytes, receive bytes" {
296 try testing.expectEqualSlices(u8, "Hello world!", buf[0..n]);296 try testing.expectEqualSlices(u8, "Hello world!", buf[0..n]);
297}297}
298298
299test "listen on a unix socket with reuse_port option" {
300 if (!net.has_unix_sockets) return error.SkipZigTest;
301 // Windows doesn't implement reuse port option.
302 if (builtin.os.tag == .windows) return error.SkipZigTest;
303
304 const socket_path = try generateFileName("socket.unix");
305 defer testing.allocator.free(socket_path);
306
307 const socket_addr = try net.Address.initUnix(socket_path);
308 defer std.fs.cwd().deleteFile(socket_path) catch {};
309
310 var server = try socket_addr.listen(.{ .reuse_port = true });
311 server.deinit();
312}
313
299fn generateFileName(base_name: []const u8) ![]const u8 {314fn generateFileName(base_name: []const u8) ![]const u8 {
300 const random_bytes_count = 12;315 const random_bytes_count = 12;
301 const sub_path_len = comptime std.fs.base64_encoder.calcSize(random_bytes_count);316 const sub_path_len = comptime std.fs.base64_encoder.calcSize(random_bytes_count);