@@ -133,8 +133,6 @@ static const char *TRANSPORT_STRINGS[] = {
133133};
134134
135135static str dual_uri_skip_params [] = {
136- str_init ("transport" ),
137- str_init ("lr" ),
138136 str_init ("r2" )
139137};
140138
@@ -173,9 +171,7 @@ static uint8_t encode_params(unsigned char *p, uint16_t *uri_properties, str *pa
173171 LM_DBG ("Checking param [%.*s]\n" , params_to_skip [i ].len , params_to_skip [i ].s );
174172 if (param_len_current >= params_to_skip [i ].len && strncmp (src , params_to_skip [i ].s , params_to_skip [i ].len ) == 0 ) {
175173 /* Setting some flags in case of lr or r2 params which will be encoded into the uri properties */
176- if (param_len_current == r2_on .len && memcmp (src , r2_on .s , r2_on .len ) == 0 ) {
177- * uri_properties |= URI2_HAS_R2 ;
178- } else if ((param_len_current == lr .len && memcmp (src , lr .s , lr .len ) == 0 ) ||
174+ if ((param_len_current == lr .len && memcmp (src , lr .s , lr .len ) == 0 ) ||
179175 (param_len_current == lr_on .len && memcmp (src , lr_on .s , lr_on .len ) == 0 )) {
180176 * uri_properties |= HAS_LR ;
181177 }
@@ -206,13 +202,27 @@ static uint8_t encode_params(unsigned char *p, uint16_t *uri_properties, str *pa
206202 return param_len ;
207203}
208204
209- int encode_dual_uri (encoded_uri_t * encoding_uri , struct sip_uri * uri1 , struct sip_uri * uri2 ) {
205+ #define ENCODE_URI_FIELD (_uri , _field , _flag_expr , _props , _p ) \
206+ do { \
207+ if ((_uri)->_field.len > 0 && (_uri)->_field.len <= UINT8_MAX) { \
208+ (_props) = (_flag_expr); \
209+ *(_p)++ = (uint8_t)(_uri)->_field.len; \
210+ memcpy((_p), (_uri)->_field.s, (_uri)->_field.len); \
211+ (_p) += (_uri)->_field.len; \
212+ } else if ((_uri)->_field.len > UINT8_MAX) { \
213+ LM_WARN("URI " #_field " length '%d' larger than 255\n", (_uri)->_field.len); \
214+ } \
215+ } while(0)
216+
217+ static int encode_uris (encoded_uri_t * encoding_uri , struct sip_uri * uri1 , struct sip_uri * uri2 , int param_count , str * params_to_skip ) {
210218 unsigned char * p , * props_ptr , * param_len_ptr , * uri2_props_ptr ;
211- uint16_t props ;
219+ uint16_t props = 0 ;
212220 uint8_t uri2_props ;
213221 char tmp [256 ];
214222 uint8_t param_len ;
215223 size_t start_pos ;
224+ str extra_params [param_count + 2 ];
225+ int extra_param_count = param_count ;
216226
217227 if (encoding_uri -> len + MAX_ENCODED_URI_SIZE * 2 > MAX_THINFO_BUFFER_SIZE ) {
218228 return -1 ;
@@ -228,31 +238,22 @@ int encode_dual_uri(encoded_uri_t *encoding_uri, struct sip_uri *uri1, struct si
228238
229239 start_pos = p - encoding_uri -> buf ;
230240
231- // Initialize URI1 properties with IS_DUAL_URI flag
232- props = IS_DUAL_URI ;
241+ if (uri2 != NULL ) {
242+ props = IS_DUAL_URI ;
243+ }
244+
233245 props_ptr = p ;
234246 p += 2 ;
235-
236247 props |= SCHEMES [uri1 -> type ];
237248 if (uri1 -> proto >= PROTO_UDP && uri1 -> proto <= PROTO_WSS ) {
238249 props = (props & ~TRANSPORT_MASK ) | TRANSPORTS [uri1 -> proto ];
239250 } else {
240251 props = (props & ~TRANSPORT_MASK ) | TRANSPORTS [PROTO_UDP ];
241252 }
242253
243- if (uri1 -> user .len > 0 && uri1 -> user .len <= UINT8_MAX ) {
244- props |= HAS_USERNAME ;
245- * p ++ = (uint8_t )uri1 -> user .len ;
246- memcpy (p , uri1 -> user .s , uri1 -> user .len );
247- p += uri1 -> user .len ;
248- }
249-
250- if (uri1 -> passwd .len > 0 && uri1 -> passwd .len <= UINT8_MAX ) {
251- props |= HAS_PASSWORD ;
252- * p ++ = (uint8_t )uri1 -> passwd .len ;
253- memcpy (p , uri1 -> passwd .s , uri1 -> passwd .len );
254- p += uri1 -> passwd .len ;
255- }
254+ ENCODE_URI_FIELD (uri1 , user , props | HAS_USERNAME , props , p );
255+
256+ ENCODE_URI_FIELD (uri1 , passwd , props | HAS_PASSWORD , props , p );
256257
257258 if (uri1 -> host .len > 0 && uri1 -> host .len < sizeof (tmp )) {
258259 memcpy (tmp , uri1 -> host .s , uri1 -> host .len );
@@ -265,10 +266,7 @@ int encode_dual_uri(encoded_uri_t *encoding_uri, struct sip_uri *uri1, struct si
265266 props = (props & ~DOMAIN_MASK ) | DOMAIN_IPV6 ;
266267 p += 16 ;
267268 } else if (uri1 -> host .len <= UINT8_MAX ) {
268- props = (props & ~DOMAIN_MASK ) | DOMAIN_FQDN ;
269- * p ++ = (uint8_t )uri1 -> host .len ;
270- memcpy (p , uri1 -> host .s , uri1 -> host .len );
271- p += uri1 -> host .len ;
269+ ENCODE_URI_FIELD (uri1 , host , (props & ~DOMAIN_MASK ) | DOMAIN_FQDN , props , p );
272270 } else {
273271 return -1 ;
274272 }
@@ -282,175 +280,67 @@ int encode_dual_uri(encoded_uri_t *encoding_uri, struct sip_uri *uri1, struct si
282280 * p ++ = uri1 -> port_no & 0xFF ;
283281 }
284282
285- uri2_props = 0 ;
286- uri2_props_ptr = p ;
287- p += 1 ;
288-
289- uri2_props |= SCHEMES [uri2 -> type ] & URI2_SCHEME_MASK ;
290- if (uri2 -> proto >= PROTO_UDP && uri2 -> proto <= PROTO_WSS ) {
291- // TRANSPORTS values are already in bits 3-5 format (0x00, 0x08, 0x10, 0x18, 0x20, 0x28)
292- // Just mask to fit in URI2 byte
293- uri2_props |= TRANSPORTS [uri2 -> proto ] & URI2_TRANSPORT_MASK ;
294- }
295-
296- if (uri2 -> port_no > 0 ) {
297- uri2_props |= URI2_HAS_PORT ;
298- * p ++ = (uri2 -> port_no >> 8 ) & 0xFF ;
299- * p ++ = uri2 -> port_no & 0xFF ;
300- }
283+ if (uri2 != NULL ) {
284+ uri2_props = 0 ;
285+ uri2_props_ptr = p ;
286+ p += 1 ;
301287
302- if (uri1 -> params .len > 0 && uri1 -> params .len <= UINT8_MAX ) {
303- param_len_ptr = p ++ ;
304- param_len = encode_params (p , & props , & uri1 -> params , dual_uri_skip_params_count , dual_uri_skip_params );
305-
306- if (props & URI2_HAS_R2 ) {
307- uri2_props |= URI2_HAS_R2 ;
308- props &= ~URI2_HAS_R2 ; // Clear it from props since it belongs in uri2_props
288+ uri2_props |= SCHEMES [uri2 -> type ] & URI2_SCHEME_MASK ;
289+ if (uri2 -> proto >= PROTO_UDP && uri2 -> proto <= PROTO_WSS ) {
290+ // TRANSPORTS values are already in bits 3-5 format (0x00, 0x08, 0x10, 0x18, 0x20, 0x28)
291+ // Just mask to fit in URI2 byte
292+ uri2_props |= TRANSPORTS [uri2 -> proto ] & URI2_TRANSPORT_MASK ;
309293 }
310294
311- if (param_len > 0 ) {
312- * param_len_ptr = param_len ;
313- props |= HAS_PARAMS ;
314- p += param_len ;
315- } else {
316- p = param_len_ptr ;
295+ if (uri2 -> port_no > 0 ) {
296+ uri2_props |= URI2_HAS_PORT ;
297+ * p ++ = (uri2 -> port_no >> 8 ) & 0xFF ;
298+ * p ++ = uri2 -> port_no & 0xFF ;
317299 }
300+ uri2_props |= URI2_HAS_R2 ;
301+ * uri2_props_ptr = uri2_props ;
318302 }
319303
320- if (uri1 -> headers .len > 0 && uri1 -> headers .len <= UINT8_MAX ) {
321- props |= HAS_HEADERS ;
322- * p ++ = (uint8_t )uri1 -> headers .len ;
323- memcpy (p , uri1 -> headers .s , uri1 -> headers .len );
324- p += uri1 -> headers .len ;
325- }
326-
327- props_ptr [0 ] = (props >> 8 ) & 0xFF ;
328- props_ptr [1 ] = props & 0xFF ;
329-
330- * uri2_props_ptr = uri2_props ;
331-
332- encoding_uri -> len = p - encoding_uri -> buf ;
333- return p - (encoding_uri -> buf + start_pos );
334- }
335-
336-
337- int encode_uri (encoded_uri_t * encoding_uri , struct sip_uri * uri , int param_count , str * params_to_skip ) {
338- unsigned char * p , * props_ptr , * param_len_ptr ;
339- uint16_t props ;
340- char tmp [256 ];
341- uint8_t param_len ;
342- size_t start_pos ;
343- str extra_params [param_count + 2 ];
344- int extra_param_count = param_count ;
345-
346- if (encoding_uri -> len + MAX_ENCODED_URI_SIZE > MAX_THINFO_BUFFER_SIZE ) {
347- return -1 ;
348- }
349-
350- if (encoding_uri -> len == 0 ) {
351- p = encoding_uri -> buf + 3 ;
352- encoding_uri -> len = 3 ;
353- encoding_uri -> pos = 0 ;
354- } else {
355- p = encoding_uri -> buf + encoding_uri -> len ;
356- }
357-
358- start_pos = p - encoding_uri -> buf ;
359- props = 0 ;
360- props_ptr = p ;
361- p += 2 ;
362-
363- props = (props & ~SCHEME_MASK ) | SCHEMES [uri -> type ];
364-
365- if (uri -> user .len > 0 && uri -> user .len <= UINT8_MAX ) {
366- props |= HAS_USERNAME ;
367- * p ++ = (uint8_t )uri -> user .len ;
368- memcpy (p , uri -> user .s , uri -> user .len );
369- p += uri -> user .len ;
370- }
371-
372- if (uri -> passwd .len > 0 && uri -> passwd .len <= UINT8_MAX ) {
373- props |= HAS_PASSWORD ;
374- * p ++ = (uint8_t )uri -> passwd .len ;
375- memcpy (p , uri -> passwd .s , uri -> passwd .len );
376- p += uri -> passwd .len ;
377- }
378-
379- if (uri -> host .len > 0 && uri -> host .len < sizeof (tmp )) {
380- memcpy (tmp , uri -> host .s , uri -> host .len );
381- tmp [uri -> host .len ] = '\0' ;
382-
383- if (inet_pton (AF_INET , tmp , p ) == 1 ) {
384- props = (props & ~DOMAIN_MASK ) | DOMAIN_IPV4 ;
385- p += 4 ;
386- } else if (inet_pton (AF_INET6 , tmp , p ) == 1 ) {
387- props = (props & ~DOMAIN_MASK ) | DOMAIN_IPV6 ;
388- p += 16 ;
389- } else if (uri -> host .len <= UINT8_MAX ) {
390- props = (props & ~DOMAIN_MASK ) | DOMAIN_FQDN ;
391- * p ++ = (uint8_t )uri -> host .len ;
392- memcpy (p , uri -> host .s , uri -> host .len );
393- p += uri -> host .len ;
394- } else {
395- return -1 ;
396- }
397- } else {
398- return -1 ;
399- }
400-
401- if (uri -> port_no > 0 ) {
402- props |= HAS_PORT ;
403- * p ++ = (uri -> port_no >> 8 ) & 0xFF ;
404- * p ++ = uri -> port_no & 0xFF ;
405- }
406-
407- if (uri -> proto >= PROTO_UDP && uri -> proto <= PROTO_WSS ) {
408- props = (props & ~TRANSPORT_MASK ) | TRANSPORTS [uri -> proto ];
409- } else {
410- props = (props & ~TRANSPORT_MASK ) | TRANSPORTS [PROTO_UDP ];
411- }
412-
413- if (uri -> params .len > 0 && uri -> params .len <= UINT8_MAX ) {
304+ if (uri1 -> params .len > 0 && uri1 -> params .len <= UINT8_MAX ) {
414305 if (params_to_skip != NULL && param_count > 0 ) {
415306 memcpy (extra_params , params_to_skip , param_count * sizeof (params_to_skip [0 ]));
416307 } else if (params_to_skip == NULL && param_count > 0 ) {
417308 LM_WARN ("params_to_skip is null but param_count is greater than 0\n" );
418309 extra_param_count = 0 ;
419310 }
311+
420312 extra_params [extra_param_count ++ ] = str_init ("transport" );
421313 extra_params [extra_param_count ++ ] = str_init ("lr" );
422314
423315 param_len_ptr = p ++ ;
424- param_len = encode_params (p , & props , & uri -> params , extra_param_count , extra_params );
425-
316+ param_len = encode_params (p , & props , & uri1 -> params , extra_param_count , extra_params );
317+
426318 if (param_len > 0 ) {
427319 * param_len_ptr = param_len ;
428320 props |= HAS_PARAMS ;
429321 p += param_len ;
430322 } else {
431- p = param_len_ptr ; // Rewind if no params left
323+ p = param_len_ptr ;
432324 }
433325 }
434326
435- if (uri -> headers .len > 0 && uri -> headers .len <= UINT8_MAX ) {
436- props |= HAS_HEADERS ;
437- * p ++ = (uint8_t )uri -> headers .len ;
438- memcpy (p , uri -> headers .s , uri -> headers .len );
439- p += uri -> headers .len ;
440- }
327+ ENCODE_URI_FIELD (uri1 , headers , props | HAS_HEADERS , props , p );
441328
442- LM_ERR ("ENCODE URI: props=0x%04x, buffer_pos=%ld, bytes_written=%ld\n" ,
443- props , (long )(props_ptr - encoding_uri -> buf ), (long )(p - props_ptr ));
444-
445329 props_ptr [0 ] = (props >> 8 ) & 0xFF ;
446330 props_ptr [1 ] = props & 0xFF ;
447331
448332 encoding_uri -> len = p - encoding_uri -> buf ;
449333 return p - (encoding_uri -> buf + start_pos );
450334}
451335
336+ int encode_dual_uri (encoded_uri_t * encoding_uri , struct sip_uri * uri1 , struct sip_uri * uri2 ) {
337+ return encode_uris (encoding_uri , uri1 , uri2 , dual_uri_skip_params_count , dual_uri_skip_params );
338+ }
339+
340+ int encode_uri (encoded_uri_t * encoding_uri , struct sip_uri * uri , int param_count , str * params_to_skip ) {
341+ return encode_uris (encoding_uri , uri , NULL , param_count , params_to_skip );
342+ }
452343
453- // Socket encoding/decoding functions
454344int encode_socket (encoded_uri_t * encoding_uri , const struct socket_info * si ) {
455345 unsigned char * p ;
456346 uint8_t flags = 0 ;
@@ -484,9 +374,7 @@ int encode_socket(encoded_uri_t *encoding_uri, const struct socket_info *si) {
484374 } else {
485375 return -1 ;
486376 }
487-
488- // Check if port is non-standard (not default for protocol)
489- // For now, always encode port - can optimize later
377+
490378 has_port = (si -> port_no > 0 ) ? 1 : 0 ;
491379 if (has_port ) {
492380 flags |= SOCKET_HAS_PORT ;
@@ -546,8 +434,7 @@ int decode_socket(encoded_uri_t *encoded_uri, int *proto, str *ip, unsigned shor
546434
547435 ip_type = flags & SOCKET_IP_MASK ;
548436 has_port = (flags & SOCKET_HAS_PORT ) ? 1 : 0 ;
549-
550- // Read IP address
437+
551438 if (ip_type == SOCKET_IPV4 ) {
552439 if (remaining < (4 + (has_port ? 2 : 0 ))) return -1 ; // Need 4 bytes for IP + optional 2 for port
553440 inet_ntop (AF_INET , p , ip_str , INET_ADDRSTRLEN );
@@ -622,9 +509,6 @@ int decode_uris(encoded_uri_t *encoded_uri, char decoded_uri_str[static MAX_ENCO
622509 props = (p [0 ] << 8 ) | p [1 ];
623510 p += 2 ;
624511
625- LM_ERR ("DECODE URI[%d]: props=0x%04x, HAS_LR=%d, IS_DUAL=%d, buffer_pos=%ld\n" ,
626- uri_idx , props , !!(props & HAS_LR ), !!(props & IS_DUAL_URI ), (long )(p - encoded_uri -> buf ));
627-
628512 // Validate magic bits - detect garbage data
629513 // Must check exact values, not just bit patterns
630514 scheme = props & SCHEME_MASK ;
@@ -881,10 +765,6 @@ int decode_uris(encoded_uri_t *encoded_uri, char decoded_uri_str[static MAX_ENCO
881765 * s ++ = ',' ;
882766 * s ++ = ' ' ;
883767 }
884-
885- LM_ERR ("DEBUG decode_uris[%d]: s=%p, len=%d, content=[%.*s]\n" ,
886- uri_idx , uris [uri_idx ].s , uris [uri_idx ].len ,
887- uris [uri_idx ].len , uris [uri_idx ].s );
888768 }
889769
890770 // Dual URI: we decoded 2 URIs, so increment uri_idx by 2
0 commit comments