Open simple socket

OS: OpenBSD
Zig Version: zig-dev

I am trying to write a integration test for my library restricted and in this case for “inet”.

Rights a program has when having “inet”:

The following system calls are allowed to operate in the AF_INET and AF_INET6 >domains (though setsockopt(2) has been substantially reduced in functionality):
socket(2), listen(2), bind(2), connect(2), accept4(2), accept(2), getpeername(2), > getsockname(2), setsockopt(2), getsockopt(2)

Which internally uses pledge and now I try to get the following C code into zig and running.

#include <sys/socket.h>
#include <netinet/in.h>
#include <unistd.h>

int main(void) {
    pledge("stdio inet", NULL);
    int sock = socket(PF_INET, SOCK_STREAM, 0);
    if (sock >= 0) {
        close(sock);
    }
    return 0;
}

This is the zig code:

const std = @import("std");
const restricted = @import("restricted");

pub fn main(init: std.process.Init) !void {
    try restricted.restrict(&[_]restricted.SystemOperation{
        .StdinStdoutStderrAndBasicFunctionality,
        .ReadFromFilesystem,
        .Networking,
    }, &[_]restricted.PathAccess{}, init.gpa);
    const socket_pair: [2]std.Io.net.Socket = try std.Io.net.Socket.createPair(init.io, .{});
    const sock0, const sock1 = socket_pair;
    defer sock0.close(init.io);
    defer sock1.close(init.io);
}

And this the error when running:

unexpected errno: 45
/home/rw/setup/zig/lib/std/posix.zig:1672:40: 0xc7fb8606a5a in unexpectedErrno (networking_success)
        std.debug.dumpCurrentStackTrace(.{});
                                       ^
/home/rw/setup/zig/lib/std/Io/Threaded.zig:1447:37: 0xc7fb863e639 in unexpectedErrno (networking_success)
        return posix.unexpectedErrno(err);
                                    ^
/home/rw/setup/zig/lib/std/Io/Threaded.zig:12541:53: 0xc7fb863df95 in netSocketCreatePair (networking_success)
        else => |err| return syscall.unexpectedErrno(err),
                                                    ^
/home/rw/setup/zig/lib/std/Io/net.zig:1235:45: 0xc7fb86a2df5 in createPair (networking_success)
        return io.vtable.netSocketCreatePair(io.userdata, options);
                                            ^
/home/rw/media/repos/restricted-zig/test/networking_success.zig:10:79: 0xc7fb869c230 in main (networking_success)
    const socket_pair: [2]std.Io.net.Socket = try std.Io.net.Socket.createPair(init.io, .{});
                                                                              ^
/home/rw/setup/zig/lib/std/start.zig:791:30: 0xc7fb869ca1b in callMain (networking_success)
    return wrapMain(root.main(.{
                             ^
???:?:?: 0xc7fb857cbda in ??? (./zig-out/bin/networking_success)
error: Unexpected
/home/rw/setup/zig/lib/std/posix.zig:1674:5: 0xc7fb8606a63 in unexpectedErrno (networking_success)
    return error.Unexpected;
    ^
/home/rw/setup/zig/lib/std/Io/Threaded.zig:1447:9: 0xc7fb863e646 in unexpectedErrno (networking_success)
        return posix.unexpectedErrno(err);
        ^
/home/rw/setup/zig/lib/std/Io/Threaded.zig:12541:23: 0xc7fb863e54d in netSocketCreatePair (networking_success)
        else => |err| return syscall.unexpectedErrno(err),
                      ^
/home/rw/setup/zig/lib/std/Io/net.zig:1235:9: 0xc7fb86a2e38 in createPair (networking_success)
        return io.vtable.netSocketCreatePair(io.userdata, options);
        ^
/home/rw/media/repos/restricted-zig/test/networking_success.zig:10:47: 0xc7fb869c3ac in main (networking_success)
    const socket_pair: [2]std.Io.net.Socket = try std.Io.net.Socket.createPair(init.io, .{});
                                              ^

So my question is, how to reproduce the C Code in zig.

1 Like

As far as remember, std.Io.net.Socket.createPair is broken. It tries to open it as TCP, but no POSIX system will accept that. And then you have cascading error, because the coded in std.Io.Threaded doesn’t handle the errno correctly, and then it fails to print the error details.

Your best bet with the restricted syscalls is unfortunately to use the libc API. Or try the usual addr.listen() route and connect them manually.

Ok, unlucky, thanks, I went with:

 const sock = std.c.socket(std.c.PF.INET, std.c.SOCK.STREAM, 0);
	if (sock >= 0) {
	   _ = std.c.close(sock);
}