Skip to content

SocketAddr

Description

Wraps struct sockaddr_storage. raw[0..length] carries the actual address bytes; family records the address family so callers do not have to peek into raw.

Usage example (Cross-references)

Usage examples (Cross-references)
        Socket   server = {0};
    
        SocketAddr bind_addr;
        if (!SocketAddrParse(&bind_addr, "127.0.0.1:0", SOCKET_KIND_TCP)) {
            return false;
        char spec[64];
        snprintf(spec, sizeof(spec), "127.0.0.1:%u", (unsigned)port);
        SocketAddr connect_addr;
        if (!SocketAddrParse(&connect_addr, spec, SOCKET_KIND_TCP)) {
            ListenerClose(&listener);
    
        {
            SocketAddr addr;
            if (!SocketAddrParse(&addr, "127.0.0.1:8080", SOCKET_KIND_TCP)) {
                DefaultAllocatorDeinit(&alloc);
    
        {
            SocketAddr addr;
            if (!SocketAddrParse(&addr, "[::1]:8080", SOCKET_KIND_TCP)) {
                DefaultAllocatorDeinit(&alloc);
    }
    
    static void fill_socket_addr_from_sockaddr(SocketAddr *out, const struct sockaddr *sa, socklen_t len) {
        MemSet(out, 0, sizeof(*out));
        if (len > (socklen_t)SOCKET_ADDR_MAX_SIZE) {
    // ---------------------------------------------------------------------------
    
    bool SocketAddrParse(SocketAddr *out, const char *spec, SocketKind kind) {
        if (!out) {
            LOG_ERROR("SocketAddrParse: out is NULL");
    }
    
    Str SocketAddrFormat(const SocketAddr *addr, Allocator *alloc) {
        Str out = StrInit(alloc);
        if (!addr || addr->length == 0) {
    // ---------------------------------------------------------------------------
    
    bool ListenerOpen(Listener *out, SocketKind kind, const SocketAddr *addr, i32 backlog) {
        if (!out || !addr) {
            LOG_ERROR("ListenerOpen: NULL argument");
    // ---------------------------------------------------------------------------
    
    bool SocketConnect(Socket *out, SocketKind kind, const SocketAddr *target) {
        if (!out || !target) {
            LOG_ERROR("SocketConnect: NULL argument");
        u32          length;
        SocketFamily family;
    } SocketAddr;
    
    ///
        i32        fd;
        SocketKind kind;
        SocketAddr bound;
    } Listener;
        i32        fd;
        SocketKind kind;
        SocketAddr peer;
    } Socket;
    /// TAGS: Socket, Address, DNS
    ///
    bool SocketAddrParse(SocketAddr *out, const char *spec, SocketKind kind);
    
    ///
    /// TAGS: Socket, Address, Format
    ///
    Str SocketAddrFormat(const SocketAddr *addr, Allocator *alloc);
    
    // --- Listener (server side) -------------------------------------------------
    /// TAGS: Socket, Listener, Bind
    ///
    bool ListenerOpen(Listener *out, SocketKind kind, const SocketAddr *addr, i32 backlog);
    
    ///
    /// TAGS: Socket, Connect
    ///
    bool SocketConnect(Socket *out, SocketKind kind, const SocketAddr *target);
    
    ///
    }
    
    static void handle_connection(Allocator *alloc, Socket *client, const SocketAddr *upstream_addr) {
        Str peer_str = SocketAddrFormat(&client->peer, alloc);
            LogInit(false, alloc);
    
            SocketAddr listen_addr;
            if (!SocketAddrParse(&listen_addr, listen_spec, SOCKET_KIND_TCP)) {
                LOG_ERROR("invalid --listen address: {}", listen_spec);
            }
    
            SocketAddr upstream_addr;
            if (!SocketAddrParse(&upstream_addr, upstream_spec, SOCKET_KIND_TCP)) {
                LOG_ERROR("invalid --upstream address: {}", upstream_spec);
Last updated on