Example #1
0
int sipevent_substate_decode(struct sipevent_substate *ss, const struct pl *pl)
{
	struct pl state, param;
	int err;

	if (!ss || !pl)
		return EINVAL;

	err = re_regex(pl->p, pl->l, "[a-z]+[ \t\r\n]*[^]*",
		       &state, NULL, &ss->params);
	if (err)
		return EBADMSG;

	if (!pl_strcasecmp(&state, "active"))
		ss->state = SIPEVENT_ACTIVE;
	else if (!pl_strcasecmp(&state, "pending"))
		ss->state = SIPEVENT_PENDING;
	else if (!pl_strcasecmp(&state, "terminated"))
		ss->state = SIPEVENT_TERMINATED;
	else
		ss->state = -1;

	if (!sip_param_decode(&ss->params, "reason", &param)) {

		if (!pl_strcasecmp(&param, "deactivated"))
			ss->reason = SIPEVENT_DEACTIVATED;
		else if (!pl_strcasecmp(&param, "probation"))
			ss->reason = SIPEVENT_PROBATION;
		else if (!pl_strcasecmp(&param, "rejected"))
			ss->reason = SIPEVENT_REJECTED;
		else if (!pl_strcasecmp(&param, "timeout"))
			ss->reason = SIPEVENT_TIMEOUT;
		else if (!pl_strcasecmp(&param, "giveup"))
			ss->reason = SIPEVENT_GIVEUP;
		else if (!pl_strcasecmp(&param, "noresource"))
			ss->reason = SIPEVENT_NORESOURCE;
		else
			ss->reason = -1;
	}
	else {
		ss->reason = -1;
	}

	if (!sip_param_decode(&ss->params, "expires", &param))
		ss->expires = param;
	else
		ss->expires = pl_null;

	if (!sip_param_decode(&ss->params, "retry-after", &param))
		ss->retry_after = param;
	else
		ss->retry_after = pl_null;

	return 0;
}
Example #2
0
static bool contact_handler(const struct sip_hdr *hdr,
			    const struct sip_msg *msg, void *arg)
{
	struct sipreg *reg = arg;
	struct sip_addr c;
	struct pl pval;
	char uri[256];

	if (sip_addr_decode(&c, &hdr->val))
		return false;

	if (re_snprintf(uri, sizeof(uri), "sip:%s@%J%s", reg->cuser,
			&reg->laddr, sip_transp_param(reg->tp)) < 0)
		return false;

	if (pl_strcmp(&c.auri, uri))
		return false;

	if (!sip_param_decode(&c.params, "expires", &pval)) {
	        reg->wait = pl_u32(&pval);
	}
	else if (pl_isset(&msg->expires))
	        reg->wait = pl_u32(&msg->expires);
	else
	        reg->wait = DEFAULT_EXPIRES;

	return true;
}
Example #3
0
int sipevent_event_decode(struct sipevent_event *se, const struct pl *pl)
{
	struct pl param;
	int err;

	if (!se || !pl)
		return EINVAL;

	err = re_regex(pl->p, pl->l, "[^; \t\r\n]+[ \t\r\n]*[^]*",
		       &se->event, NULL, &se->params);
	if (err)
		return EBADMSG;

	if (!sip_param_decode(&se->params, "id", &param))
		se->id = param;
	else
		se->id = pl_null;

	return 0;
}
Example #4
0
int sip_via_decode(struct sip_via *via, const struct pl *pl)
{
	struct pl transp, host, port;
	int err;

	if (!via || !pl)
		return EINVAL;

	err = re_regex(pl->p, pl->l,
		       "SIP[  \t\r\n]*/[ \t\r\n]*2.0[ \t\r\n]*/[ \t\r\n]*"
		       "[A-Z]+[ \t\r\n]*[^; \t\r\n]+[ \t\r\b]*[^]*",
		       NULL, NULL, NULL, NULL, &transp,
		       NULL, &via->sentby, NULL, &via->params);
	if (err)
		return err;

	if (!pl_strcmp(&transp, "TCP"))
		via->tp = SIP_TRANSP_TCP;
	else if (!pl_strcmp(&transp, "TLS"))
		via->tp = SIP_TRANSP_TLS;
	else if (!pl_strcmp(&transp, "UDP"))
		via->tp = SIP_TRANSP_UDP;
	else
		via->tp = SIP_TRANSP_NONE;

	err = decode_hostport(&via->sentby, &host, &port);
	if (err)
		return err;

	sa_init(&via->addr, AF_INET);

	(void)sa_set(&via->addr, &host, 0);

	if (pl_isset(&port))
		sa_set_port(&via->addr, pl_u32(&port));

	via->val = *pl;

	return sip_param_decode(&via->params, "branch", &via->branch);
}
Example #5
0
int subscriber_init(void)
{
	struct le *le;
	int err = 0;

	for (le = list_head(contact_list()); le; le = le->next) {

		struct contact *c = le->data;
		struct sip_addr *addr = contact_addr(c);
		struct pl val;

		if (0 == sip_param_decode(&addr->params, "presence", &val) &&
		    0 == pl_strcasecmp(&val, "p2p")) {

			err |= presence_alloc(le->data);
		}
	}

	info("Subscribing to %u contacts\n", list_count(&presencel));

	return err;
}
Example #6
0
/**
 * Send a SIP request
 *
 * @param reqp     Pointer to allocated SIP request object
 * @param sip      SIP Stack
 * @param stateful Stateful client transaction
 * @param met      SIP Method string
 * @param metl     Length of SIP Method string
 * @param uri      Request URI
 * @param uril     Length of Request URI string
 * @param route    Next hop route URI
 * @param mb       Buffer containing SIP request
 * @param sendh    Send handler
 * @param resph    Response handler
 * @param arg      Handler argument
 *
 * @return 0 if success, otherwise errorcode
 */
