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; }
/** 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); } }
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"); } }
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; }
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); } } }
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; }
/* 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; } }