From a5d2b4d4bed807964dccae46bc2386cc39ee82e5 Mon Sep 17 00:00:00 2001 From: ireader Date: Sat, 11 Oct 2025 17:43:34 +0800 Subject: [PATCH] fix: sip dialog/subscribe id by uas/uac --- libsip/include/sip-dialog.h | 2 +- libsip/include/sip-subscribe.h | 2 +- libsip/src/sip-dialog.c | 6 ++++-- libsip/src/sip-subscribe.c | 6 ++++-- libsip/src/uas/sip-uas-bye.c | 2 +- libsip/src/uas/sip-uas-cancel.c | 2 +- libsip/src/uas/sip-uas-info.c | 2 +- libsip/src/uas/sip-uas-prack.c | 4 ++-- libsip/src/uas/sip-uas-register.c | 15 ++++++++++++++- 9 files changed, 29 insertions(+), 12 deletions(-) diff --git a/libsip/include/sip-dialog.h b/libsip/include/sip-dialog.h index 5205401..97bf582 100644 --- a/libsip/include/sip-dialog.h +++ b/libsip/include/sip-dialog.h @@ -53,7 +53,7 @@ int sip_dialog_target_refresh(struct sip_dialog_t* dialog, const struct sip_mess int sip_dialog_set_local_target(struct sip_dialog_t* dialog, const struct sip_message_t* msg); int sip_dialog_id(struct cstring_t* id, const struct sip_dialog_t* dialog, char* ptr, int len); -int sip_dialog_id_with_message(struct cstring_t* id, const struct sip_message_t* msg, char* ptr, int len); +int sip_dialog_id_with_message(struct cstring_t* id, const struct sip_message_t* msg, char* ptr, int len, int uas); #if defined(__cplusplus) } diff --git a/libsip/include/sip-subscribe.h b/libsip/include/sip-subscribe.h index 0dff680..b416771 100644 --- a/libsip/include/sip-subscribe.h +++ b/libsip/include/sip-subscribe.h @@ -46,7 +46,7 @@ int sip_subscribe_addref(struct sip_subscribe_t* subscribe); struct sip_subscribe_t* sip_subscribe_internal_create(struct sip_agent_t* sip, const struct sip_message_t* msg, const struct sip_event_t* event, int uac); int sip_subscribe_id(struct cstring_t* id, const struct sip_subscribe_t* subscribe, char* ptr, int len); -int sip_subscribe_id_with_message(struct cstring_t* id, const struct sip_message_t* msg, char* ptr, int len); +int sip_subscribe_id_with_message(struct cstring_t* id, const struct sip_message_t* msg, char* ptr, int len, int uas); #if defined(__cplusplus) } diff --git a/libsip/src/sip-dialog.c b/libsip/src/sip-dialog.c index 40a9536..c40a447 100644 --- a/libsip/src/sip-dialog.c +++ b/libsip/src/sip-dialog.c @@ -192,10 +192,12 @@ int sip_dialog_id(struct cstring_t* id, const struct sip_dialog_t* dialog, char* return r; } -int sip_dialog_id_with_message(struct cstring_t *id, const struct sip_message_t* msg, char* ptr, int len) +// @param[in] uas 1-local is uas +int sip_dialog_id_with_message(struct cstring_t *id, const struct sip_message_t* msg, char* ptr, int len, int uas) { int r; - if (msg->mode == SIP_MESSAGE_REQUEST) + assert(msg->mode == SIP_MESSAGE_REQUEST); + if (uas) r = snprintf(ptr, len, "%.*s@%.*s@%.*s", (int)msg->callid.n, msg->callid.p, (int)msg->to.tag.n, msg->to.tag.p, (int)msg->from.tag.n, msg->from.tag.p); else r = snprintf(ptr, len, "%.*s@%.*s@%.*s", (int)msg->callid.n, msg->callid.p, (int)msg->from.tag.n, msg->from.tag.p, (int)msg->to.tag.n, msg->to.tag.p); diff --git a/libsip/src/sip-subscribe.c b/libsip/src/sip-subscribe.c index b1195e5..04cca86 100644 --- a/libsip/src/sip-subscribe.c +++ b/libsip/src/sip-subscribe.c @@ -171,10 +171,12 @@ int sip_subscribe_id(struct cstring_t* id, const struct sip_subscribe_t* subscri return r; } -int sip_subscribe_id_with_message(struct cstring_t* id, const struct sip_message_t* msg, char* ptr, int len) +// @param[in] uas 1-local is uas +int sip_subscribe_id_with_message(struct cstring_t* id, const struct sip_message_t* msg, char* ptr, int len, int uas) { int r; - if (msg->mode == SIP_MESSAGE_REQUEST) + assert(msg->mode == SIP_MESSAGE_REQUEST); + if (uas) r = snprintf(ptr, len, "%.*s@%.*s@%.*s@%.*s@%.*s", (int)msg->callid.n, msg->callid.p, (int)msg->to.tag.n, msg->to.tag.p, (int)msg->from.tag.n, msg->from.tag.p, (int)msg->event.event.n, msg->event.event.p, (int)msg->event.id.n, msg->event.id.p); else r = snprintf(ptr, len, "%.*s@%.*s@%.*s@%.*s@%.*s", (int)msg->callid.n, msg->callid.p, (int)msg->from.tag.n, msg->from.tag.p, (int)msg->to.tag.n, msg->to.tag.p, (int)msg->event.event.n, msg->event.event.p, (int)msg->event.id.n, msg->event.id.p); diff --git a/libsip/src/uas/sip-uas-bye.c b/libsip/src/uas/sip-uas-bye.c index 7a42eb8..5540a60 100644 --- a/libsip/src/uas/sip-uas-bye.c +++ b/libsip/src/uas/sip-uas-bye.c @@ -5,7 +5,7 @@ int sip_uas_onbye(struct sip_uas_transaction_t* t, const struct sip_message_t* r char ptr[256]; struct cstring_t id; - sip_dialog_id_with_message(&id, req, ptr, sizeof(ptr)); + sip_dialog_id_with_message(&id, req, ptr, sizeof(ptr), 1); //session = dialog ? dialog->session : NULL; // get session before dialog remove //if (0 != sip_dialog_remove(t->agent, dialog)) diff --git a/libsip/src/uas/sip-uas-cancel.c b/libsip/src/uas/sip-uas-cancel.c index 9ee9d8e..61a270d 100644 --- a/libsip/src/uas/sip-uas-cancel.c +++ b/libsip/src/uas/sip-uas-cancel.c @@ -7,7 +7,7 @@ int sip_uas_oncancel(struct sip_uas_transaction_t* t, const struct sip_message_t struct cstring_t id; struct sip_uas_transaction_t* origin; - sip_dialog_id_with_message(&id, req, ptr, sizeof(ptr)); + sip_dialog_id_with_message(&id, req, ptr, sizeof(ptr), 1); // 487 Request Terminated // CANCEL has no effect on a request to which a UAS has already given a final response diff --git a/libsip/src/uas/sip-uas-info.c b/libsip/src/uas/sip-uas-info.c index b76ee8a..c89b16a 100644 --- a/libsip/src/uas/sip-uas-info.c +++ b/libsip/src/uas/sip-uas-info.c @@ -6,7 +6,7 @@ int sip_uas_oninfo(struct sip_uas_transaction_t* t, const struct sip_message_t* char ptr[256]; struct cstring_t id; - sip_dialog_id_with_message(&id, req, ptr, sizeof(ptr)); + sip_dialog_id_with_message(&id, req, ptr, sizeof(ptr), 1); // compatible rfc 2976 as "legacy INFO Usage" // if(!cstrvalid(&req->info_package)) diff --git a/libsip/src/uas/sip-uas-prack.c b/libsip/src/uas/sip-uas-prack.c index 85f5611..6b66487 100644 --- a/libsip/src/uas/sip-uas-prack.c +++ b/libsip/src/uas/sip-uas-prack.c @@ -6,7 +6,7 @@ int sip_uas_onprack(struct sip_uas_transaction_t* t, const struct sip_message_t* char ptr[256]; struct cstring_t id; - sip_dialog_id_with_message(&id, req, ptr, sizeof(ptr)); + sip_dialog_id_with_message(&id, req, ptr, sizeof(ptr), 1); if (t->handler->onprack) r = t->handler->onprack(param, req, t, &id, req->payload, req->size); else @@ -20,7 +20,7 @@ int sip_uas_onupdate(struct sip_uas_transaction_t* t, const struct sip_message_t char ptr[256]; struct cstring_t id; - sip_dialog_id_with_message(&id, req, ptr, sizeof(ptr)); + sip_dialog_id_with_message(&id, req, ptr, sizeof(ptr), 1); if (t->handler->onupdate) r = t->handler->onupdate(param, req, t, &id, req->payload, req->size); else diff --git a/libsip/src/uas/sip-uas-register.c b/libsip/src/uas/sip-uas-register.c index fd30d49..27d4ccb 100644 --- a/libsip/src/uas/sip-uas-register.c +++ b/libsip/src/uas/sip-uas-register.c @@ -138,8 +138,21 @@ int sip_uas_onregister(struct sip_uas_transaction_t* t, const struct sip_message // zero or more values containing address bindings contact = sip_contacts_get(&req->contacts, 0); uri = contact ? uri_parse(contact->uri.host.p, (int)contact->uri.host.n) : NULL; - if(contact && contact->expires > 0) + if (contact && contact->expires > 0) + { + // https://datatracker.ietf.org/doc/html/rfc3261#section-10.3 + // 7. The registrar now processes each contact address in the Contact + // header field in turn. For each address, it determines the + // expiration interval as follows: + // - If the field value has an "expires" parameter, that value + // MUST be taken as the requested expiration. + // - If there is no such parameter, but the request has an + // Expires header field, that value MUST be taken as the + // requested expiration. + // - If there is neither, a locally-configured default value MUST + // be taken as the requested expiration. expires = (int)contact->expires; + } // The Record-Route header field has no meaning in REGISTER // requests or responses, and MUST be ignored if present.