Skip to content

Commit

Permalink
sipsess: allow UPDATE in early dialog (#878)
Browse files Browse the repository at this point in the history
Allows SIP UPDATE requests without SDP within early dialogs (RFC 6086 mentions this in section 4.2.1, RFC 3311 in section 5.1).
  • Loading branch information
maximilianfridrich authored Jul 25, 2023
1 parent a856bb8 commit e414033
Show file tree
Hide file tree
Showing 7 changed files with 125 additions and 13 deletions.
11 changes: 8 additions & 3 deletions src/sipsess/connect.c
Original file line number Diff line number Diff line change
Expand Up @@ -100,16 +100,21 @@ static void invite_resp_handler(int err, const struct sip_msg *msg, void *arg)
goto out;
}

if (pl_isset(&msg->to.tag)) {
err = sip_dialog_established(sess->dlg) ?
sip_dialog_update(sess->dlg, msg) :
sip_dialog_create(sess->dlg, msg);
if (err)
goto out;
}

if (sip_msg_hdr_has_value(msg, SIP_HDR_REQUIRE, "100rel")
&& sess->rel100_supported) {
if (sdp && !sess->sent_offer) {
sess->modify_pending = false;
err = sess->offerh(&desc, msg, sess->arg);
}

err |= sip_dialog_established(sess->dlg) ?
sip_dialog_update(sess->dlg, msg) :
sip_dialog_create(sess->dlg, msg);
err |= sipsess_prack(sess, msg->cseq.num, msg->rel_seq,
&msg->cseq.met, desc);
mem_deref(desc);
Expand Down
7 changes: 6 additions & 1 deletion src/sipsess/listen.c
Original file line number Diff line number Diff line change
Expand Up @@ -253,7 +253,12 @@ static void target_refresh_handler(struct sipsess_sock *sock,
return;
}

if (got_offer || is_invite) {
if (got_offer && !sess->refresh_allowed) {
(void)sip_reply(sip, msg, 488, "Not Acceptable Here");
return;
}

if (is_invite || got_offer) {
err = sess->offerh(&desc, msg, sess->arg);
if (err) {
(void)sip_reply(sip, msg, 488,
Expand Down
9 changes: 7 additions & 2 deletions src/sipsess/modify.c
Original file line number Diff line number Diff line change
Expand Up @@ -161,10 +161,14 @@ int sipsess_reinvite(struct sipsess *sess, bool reset_ls)
*/
int sipsess_modify(struct sipsess *sess, struct mbuf *desc)
{
if (!sess || (!sess->established && !sess->refresh_allowed)
|| sess->terminated || sess->awaiting_answer)
if (!sess || sess->terminated || sess->awaiting_answer
|| !sip_dialog_established(sess->dlg))
return EINVAL;

if (!sess->established && !sess->refresh_allowed
&& mbuf_get_left(desc))
return EPROTO;

mem_deref(sess->desc);
sess->desc = mem_ref(desc);

Expand All @@ -175,5 +179,6 @@ int sipsess_modify(struct sipsess *sess, struct mbuf *desc)
sess->modify_pending = true;
return 0;
}

return sipsess_reinvite(sess, true);
}
4 changes: 0 additions & 4 deletions src/sipsess/update.c
Original file line number Diff line number Diff line change
Expand Up @@ -154,10 +154,6 @@ int sipsess_update(struct sipsess *sess)
if (!sess || sess->terminated || !sess->ctype || !sess->desc)
return EINVAL;

if ((!sess->established && !sess->refresh_allowed)
|| sess->awaiting_answer)
return EPROTO;

err = sipsess_request_alloc(&req, sess, sess->ctype, sess->desc, NULL,
NULL);
if (err)
Expand Down
105 changes: 102 additions & 3 deletions test/sipsess.c
Original file line number Diff line number Diff line change
Expand Up @@ -34,8 +34,9 @@ enum rel100_state {
enum connect_action {
CONN_PROGRESS = 1,
CONN_PROGR_ANS = 2,
CONN_ANSWER = 4,
CONN_BUSY = 8
CONN_PROGR_UPD = 4,
CONN_ANSWER = 8,
CONN_BUSY = 16
};


Expand Down Expand Up @@ -408,7 +409,8 @@ static void conn_handler(const struct sip_msg *msg, void *arg)
test->desc = desc;

if (test->conn_action & CONN_PROGRESS
|| test->conn_action & CONN_PROGR_ANS) {
|| test->conn_action & CONN_PROGR_ANS
|| test->conn_action & CONN_PROGR_UPD) {
err = sipsess_accept(&test->b, test->sock, msg, 183,
"Progress", test->rel100_b, "b",
"application/sdp", desc, NULL, NULL, false,
Expand All @@ -435,6 +437,20 @@ static void conn_handler(const struct sip_msg *msg, void *arg)
goto out;
}
}
else if (test->conn_action & CONN_PROGR_UPD) {
mem_deref(desc);
desc = mbuf_alloc(0);
if (!desc) {
err = ENOMEM;
goto out;
}

mbuf_set_pos(desc, 0);
test->desc = desc;

err = sipsess_modify(test->b, desc);
TEST_ERR(err);
}
else if (test->conn_action & CONN_ANSWER) {
err = sipsess_accept(&test->b, test->sock, msg, 200, "OK",
test->rel100_b, "b", "application/sdp",
Expand Down Expand Up @@ -1306,3 +1322,86 @@ int test_sipsess_update_uas(void)

return err;
}


int test_sipsess_update_no_sdp(void)
{
struct test test;
struct sa laddr;
char to_uri[256];
struct mbuf *desc_a = NULL;
int err;
uint16_t port;
char *callid;

memset(&test, 0, sizeof(test));

test.rel100_a = REL100_DISABLED;
test.rel100_b = REL100_DISABLED;
test.conn_action = CONN_PROGR_UPD;

err = sip_alloc(&test.sip, NULL, 32, 32, 32,
"retest", exit_handler, NULL);
TEST_ERR(err);

(void)sa_set_str(&laddr, "127.0.0.1", 0);
err = sip_transp_add(test.sip, SIP_TRANSP_UDP, &laddr);
TEST_ERR(err);

err = sip_transp_laddr(test.sip, &laddr, SIP_TRANSP_UDP, NULL);
TEST_ERR(err);

port = sa_port(&laddr);

err = sipsess_listen(&test.sock, test.sip, 32, conn_handler,
&test);
TEST_ERR(err);

err = str_x64dup(&callid, rand_u64());
TEST_ERR(err);

/* Connect to "b" */
(void)re_snprintf(to_uri, sizeof(to_uri), "sip:[email protected]:%u", port);
err = sipsess_connect(&test.a, test.sock, to_uri, NULL,
"sip:[email protected]", "a", NULL, 0,
"application/sdp", NULL, NULL, false,
callid, desc_handler_a,
offer_handler_a, answer_handler_a,
progr_handler_a, estab_handler_a, NULL,
NULL, close_handler, &test, NULL);
mem_deref(callid);
TEST_ERR(err);

err = re_main_timeout(200);
TEST_ERR(err);

if (test.err) {
err = test.err;
TEST_ERR(err);
}

/* okay here -- verify */
ASSERT_TRUE(test.estab_a);
ASSERT_TRUE(test.estab_b);
ASSERT_TRUE(test.answr_a);
ASSERT_TRUE(test.answr_b);
ASSERT_TRUE(!test.offer_a);
ASSERT_TRUE(test.offer_b);
ASSERT_TRUE(test.progr_a);

out:
tmr_cancel(&test.ans_tmr);
test.a = mem_deref(test.a);
test.b = mem_deref(test.b);

sipsess_close_all(test.sock);
test.sock = mem_deref(test.sock);

sip_close(test.sip, false);
test.sip = mem_deref(test.sip);

mem_deref(desc_a);
mem_deref(test.desc);

return err;
}
1 change: 1 addition & 0 deletions test/test.c
Original file line number Diff line number Diff line change
Expand Up @@ -191,6 +191,7 @@ static const struct test tests[] = {
TEST(test_sipsess_100rel_421),
TEST(test_sipsess_update_uac),
TEST(test_sipsess_update_uas),
TEST(test_sipsess_update_no_sdp),
TEST(test_srtp),
TEST(test_srtcp),
TEST(test_srtp_gcm),
Expand Down
1 change: 1 addition & 0 deletions test/test.h
Original file line number Diff line number Diff line change
Expand Up @@ -310,6 +310,7 @@ int test_sipsess_100rel_420(void);
int test_sipsess_100rel_421(void);
int test_sipsess_update_uac(void);
int test_sipsess_update_uas(void);
int test_sipsess_update_no_sdp(void);
int test_srtp(void);
int test_srtcp(void);
int test_srtp_gcm(void);
Expand Down

0 comments on commit e414033

Please sign in to comment.