authorgravatar for jon@idk.clubJon <jon@idk.club> 2023-04-24 05:23:22-04:00
committergravatar for noreply@github.comGitHub <noreply@github.com> 2023-04-24 12:23:22+03:00
log529064856a2e5466c890869f786b73442bc5c84b
treebc9cdd56a16c6c94d75721c84657a2d5a42c661d
parent2be347a2c88e435079333773fc30b8e967cc7068
signaturebadge-question-mark Signed by PGP key 4AEE18F83AFDEB23

std.net.StreamServer.Options: add reuse_port


2 files changed, 34 insertions(+), 0 deletions(-)

lib/std/net.zig+13
......@@ -1867,6 +1867,7 @@ pub const StreamServer = struct {
18671867 /// Copied from `Options` on `init`.
18681868 kernel_backlog: u31,
18691869 reuse_address: bool,
1870 reuse_port: bool,
18701871
18711872 /// `undefined` until `listen` returns successfully.
18721873 listen_address: Address,
......@@ -1881,6 +1882,9 @@ pub const StreamServer = struct {
18811882
18821883 /// Enable SO.REUSEADDR on the socket.
18831884 reuse_address: bool = false,
1885
1886 /// Enable SO.REUSEPORT on the socket.
1887 reuse_port: bool = false,
18841888 };
18851889
18861890 /// After this call succeeds, resources have been acquired and must
......@@ -1890,6 +1894,7 @@ pub const StreamServer = struct {
18901894 .sockfd = null,
18911895 .kernel_backlog = options.kernel_backlog,
18921896 .reuse_address = options.reuse_address,
1897 .reuse_port = options.reuse_port,
18931898 .listen_address = undefined,
18941899 };
18951900 }
......@@ -1920,6 +1925,14 @@ pub const StreamServer = struct {
19201925 &mem.toBytes(@as(c_int, 1)),
19211926 );
19221927 }
1928 if (@hasDecl(os.SO, "REUSEPORT") and self.reuse_port) {
1929 try os.setsockopt(
1930 sockfd,
1931 os.SOL.SOCKET,
1932 os.SO.REUSEPORT,
1933 &mem.toBytes(@as(c_int, 1)),
1934 );
1935 }
19231936
19241937 var socklen = address.getOsSockLen();
19251938 try os.bind(sockfd, &address.any, socklen);
lib/std/net/test.zig+21
......@@ -230,6 +230,27 @@ test "listen on ipv4 try connect on ipv6 then ipv4" {
230230 try await client_frame;
231231}
232232
233test "listen on an in use port" {
234 if (builtin.os.tag != .linux and comptime !builtin.os.tag.isDarwin()) {
235 // TODO build abstractions for other operating systems
236 return error.SkipZigTest;
237 }
238
239 const localhost = try net.Address.parseIp("127.0.0.1", 0);
240
241 var server1 = net.StreamServer.init(net.StreamServer.Options{
242 .reuse_port = true,
243 });
244 defer server1.deinit();
245 try server1.listen(localhost);
246
247 var server2 = net.StreamServer.init(net.StreamServer.Options{
248 .reuse_port = true,
249 });
250 defer server2.deinit();
251 try server2.listen(server1.listen_address);
252}
253
233254fn testClientToHost(allocator: mem.Allocator, name: []const u8, port: u16) anyerror!void {
234255 if (builtin.os.tag == .wasi) return error.SkipZigTest;
235256