Zig 0.16: setting socket options on Windows

According to https://codeberg.org/ziglang/zig/issues/31694 Zig 0.16 started to move away from std.posix.

std.posix.setsockopt now has the following for Windows:

/// Set a socket's options.
pub fn setsockopt(fd: socket_t, level: i32, optname: u32, opt: []const u8) SetSockOptError!void {
    if (native_os == .windows) {
        @compileError("use std.Io instead");
    }
    // ...
}

And Io has the following methods related to networking:

netListenIp
netAccept
netBindIp
netConnectIp
netListenUnix
netConnectUnix
netSocketCreatePair
netSend
netRead
netWrite
netWriteFile
netClose
netShutdown
netInterfaceNameResolve
netInterfaceName
netLookup

Does not look like there is anything to set socket options.

Moreover, trying to import and use setsockopt from ws2_32 does not work either, Winsock just reports that provided handle is not a socket handle. I believe it happens because netConnectIpWindows implementation calls AFD functions directly, bypassing Winsock API.

Am I missing something?

const std = @import("std");
const Io = std.Io;
const HostName = Io.net.HostName;

pub fn main(init: std.process.Init) !void {
    const hostname = try HostName.init("ziglang.org");
    const stream = try hostname.connect(init.io, 443, .{ .mode = .stream });
    defer stream.close(init.io);

    // How to set SO_KEEPALIVE for stream here?
}

Thanks in advance!

1 Like

Correct, zig std tries to use ntdll directly as it is more efficient and has a better api (I am told, I don’t work with windows)

try to “borrow” setSocketOptionAfd

Very interesting articles regarding AFD

As far as I understand Threaded code, you can remove “on Windows” from the title: all setSocketOption are non pub setSocketOptionAfd , setSocketOptionPosix and setSocketOption (for Kqueue)

I think in the future all such functions will be public

Btw anyone requires Io

2 Likes

Indeed, I noticed those too while looking into the issue.

It is what I missed, thanks! Borrowing it brings a bit too much though, like for instance it needs std.Io.Threaded.Thread which is private (not to be confused with std.Thread). Instead as a quick and dirty check I made setSocketOptionAfd pub in my local Zig installation and it worked perfectly fine.

Should I create an issue in Zig repo to make setSocketOption part of Io public API?

2 Likes

great idea

btw as far as i understand from https://codeberg.org/ziglang/zig/issues/32088
setsockopt exists for linux and it is not under io

It’s #35649

So the bottom line is:

  • Io.net does not have a universal setSocketOption.
  • For Linux there is std.os.linux.setsockopt.
  • For Windows setsockopt from ws2_32 does not work.

Hence “on Windows” it the title :slightly_smiling_face:

1 Like