+
+int ir_read(IOCHAN h, int event)
+{
+ association *assoc = (association *)iochan_getdata(h);
+ COMSTACK conn = assoc->client_link;
+ request *req;
+
+ if ((assoc->cs_put_mask & EVENT_INPUT) == 0 && (event & assoc->cs_get_mask))
+ {
+ yaz_log(YLOG_DEBUG, "ir_session (input)");
+ /* We aren't speaking to this fellow */
+ if (assoc->state == ASSOC_DEAD)
+ {
+ yaz_log(log_sessiondetail, "Connection closed - end of session");
+ cs_close(conn);
+ destroy_association(assoc);
+ iochan_destroy(h);
+ return 0;
+ }
+ assoc->cs_get_mask = EVENT_INPUT;
+
+ do
+ {
+ int res = cs_get(conn, &assoc->input_buffer,
+ &assoc->input_buffer_len);
+ if (res < 0 && cs_errno(conn) == CSBUFSIZE)
+ {
+ yaz_log(log_session, "Connection error: %s res=%d",
+ cs_errmsg(cs_errno(conn)), res);
+ req = request_get(&assoc->incoming); /* get a new request */
+ do_close_req(assoc, Z_Close_protocolError,
+ "Incoming package too large", req);
+ return 0;
+ }
+ else if (res <= 0)
+ {
+ yaz_log(log_session, "Connection closed by client");
+ assoc->state = ASSOC_DEAD;
+ return 0;
+ }
+ else if (res == 1) /* incomplete read - wait for more */
+ {
+ if (conn->io_pending & CS_WANT_WRITE)
+ assoc->cs_get_mask |= EVENT_OUTPUT;
+ iochan_setflag(h, assoc->cs_get_mask);
+ return 0;
+ }
+ /* we got a complete PDU. Let's decode it */
+ yaz_log(YLOG_DEBUG, "Got PDU, %d bytes: lead=%02X %02X %02X", res,
+ assoc->input_buffer[0] & 0xff,
+ assoc->input_buffer[1] & 0xff,
+ assoc->input_buffer[2] & 0xff);
+ req = request_get(&assoc->incoming); /* get a new request */
+ odr_reset(assoc->decode);
+ odr_setbuf(assoc->decode, assoc->input_buffer, res, 0);
+ if (!z_GDU(assoc->decode, &req->gdu_request, 0, 0))
+ {
+ yaz_log(YLOG_WARN, "ODR error on incoming PDU: %s [element %s] "
+ "[near byte %ld] ",
+ odr_errmsg(odr_geterror(assoc->decode)),
+ odr_getelement(assoc->decode),
+ (long) odr_offset(assoc->decode));
+ if (assoc->decode->error != OHTTP)
+ {
+ yaz_log(YLOG_WARN, "PDU dump:");
+ odr_dumpBER(yaz_log_file(), assoc->input_buffer, res);
+ request_release(req);
+ do_close(assoc, Z_Close_protocolError, "Malformed package");
+ }
+ else
+ {
+ Z_GDU *p = z_get_HTTP_Response(assoc->encode, 400);
+ assoc->state = ASSOC_DEAD;
+ process_gdu_response(assoc, req, p);
+ }
+ return 0;
+ }
+ req->request_mem = odr_extract_mem(assoc->decode);
+ if (assoc->print)
+ {
+ if (!z_GDU(assoc->print, &req->gdu_request, 0, 0))
+ yaz_log(YLOG_WARN, "ODR print error: %s",
+ odr_errmsg(odr_geterror(assoc->print)));
+ odr_reset(assoc->print);
+ }
+ request_enq(&assoc->incoming, req);
+ }
+ while (cs_more(conn));
+ }
+ return 1;
+}
+