Exemple #1
0
static void cmd_init(struct http_channel *c)
{
    struct http_request *r = c->request;
    const char *clear = http_argbyname(r, "clear");
    const char *content_type = http_lookup_header(r->headers, "Content-Type");
    unsigned int sesid;
    struct http_session *s;
    struct http_response *rs = c->response;
    struct conf_service *service = 0; /* no service (yet) */

    if (r->content_len && content_type &&
            !yaz_strcmp_del("text/xml", content_type, "; "))
    {
        xmlDoc *doc = xmlParseMemory(r->content_buf, r->content_len);
        xmlNode *root_n;
        if (!doc)
        {
            error(rs, PAZPAR2_MALFORMED_SETTING, 0);
            return;
        }
        root_n = xmlDocGetRootElement(doc);
        service = service_create(c->server, root_n);
        xmlFreeDoc(doc);
        if (!service)
        {
            error(rs, PAZPAR2_MALFORMED_SETTING, 0);
            return;
        }
    }

    if (!service)
    {
        const char *service_name = http_argbyname(c->request, "service");
        service = locate_service(c->server, service_name);
        if (!service)
        {
            error(rs, PAZPAR2_NO_SERVICE, service_name ? service_name : "unnamed");
            return;
        }
    }
    sesid = make_sessionid();
    s = http_session_create(service, c->http_sessions, sesid);

    yaz_log(c->http_sessions->log_level, "Session init %u ", sesid);
    if (!clear || *clear == '0')
        session_init_databases(s->psession);
    else
        yaz_log(YLOG_LOG, "Session %u init: No databases preloaded", sesid);

    if (process_settings(s->psession, c->request, c->response) < 0)
        return;

    response_open(c, "init");
    wrbuf_printf(c->wrbuf, "<session>%d", sesid);
    if (c->server->server_id)
    {
        wrbuf_puts(c->wrbuf, ".");
        wrbuf_puts(c->wrbuf, c->server->server_id);
    }
    wrbuf_puts(c->wrbuf, "</session>"
               "<protocol>" PAZPAR2_PROTOCOL_VERSION "</protocol>");

    wrbuf_printf(c->wrbuf, "<keepAlive>%d</keepAlive>\n", 1000 * ((s->psession->service->session_timeout >= 20) ?
                 (s->psession->service->session_timeout - 10) : 50));
    response_close(c, "init");
}
Exemple #2
0
/*
 * Dispatch a message from the tunnel driver.  It could be an actual
 * PPPoE message or just an event notification.
 */
static void
handle_input(uint32_t *ctrlbuf, int ctrllen, uint32_t *databuf, int datalen)
{
	poep_t *poep = (poep_t *)databuf;
	union ppptun_name ptn;
	int retv;
	struct strbuf ctrl;
	struct strbuf data;
	void *srvp;
	boolean_t launch;
	struct ppptun_control *ptc;

	if (ctrllen != sizeof (*ptc)) {
		logdbg("bogus %d byte control message from driver",
		    ctrllen);
		return;
	}
	ptc = (struct ppptun_control *)ctrlbuf;

	/* Switch out on event notifications. */
	switch (ptc->ptc_action) {
	case PTCA_TEST:
		logdbg("test reply for discriminator %X", ptc->ptc_discrim);
		return;

	case PTCA_CONTROL:
		break;

	case PTCA_DISCONNECT:
		logdbg("session %d disconnected on %s; send PADT",
		    ptc->ptc_rsessid, ptc->ptc_name);
		poep = poe_mkheader(pkt_output, POECODE_PADT,
		    ptc->ptc_rsessid);
		ptc->ptc_action = PTCA_CONTROL;
		ctrl.len = sizeof (*ptc);
		ctrl.buf = (caddr_t)ptc;
		data.len = poe_length(poep) + sizeof (*poep);
		data.buf = (caddr_t)poep;
		if (putmsg(tunfd, &ctrl, &data, 0) < 0) {
			logerr("putmsg PADT: %s", mystrerror(errno));
		} else {
			output_packets++;
		}
		return;

	case PTCA_UNPLUMB:
		logdbg("%s unplumbed", ptc->ptc_name);
		return;

	default:
		logdbg("unexpected code %d from driver", ptc->ptc_action);
		return;
	}

	/* Only PPPoE control messages get here. */

	input_packets++;
	if (datalen < sizeof (*poep)) {
		logdbg("incomplete PPPoE message from %s/%s",
		    ehost(&ptc->ptc_address), ptc->ptc_name);
		return;
	}

	/* Server handles only PADI and PADR; all others are ignored. */
	if (poep->poep_code == POECODE_PADI) {
		padi_packets++;
	} else if (poep->poep_code == POECODE_PADR) {
		padr_packets++;
	} else {
		loginfo("unexpected %s from %s",
		    poe_codename(poep->poep_code), ehost(&ptc->ptc_address));
		return;
	}
	logdbg("Recv from %s/%s: %s", ehost(&ptc->ptc_address), ptc->ptc_name,
	    poe_codename(poep->poep_code));

	/* Parse out service and formulate template reply. */
	retv = locate_service(poep, datalen, ptc->ptc_name, &ptc->ptc_address,
	    pkt_output, &srvp);

	/* Continue formulating reply */
	launch = B_FALSE;
	if (retv != 1) {
		/* Ignore initiation if we don't offer a service. */
		if (retv <= 0 && poep->poep_code == POECODE_PADI) {
			logdbg("no services; no reply");
			return;
		}
		if (retv == 0)
			(void) poe_add_str((poep_t *)pkt_output, POETT_NAMERR,
			    "No such service.");
	} else {
		/* Exactly one service chosen; if it's PADR, then we start. */
		if (poep->poep_code == POECODE_PADR) {
			launch = B_TRUE;
		}
	}
	poep = (poep_t *)pkt_output;

	/* Select control interface for output. */
	(void) strncpy(ptn.ptn_name, ptc->ptc_name, sizeof (ptn.ptn_name));
	if (strioctl(tunfd, PPPTUN_SCTL, &ptn, sizeof (ptn), 0) < 0) {
		logerr("PPPTUN_SCTL %s: %s", ptn.ptn_name, mystrerror(errno));
		return;
	}

	/* Launch the PPP service */
	if (launch && launch_service(tunfd, poep, srvp, ptc))
		sessions_started++;

	/* Send the reply. */
	ctrl.len = sizeof (*ptc);
	ctrl.buf = (caddr_t)ptc;
	data.len = poe_length(poep) + sizeof (*poep);
	data.buf = (caddr_t)poep;
	if (putmsg(tunfd, &ctrl, &data, 0) < 0) {
		logerr("putmsg %s: %s", ptc->ptc_name, mystrerror(errno));
	} else {
		output_packets++;
		logdbg("Send to   %s/%s: %s", ehost(&ptc->ptc_address),
		    ptc->ptc_name, poe_codename(poep->poep_code));
	}
}