2727#include <string.h>
2828#include <stdlib.h>
2929
30-
3130#include "topo_hiding_logic.h"
32- #include "th_common_logic .h"
31+ #include "th_no_dlg_logic .h"
3332
3433struct tm_binds tm_api ;
3534struct dlg_binds dlg_api ;
@@ -45,8 +44,30 @@ str th_contact_encode_param = str_init("thinfo");
4544str th_contact_encode_scheme = str_init ("base64" );
4645str th_contact_caller_var = str_init ("_th_contact_caller_username_var_" );
4746str th_contact_callee_var = str_init ("_th_contact_callee_username_var_" );
47+ str topo_hiding_ct_encode_pw_legacy = str_init ("ToPoCtPaSS" );
48+ str th_contact_encode_param_legacy = str_init ("thinfol" );
49+ str th_contact_encode_scheme_legacy = str_init ("base64" );
50+ str th_internal_trusted_tag = STR_EMPTY ;
51+ str th_external_socket_tag = STR_EMPTY ;
52+ int auto_route_on_trusted_socket = 1 ;
53+ int th_compact_encoding = 0 ;
4854
4955int th_ct_enc_scheme ;
56+ int th_ct_enc_scheme_legacy ;
57+
58+ /* Global buffer for decoded routes */
59+ str decoded_uris [12 ];
60+ int decoded_uris_count = 0 ;
61+
62+ /* Context flag to track if decoded routes are valid for current message */
63+ int ctx_decoded_routes_valid_idx = -1 ;
64+
65+ /* Route field IDs for nested property access */
66+ #define TH_ROUTE_FULL 0 // Full URI (default)
67+ #define TH_ROUTE_HOST 1 // Host part
68+ #define TH_ROUTE_PORT 2 // Port part
69+ #define TH_ROUTE_USER 3 // User part
70+ #define TH_ROUTE_PARAMS 4 // Parameters
5071
5172static int mod_init (void );
5273static void mod_destroy (void );
@@ -55,6 +76,11 @@ static int fixup_th_params(void **param);
5576int w_topology_hiding (struct sip_msg * req , str * flags_s , struct th_params * params );
5677int w_topology_hiding_match (struct sip_msg * req , void * seq_match_mode_val );
5778static int pv_topo_callee_callid (struct sip_msg * msg , pv_param_t * param , pv_value_t * res );
79+ static int pv_topo_decoded_routes (struct sip_msg * msg , pv_param_t * param , pv_value_t * res );
80+ static int pv_topo_decoded_routes_count (struct sip_msg * msg , pv_param_t * param , pv_value_t * res );
81+ static int pv_topo_decoded_contact (struct sip_msg * msg , pv_param_t * param , pv_value_t * res );
82+ static int pv_parse_nameaddr_part (pv_spec_p sp , const str * in );
83+ static int pv_parse_idx_th_route (pv_spec_p sp , const str * in );
5884
5985static const cmd_export_t cmds []= {
6086 {"topology_hiding" ,(cmd_function )w_topology_hiding , {
@@ -69,23 +95,36 @@ static const cmd_export_t cmds[]={
6995
7096/* Exported parameters */
7197static const param_export_t params [] = {
72- { "force_dialog" , INT_PARAM , & force_dialog },
73- { "th_passed_contact_uri_params" ,STR_PARAM , & topo_hiding_ct_params .s },
74- { "th_passed_contact_params" , STR_PARAM , & topo_hiding_ct_hdr_params .s },
75- { "th_callid_passwd" , STR_PARAM , & topo_hiding_seed .s },
76- { "th_callid_prefix" , STR_PARAM , & topo_hiding_prefix .s },
77- { "th_contact_encode_passwd" , STR_PARAM , & topo_hiding_ct_encode_pw .s },
78- { "th_contact_encode_param" , STR_PARAM , & th_contact_encode_param .s },
79- { "th_contact_encode_scheme" , STR_PARAM , & th_contact_encode_scheme .s },
80- { "th_contact_caller_username_var" , STR_PARAM , & th_contact_caller_var .s },
81- { "th_contact_callee_username_var" , STR_PARAM , & th_contact_callee_var .s },
82- { "th_callid_loop_protection" , INT_PARAM , & th_loop_protection },
98+ { "force_dialog" , INT_PARAM , & force_dialog },
99+ { "th_passed_contact_uri_params" , STR_PARAM , & topo_hiding_ct_params .s },
100+ { "th_passed_contact_params" , STR_PARAM , & topo_hiding_ct_hdr_params .s },
101+ { "th_callid_passwd" , STR_PARAM , & topo_hiding_seed .s },
102+ { "th_callid_prefix" , STR_PARAM , & topo_hiding_prefix .s },
103+ { "th_contact_encode_passwd" , STR_PARAM , & topo_hiding_ct_encode_pw .s },
104+ { "th_contact_encode_param" , STR_PARAM , & th_contact_encode_param .s },
105+ { "th_contact_encode_scheme" , STR_PARAM , & th_contact_encode_scheme .s },
106+ { "th_contact_caller_username_var" , STR_PARAM , & th_contact_caller_var .s },
107+ { "th_contact_callee_username_var" , STR_PARAM , & th_contact_callee_var .s },
108+ { "th_contact_encode_passwd_legacy" , STR_PARAM , & topo_hiding_ct_encode_pw_legacy .s },
109+ { "th_contact_encode_param_legacy" , STR_PARAM , & th_contact_encode_param_legacy .s },
110+ { "th_contact_encode_scheme_legacy" , STR_PARAM , & th_contact_encode_scheme_legacy .s },
111+ { "th_internal_trusted_tag" , STR_PARAM , & th_internal_trusted_tag .s },
112+ { "th_external_socket_tag" , STR_PARAM , & th_external_socket_tag .s },
113+ { "th_auto_route_on_trusted_socket" , INT_PARAM , & auto_route_on_trusted_socket },
114+ { "th_compact_encoding" , INT_PARAM , & th_compact_encoding },
115+ { "th_callid_loop_protection" , INT_PARAM , & th_loop_protection },
83116 {0 , 0 , 0 }
84117};
85118
86119static const pv_export_t pvars [] = {
87120 { str_const_init ("TH_callee_callid" ), 1000 ,
88121 pv_topo_callee_callid ,0 ,0 , 0 , 0 , 0 },
122+ { str_const_init ("TH_decoded_routes" ), 1001 ,
123+ pv_topo_decoded_routes , 0 , pv_parse_nameaddr_part , pv_parse_idx_th_route , 0 , 0 },
124+ { str_const_init ("TH_decoded_routes_count" ), 1002 ,
125+ pv_topo_decoded_routes_count , 0 , 0 , 0 , 0 , 0 },
126+ { str_const_init ("TH_decoded_contact" ), 1003 ,
127+ pv_topo_decoded_contact , 0 , pv_parse_nameaddr_part , 0 , 0 , 0 },
89128 { {0 , 0 }, 0 , 0 , 0 , 0 , 0 , 0 , 0 }
90129};
91130
@@ -101,7 +140,7 @@ static module_dependency_t *get_deps_dialog(const param_export_t *param)
101140
102141static const dep_export_t deps = {
103142 { /* OpenSIPS module dependencies */
104- { MOD_TYPE_DEFAULT , "tm" , DEP_ABORT },
143+ { MOD_TYPE_DEFAULT , "tm" , DEP_ABORT },
105144 { MOD_TYPE_DEFAULT , "dialog" , DEP_SILENT },
106145 { MOD_TYPE_NULL , NULL , 0 },
107146 },
@@ -138,11 +177,16 @@ static int mod_init(void)
138177{
139178 LM_INFO ("initializing...\n" );
140179
180+ /* Register context for decoded routes validity flag */
181+ ctx_decoded_routes_valid_idx = context_register_int (CONTEXT_GLOBAL , NULL );
182+
141183 /* param handling */
142184 topo_hiding_prefix .len = strlen (topo_hiding_prefix .s );
143185 topo_hiding_seed .len = strlen (topo_hiding_seed .s );
144186 th_contact_encode_param .len = strlen (th_contact_encode_param .s );
145187 topo_hiding_ct_encode_pw .len = strlen (topo_hiding_ct_encode_pw .s );
188+ th_contact_encode_param_legacy .len = strlen (th_contact_encode_param_legacy .s );
189+ topo_hiding_ct_encode_pw_legacy .len = strlen (topo_hiding_ct_encode_pw_legacy .s );
146190 if (topo_hiding_ct_params .s ) {
147191 topo_hiding_ct_params .len = strlen (topo_hiding_ct_params .s );
148192 topo_parse_passed_ct_params (& topo_hiding_ct_params );
@@ -163,7 +207,25 @@ static int mod_init(void)
163207 "Use 'base64' or 'base32'\n" );
164208 goto error ;
165209 }
210+
211+ th_contact_encode_scheme_legacy .len = strlen (th_contact_encode_scheme_legacy .s );
212+ if (!str_strcmp (& th_contact_encode_scheme_legacy , const_str ("base64" )))
213+ th_ct_enc_scheme_legacy = ENC_BASE64 ;
214+ else if (!str_strcmp (& th_contact_encode_scheme_legacy , const_str ("base32" )))
215+ th_ct_enc_scheme_legacy = ENC_BASE32 ;
216+ else {
217+ LM_ERR ("Unsupported value for 'th_contact_encode_scheme_legacy' modparam!"
218+ "Use 'base64' or 'base32'\n" );
219+ goto error ;
220+ }
166221
222+ if (th_internal_trusted_tag .s ) {
223+ th_internal_trusted_tag .len = strlen (th_internal_trusted_tag .s );
224+ }
225+
226+ if (th_external_socket_tag .s ) {
227+ th_external_socket_tag .len = strlen (th_external_socket_tag .s );
228+ }
167229
168230 /* loading dependencies */
169231 if (load_tm_api (& tm_api )!= 0 ) {
@@ -197,7 +259,6 @@ static int mod_init(void)
197259 "restart\n" );
198260
199261
200-
201262 return 0 ;
202263error :
203264 return -1 ;
@@ -339,6 +400,8 @@ int w_topology_hiding_match(struct sip_msg *req, void *seq_match_mode_val)
339400}
340401
341402static char * callid_buf = NULL ;
403+ static int callid_buf_len = 0 ;
404+
342405static int pv_topo_callee_callid (struct sip_msg * msg , pv_param_t * param , pv_value_t * res )
343406{
344407 struct dlg_cell * dlg ;
@@ -367,3 +430,131 @@ static int pv_topo_callee_callid(struct sip_msg *msg, pv_param_t *param, pv_valu
367430
368431 return 0 ;
369432}
433+
434+ static int pv_parse_idx_th_route (pv_spec_p sp , const str * in )
435+ {
436+ if (!in || in -> len == 0 ) {
437+ LM_ERR ("invalid index\n" );
438+ return -1 ;
439+ }
440+
441+ return pv_parse_index (sp , in );
442+ }
443+
444+
445+ static int pv_parse_nameaddr_part (pv_spec_p sp , const str * in )
446+ {
447+ if (sp == NULL || in == NULL || in -> s == NULL || in -> len == 0 )
448+ return -1 ;
449+
450+ sp -> pvp .pvn .type = PV_NAME_INTSTR ;
451+ sp -> pvp .pvn .u .isname .type = 0 ;
452+
453+ if (in -> len == 4 && strncasecmp (in -> s , "host" , 4 ) == 0 ) {
454+ sp -> pvp .pvn .u .isname .name .n = TH_ROUTE_HOST ;
455+ } else if (in -> len == 4 && strncasecmp (in -> s , "port" , 4 ) == 0 ) {
456+ sp -> pvp .pvn .u .isname .name .n = TH_ROUTE_PORT ;
457+ } else if (in -> len == 4 && strncasecmp (in -> s , "user" , 4 ) == 0 ) {
458+ sp -> pvp .pvn .u .isname .name .n = TH_ROUTE_USER ;
459+ } else if (in -> len == 6 && strncasecmp (in -> s , "params" , 6 ) == 0 ) {
460+ sp -> pvp .pvn .u .isname .name .n = TH_ROUTE_PARAMS ;
461+ } else {
462+ LM_ERR ("unsupported route field <%.*s>\n" , in -> len , in -> s );
463+ return -1 ;
464+ }
465+
466+ return 0 ;
467+ }
468+
469+ static int pv_topo_decoded_uri (struct sip_msg * msg , pv_param_t * param , pv_value_t * res , int index )
470+ {
471+ int field_id = 0 ;
472+ struct sip_uri uri ;
473+
474+ if (msg == NULL || res == NULL )
475+ return -1 ;
476+
477+ if (!ctx_decoded_routes_is_valid ()) {
478+ return pv_get_null (msg , param , res );
479+ }
480+
481+ if (param -> pvn .type == PV_NAME_INTSTR ) {
482+ field_id = param -> pvn .u .isname .name .n ;
483+ }
484+
485+ if (field_id == TH_ROUTE_FULL ) {
486+ return pv_get_strval (msg , param , res , & decoded_uris [index ]);
487+ }
488+
489+ if (parse_uri (decoded_uris [index ].s + 1 , decoded_uris [index ].len - 1 , & uri ) < 0 ) {
490+ LM_ERR ("Bad Contact URI\n" );
491+ return -1 ;
492+ }
493+
494+ switch (field_id ) {
495+ case TH_ROUTE_HOST :
496+ if (uri .host .len == 0 )
497+ return pv_get_null (msg , param , res );
498+ return pv_get_strval (msg , param , res , & uri .host );
499+
500+ case TH_ROUTE_PORT :
501+ return pv_get_uintval (msg , param , res , uri .port_no );
502+
503+ case TH_ROUTE_USER :
504+ if (uri .user .len == 0 )
505+ return pv_get_null (msg , param , res );
506+ return pv_get_strval (msg , param , res , & uri .user );
507+
508+ case TH_ROUTE_PARAMS :
509+ if (uri .params .len == 0 )
510+ return pv_get_null (msg , param , res );
511+ return pv_get_strval (msg , param , res , & uri .params );
512+
513+ default :
514+ LM_ERR ("unknown route field %d\n" , field_id );
515+ return pv_get_null (msg , param , res );
516+ }
517+ }
518+
519+ static int pv_topo_decoded_routes_count (struct sip_msg * msg , pv_param_t * param , pv_value_t * res )
520+ {
521+ if (msg == NULL || res == NULL )
522+ return -1 ;
523+
524+ /* Check if decoded routes are valid for this message context */
525+ if (!ctx_decoded_routes_is_valid ()) {
526+ return pv_get_sintval (msg , param , res , 0 );
527+ }
528+
529+ return pv_get_sintval (msg , param , res , decoded_uris_count - 1 );
530+ }
531+
532+ static int pv_topo_decoded_routes (struct sip_msg * msg , pv_param_t * param , pv_value_t * res )
533+ {
534+ int idx , idxf ;
535+
536+ if (pv_get_spec_index (msg , param , & idx , & idxf ) != 0 ) {
537+ LM_ERR ("invalid index\n" );
538+ return -1 ;
539+ }
540+
541+ if (idx < 0 ) {
542+ idx = (decoded_uris_count - 1 ) + idx ;
543+ }
544+
545+ if (idx < 0 || idx >= (decoded_uris_count - 1 ))
546+ return pv_get_null (msg , param , res );
547+
548+ /* Adjust index: route 0 is at decoded_uris[1], contact is at [0] */
549+ idx = idx + 1 ;
550+
551+ return pv_topo_decoded_uri (msg , param , res , idx );
552+ }
553+
554+ static int pv_topo_decoded_contact (struct sip_msg * msg , pv_param_t * param , pv_value_t * res )
555+ {
556+ if (decoded_uris_count == 0 )
557+ return pv_get_null (msg , param , res );
558+
559+ return pv_topo_decoded_uri (msg , param , res , 0 );
560+ }
0 commit comments