diff --git a/include/re_sip.h b/include/re_sip.h index 5feb216bb..5548c2a93 100644 --- a/include/re_sip.h +++ b/include/re_sip.h @@ -402,6 +402,7 @@ void sip_dialog_set_srcport(struct sip_dialog *dlg, uint16_t srcport); uint16_t sip_dialog_srcport(struct sip_dialog *dlg); const char *sip_dialog_uri(const struct sip_dialog *dlg); uint32_t sip_dialog_lseq(const struct sip_dialog *dlg); +uint32_t sip_dialog_lseqinv(const struct sip_dialog *dlg); enum sip_transp sip_dialog_tp(const struct sip_dialog *dlg); bool sip_dialog_established(const struct sip_dialog *dlg); bool sip_dialog_cmp(const struct sip_dialog *dlg, const struct sip_msg *msg); diff --git a/src/sip/dialog.c b/src/sip/dialog.c index 79f9bcfa1..9bab1e9b7 100644 --- a/src/sip/dialog.c +++ b/src/sip/dialog.c @@ -34,6 +34,7 @@ struct sip_dialog { uint32_t hash; uint32_t lseq; uint32_t rseq; + uint32_t lseqinv; size_t cpos; size_t rpos; enum sip_transp tp; @@ -395,12 +396,13 @@ int sip_dialog_fork(struct sip_dialog **dlgp, struct sip_dialog *odlg, if (!dlg) return ENOMEM; - dlg->callid = mem_ref(odlg->callid); - dlg->ltag = mem_ref(odlg->ltag); - dlg->hash = odlg->hash; - dlg->lseq = odlg->lseq; - dlg->rseq = msg->req ? msg->cseq.num : 0; - dlg->tp = msg->tp; + dlg->callid = mem_ref(odlg->callid); + dlg->ltag = mem_ref(odlg->ltag); + dlg->hash = odlg->hash; + dlg->lseq = odlg->lseq; + dlg->lseqinv = odlg->lseqinv; + dlg->rseq = msg->req ? msg->cseq.num : 0; + dlg->tp = msg->tp; err = pl_strdup(&dlg->uri, &addr.auri); if (err) @@ -570,6 +572,9 @@ int sip_dialog_encode(struct mbuf *mb, struct sip_dialog *dlg, uint32_t cseq, if (!mb || !dlg || !met) return EINVAL; + if (!strcmp(met, "INVITE")) + dlg->lseqinv = dlg->lseq; + err |= mbuf_write_mem(mb, mbuf_buf(dlg->mb), mbuf_get_left(dlg->mb)); err |= mbuf_printf(mb, "Call-ID: %s\r\n", dlg->callid); err |= mbuf_printf(mb, "CSeq: %u %s\r\n", strcmp(met, "ACK") ? @@ -661,6 +666,19 @@ uint32_t sip_dialog_lseq(const struct sip_dialog *dlg) } +/** + * Get the local sequence number of the last sent INVITE + * + * @param dlg SIP Dialog + * + * @return Local sequence number + */ +uint32_t sip_dialog_lseqinv(const struct sip_dialog *dlg) +{ + return dlg ? dlg->lseqinv : 0; +} + + /** * Check if a SIP Dialog is established * diff --git a/src/sipsess/connect.c b/src/sipsess/connect.c index 27a12358d..7f3c8a950 100644 --- a/src/sipsess/connect.c +++ b/src/sipsess/connect.c @@ -91,6 +91,10 @@ static void invite_resp_handler(int err, const struct sip_msg *msg, void *arg) if (!msg || err || sip_request_loops(&sess->ls, msg->scode)) goto out; + if (!sip_dialog_cmp_half(sess->dlg, msg) + || sip_dialog_lseqinv(sess->dlg) != msg->cseq.num) + goto out; + sdp = mbuf_get_left(msg->mb) > 0; if (msg->scode < 200) {