|
@@ -1,6 +1,7 @@
|
|
|
/*
|
|
|
* Copyright (C) 2012 Smile Communications, [email protected]
|
|
|
* Copyright (C) 2012 Smile Communications, [email protected]
|
|
|
+ * Copyright (C) 2019 Aleksandar Yosifov
|
|
|
*
|
|
|
* The initial version of this code was written by Dragos Vingarzan
|
|
|
* (dragos(dot)vingarzan(at)fokus(dot)fraunhofer(dot)de and the
|
|
@@ -49,6 +50,9 @@
|
|
|
|
|
|
#include "ipsec.h"
|
|
|
#include "spi_gen.h"
|
|
|
+#include "port_gen.h"
|
|
|
+#include "cmd.h"
|
|
|
+#include "sec_agree.h"
|
|
|
|
|
|
#include <stdlib.h>
|
|
|
#include <string.h>
|
|
@@ -58,9 +62,12 @@
|
|
|
|
|
|
extern str ipsec_listen_addr;
|
|
|
extern str ipsec_listen_addr6;
|
|
|
-extern short ipsec_listen_port;
|
|
|
-extern short ipsec_server_port;
|
|
|
-extern short ipsec_client_port;
|
|
|
+extern int ipsec_server_port;
|
|
|
+extern int ipsec_client_port;
|
|
|
+
|
|
|
+extern int spi_id_start;
|
|
|
+
|
|
|
+extern unsigned int init_flag;
|
|
|
|
|
|
// check http://www.asipto.com/pub/kamailio-devel-guide/#c16return_values
|
|
|
const int IPSEC_CMD_FAIL = -1;
|
|
@@ -69,6 +76,20 @@ const int IPSEC_CMD_SUCCESS = 1;
|
|
|
extern usrloc_api_t ul;
|
|
|
extern struct tm_binds tmb;
|
|
|
|
|
|
+int bind_ipsec_pcscf(ipsec_pcscf_api_t* api) {
|
|
|
+ if(!api){
|
|
|
+ LM_ERR("invalid parameter value\n");
|
|
|
+ return -1;
|
|
|
+ }
|
|
|
+ if(init_flag == 0){
|
|
|
+ LM_ERR("configuration error - trying to bind to ipsec pscscf module before being initialized\n");
|
|
|
+ return -1;
|
|
|
+ }
|
|
|
+
|
|
|
+ api->ipsec_on_expire = ipsec_on_expire;
|
|
|
+
|
|
|
+ return 0;
|
|
|
+}
|
|
|
|
|
|
static str get_www_auth_param(const char* param_name, str www_auth)
|
|
|
{
|
|
@@ -139,6 +160,7 @@ static int fill_contact(struct pcontact_info* ci, struct sip_msg* m)
|
|
|
ci->via_port = uri.port_no ? uri.port_no : 5060;
|
|
|
ci->via_prot = 0;
|
|
|
ci->aor = m->first_line.u.request.uri;
|
|
|
+ ci->searchflag = SEARCH_NORMAL;
|
|
|
|
|
|
req = m;
|
|
|
}
|
|
@@ -168,6 +190,7 @@ static int fill_contact(struct pcontact_info* ci, struct sip_msg* m)
|
|
|
ci->via_port = vb->port;
|
|
|
ci->via_prot = vb->proto;
|
|
|
ci->aor = cb->contacts->uri;
|
|
|
+ ci->searchflag = SEARCH_RECEIVED;
|
|
|
}
|
|
|
else {
|
|
|
LM_ERR("Unknown first line type: %d\n", m->first_line.type);
|
|
@@ -270,10 +293,23 @@ static int update_contact_ipsec_params(ipsec_t* s, const struct sip_msg* m)
|
|
|
return -1;
|
|
|
}
|
|
|
|
|
|
+ s->port_pc = acquire_cport();
|
|
|
+ s->port_ps = acquire_sport();
|
|
|
+
|
|
|
+ if(s->port_pc == 0){
|
|
|
+ LM_ERR("No free client port for IPSEC tunnel creation\n");
|
|
|
+ return -1;
|
|
|
+ }
|
|
|
+
|
|
|
+ if(s->port_ps == 0){
|
|
|
+ LM_ERR("No free server port for IPSEC tunnel creation\n");
|
|
|
+ return -1;
|
|
|
+ }
|
|
|
+
|
|
|
return 0;
|
|
|
}
|
|
|
|
|
|
-static int create_ipsec_tunnel(const struct ip_addr *remote_addr, unsigned short proto, ipsec_t* s)
|
|
|
+static int create_ipsec_tunnel(const struct ip_addr *remote_addr, ipsec_t* s)
|
|
|
{
|
|
|
struct mnl_socket* sock = init_mnl_socket();
|
|
|
if (sock == NULL) {
|
|
@@ -306,74 +342,91 @@ static int create_ipsec_tunnel(const struct ip_addr *remote_addr, unsigned short
|
|
|
return -1;
|
|
|
}
|
|
|
|
|
|
- LM_DBG("Creating security associations: Local IP: %.*s client port: %d server port: %d; UE IP: %s; client port %d server port %d; spi_ps %u, spi_pc %u, spi_us %u, spi_uc %u\n",
|
|
|
+ LM_DBG("Creating security associations: Local IP: %.*s port_pc: %d port_ps: %d; UE IP: %s; port_uc %d port_us %d; spi_pc %u, spi_ps %u, spi_uc %u, spi_us %u\n",
|
|
|
remote_addr->af == AF_INET ? ipsec_listen_addr.len : ipsec_listen_addr6.len,
|
|
|
remote_addr->af == AF_INET ? ipsec_listen_addr.s : ipsec_listen_addr6.s,
|
|
|
- ipsec_client_port, ipsec_server_port, remote_addr_str, s->port_uc, s->port_us, s->spi_ps, s->spi_pc, s->spi_us, s->spi_uc);
|
|
|
+ s->port_pc, s->port_ps, remote_addr_str, s->port_uc, s->port_us, s->spi_pc, s->spi_ps, s->spi_uc, s->spi_us);
|
|
|
|
|
|
// SA1 UE client to P-CSCF server
|
|
|
- // src adrr dst addr src port dst port
|
|
|
- add_sa (sock, proto, remote_addr, &ipsec_addr, s->port_uc, ipsec_server_port, s->spi_ps, s->ck, s->ik, s->r_alg);
|
|
|
- add_policy(sock, proto, remote_addr, &ipsec_addr, s->port_uc, ipsec_server_port, s->spi_ps, IPSEC_POLICY_DIRECTION_IN);
|
|
|
+ // src adrr dst addr src port dst port
|
|
|
+ add_sa (sock, remote_addr, &ipsec_addr, s->port_uc, s->port_ps, s->spi_ps, s->ck, s->ik, s->r_alg);
|
|
|
+ add_policy(sock, remote_addr, &ipsec_addr, s->port_uc, s->port_ps, s->spi_ps, IPSEC_POLICY_DIRECTION_IN);
|
|
|
|
|
|
// SA2 P-CSCF client to UE server
|
|
|
- // src adrr dst addr src port dst port
|
|
|
- add_sa (sock, proto, &ipsec_addr, remote_addr, ipsec_client_port, s->port_us, s->spi_us, s->ck, s->ik, s->r_alg);
|
|
|
- add_policy(sock, proto, &ipsec_addr, remote_addr, ipsec_client_port, s->port_us, s->spi_us, IPSEC_POLICY_DIRECTION_OUT);
|
|
|
+ // src adrr dst addr src port dst port
|
|
|
+ add_sa (sock, &ipsec_addr, remote_addr, s->port_pc, s->port_us, s->spi_us, s->ck, s->ik, s->r_alg);
|
|
|
+ add_policy(sock, &ipsec_addr, remote_addr, s->port_pc, s->port_us, s->spi_us, IPSEC_POLICY_DIRECTION_OUT);
|
|
|
|
|
|
// SA3 P-CSCF server to UE client
|
|
|
- // src adrr dst addr src port dst port
|
|
|
- add_sa (sock, proto, &ipsec_addr, remote_addr, ipsec_server_port, s->port_uc, s->spi_uc, s->ck, s->ik, s->r_alg);
|
|
|
- add_policy(sock, proto, &ipsec_addr, remote_addr, ipsec_server_port, s->port_uc, s->spi_uc, IPSEC_POLICY_DIRECTION_OUT);
|
|
|
+ // src adrr dst addr src port dst port
|
|
|
+ add_sa (sock, &ipsec_addr, remote_addr, s->port_ps, s->port_uc, s->spi_uc, s->ck, s->ik, s->r_alg);
|
|
|
+ add_policy(sock, &ipsec_addr, remote_addr, s->port_ps, s->port_uc, s->spi_uc, IPSEC_POLICY_DIRECTION_OUT);
|
|
|
|
|
|
// SA4 UE server to P-CSCF client
|
|
|
- // src adrr dst addr src port dst port
|
|
|
- add_sa (sock, proto, remote_addr, &ipsec_addr, s->port_us, ipsec_client_port, s->spi_pc, s->ck, s->ik, s->r_alg);
|
|
|
- add_policy(sock, proto, remote_addr, &ipsec_addr, s->port_us, ipsec_client_port, s->spi_pc, IPSEC_POLICY_DIRECTION_IN);
|
|
|
+ // src adrr dst addr src port dst port
|
|
|
+ add_sa (sock, remote_addr, &ipsec_addr, s->port_us, s->port_pc, s->spi_pc, s->ck, s->ik, s->r_alg);
|
|
|
+ add_policy(sock, remote_addr, &ipsec_addr, s->port_us, s->port_pc, s->spi_pc, IPSEC_POLICY_DIRECTION_IN);
|
|
|
|
|
|
close_mnl_socket(sock);
|
|
|
|
|
|
return 0;
|
|
|
}
|
|
|
|
|
|
-static int destroy_ipsec_tunnel(const str remote_addr, unsigned short proto, ipsec_t* s)
|
|
|
+static int destroy_ipsec_tunnel(str remote_addr, ipsec_t* s, unsigned short received_port)
|
|
|
{
|
|
|
struct mnl_socket* sock = init_mnl_socket();
|
|
|
if (sock == NULL) {
|
|
|
return -1;
|
|
|
}
|
|
|
|
|
|
- // TODO: pass ipsec listen address v4 or v6 to destroy the tunnel
|
|
|
+ ip_addr_t ip_addr;
|
|
|
+ str ipsec_addr;
|
|
|
+
|
|
|
+ // convert 'remote_addr' ip string to ip_addr_t
|
|
|
+ if(str2ipxbuf(&remote_addr, &ip_addr) < 0){
|
|
|
+ LM_ERR("Unable to convert remote address [%.*s]\n", remote_addr.len, remote_addr.s);
|
|
|
+ return -1;
|
|
|
+ }
|
|
|
+
|
|
|
+ if(ip_addr.af == AF_INET6){
|
|
|
+ ipsec_addr = ipsec_listen_addr6;
|
|
|
+ }else{
|
|
|
+ ipsec_addr = ipsec_listen_addr;
|
|
|
+ }
|
|
|
|
|
|
- LM_DBG("Destroying security associations: Local IP: %.*s client port: %d server port: %d; UE IP: %.*s; client port %d server port %d\n",
|
|
|
- ipsec_listen_addr.len, ipsec_listen_addr.s, ipsec_client_port, ipsec_server_port,
|
|
|
- remote_addr.len, remote_addr.s, s->port_uc, s->port_us);
|
|
|
+ LM_DBG("Destroying security associations: Local IP: %.*s client port: %d server port: %d; UE IP: %.*s; client port %d server port %d; spi_ps %u, spi_pc %u, spi_us %u, spi_uc %u\n",
|
|
|
+ ipsec_addr.len, ipsec_addr.s, s->port_pc, s->port_ps,
|
|
|
+ remote_addr.len, remote_addr.s, s->port_uc, s->port_us, s->spi_ps, s->spi_pc, s->spi_us, s->spi_uc);
|
|
|
|
|
|
// SA1 UE client to P-CSCF server
|
|
|
- remove_sa (sock, remote_addr, ipsec_listen_addr, s->port_uc, ipsec_server_port, s->spi_ps);
|
|
|
- remove_policy(sock, proto, remote_addr, ipsec_listen_addr, s->port_uc, ipsec_server_port, s->spi_ps, IPSEC_POLICY_DIRECTION_IN);
|
|
|
+ remove_sa (sock, remote_addr, ipsec_addr, s->port_uc, s->port_ps, s->spi_ps, ip_addr.af);
|
|
|
+ remove_policy(sock, remote_addr, ipsec_addr, s->port_uc, s->port_ps, s->spi_ps, ip_addr.af, IPSEC_POLICY_DIRECTION_IN);
|
|
|
|
|
|
// SA2 P-CSCF client to UE server
|
|
|
- remove_sa (sock, ipsec_listen_addr, remote_addr, ipsec_client_port, s->port_us, s->spi_us);
|
|
|
- remove_policy(sock, proto, ipsec_listen_addr, remote_addr, ipsec_client_port, s->port_us, s->spi_us, IPSEC_POLICY_DIRECTION_OUT);
|
|
|
+ remove_sa (sock, ipsec_addr, remote_addr, s->port_pc, s->port_us, s->spi_us, ip_addr.af);
|
|
|
+ remove_policy(sock, ipsec_addr, remote_addr, s->port_pc, s->port_us, s->spi_us, ip_addr.af, IPSEC_POLICY_DIRECTION_OUT);
|
|
|
|
|
|
// SA3 P-CSCF server to UE client
|
|
|
- remove_sa (sock, ipsec_listen_addr, remote_addr, ipsec_server_port, s->port_uc, s->spi_uc);
|
|
|
- remove_policy(sock, proto, ipsec_listen_addr, remote_addr, ipsec_server_port, s->port_uc, s->spi_uc, IPSEC_POLICY_DIRECTION_OUT);
|
|
|
+ remove_sa (sock, ipsec_addr, remote_addr, s->port_ps, s->port_uc, s->spi_uc, ip_addr.af);
|
|
|
+ remove_policy(sock, ipsec_addr, remote_addr, s->port_ps, s->port_uc, s->spi_uc, ip_addr.af, IPSEC_POLICY_DIRECTION_OUT);
|
|
|
|
|
|
// SA4 UE server to P-CSCF client
|
|
|
- remove_sa (sock, remote_addr, ipsec_listen_addr, s->port_us, ipsec_client_port, s->spi_pc);
|
|
|
- remove_policy(sock, proto, remote_addr, ipsec_listen_addr, s->port_us, ipsec_client_port, s->spi_pc, IPSEC_POLICY_DIRECTION_IN);
|
|
|
+ remove_sa (sock, remote_addr, ipsec_addr, s->port_us, s->port_pc, s->spi_pc, ip_addr.af);
|
|
|
+ remove_policy(sock, remote_addr, ipsec_addr, s->port_us, s->port_pc, s->spi_pc, ip_addr.af, IPSEC_POLICY_DIRECTION_IN);
|
|
|
|
|
|
// Release SPIs
|
|
|
- release_spi(s->spi_uc);
|
|
|
- release_spi(s->spi_us);
|
|
|
+ release_spi(s->spi_pc);
|
|
|
+ release_spi(s->spi_ps);
|
|
|
+
|
|
|
+ // Release the client and the server ports
|
|
|
+ release_cport(s->port_pc);
|
|
|
+ release_sport(s->port_ps);
|
|
|
|
|
|
close_mnl_socket(sock);
|
|
|
return 0;
|
|
|
}
|
|
|
|
|
|
-static void on_expire(struct pcontact *c, int type, void *param)
|
|
|
+void ipsec_on_expire(struct pcontact *c, int type, void *param)
|
|
|
{
|
|
|
if(type != PCSCF_CONTACT_EXPIRE && type != PCSCF_CONTACT_DELETE) {
|
|
|
LM_ERR("Unexpected event type %d\n", type);
|
|
@@ -392,7 +445,7 @@ static void on_expire(struct pcontact *c, int type, void *param)
|
|
|
return;
|
|
|
}
|
|
|
|
|
|
- destroy_ipsec_tunnel(c->received_host, c->received_proto, c->security_temp->data.ipsec);
|
|
|
+ destroy_ipsec_tunnel(c->received_host, c->security_temp->data.ipsec, c->contact_port);
|
|
|
}
|
|
|
|
|
|
int add_supported_secagree_header(struct sip_msg* m)
|
|
@@ -441,7 +494,7 @@ int add_security_server_header(struct sip_msg* m, ipsec_t* s)
|
|
|
memset(sec_hdr_buf, 0, sizeof(sec_hdr_buf));
|
|
|
sec_header->len = snprintf(sec_hdr_buf, sizeof(sec_hdr_buf) - 1,
|
|
|
"Security-Server: ipsec-3gpp;prot=esp;mod=trans;spi-c=%d;spi-s=%d;port-c=%d;port-s=%d;alg=%.*s;ealg=%.*s\r\n",
|
|
|
- s->spi_pc, s->spi_ps, ipsec_client_port, ipsec_server_port,
|
|
|
+ s->spi_pc, s->spi_ps, s->port_pc, s->port_ps,
|
|
|
s->r_alg.len, s->r_alg.s,
|
|
|
s->r_ealg.len, s->r_ealg.s
|
|
|
);
|
|
@@ -497,12 +550,6 @@ int ipsec_create(struct sip_msg* m, udomain_t* d)
|
|
|
goto cleanup;
|
|
|
}
|
|
|
|
|
|
- ipsec_t* s = pcontact->security_temp->data.ipsec;
|
|
|
-
|
|
|
- if(update_contact_ipsec_params(s, m) != 0) {
|
|
|
- goto cleanup;
|
|
|
- }
|
|
|
-
|
|
|
// Get request from reply
|
|
|
struct cell *t = tmb.t_gett();
|
|
|
if (!t || t == (void*) -1) {
|
|
@@ -511,38 +558,83 @@ int ipsec_create(struct sip_msg* m, udomain_t* d)
|
|
|
}
|
|
|
|
|
|
struct sip_msg* req = t->uas.request;
|
|
|
- ////
|
|
|
|
|
|
- if(create_ipsec_tunnel(&req->rcv.src_ip, ci.received_proto, s) != 0) {
|
|
|
- goto cleanup;
|
|
|
- }
|
|
|
+ // Update contacts only for initial registration, for re-registration the existing contacts shouldn't be updated.
|
|
|
+ if(ci.via_port == SIP_PORT){
|
|
|
+ LM_DBG("Registration for contact with AOR [%.*s], VIA [%d://%.*s:%d], received_host [%d://%.*s:%d]\n",
|
|
|
+ ci.aor.len, ci.aor.s, ci.via_prot, ci.via_host.len, ci.via_host.s, ci.via_port,
|
|
|
+ ci.received_proto, ci.received_host.len, ci.received_host.s, ci.received_port);
|
|
|
|
|
|
- // TODO: Save security_tmp to security!!!!!
|
|
|
+ ipsec_t* s = pcontact->security_temp->data.ipsec;
|
|
|
|
|
|
- if (ul.update_pcontact(d, &ci, pcontact) != 0) {
|
|
|
- LM_ERR("Error updating contact\n");
|
|
|
- goto cleanup;
|
|
|
- }
|
|
|
+ if(update_contact_ipsec_params(s, m) != 0) {
|
|
|
+ goto cleanup;
|
|
|
+ }
|
|
|
|
|
|
- // Update temp security parameters
|
|
|
- if(ul.update_temp_security(d, pcontact->security_temp->type, pcontact->security_temp, pcontact) != 0)
|
|
|
- {
|
|
|
- LM_ERR("Error updating temp security\n");
|
|
|
- }
|
|
|
+ if(create_ipsec_tunnel(&req->rcv.src_ip, s) != 0){
|
|
|
+ goto cleanup;
|
|
|
+ }
|
|
|
|
|
|
- // Destroy the tunnel, if the contact expires
|
|
|
- if(ul.register_ulcb(pcontact, PCSCF_CONTACT_EXPIRE|PCSCF_CONTACT_DELETE, on_expire, NULL) != 1) {
|
|
|
- LM_ERR("Error subscribing for contact\n");
|
|
|
- goto cleanup;
|
|
|
- }
|
|
|
+ if (ul.update_pcontact(d, &ci, pcontact) != 0){
|
|
|
+ LM_ERR("Error updating contact\n");
|
|
|
+ goto cleanup;
|
|
|
+ }
|
|
|
|
|
|
+ // Update temp security parameters
|
|
|
+ if(ul.update_temp_security(d, pcontact->security_temp->type, pcontact->security_temp, pcontact) != 0){
|
|
|
+ LM_ERR("Error updating temp security\n");
|
|
|
+ }
|
|
|
|
|
|
- if(add_supported_secagree_header(m) != 0) {
|
|
|
- goto cleanup;
|
|
|
- }
|
|
|
+ if(add_supported_secagree_header(m) != 0) {
|
|
|
+ goto cleanup;
|
|
|
+ }
|
|
|
|
|
|
- if(add_security_server_header(m, s) != 0) {
|
|
|
- goto cleanup;
|
|
|
+ if(add_security_server_header(m, s) != 0) {
|
|
|
+ goto cleanup;
|
|
|
+ }
|
|
|
+
|
|
|
+ if(ul.register_ulcb(pcontact, PCSCF_CONTACT_EXPIRE|PCSCF_CONTACT_DELETE, ipsec_on_expire, (void*)&pcontact->received_port) != 1) {
|
|
|
+ LM_ERR("Error subscribing for contact\n");
|
|
|
+ goto cleanup;
|
|
|
+ }
|
|
|
+ }else{
|
|
|
+ LM_DBG("RE-Registration for contact with AOR [%.*s], VIA [%d://%.*s:%d], received_host [%d://%.*s:%d]\n",
|
|
|
+ ci.aor.len, ci.aor.s, ci.via_prot, ci.via_host.len, ci.via_host.s, ci.via_port,
|
|
|
+ ci.received_proto, ci.received_host.len, ci.received_host.s, ci.received_port);
|
|
|
+
|
|
|
+ security_t* req_sec_params = NULL;
|
|
|
+
|
|
|
+ // Parse security parameters from the REGISTER request and get some data for the new tunnels
|
|
|
+ if((req_sec_params = cscf_get_security(req)) == NULL) {
|
|
|
+ LM_CRIT("No security parameters in REGISTER request\n");
|
|
|
+ goto cleanup;
|
|
|
+ }
|
|
|
+
|
|
|
+ if(update_contact_ipsec_params(req_sec_params->data.ipsec, m) != 0) {
|
|
|
+ goto cleanup;
|
|
|
+ }
|
|
|
+
|
|
|
+ if(create_ipsec_tunnel(&req->rcv.src_ip, req_sec_params->data.ipsec) != 0){
|
|
|
+ goto cleanup;
|
|
|
+ }
|
|
|
+
|
|
|
+ // if (ul.update_pcontact(d, &ci, pcontact) != 0){
|
|
|
+ // LM_ERR("Error updating contact\n");
|
|
|
+ // goto cleanup;
|
|
|
+ // }
|
|
|
+
|
|
|
+ // // Update temp security parameters
|
|
|
+ // if(ul.update_temp_security(d, req_sec_params->type, req_sec_params, pcontact) != 0){
|
|
|
+ // LM_ERR("Error updating temp security\n");
|
|
|
+ // }
|
|
|
+
|
|
|
+ if(add_supported_secagree_header(m) != 0) {
|
|
|
+ goto cleanup;
|
|
|
+ }
|
|
|
+
|
|
|
+ if(add_security_server_header(m, req_sec_params->data.ipsec) != 0) {
|
|
|
+ goto cleanup;
|
|
|
+ }
|
|
|
}
|
|
|
|
|
|
ret = IPSEC_CMD_SUCCESS; // all good, set ret to SUCCESS, and exit
|
|
@@ -633,7 +725,7 @@ int ipsec_forward(struct sip_msg* m, udomain_t* d)
|
|
|
dst_proto = req->rcv.proto;
|
|
|
|
|
|
// for Reply and TCP sends from P-CSCF server port, for Reply and UDP sends from P-CSCF client port
|
|
|
- src_port = dst_proto == PROTO_TCP ? ipsec_server_port : ipsec_client_port;
|
|
|
+ src_port = dst_proto == PROTO_TCP ? s->port_ps : s->port_pc;
|
|
|
|
|
|
// for Reply and TCP sends to UE client port, for Reply and UDP sends to UE server port
|
|
|
dst_port = dst_proto == PROTO_TCP ? s->port_uc : s->port_us;
|
|
@@ -642,7 +734,7 @@ int ipsec_forward(struct sip_msg* m, udomain_t* d)
|
|
|
dst_proto = pcontact->received_proto;
|
|
|
|
|
|
// for Request sends from P-CSCF client port
|
|
|
- src_port = ipsec_client_port;
|
|
|
+ src_port = s->port_pc;
|
|
|
|
|
|
// for Request sends to UE server port
|
|
|
dst_port = s->port_us;
|
|
@@ -742,7 +834,7 @@ int ipsec_destroy(struct sip_msg* m, udomain_t* d)
|
|
|
goto cleanup;
|
|
|
}
|
|
|
|
|
|
- destroy_ipsec_tunnel(ci.received_host, ci.received_proto, pcontact->security_temp->data.ipsec);
|
|
|
+ destroy_ipsec_tunnel(ci.received_host, pcontact->security_temp->data.ipsec, pcontact->contact_port);
|
|
|
|
|
|
ret = IPSEC_CMD_SUCCESS; // all good, set ret to SUCCESS, and exit
|
|
|
|