Esempio n. 1
0
/*ARGSUSED*/
const SSERV_VTable* SERV_DISPD_Open(SERV_ITER iter,
                                    const SConnNetInfo* net_info,
                                    SSERV_Info** info, HOST_INFO* u/*unused*/)
{
    struct SDISPD_Data* data;

    if (!(data = (struct SDISPD_Data*) calloc(1, sizeof(*data))))
        return 0;
    iter->data = data;

    assert(net_info); /*must be called with non-NULL*/
    data->net_info = ConnNetInfo_Clone(net_info);
    if (!ConnNetInfo_SetupStandardArgs(data->net_info, iter->name)) {
        s_Close(iter);
        return 0;
    }

    if (g_NCBI_ConnectRandomSeed == 0) {
        g_NCBI_ConnectRandomSeed  = iter->time ^ NCBI_CONNECT_SRAND_ADDEND;
        srand(g_NCBI_ConnectRandomSeed);
    }

    /* Reset request method to be GET ('cause no HTTP body is ever used) */
    data->net_info->req_method = eReqMethod_Get;
    if (iter->stateless)
        data->net_info->stateless = 1/*true*/;
    if ((iter->types & fSERV_Firewall)  &&  !data->net_info->firewall)
        data->net_info->firewall = eFWMode_Adaptive;
    ConnNetInfo_ExtendUserHeader(data->net_info,
                                 "User-Agent: NCBIServiceDispatcher/"
                                 HTTP_DISP_VERSION
#ifdef NCBI_CXX_TOOLKIT
                                 " (CXX Toolkit)"
#else
                                 " (C Toolkit)"
#endif /*NCBI_CXX_TOOLKIT*/
                                 "\r\n");
    data->n_skip = iter->n_skip;

    iter->op = &s_op; /*SERV_Update() [from HTTP callback] expects*/
    s_Resolve(iter);
    iter->op = 0;

    if (!data->n_cand  &&  (data->fail
                            ||  !(data->net_info->stateless  &&
                                  data->net_info->firewall))) {
        s_Reset(iter);
        s_Close(iter);
        return 0;
    }

    /* call GetNextInfo subsequently if info is actually needed */
    if (info)
        *info = 0;
    return &s_op;
}
Esempio n. 2
0
/*ARGSUSED*/
const SSERV_VTable* SERV_LOCAL_Open(SERV_ITER iter,
                                    SSERV_Info** info, HOST_INFO* u/*unused*/)
{
    struct SLOCAL_Data* data;

    if (!iter->ismask  &&  strpbrk(iter->name, "?*"))
        return 0/*failed to start unallowed wildcard search*/;

    if (!(data = (struct SLOCAL_Data*) calloc(1, sizeof(*data))))
        return 0;

    iter->data = data;

    if (g_NCBI_ConnectRandomSeed == 0) {
        g_NCBI_ConnectRandomSeed = iter->time ^ NCBI_CONNECT_SRAND_ADDEND;
        srand(g_NCBI_ConnectRandomSeed);
    }

    if (!s_LoadServices(iter)) {
        s_Reset(iter);
        s_Close(iter);
        return 0;
    }
    if (data->n_cand > 1)
        qsort(data->cand, data->n_cand, sizeof(*data->cand), s_Sort);

    /* call GetNextInfo subsequently if info is actually needed */
    if (info)
        *info = 0;
    return &s_op;
}
Esempio n. 3
0
static EIO_Status s_VT_Close(CONNECTOR connector, const STimeout* timeout)
{
    SServiceConnector* uuu = (SServiceConnector*) connector->handle;
    EIO_Status status = uuu->meta.close
        ? uuu->meta.close(uuu->meta.c_close, timeout)
        : eIO_Success;
    s_Close(connector, timeout, 1/*close_dispatcher*/);
    return status;
}
Esempio n. 4
0
const SSERV_VTable* SERV_LBSMD_Open(SERV_ITER    iter,
                                    SSERV_Info** info,
                                    HOST_INFO*   host_info,
                                    int/*bool*/  no_dispd_follows)
{
    static int s_Init = 0;
    SSERV_Info* tmp;
    /* Daemon is running if LBSM_LBSMD returns 1: mutex exists but read
       operation failed with errno == EAGAIN (the mutex is busy) */
    if (LBSM_LBSMD(0) <= 0  ||  errno != EAGAIN)
        return 0;
    if (!s_Init) {
        CORE_LOCK_WRITE;
        if (!s_Init  &&  atexit(s_Fini) == 0)
            s_Init = 1;
        CORE_UNLOCK;
    }
    if (g_NCBI_ConnectRandomSeed == 0) {
        g_NCBI_ConnectRandomSeed = iter->time ^ NCBI_CONNECT_SRAND_ADDEND;
        srand(g_NCBI_ConnectRandomSeed);
    }
    if (!no_dispd_follows)
        iter->data =  iter;
    tmp = s_GetNextInfo(iter, host_info);
    if (iter->data == iter)
        iter->data =  0;
    if (!tmp) {
        s_Close(iter);
        return 0;
    }
    if (info)
        *info = tmp;
    else if (tmp)
        free(tmp);
    return &s_op;
}
Esempio n. 5
0
static EIO_Status s_VT_Open(CONNECTOR connector, const STimeout* timeout)
{
    SServiceConnector* uuu = (SServiceConnector*) connector->handle;
    SMetaConnector* meta = connector->meta;
    EIO_Status status;

    for (;;) {
        const SSERV_Info* info;
        SConnNetInfo* net_info;
        CONNECTOR conn;
        int stateless;

        assert(!uuu->meta.list  &&  !uuu->name  &&  !uuu->descr);
        if (!uuu->iter  &&  !s_OpenDispatcher(uuu)) {
            status = eIO_Closed;
            break;
        }

        if (uuu->net_info->firewall  &&  strcasecmp(uuu->iter->name, "local"))
            info = 0;
        else if (!(info = s_GetNextInfo(uuu))) {
            status = eIO_Closed;
            break;
        }

        if (!(net_info = ConnNetInfo_Clone(uuu->net_info))) {
            status = eIO_Unknown;
            break;
        }

        net_info->scheme = eURL_Unspec;
        conn = s_Open(uuu, timeout, info, net_info, 0/*!second_try*/);
        if (conn)
            uuu->descr = ConnNetInfo_URL(net_info);
        stateless = net_info->stateless;

        ConnNetInfo_Destroy(net_info);

        if (!conn) {
            if (!info) {
                status = eIO_Closed;
                break;
            }
            continue;
        }

        /* Setup the new connector on a temporary meta-connector... */
        memset(&uuu->meta, 0, sizeof(uuu->meta));
        METACONN_Add(&uuu->meta, conn);
        /* ...then link it in using current connection's meta */
        conn->meta = meta;
        conn->next = meta->list;
        meta->list = conn;

        if (!uuu->descr  &&  uuu->meta.descr)
            CONN_SET_METHOD(meta, descr, uuu->meta.descr, uuu->meta.c_descr);
        CONN_SET_METHOD    (meta, wait,  uuu->meta.wait,  uuu->meta.c_wait);
        CONN_SET_METHOD    (meta, write, uuu->meta.write, uuu->meta.c_write);
        CONN_SET_METHOD    (meta, flush, uuu->meta.flush, uuu->meta.c_flush);
        CONN_SET_METHOD    (meta, read,  uuu->meta.read,  uuu->meta.c_read);
        CONN_SET_METHOD    (meta, status,uuu->meta.status,uuu->meta.c_status);
        if (uuu->meta.get_type) {
            const char* type;
            if ((type = uuu->meta.get_type(uuu->meta.c_get_type)) != 0) {
                size_t slen = strlen(uuu->service);
                size_t tlen = strlen(type);
                char* name = (char*) malloc(slen + tlen + 2);
                if (name) {
                    memcpy(name,        uuu->service, slen);
                    name[slen++] = '/';
                    memcpy(name + slen, type,         tlen);
                    tlen += slen;
                    name[tlen]   = '\0';
                    uuu->name = name;
                }
            }
        }

        status = uuu->meta.open
            ? uuu->meta.open(uuu->meta.c_open, timeout) : eIO_Success;
        if (status == eIO_Success)
            break;

        if (!stateless  &&  (!info  ||  info->type == fSERV_Firewall)) {
            static const char kFWLink[] = { "http://www.ncbi.nlm.nih.gov"
                                            "/IEB/ToolBox/NETWORK"
                                            "/dispatcher.html#Firewalling"};
            CORE_LOGF_X(6, eLOG_Error,
                        ("[%s]  %s connection failed (%s) indicating possible "
                         "firewall configuration problem; please consult <%s>",
                         uuu->service, !info ? "Firewall" : "Stateful relay",
                         IO_StatusStr(status), kFWLink));
        }
        s_Close(connector, timeout, 0/*don't close dispatcher just as yet*/);
    }

    uuu->status = status;
    return status;
}
static EIO_Status s_VT_Close(CONNECTOR connector, const STimeout* timeout)
{
    return s_Close(connector, timeout, 1/*close_dispatcher*/);
}