Taking a cue from code in ims_registrar_pcscf / w_unregister, this patch replaces the dummy AOR in the SIP message passed to fill_contact: ``` diff -urw a/src/modules/ims_ipsec_pcscf/cmd.c b/src/modules/ims_ipsec_pcscf/cmd.c --- a/src/modules/ims_ipsec_pcscf/cmd.c 2023-06-28 09:40:45.000000000 +0200 +++ b/src/modules/ims_ipsec_pcscf/cmd.c 2023-09-29 15:26:52.200511805 +0200 @@ -1039,7 +1039,7 @@ }
-int ipsec_destroy(struct sip_msg *m, udomain_t *d) +int ipsec_destroy(struct sip_msg *m, udomain_t *d, str *uri) { struct pcontact_info ci; pcontact_t *pcontact = NULL; @@ -1050,6 +1050,12 @@ t = tmb.t_gett(); }
+ // Insert URI in SIP message + if(uri != NULL) { + m->first_line.u.request.uri.s = uri->s; + m->first_line.u.request.uri.len = uri->len; + } + // Find the contact if(fill_contact(&ci, m, t, 0) != 0) { LM_ERR("Error filling in contact data\n"); diff -urw a/src/modules/ims_ipsec_pcscf/cmd.h b/src/modules/ims_ipsec_pcscf/cmd.h --- a/src/modules/ims_ipsec_pcscf/cmd.h 2023-06-28 09:40:45.000000000 +0200 +++ b/src/modules/ims_ipsec_pcscf/cmd.h 2023-09-29 15:24:42.422362274 +0200 @@ -65,7 +65,7 @@
int ipsec_create(struct sip_msg *m, udomain_t *d, int _cflags); int ipsec_forward(struct sip_msg *m, udomain_t *d, int _cflags); -int ipsec_destroy(struct sip_msg *m, udomain_t *d); +int ipsec_destroy(struct sip_msg *m, udomain_t *d, str *uri); int ipsec_cleanall(); int ipsec_reconfig(); void ipsec_on_expire(pcontact_t *c, int type, void *param); diff -urw a/src/modules/ims_ipsec_pcscf/ims_ipsec_pcscf_mod.c b/src/modules/ims_ipsec_pcscf/ims_ipsec_pcscf_mod.c --- a/src/modules/ims_ipsec_pcscf/ims_ipsec_pcscf_mod.c 2023-06-28 09:40:45.000000000 +0200 +++ b/src/modules/ims_ipsec_pcscf/ims_ipsec_pcscf_mod.c 2023-10-02 12:51:04.135697115 +0200 @@ -56,12 +56,13 @@ static void mod_destroy(void); static int w_create(struct sip_msg *_m, char *_d, char *_cflags); static int w_forward(struct sip_msg *_m, char *_d, char *_cflags); -static int w_destroy(struct sip_msg *_m, char *_d, char *_cflags); +static int w_destroy(struct sip_msg *_m, char *_d, char *_aor);
/*! \brief Fixup functions */ static int domain_fixup(void **param, int param_no); static int save_fixup2(void **param, int param_no); static int free_uint_fixup(void **param, int param_no); +static int unregister_fixup(void **param, int param_no);
extern int bind_ipsec_pcscf(usrloc_api_t *api);
@@ -83,6 +84,8 @@ free_uint_fixup, REQUEST_ROUTE | ONREPLY_ROUTE }, {"ipsec_destroy", (cmd_function)w_destroy, 1, save_fixup2, 0, REQUEST_ROUTE | ONREPLY_ROUTE }, + {"ipsec_destroy", (cmd_function)w_destroy, 2, unregister_fixup, + 0, ANY_ROUTE }, {"bind_ims_ipsec_pcscf", (cmd_function)bind_ipsec_pcscf, 1, 0, 0, 0}, {0, 0, 0, 0, 0, 0} @@ -448,6 +451,36 @@ return 0; }
+/*! \brief + * Fixup for "unregister" operation - both domain and aor + */ +static int unregister_fixup(void **param, int param_no) +{ + if(param_no == 1) { + return domain_fixup(param, param_no); + } else { + pv_elem_t *model=NULL; + str s; + + /* convert to str */ + s.s = (char*)*param; + s.len = strlen(s.s); + + model = NULL; + if(s.len==0) { + LM_ERR("no param!\n"); + return E_CFG; + } + if(pv_parse_format(&s, &model)<0 || model==NULL) { + LM_ERR("wrong format [%s]!\n", s.s); + return E_CFG; + } + *param = (void*)model; + return 0; + } + return E_CFG; +} +
/*! \brief * Wrapper to ipsec functions @@ -468,7 +501,20 @@ return ipsec_forward(_m, (udomain_t *)_d, 0); }
-static int w_destroy(struct sip_msg *_m, char *_d, char *_cflags) +static int w_destroy(struct sip_msg *_m, char *_d, char *_aor) { - return ipsec_destroy(_m, (udomain_t *)_d); + pv_elem_t *model; + str aor; + + if(_aor) { + model = (pv_elem_t*)_aor; + if (pv_printf_s(_m, model, &aor) < 0) { + LM_ERR("error - cannot print the format\n"); + return -1; + } + LM_DBG("URI: %.*s\n", aor.len, aor.s); + + return ipsec_destroy(_m, (udomain_t *)_d, &aor); + } + return ipsec_destroy(_m, (udomain_t *)_d, NULL); } ``` This patch allows ipsec_destroy to be called from the PCSCF cfg file with the optional argument: $uac_req(ruri): ``` event_route[uac:reply] { #!ifdef WITH_DEBUG xnotice("request sent to $uac_req(ruri) completed with code: $uac_req(evcode), Type $uac_req(evtype)\n"); #!endif if (($uac_req(evtype) != 1) || ($uac_req(evcode) != 200)) { if ($sht(natpingfail=>$uac_req(ouri)) == $null) { $sht(natpingfail=>$uac_req(ouri)) = 1; } else { $sht(natpingfail=>$uac_req(ouri)) = $sht(natpingfail=>$uac_req(ouri)) + 1; } xnotice(" request sent to $uac_req(ruri): Fail Counter is $sht(natpingfail=>$uac_req(ouri))\n"); if ($sht(natpingfail=>$uac_req(ouri)) > 3) { if ($(uac_req(ouri){uri.transport}) == "tcp") { $var(alias) = "alias="+$(uac_req(ouri){uri.host})+"~"+$(uac_req(ouri){uri.port})+"~2"; } else if ($(uac_req(ouri){uri.transport}) == "tls") { $var(alias) = "alias="+$(uac_req(ouri){uri.host})+"~"+$(uac_req(ouri){uri.port})+"~3"; } else { $var(alias) = "alias="+$(uac_req(ouri){uri.host})+"~"+$(uac_req(ouri){uri.port})+"~1"; } xnotice(" Unregistering $uac_req(ruri);$var(alias)\n"); setdebug("9"); ipsec_destroy("location", "$uac_req(ruri)"); pcscf_unregister("location", "$uac_req(ruri);$var(alias)", "$(uac_req(ouri){uri.host})", "$(uac_req(ouri){uri.port})"); resetdebug(); sht_lock("natping=>natpinglock"); $sht(natping=>$uac_req(ouri)) = $null; sht_unlock("natping=>natpinglock");
sht_lock("natpingfrom=>natpingfromlock"); $sht(natpingfrom=>$uac_req(ouri)) = $null; sht_unlock("natpingfrom=>natpingfromlock");
$sht(natpingfail=>$uac_req(ouri)) = $null; } } else { $sht(natpingfail=>$uac_req(ouri)) = $null; } } ``` Logs shows the contact being found and destroy_ipsec_tunnel being called: ``` Oct 1 04:37:16 corsa03 p-cscf[50066]: NOTICE: <script>: request sent to sip:001010000051194@10.46.0.6:31904: Fail Counter is 4 Oct 1 04:37:16 corsa03 p-cscf[50066]: NOTICE: <script>: Unregistering sip:001010000051194@10.46.0.6:31904;alias=10.46.0.6~31904~2 Oct 1 04:37:16 corsa03 p-cscf[50066]: DEBUG: ims_ipsec_pcscf [ims_ipsec_pcscf_mod.c:514]: w_destroy(): URI: sip:001010000051194@10.46.0.6:31904 Oct 1 04:37:16 corsa03 p-cscf[50066]: DEBUG: ims_ipsec_pcscf [cmd.c:198]: fill_contact(): using original uri for contact filling: sip:001010000051194@10.46.0.6:31904 Oct 1 04:37:16 corsa03 p-cscf[50066]: DEBUG: <core> [core/mem/q_malloc.c:373]: qm_malloc(): qm_malloc(0x7f03a61c7010, 50) called from ims_ipsec_pcscf: cmd.c: fill_contact(282) Oct 1 04:37:16 corsa03 p-cscf[50066]: DEBUG: <core> [core/mem/q_malloc.c:416]: qm_malloc(): qm_malloc(0x7f03a61c7010, 56) returns address 0x7f03a6493260 frag. 0x7f03a6493228 (size=56) on 1 -th hit Oct 1 04:37:16 corsa03 p-cscf[50066]: DEBUG: ims_ipsec_pcscf [cmd.c:333]: fill_contact(): SIP REQUEST fill contact with AOR [sip:001010000051194@10.46.0.6:31904], VIA [0://10.46.0.6:31904], received_host [1://1.0.0.127:5060] Oct 1 04:37:16 corsa03 p-cscf[50066]: DEBUG: ims_usrloc_pcscf [usrloc.c:157]: get_aor_hash(): Returning hash: [1746035570] Oct 1 04:37:16 corsa03 p-cscf[50066]: DEBUG: ims_usrloc_pcscf [usrloc.c:148]: get_hash_slot(): Returning hash slot: [370] <omitted get_pcontact_from_cache messages> Oct 1 04:37:16 corsa03 p-cscf[50066]: DEBUG: ims_usrloc_pcscf [udomain.c:513]: get_pcontact_from_cache(): comparing contact with aorhash [1746035570], aor [sip:001010000051194@10.46.0.6:31904] Oct 1 04:37:16 corsa03 p-cscf[50066]: DEBUG: ims_usrloc_pcscf [udomain.c:514]: get_pcontact_from_cache(): contact host [10.46.0.6:31904] Oct 1 04:37:16 corsa03 p-cscf[50066]: DEBUG: ims_usrloc_pcscf [udomain.c:515]: get_pcontact_from_cache(): contact received [2:10.46.0.6:31435] Oct 1 04:37:16 corsa03 p-cscf[50066]: DEBUG: ims_usrloc_pcscf [udomain.c:522]: get_pcontact_from_cache(): mached a record by aorhash: 1746035570 Oct 1 04:37:16 corsa03 p-cscf[50066]: DEBUG: ims_usrloc_pcscf [udomain.c:541]: get_pcontact_from_cache(): matched contact ip address and port Oct 1 04:37:16 corsa03 p-cscf[50066]: DEBUG: ims_usrloc_pcscf [udomain.c:569]: get_pcontact_from_cache(): found contact with URI [sip:001010000051194@10.46.0.6:31904] Oct 1 04:37:16 corsa03 p-cscf[50066]: DEBUG: ims_usrloc_pcscf [udomain.c:599]: get_pcontact_from_cache(): Hit patch usrloc pcscf skip user name check Oct 1 04:37:16 corsa03 p-cscf[50066]: DEBUG: ims_usrloc_pcscf [udomain.c:634]: get_pcontact_from_cache(): contact found in memory Oct 1 04:37:16 corsa03 p-cscf[50066]: DEBUG: ims_ipsec_pcscf [cmd.c:529]: destroy_ipsec_tunnel(): Destroying security associations: Local IP: 10.169.138.17 client port: 5105 server port: 6105; UE IP: 1.0.0.127; client port 31435 server port 31904; spi_ps 4147, spi_pc 4146, spi_us 89953814, spi_uc 45782418 ``` Old (i.e. unregistered) contacts appear to accumulate in the cache; I see that ims_registrar_pcscf / w_unregister generates identical log message when it searches for the same AOR. Perhaps ims_registrar_pcscf should remove old contacts from the cache on unregistration?