Пример #1
0
struct http_session *http_session_create(struct conf_service *service,
        http_sessions_t http_sessions,
        unsigned int sesid)
{
    NMEM nmem = nmem_create();
    struct http_session *r = nmem_malloc(nmem, sizeof(*r));
    char tmp_str[50];

    sprintf(tmp_str, "session#%u", sesid);
    r->psession = new_session(nmem, service, sesid);
    r->session_id = sesid;
    r->timestamp = 0;
    r->nmem = nmem;
    r->destroy_counter = r->activity_counter = 0;
    r->http_sessions = http_sessions;

    yaz_mutex_enter(http_sessions->mutex);
    r->next = http_sessions->session_list;
    http_sessions->session_list = r;
    yaz_mutex_leave(http_sessions->mutex);

    r->timeout_iochan = iochan_create(-1, session_timeout, 0, "http_session_timeout");
    iochan_setdata(r->timeout_iochan, r);
    yaz_log(http_sessions->log_level, "Session %u created. timeout chan=%p timeout=%d", sesid, r->timeout_iochan, service->session_timeout);
    iochan_settimeout(r->timeout_iochan, service->session_timeout);

    iochan_add(service->server->iochan_man, r->timeout_iochan);
    http_session_use(1);
    return r;
}
Пример #2
0
/** brief use the fd for something */
static void test_for_real_work(int no_threads)
{
    int thread_fd;
    sel_thread_t p = sel_thread_create(work_handler, work_destroy,
                                       &thread_fd, no_threads);
    YAZ_CHECK(p);
    if (p)
    {
        iochan_man_t chan_man = iochan_man_create(10);
        IOCHAN chan = iochan_create(thread_fd, iochan_handler,
                                    EVENT_INPUT|EVENT_TIMEOUT, "test_chan");
        iochan_settimeout(chan, 1);
        iochan_setdata(chan, p);
        iochan_add(chan_man, chan);

        iochan_man_events(chan_man);
        sel_thread_destroy(p);
        iochan_man_destroy(&chan_man);
    }
}
Пример #3
0
static void inetd_connection(int what)
{
    COMSTACK line;
    IOCHAN chan;
    association *assoc;
    char *addr;

    if ((line = cs_createbysocket(0, tcpip_type, 0, what)))
    {
        if ((chan = iochan_create(cs_fileno(line), ir_session, EVENT_INPUT,
                                  0)))
        {
            if ((assoc = create_association(chan, line,
                                            control_block.apdufile)))
            {
                iochan_setdata(chan, assoc);
                iochan_settimeout(chan, 60);
                addr = cs_addrstr(line);
                yaz_log(log_sessiondetail, "Inetd association from %s",
                        addr ? addr : "[UNKNOWN]");
                assoc->cs_get_mask = EVENT_INPUT;
            }
            else
            {
                yaz_log(YLOG_FATAL, "Failed to create association structure");
            }
            chan->next = pListener;
            pListener = chan;
        }
        else
        {
            yaz_log(YLOG_FATAL, "Failed to create iochan");
        }
    }
    else
    {
        yaz_log(YLOG_ERRNO|YLOG_FATAL, "Failed to create comstack on socket 0");
    }
}
Пример #4
0
static int connection_connect(struct connection *con, iochan_man_t iochan_man)
{
    struct host *host = connection_get_host(con);
    ZOOM_options zoptions = ZOOM_options_create();
    const char *auth;
    const char *charset;
    const char *sru;
    const char *sru_version = 0;

    struct session_database *sdb = client_get_database(con->client);
    const char *apdulog = session_setting_oneval(sdb, PZ_APDULOG);

    assert(con);

    ZOOM_options_set(zoptions, "async", "1");
    ZOOM_options_set(zoptions, "implementationName", PACKAGE_NAME);
    ZOOM_options_set(zoptions, "implementationVersion", VERSION);
	
    if ((charset = session_setting_oneval(sdb, PZ_NEGOTIATION_CHARSET)))
        ZOOM_options_set(zoptions, "charset", charset);
    
    assert(host->ipport);
    if (host->proxy)
    {
        yaz_log(YLOG_LOG, "proxy=%s", host->ipport);
        ZOOM_options_set(zoptions, "proxy", host->ipport);
    }
    else
    {
        assert(host->tproxy);
        yaz_log(YLOG_LOG, "tproxy=%s", host->ipport);
        ZOOM_options_set(zoptions, "tproxy", host->ipport);
    }   

    if (apdulog && *apdulog)
        ZOOM_options_set(zoptions, "apdulog", apdulog);

    if ((auth = session_setting_oneval(sdb, PZ_AUTHENTICATION)))
        ZOOM_options_set(zoptions, "user", auth);
    if ((sru = session_setting_oneval(sdb, PZ_SRU)) && *sru)
        ZOOM_options_set(zoptions, "sru", sru);
    if ((sru_version = session_setting_oneval(sdb, PZ_SRU_VERSION)) 
        && *sru_version)
        ZOOM_options_set(zoptions, "sru_version", sru_version);
    if (!(con->link = ZOOM_connection_create(zoptions)))
    {
        yaz_log(YLOG_FATAL|YLOG_ERRNO, "Failed to create ZOOM Connection");
        ZOOM_options_destroy(zoptions);
        return -1;
    }

    if (sru && *sru)
    {
        char http_hostport[512];
        strcpy(http_hostport, "http://");
        strcat(http_hostport, host->url);
        yaz_log(YLOG_LOG, "SRU connect to : %s", http_hostport);
        ZOOM_connection_connect(con->link, http_hostport, 0);
    }
    else
    {
        ZOOM_connection_connect(con->link, host->url, 0);
    }
    con->iochan = iochan_create(-1, connection_handler, 0, "connection_socket");
    con->state = Conn_Connecting;
    iochan_settimeout(con->iochan, con->operation_timeout);
    iochan_setdata(con->iochan, con);
    iochan_add(iochan_man, con->iochan);

    client_set_state(con->client, Client_Connecting);
    ZOOM_options_destroy(zoptions);
    return 0;
}
Пример #5
0
static void non_block_events(struct connection *co)
{
    int got_records = 0;
    IOCHAN iochan = co->iochan;
    ZOOM_connection link = co->link;
    while (1)
    {
        struct client *cl = co->client;
        int ev;
        int r = ZOOM_event_nonblock(1, &link);
        if (!r)
            break;
        if (!cl)
            continue;
        ev = ZOOM_connection_last_event(link);
        
#if 1
        yaz_log(YLOG_DEBUG, "%p Connection ZOOM_EVENT_%s", co, ZOOM_get_event_str(ev));
#endif
        switch (ev) 
        {
        case ZOOM_EVENT_END:
            {
                const char *error, *addinfo;
                int err;
                if ((err = ZOOM_connection_error(link, &error, &addinfo)))
                {
                    yaz_log(YLOG_LOG, "Error %s from %s",
                            error, client_get_id(cl));
                    client_set_diagnostic(cl, err, addinfo);
                    client_set_state(cl, Client_Error);
                }
                else
                {
                    iochan_settimeout(iochan, co->session_timeout);
                    client_set_state(cl, Client_Idle);
                }
                yaz_cond_broadcast(co->host->cond_ready);
            }
            break;
        case ZOOM_EVENT_SEND_DATA:
            break;
        case ZOOM_EVENT_RECV_DATA:
            break;
        case ZOOM_EVENT_UNKNOWN:
            break;
        case ZOOM_EVENT_SEND_APDU:
            client_set_state(co->client, Client_Working);
            iochan_settimeout(iochan, co->operation_timeout);
            break;
        case ZOOM_EVENT_RECV_APDU:
            break;
        case ZOOM_EVENT_CONNECT:
            yaz_log(YLOG_LOG, "Connected to %s", client_get_id(cl));
            co->state = Conn_Open;
            break;
        case ZOOM_EVENT_RECV_SEARCH:
            client_search_response(cl);
            break;
        case ZOOM_EVENT_RECV_RECORD:
            client_record_response(cl);
            got_records = 1;
            break;
        default:
            yaz_log(YLOG_LOG, "Unhandled event (%d) from %s",
                    ev, client_get_id(cl));
            break;
        }
    }
    if (got_records)
    {
        struct client *cl = co->client;
        if (cl)
        {
            client_check_preferred_watch(cl);
            client_got_records(cl);
        }
    }
}
Пример #6
0
static void *new_session(void *vp)
{
    char *a;
    association *newas;
    IOCHAN new_chan;
    COMSTACK new_line = (COMSTACK) vp;
    IOCHAN parent_chan = (IOCHAN) new_line->user;

    unsigned cs_get_mask, cs_accept_mask, mask =  
        ((new_line->io_pending & CS_WANT_WRITE) ? EVENT_OUTPUT : 0) |
        ((new_line->io_pending & CS_WANT_READ) ? EVENT_INPUT : 0);

    if (mask)
    {
        cs_accept_mask = mask;  /* accept didn't complete */
        cs_get_mask = 0;
    }
    else
    {
        cs_accept_mask = 0;     /* accept completed.  */
        cs_get_mask = mask = EVENT_INPUT;
    }

    if (!(new_chan = iochan_create(cs_fileno(new_line), ir_session, mask,
                                   parent_chan->chan_id)))
    {
        yaz_log(YLOG_FATAL, "Failed to create iochan");
        return 0;
    }
    if (!(newas = create_association(new_chan, new_line,
                                     control_block.apdufile)))
    {
        yaz_log(YLOG_FATAL, "Failed to create new assoc.");
        return 0;
    }
    newas->cs_accept_mask = cs_accept_mask;
    newas->cs_get_mask = cs_get_mask;

    iochan_setdata(new_chan, newas);
    iochan_settimeout(new_chan, 60);
#if 1
    a = cs_addrstr(new_line);
#else
    a = 0;
#endif
    yaz_log_xml_errors(0, YLOG_WARN);
    yaz_log(log_session, "Session - OK %d %s %ld",
            no_sessions, a ? a : "[Unknown]", (long) getpid());
    if (max_sessions && no_sessions >= max_sessions)
        control_block.one_shot = 1;
    if (control_block.threads)
    {
        iochan_event_loop(&new_chan);
    }
    else
    {
        new_chan->next = pListener;
        pListener = new_chan;
    }
    return 0;
}
Пример #7
0
/* WIN32 listener */
static void listener(IOCHAN h, int event)   
{
    COMSTACK line = (COMSTACK) iochan_getdata(h);
    IOCHAN parent_chan = line->user;
    association *newas;
    int res;
    HANDLE newHandle;

    if (event == EVENT_INPUT)
    {
        COMSTACK new_line;
        IOCHAN new_chan;

        if ((res = cs_listen(line, 0, 0)) < 0)
        {
            yaz_log(YLOG_FATAL|YLOG_ERRNO, "cs_listen failed");
            return;
        }
        else if (res == 1)
            return; /* incomplete */
        yaz_log(YLOG_DEBUG, "listen ok");
        new_line = cs_accept(line);
	if (!new_line)
        {
            yaz_log(YLOG_FATAL, "Accept failed.");
            return;
        }
        yaz_log(YLOG_DEBUG, "Accept ok");

        if (!(new_chan = iochan_create(cs_fileno(new_line), ir_session,
                                       EVENT_INPUT, parent_chan->chan_id)))
        {
            yaz_log(YLOG_FATAL, "Failed to create iochan");
            iochan_destroy(h);
            return;
        }

        yaz_log(YLOG_DEBUG, "Creating association");
        if (!(newas = create_association(new_chan, new_line,
                                         control_block.apdufile)))
        {
            yaz_log(YLOG_FATAL, "Failed to create new assoc.");
            iochan_destroy(h);
            return;
        }
        newas->cs_get_mask = EVENT_INPUT;
        newas->cs_put_mask = 0;
        newas->cs_accept_mask = 0;

        yaz_log(YLOG_DEBUG, "Setting timeout %d", control_block.idle_timeout);
        iochan_setdata(new_chan, newas);
        iochan_settimeout(new_chan, 60);

        /* Now what we need todo is create a new thread with this iochan as
           the parameter */
        newHandle = (HANDLE) _beginthread(event_loop_thread, 0, new_chan);
        if (newHandle == (HANDLE) -1)
        {
            
            yaz_log(YLOG_FATAL|YLOG_ERRNO, "Failed to create new thread.");
            iochan_destroy(h);
            return;
        }
        /* We successfully created the thread, so add it to the list */
        statserv_add(newHandle, new_chan);

        yaz_log(YLOG_DEBUG, "Created new thread, id = %ld iochan %p",(long) newHandle, new_chan);
        iochan_setflags(h, EVENT_INPUT | EVENT_EXCEPT); /* reset listener */
    }
    else
    {
        yaz_log(YLOG_FATAL, "Bad event on listener.");
        iochan_destroy(h);
        return;
    }
}