diff --git a/include/re_sip.h b/include/re_sip.h index fa1d2e2..9a2af7a 100644 --- a/include/re_sip.h +++ b/include/re_sip.h @@ -271,7 +271,7 @@ int sip_transp_laddr(struct sip *sip, struct sa *laddr, enum sip_transp tp, /* request */ 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, + const struct uri *route, struct mbuf *mb, size_t sortkey, sip_send_h *sendh, sip_resp_h *resph, void *arg); int sip_requestf(struct sip_request **reqp, struct sip *sip, bool stateful, const char *met, const char *uri, const struct uri *route, diff --git a/src/sip/dialog.c b/src/sip/dialog.c index be152c1..5863e20 100644 --- a/src/sip/dialog.c +++ b/src/sip/dialog.c @@ -32,6 +32,7 @@ struct sip_dialog { char *ltag; char *rtag; char *uri; + uint32_t hash; uint32_t lseq; uint32_t rseq; size_t cpos; @@ -105,6 +106,7 @@ int sip_dialog_alloc(struct sip_dialog **dlgp, if (!dlg) return ENOMEM; + dlg->hash = hash_fast_str(from_uri); dlg->lseq = rand_u16(); err = str_dup(&dlg->uri, uri); @@ -211,6 +213,7 @@ int sip_dialog_accept(struct sip_dialog **dlgp, const struct sip_msg *msg) if (!dlg) return ENOMEM; + dlg->hash = rand_u32(); dlg->lseq = rand_u16(); dlg->rseq = msg->cseq.num; @@ -401,6 +404,7 @@ int sip_dialog_fork(struct sip_dialog **dlgp, struct sip_dialog *odlg, 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; @@ -560,6 +564,12 @@ const struct uri *sip_dialog_route(const struct sip_dialog *dlg) } +uint32_t sip_dialog_hash(const struct sip_dialog *dlg) +{ + return dlg ? dlg->hash : 0; +} + + /** * Get the Call-ID from a SIP Dialog * diff --git a/src/sip/request.c b/src/sip/request.c index 921ad89..aca2935 100644 --- a/src/sip/request.c +++ b/src/sip/request.c @@ -35,6 +35,7 @@ struct sip_request { sip_send_h *sendh; sip_resp_h *resph; void *arg; + size_t sortkey; enum sip_transp tp; bool tp_selected; bool stateful; @@ -227,7 +228,7 @@ static int request_next(struct sip_request *req) list_unlink(&rr->le); if (req->addrl.head) { - dns_rrlist_sort_addr(&req->addrl, (size_t)req->arg); + dns_rrlist_sort_addr(&req->addrl, req->sortkey); mem_deref(rr); goto again; } @@ -393,7 +394,7 @@ static void naptr_handler(int err, const struct dnshdr *hdr, struct list *ansl, (void)hdr; (void)authl; - dns_rrlist_sort(ansl, DNS_TYPE_NAPTR, (size_t)req->arg); + dns_rrlist_sort(ansl, DNS_TYPE_NAPTR, req->sortkey); rr = dns_rrlist_apply(ansl, NULL, DNS_TYPE_NAPTR, DNS_CLASS_IN, false, rr_naptr_handler, req); @@ -424,7 +425,7 @@ static void naptr_handler(int err, const struct dnshdr *hdr, struct list *ansl, return; } - dns_rrlist_sort(&req->srvl, DNS_TYPE_SRV, (size_t)req->arg); + dns_rrlist_sort(&req->srvl, DNS_TYPE_SRV, req->sortkey); dns_rrlist_apply(addl, NULL, DNS_QTYPE_ANY, DNS_CLASS_IN, false, rr_cache_handler, req); @@ -478,7 +479,7 @@ static void srv_handler(int err, const struct dnshdr *hdr, struct list *ansl, return; } - dns_rrlist_sort(&req->srvl, DNS_TYPE_SRV, (size_t)req->arg); + dns_rrlist_sort(&req->srvl, DNS_TYPE_SRV, req->sortkey); dns_rrlist_apply(addl, NULL, DNS_QTYPE_ANY, DNS_CLASS_IN, false, rr_cache_handler, req); @@ -515,7 +516,7 @@ static void addr_handler(int err, const struct dnshdr *hdr, struct list *ansl, goto fail; } - dns_rrlist_sort_addr(&req->addrl, (size_t)req->arg); + dns_rrlist_sort_addr(&req->addrl, req->sortkey); err = request_next(req); if (err) @@ -585,6 +586,7 @@ static int addr_lookup(struct sip_request *req, const char *name) * @param uril Length of Request URI string * @param route Next hop route URI * @param mb Buffer containing SIP request + * @param sortkey Key for DNS record sorting * @param sendh Send handler * @param resph Response handler * @param arg Handler argument @@ -593,7 +595,7 @@ static int addr_lookup(struct sip_request *req, const char *name) */ 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, + const struct uri *route, struct mbuf *mb, size_t sortkey, sip_send_h *sendh, sip_resp_h *resph, void *arg) { struct sip_request *req; @@ -629,6 +631,7 @@ int sip_request(struct sip_request **reqp, struct sip *sip, bool stateful, goto out; req->stateful = stateful; + req->sortkey = sortkey; req->mb = mem_ref(mb); req->sip = sip; req->sendh = sendh; @@ -765,7 +768,7 @@ int sip_requestf(struct sip_request **reqp, struct sip *sip, bool stateful, mb->pos = 0; err = sip_request(reqp, sip, stateful, met, -1, uri, -1, route, mb, - sendh, resph, arg); + (size_t)arg, sendh, resph, arg); if (err) goto out; @@ -832,7 +835,8 @@ int sip_drequestf(struct sip_request **reqp, struct sip *sip, bool stateful, mb->pos = 0; err = sip_request(reqp, sip, stateful, met, -1, sip_dialog_uri(dlg), - -1, sip_dialog_route(dlg), mb, sendh, resph, arg); + -1, sip_dialog_route(dlg), mb, sip_dialog_hash(dlg), + sendh, resph, arg); if (err) goto out; diff --git a/src/sip/sip.h b/src/sip/sip.h index ad5e74a..912c69b 100644 --- a/src/sip/sip.h +++ b/src/sip/sip.h @@ -86,6 +86,7 @@ int sip_dialog_encode(struct mbuf *mb, struct sip_dialog *dlg, uint32_t cseq, const char *met); const char *sip_dialog_uri(const struct sip_dialog *dlg); const struct uri *sip_dialog_route(const struct sip_dialog *dlg); +uint32_t sip_dialog_hash(const struct sip_dialog *dlg); /* keepalive */