From b59a39f8577d9454cdeb317290af3339cad266e2 Mon Sep 17 00:00:00 2001 From: Maximilian Fridrich Date: Mon, 18 Jul 2022 15:22:35 +0200 Subject: [PATCH] sipsess: improve prack handling by adding prack handler and other improvements --- include/re_sipsess.h | 2 ++ src/sipsess/listen.c | 21 +++---------------- src/sipsess/prack.c | 48 ++++++------------------------------------- src/sipsess/sess.c | 29 ++++++++++++++++++++++++++ src/sipsess/sipsess.h | 4 +++- 5 files changed, 43 insertions(+), 61 deletions(-) diff --git a/include/re_sipsess.h b/include/re_sipsess.h index 335b7b212..5405c3d51 100644 --- a/include/re_sipsess.h +++ b/include/re_sipsess.h @@ -24,6 +24,7 @@ typedef void (sipsess_close_h)(int err, const struct sip_msg *msg, void *arg); typedef void (sipsess_redirect_h)(const struct sip_msg *msg, const char *uri, void *arg); +typedef void (sipsess_prack_h)(const struct sip_msg *msg, void *arg); int sipsess_listen(struct sipsess_sock **sockp, struct sip *sip, int htsize, sipsess_conn_h *connh, void *arg); @@ -54,6 +55,7 @@ int sipsess_accept(struct sipsess **sessp, struct sipsess_sock *sock, int sipsess_set_redirect_handler(struct sipsess *sess, sipsess_redirect_h *redirecth); +int sipsess_set_prack_handler(struct sipsess *sess, sipsess_prack_h *prackh); int sipsess_progress(struct sipsess *sess, uint16_t scode, const char *reason, enum rel100_mode rel100, diff --git a/src/sipsess/listen.c b/src/sipsess/listen.c index dec7eb3bf..c4b41ccd9 100644 --- a/src/sipsess/listen.c +++ b/src/sipsess/listen.c @@ -41,24 +41,6 @@ static void internal_connect_handler(const struct sip_msg *msg, void *arg) } -static bool cmp_handler(struct le *le, void *arg) -{ - struct sipsess *sess = le->data; - const struct sip_msg *msg = arg; - - return sip_dialog_cmp(sess->dlg, msg); -} - - -static struct sipsess *sipsess_find(struct sipsess_sock *sock, - const struct sip_msg *msg) -{ - return list_ledata(hash_lookup(sock->ht_sess, - hash_joaat_pl(&msg->callid), - cmp_handler, (void *)msg)); -} - - static void info_handler(struct sipsess_sock *sock, const struct sip_msg *msg) { struct sip *sip = sock->sip; @@ -210,6 +192,9 @@ static void prack_handler(struct sipsess_sock *sock, const struct sip_msg *msg) return; } + if (sess->prackh) + sess->prackh(msg, sess->arg); + if (awaiting_answer) { sess->awaiting_answer = false; (void)sess->answerh(msg, sess->arg); diff --git a/src/sipsess/prack.c b/src/sipsess/prack.c index a21431468..93f960905 100644 --- a/src/sipsess/prack.c +++ b/src/sipsess/prack.c @@ -72,15 +72,16 @@ static int send_handler(enum sip_transp tp, struct sa *src, static void resp_handler(int err, const struct sip_msg *msg, void *arg) { + struct sipsess *sess; struct sipsess_prack *prack = arg; if (err || !msg) goto out; - if (msg->scode > 100 && msg->scode < 200 - && sip_msg_hdr_has_value(msg, SIP_HDR_REQUIRE, "100rel")) { - (void)sipsess_prack_again(prack->sock, msg); - return; - } + sess = sipsess_find(prack->sock, msg); + if (!sess) + goto out; + if (sess->prackh) + sess->prackh(msg, sess->arg); out: mem_deref(prack); @@ -143,40 +144,3 @@ int sipsess_prack(struct sipsess *sess, uint32_t cseq, uint32_t rseq, return err; } - - -static bool cmp_handler(struct le *le, void *arg) -{ - struct sipsess_prack *prack = le->data; - const struct sip_msg *msg = arg; - - if (!sip_dialog_cmp(prack->dlg, msg)) - return false; - - if (prack->cseq != msg->cseq.num) - return false; - - return true; -} - - -/** - * Re-send a PRACK message (RFC 3262) - * - * @param sock SIP Session socket - * @param msg SIP message - * - * @return 0 if success, otherwise errorcode - */ -int sipsess_prack_again(struct sipsess_sock *sock, const struct sip_msg *msg) -{ - struct sipsess_prack *prack; - - prack = list_ledata(hash_lookup(sock->ht_prack, - hash_joaat_pl(&msg->callid), - cmp_handler, (void *)msg)); - if (!prack) - return ENOENT; - - return sip_send(sock->sip, NULL, prack->tp, &prack->dst, prack->mb); -} diff --git a/src/sipsess/sess.c b/src/sipsess/sess.c index 9686c1f65..84491fca3 100644 --- a/src/sipsess/sess.c +++ b/src/sipsess/sess.c @@ -218,6 +218,35 @@ int sipsess_set_redirect_handler(struct sipsess *sess, } +int sipsess_set_prack_handler(struct sipsess *sess, sipsess_prack_h *prackh) +{ + if (!sess || !prackh) + return EINVAL; + + sess->prackh = prackh; + + return 0; +} + + +static bool cmp_handler(struct le *le, void *arg) +{ + struct sipsess *sess = le->data; + const struct sip_msg *msg = arg; + + return sip_dialog_cmp(sess->dlg, msg); +} + + +struct sipsess *sipsess_find(struct sipsess_sock *sock, + const struct sip_msg *msg) +{ + return list_ledata(hash_lookup(sock->ht_sess, + hash_joaat_pl(&msg->callid), + cmp_handler, (void *)msg)); +} + + void sipsess_terminate(struct sipsess *sess, int err, const struct sip_msg *msg) { diff --git a/src/sipsess/sipsess.h b/src/sipsess/sipsess.h index 0b6e62d45..44480dac6 100644 --- a/src/sipsess/sipsess.h +++ b/src/sipsess/sipsess.h @@ -32,6 +32,7 @@ struct sipsess { sipsess_refer_h *referh; sipsess_close_h *closeh; sipsess_redirect_h *redirecth; + sipsess_prack_h *prackh; void *arg; bool owner; bool sent_offer; @@ -84,7 +85,6 @@ int sipsess_ack(struct sipsess_sock *sock, struct sip_dialog *dlg, int sipsess_ack_again(struct sipsess_sock *sock, const struct sip_msg *msg); int sipsess_prack(struct sipsess *sess, uint32_t cseq, uint32_t rseq, const struct pl *met, struct mbuf *desc); -int sipsess_prack_again(struct sipsess_sock *sock, const struct sip_msg *msg); int sipsess_reply_2xx(struct sipsess *sess, const struct sip_msg *msg, uint16_t scode, const char *reason, struct mbuf *desc, const char *fmt, va_list *ap); @@ -100,3 +100,5 @@ int sipsess_bye(struct sipsess *sess, bool reset_ls); int sipsess_request_alloc(struct sipsess_request **reqp, struct sipsess *sess, const char *ctype, struct mbuf *body, sip_resp_h *resph, void *arg); +struct sipsess *sipsess_find(struct sipsess_sock *sock, + const struct sip_msg *msg);