int sip_request(struct sip_request **reqp, struct sip *sip, bool stateful,
		const char *met, int metl, const char *uri, int uril,
		const struct uri *route, struct mbuf *mb,
		sip_send_h *sendh, sip_resp_h *resph, void *arg)
{
	struct sip_request *req;
	struct sa dst;
	struct pl pl;
	int err;

	if (!sip || !met || !uri || !route || !mb)
		return EINVAL;

	if (pl_strcasecmp(&route->scheme, "sip"))
		return ENOSYS;

	req = mem_zalloc(sizeof(*req), destructor);
	if (!req)
		return ENOMEM;

	list_append(&sip->reql, &req->le, req);

	err = str_ldup(&req->met, met, metl);
	if (err)
		goto out;

	err = str_ldup(&req->uri, uri, uril);
	if (err)
		goto out;

	if (sip_param_decode(&route->params, "maddr", &pl))
		pl = route->host;

	err = pl_strdup(&req->host, &pl);
	if (err)
		goto out;

	req->stateful = stateful;
	req->mb    = mem_ref(mb);
	req->sip   = sip;
	req->sendh = sendh;
	req->resph = resph;
	req->arg   = arg;

	if (!sip_param_decode(&route->params, "transport", &pl)) {

		if (!pl_strcasecmp(&pl, "udp"))
			req->tp = SIP_TRANSP_UDP;
		else if (!pl_strcasecmp(&pl, "tcp"))
			req->tp = SIP_TRANSP_TCP;
		else if (!pl_strcasecmp(&pl, "tls"))
			req->tp = SIP_TRANSP_TLS;
		else {
			err = EPROTONOSUPPORT;
			goto out;
		}

		if (!sip_transp_supported(sip, req->tp, AF_UNSPEC)) {
			err = EPROTONOSUPPORT;
			goto out;
		}

		req->tp_selected = true;
	}
	else {
		req->tp = SIP_TRANSP_NONE;
		if (!transp_next(sip, &req->tp)) {
			err = EPROTONOSUPPORT;
			goto out;
		}

		req->tp_selected = false;
	}

	if (!sa_set_str(&dst, req->host,
			sip_transp_port(req->tp, route->port))) {

		err = request(req, req->tp, &dst);
		if (!req->stateful) {
			mem_deref(req);
			return err;
		}
	}
	else if (route->port) {

		req->port = sip_transp_port(req->tp, route->port);
		err = addr_lookup(req, req->host);
	}
	else if (req->tp_selected) {

		err = srv_lookup(req, req->host);
	}
	else {
	        err = dnsc_query(&req->dnsq, sip->dnsc, req->host,
				 DNS_TYPE_NAPTR, DNS_CLASS_IN, true,
				 naptr_handler, req);
	}

 out:
	if (err)
		mem_deref(req);
	else if (reqp) {
		req->reqp = reqp;
		*reqp = req;
	}

	return err;
}