How to check if a socket Is already connected

Boring issue regarding some posix sockets API.

Zig 0.14.1 (but the same will be also on 015.1).

std.posix.connect failes on already connected socket -

reached unreachable code

.ISCONN => unreachable, // The socket is already connected

Great! Code “knows” that socket is already conected, but instead of returning error.AlreadyConnected decision was to fail :joy:

It’s completely OK for Linux - looks that it does not return ISCONN for this case, but MacOS does and my code on mac failed.

One of the possible solution is to use getsockoptError(), but the same procesing of .ISCONN

.ISCONN => unreachable, // The socket is already connected.

Only setsockopt() returns AlreadyConnected for connected socket, for others - unreachable

so far not so good

I wrote simple function - send zero length buffer to the socket (btw I am working with non-blocking sockets):

pub fn knock(socket: std.posix.socket_t) bool {
    log.debug("knock-knock", .{});

    const slice: [1]u8 = .{0};

    _ = sendBufTo(socket, slice[0..0]) catch |err| {
        log.debug("knock error {s}", .{@errorName(err)});
        return false;
    };

    return true;
}

where sendBufTo is my internal function, it uses ‘std.posix.sendto’. knock() should return true for connected socket and false otherwise.

It works :waving_hand:

But may be you know simpler way?

1 Like

This is definitely an upstream bug, worth creating an issue with a reproducible example!

1 Like

I meant that it’s mac os imlpementation issue, not related to Zig

The real Zig’s problem is

Code “knows” that socket is already conected, but instead of returning error.AlreadyConnected decision was to fail.

Right, so you should open a Zig bug.

1 Like

Opened #25063

Well, if this behavior is allowed by Posix, then indeed it is a bug on Zig’s part. But it begs the question, how do you not know if you have already connected?

How to recognize not connected socket:

If socket is not connected, send fails

Why I need to check?

  • non-blocked socket
  • posix.connect returns std.posix.ConnectError.WouldBlock
  • after poll/loop I repeat connect if socket still is not connected