From ab261540d656ed456bac8876f77f940457a9baf6 Mon Sep 17 00:00:00 2001 From: Daniel-Constantin Mierla Date: Mon, 29 Apr 2024 06:32:07 +0200 Subject: [PATCH] ims_ipsec_pcscf: decouple IPSEC_FORWARD_USEVIA and IPSEC_TCPPORT_UEC for requests - both flags should be avaible for use at the same time in ipsec_forward() - for request IPSEC_FORWARD_USEVIA gets the protocol from the next hop address --- src/modules/ims_ipsec_pcscf/cmd.c | 76 ++++++++++++++++++------------- 1 file changed, 44 insertions(+), 32 deletions(-) diff --git a/src/modules/ims_ipsec_pcscf/cmd.c b/src/modules/ims_ipsec_pcscf/cmd.c index b5a598b44ba..fff9def48a2 100644 --- a/src/modules/ims_ipsec_pcscf/cmd.c +++ b/src/modules/ims_ipsec_pcscf/cmd.c @@ -942,6 +942,37 @@ int ipsec_create(struct sip_msg *m, udomain_t *d, int _cflags) return ret; } +/** + * + */ +int ims_ipsec_get_forward_proto(sip_msg_t *msg) +{ + struct sip_uri parsed_uri; + str uri; + + if(msg == NULL) { + LM_ERR("no message structure - fallback to UDP\n"); + return PROTO_UDP; + } + + if(msg->dst_uri.s != NULL && msg->dst_uri.len > 0) { + uri = msg->dst_uri; + } else { + if(msg->new_uri.s != NULL && msg->new_uri.len > 0) { + uri = msg->new_uri; + } else { + uri = msg->first_line.u.request.uri; + } + } + if(parse_uri(uri.s, uri.len, &parsed_uri) != 0) { + LM_ERR("failed to parse next hop uri [%.*s]\n", uri.len, uri.s); + return PROTO_UDP; + } + if(parsed_uri.proto == PROTO_NONE || parsed_uri.proto == PROTO_OTHER) { + return PROTO_UDP; + } + return parsed_uri.proto; +} int ipsec_forward(struct sip_msg *m, udomain_t *d, int _cflags) { @@ -1061,43 +1092,24 @@ int ipsec_forward(struct sip_msg *m, udomain_t *d, int _cflags) } } else { if(_cflags & IPSEC_FORWARD_USEVIA) { - if(req->first_line.u.request.method_value == METHOD_REGISTER) { - // for Request get the dest proto from the saved contact - dst_proto = pcontact->received_proto; - } else { - if(m->dst_uri.s != NULL - && strstr(m->dst_uri.s, ";transport=tcp") != NULL) { - dst_proto = PROTO_TCP; - } else if(m->dst_uri.s != NULL - && strstr(m->dst_uri.s, ";transport=tls") != NULL) { - dst_proto = PROTO_TLS; - } else { - dst_proto = m->rcv.proto; - } - } - - // for Request sends from P-CSCF client port - src_port = s->port_pc; - // for Request sends to UE server port - dst_port = s->port_us; + dst_proto = ims_ipsec_get_forward_proto(m); } else { - // for Request get the dest proto from the saved contact dst_proto = pcontact->received_proto; + } + if((_cflags & IPSEC_TCPPORT_UEC) + && ((dst_proto == PROTO_TCP) || (dst_proto == PROTO_TLS))) { + // TCP/TLS send from P-CSCF server port, UDP sends from P-CSCF client port + src_port = s->port_ps; - if(_cflags & IPSEC_TCPPORT_UEC) { - // for Request and TCP sends from P-CSCF server port, for Request and UDP sends from P-CSCF client port - src_port = dst_proto == PROTO_TCP ? s->port_ps : s->port_pc; - - // for Request and TCP sends to UE client port, for Request and UDP sends to UE server port - dst_port = dst_proto == PROTO_TCP ? s->port_uc : s->port_us; + // for TCP/TLS sends to UE client port, for UDP sends to UE server port + dst_port = s->port_uc; - } else { - // for Request sends from P-CSCF client port - src_port = s->port_pc; + } else { + // send from P-CSCF client port + src_port = s->port_pc; - // for Request sends to UE server port - dst_port = s->port_us; - } + // send to UE server port + dst_port = s->port_us; } }