Chandra

 view release on metacpan or  search on metacpan

include/chandra/chandra_socket_hub.h  view on Meta::CPAN


static SV *
_hub_create_tcp_listener(pTHX_ HV *hv)
{
    SV **tls_cert_svp = hv_fetchs(hv, "tls_cert", 0);
    SV **tls_key_svp  = hv_fetchs(hv, "tls_key", 0);
    SV **bind_svp     = hv_fetchs(hv, "bind_addr", 0);
    SV **port_svp     = hv_fetchs(hv, "port", 0);
    SV *host = bind_svp ? *bind_svp : sv_2mortal(newSVpvs("127.0.0.1"));
    SV *port = port_svp ? *port_svp : &PL_sv_undef;
    SV *listener = NULL;

    if (tls_cert_svp && SvOK(*tls_cert_svp) &&
        tls_key_svp  && SvOK(*tls_key_svp)) {
        listener = _sock_tls_listen(aTHX_ host, port,
            *tls_cert_svp, *tls_key_svp);
        if (!listener)
            croak("Hub: cannot listen on TLS TCP %s:%s: %s",
                bind_svp ? SvPV_nolen(*bind_svp) : "?",
                port_svp ? SvPV_nolen(*port_svp) : "?",
                SvPV_nolen(get_sv("!", 0)));
        _sock_set_nonblocking(aTHX_ listener);
    } else {
        listener = _sock_tcp_listen(aTHX_ host, port);
        if (!listener)
            croak("Hub: cannot listen on TCP %s:%s: %s",
                bind_svp ? SvPV_nolen(*bind_svp) : "?",
                port_svp ? SvPV_nolen(*port_svp) : "?",
                SvPV_nolen(get_sv("!", 0)));
    }
    return listener;
}

/* ---- Create a Unix domain listener ---- */

static SV *
_hub_create_unix_listener(pTHX_ HV *hv)
{
    SV **name_svp  = hv_fetchs(hv, "name", 0);
    SV **token_svp = hv_fetchs(hv, "_token", 0);
    const char *name_str = (name_svp && SvOK(*name_svp))
        ? SvPV_nolen(*name_svp) : "default";
    SV *path_sv, *listener;
    const char *path_str;
    STRLEN path_len;

    path_sv = _sock_build_path(aTHX_ name_str);
    path_str = SvPV(path_sv, path_len);
    (void)hv_stores(hv, "_socket_path", newSVsv(path_sv));

    (void)PerlLIO_unlink(path_str);

    listener = _sock_unix_listen(aTHX_ path_sv);
    if (!listener) {
        SvREFCNT_dec(path_sv);
        croak("Hub: cannot listen on %s: %s",
            path_str, SvPV_nolen(get_sv("!", 0)));
    }

#ifndef _WIN32
    (void)PerlLIO_chmod(path_str, 0600);
#endif
    _sock_set_nonblocking(aTHX_ listener);

    /* Write token file */
    {
        SV *token_path_sv = newSVpvf("%s.token", path_str);
        (void)hv_stores(hv, "_token_path", newSVsv(token_path_sv));

        if (token_svp && SvOK(*token_svp)) {
            STRLEN tlen;
            const char *tstr = SvPV(*token_svp, tlen);
            _sock_write_token_file(aTHX_ SvPV_nolen(token_path_sv), tstr, tlen);
        }
        SvREFCNT_dec(token_path_sv);
    }

    SvREFCNT_dec(path_sv);
    return listener;
}

/* ---- Start the listener socket ---- */

static void
_hub_start_listener(pTHX_ SV *self)
{
    HV *hv = (HV *)SvRV(self);
    SV **transport_svp = hv_fetchs(hv, "transport", 0);
    SV **select_svp    = hv_fetchs(hv, "_select", 0);
    const char *transport;
    SV *listener;

    transport = (transport_svp && SvOK(*transport_svp))
        ? SvPV_nolen(*transport_svp) : "unix";

#ifdef _WIN32
    /* Auto-upgrade to TCP on Windows - Unix domain sockets not available */
    if (!strEQ(transport, "tcp")) {
        transport = "tcp";
        (void)hv_stores(hv, "transport", newSVpvs("tcp"));
    }
#endif
    if (strEQ(transport, "tcp"))
        listener = _hub_create_tcp_listener(aTHX_ hv);
    else
        listener = _hub_create_unix_listener(aTHX_ hv);

    (void)hv_stores(hv, "_listener", listener);

    if (select_svp && SvOK(*select_svp))
        _sock_select_add(aTHX_ *select_svp, listener);

#ifdef _WIN32
    /* Write discovery file so clients can find this TCP hub by name.
     * The file contains "port\ntoken\n" and is written to the same
     * directory that would hold the Unix socket path.                */
    {
        SV **name_svp = hv_fetchs(hv, "name", 0);
        if (name_svp && SvOK(*name_svp)) {
            SV *disc_path = _sock_build_path(aTHX_ SvPV_nolen(*name_svp));
            /* Get the real bound port via sockname() */



( run in 1.767 second using v1.01-cache-2.11-cpan-cdf2f3d4e48 )