Exemple #1
0
static void info_resp_handler(int err, const struct sip_msg *msg, void *arg, void *user_data)
{
	struct sipsess_request *req = arg;

	if (err || sip_request_loops(&req->ls, msg->scode))
		goto out;

	if (msg->scode < 200) {
		return;
	}
	else if (msg->scode < 300) {
		;
	}
	else {
		if (req->sess->terminated)
			goto out;

		switch (msg->scode) {

		case 401:
		case 407:
			err = sip_auth_authenticate(req->sess->auth, msg);
			if (err) {
				err = (err == EAUTH) ? 0 : err;
				break;
			}

			err = info_request(req);
			if (err)
				break;

			return;

		case 408:
		case 481:
			sipsess_terminate(req->sess, 0, msg);
			break;
		}
	}

 out:
	if (!req->sess->terminated) {
		if (err == ETIMEDOUT)
			sipsess_terminate(req->sess, err, NULL);
		else
			req->resph(err, msg, req->arg, NULL);
	}

	mem_deref(req);
}
Exemple #2
0
static void bye_handler(struct sipsess_sock *sock, const struct sip_msg *msg)
{
	struct sip *sip = sock->sip;
	struct sipsess *sess;

	sess = sipsess_find(sock, msg);
	if (!sess) {
		(void)sip_reply(sip, msg, 481, "Call Does Not Exist");
		return;
	}

	if (!sip_dialog_rseq_valid(sess->dlg, msg)) {
		(void)sip_reply(sip, msg, 500, "Server Internal Error");
		return;
	}

	(void)sip_treplyf(NULL, NULL, sip, msg, false, 200, "OK",
			  "%s"
			  "Content-Length: 0\r\n"
			  "\r\n",
			  sess->close_hdrs);

	sess->peerterm = true;

	if (sess->terminated)
		return;

	if (sess->st) {
		(void)sip_treply(&sess->st, sess->sip, sess->msg,
				 487, "Request Terminated");
	}

	sipsess_terminate(sess, ECONNRESET, NULL);
}
Exemple #3
0
static void bye_handler(struct sipsess_sock *sock, const struct sip_msg *msg)
{
	struct sip *sip = sock->sip;
	struct sipsess *sess;

	sess = sipsess_find(sock, msg);
	if (!sess) {
		(void)sip_reply(sip, msg, 481, "Call Does Not Exist");
		return;
	}

	if (!sip_dialog_rseq_valid(sess->dlg, msg)) {
		(void)sip_reply(sip, msg, 500, "Server Internal Error");
		return;
	}

	(void)sip_treply(NULL, sip, msg, 200, "OK");

	sess->peerterm = true;

	if (sess->terminated)
		return;

	if (sess->st) {
		(void)sip_treply(&sess->st, sess->sip, sess->msg,
				 487, "Request Terminated");
	}

	sipsess_terminate(sess, E_SIP_SESSION_CLOSED_BYE, NULL);
}
Exemple #4
0
static void cancel_handler(void *arg)
{
	struct sipsess *sess = arg;

	(void)sip_treply(&sess->st, sess->sip, sess->msg,
			 487, "Request Terminated");

	sess->peerterm = true;

	if (sess->terminated)
		return;

	sipsess_terminate(sess, ECONNRESET, NULL);
}
Exemple #5
0
static void tmr_handler(void *arg)
{
	struct sipsess_reply *reply = arg;
	struct sipsess *sess = reply->sess;

	mem_deref(reply);

	/* wait for all pending ACKs */
	if (sess->replyl.head)
		return;

	/* we want to send bye */
	sess->established = true;

	if (!sess->terminated)
		sipsess_terminate(sess, ETIMEDOUT, NULL);
	else
		mem_deref(sess);
}
Exemple #6
0
static void ack_handler(struct sipsess_sock *sock, const struct sip_msg *msg)
{
	struct sipsess *sess;
	bool awaiting_answer;
	int err = 0;

	sess = sipsess_find(sock, msg);
	if (!sess)
		return;

	if (sipsess_reply_ack(sess, msg, &awaiting_answer))
		return;

	if (sess->terminated) {
		if (!sess->replyl.head) {
			sess->established = true;
			mem_deref(sess);
		}
		return;
	}

	if (awaiting_answer) {
		sess->awaiting_answer = false;
		err = sess->answerh(msg, sess->arg);
	}

	if (sess->modify_pending && !sess->replyl.head)
		(void)sipsess_reinvite(sess, true);

	if (sess->established)
		return;

	sess->msg = mem_deref((void *)sess->msg);
	sess->established = true;

	if (err)
		sipsess_terminate(sess, err, NULL);
	else
		sess->estabh(msg, sess->arg);
}
Exemple #7
0
static void bye_handler(struct sipsess_sock *sock, const struct sip_msg *msg)
{
	struct sip *sip = sock->sip;
	struct sipsess *sess;
	// char tmp[256];

	sess = sipsess_find(sock, msg);
	if (!sess) {
		(void)sip_reply(sip, msg, 481, "Call Does Not Exist");
		return;
	}

	if (!sip_dialog_rseq_valid(sess->dlg, msg)) {
		(void)sip_reply(sip, msg, 500, "Server Internal Error");
		return;
	}

	/* QXIP */
        if (sess->xrtpstats && !sess->xrtpstats[0] == '\0') {
	/* Inject X-RTP-Stat header */
		(void)sip_treplyf(NULL, NULL, sip, msg, false,
                                  200, "OK",
				  "X-RTP-Stat: %s\r\nContent-Length: 0\r\n\r\n", sess->xrtpstats);
        } else {
	/* Vanilla 200 OK */
		(void)sip_treply(NULL, sip, msg, 200, "OK");
	}

	sess->peerterm = true;

	if (sess->terminated)
		return;

	if (sess->st) {
		(void)sip_treply(&sess->st, sess->sip, sess->msg,
				 487, "Request Terminated");
	}

	sipsess_terminate(sess, ECONNRESET, NULL);
}
Exemple #8
0
static void invite_resp_handler(int err, const struct sip_msg *msg, void *arg)
{
	struct sipsess *sess = arg;
	struct mbuf *desc = NULL;

	if (err || sip_request_loops(&sess->ls, msg->scode))
		goto out;

	if (msg->scode < 200) {
		sess->progrh(msg, sess->arg);
		return;
	}
	else if (msg->scode < 300) {

		sess->hdrs = mem_deref(sess->hdrs);

		err = sip_dialog_create(sess->dlg, msg);
		if (err)
			goto out;

		if (sess->sent_offer)
			err = sess->answerh(msg, sess->arg);
		else {
			sess->modify_pending = false;
			err = sess->offerh(&desc, msg, sess->arg);
		}

	int err2 = sipsess_ack(sess->sock, sess->dlg, msg->cseq.num,
				   sess->auth, sess->ctype, desc);
    if (err2)
        printf("sipsess - sent first ACK for call %.*s, got err %d (%s)\n", msg->callid.l, msg->callid.p, err2, strerror(err2));
    err |= err2;

		sess->established = true;
		mem_deref(desc);

		if (err || sess->terminated)
			goto out;

		if (sess->modify_pending)
			(void)sipsess_reinvite(sess, true);
		else
			sess->desc = mem_deref(sess->desc);

		sess->estabh(msg, sess->arg);
		return;
	}
	else if (msg->scode < 400) {

		/* Redirect to first Contact */

		if (sess->terminated)
			goto out;

		err = sip_dialog_update(sess->dlg, msg);
		if (err)
			goto out;

		err = invite(sess);
		if (err)
			goto out;

		return;
	}
	else {
		if (sess->terminated)
			goto out;

		switch (msg->scode) {

		case 401:
		case 407:
			err = sip_auth_authenticate(sess->auth, msg);
			if (err) {
				err = (err == EAUTH) ? 0 : err;
				break;
			}

			err = invite(sess);
			if (err)
				break;

			return;
		}
	}

 out:
	if (!sess->terminated)
		sipsess_terminate(sess, err, msg);
	else
		mem_deref(sess);
}