[sr-dev] [PATCH] modules/sca: use Call-Info for canonical AoR

Timo Teräs timo.teras at iki.fi
Fri Oct 11 12:30:24 CEST 2013


RFC3261 8.1.1.2 states that To header "may or may not be the ultimate
recipient of the request", and 8.1.1.3 states that From header is
"possibly the user's address-of-record". So either of them cannot be
fully trusted.

This was already noted and fixed partially in commit 1ef4587612806a94
("modules/sca: reconcile Contact and From URIs in ACK callback").

But similar issues happen when using ENUM and/or calling using local
alias (numbers only, or local forward) and the destination is in another
SIP domain. To-header contains the initial domain, and not the AoR domain.
When handling response to such INVITE a sane way to determine correct
AoR is to inspect the Call-Info header's Application Server URI.

Thus this changes AoR canonicalization to happens as follow:
1. User portion is taken from Contact header if present, otherwise
   from the applicable From / To header.
2. Domain/port part is taken from Call-Info header if present, and
   otherwise from the applicable From / To header.
---
This has not fully tested, but this seems to be the root case why SCA does
not on certain inter-domain calls that I get. I'd like to get review comments,
and possible other fix ideas. I'll let you know how the testing goes, and
if looks OK to you can push this to master and relevant stable branches.

 modules/sca/sca_util.c | 51 +++++++++++++++++++++++++++-----------------------
 1 file changed, 28 insertions(+), 23 deletions(-)

diff --git a/modules/sca/sca_util.c b/modules/sca/sca_util.c
index 143ac47..e209cc0 100644
--- a/modules/sca/sca_util.c
+++ b/modules/sca/sca_util.c
@@ -26,6 +26,7 @@
 #include <assert.h>
 
 #include "sca_util.h"
+#include "sca_call_info.h"
 
 #include "../../parser/sdp/sdp.h"
 
@@ -343,9 +344,13 @@ sca_aor_create_from_info( str *aor, uri_type type, str *user, str *domain,
 sca_create_canonical_aor_for_ua( sip_msg_t *msg, str *c_aor, int ua_opts )
 {
     struct to_body	*tf = NULL;
-    sip_uri_t		c_uri;
-    str			tf_aor = STR_NULL;
+    str			user_portion;
+    str			domain_portion;
+    str			port_portion = STR_NULL;
     str			contact_uri = STR_NULL;
+    sip_uri_t		c_uri;
+    sca_call_info	call_info;
+    hdr_field_t		*call_info_hdr;
     int			rc = -1;
 
     assert( msg != NULL );
@@ -373,12 +378,6 @@ sca_create_canonical_aor_for_ua( sip_msg_t *msg, str *c_aor, int ua_opts )
 	}
     }
 
-    if ( sca_uri_extract_aor( &tf->uri, &tf_aor ) < 0 ) {
-	LM_ERR( "sca_create_canonical_aor: failed to extract AoR from "
-		"URI <%.*s>", STR_FMT( &tf->uri ));
-	goto done;
-    }
-
     memset( &c_uri, 0, sizeof( sip_uri_t ));
     if (( rc = sca_get_msg_contact_uri( msg, &contact_uri )) < 0 ) {
 	LM_ERR( "sca_create_canonical_aor: failed to get contact URI from "
@@ -394,22 +393,28 @@ sca_create_canonical_aor_for_ua( sip_msg_t *msg, str *c_aor, int ua_opts )
 	}
     }
 
-    if ( SCA_STR_EMPTY( &c_uri.user ) ||
-	    SCA_STR_EQ( &c_uri.user, &tf->parsed_uri.user )) {
-	/* empty contact header or Contact user matches To/From AoR */
-	c_aor->s = (char *)pkg_malloc( tf_aor.len );
-	c_aor->len = tf_aor.len;
-	memcpy( c_aor->s, tf_aor.s, tf_aor.len );
+    /* Prefer Contact header user, fallback to To/From */
+    if ( SCA_STR_EMPTY( &c_uri.user ) )
+	user_portion = tf->parsed_uri.user;
+    else
+	user_portion = c_uri.user;
+
+    memset( &call_info, 0, sizeof( sca_call_info ));
+    call_info_hdr = sca_call_info_header_find( msg->headers );
+    if ( !SCA_HEADER_EMPTY( call_info_hdr ) &&
+	 sca_call_info_body_parse( &call_info_hdr->body, &call_info ) >= 0 ) {
+	/* Call-Info present, use the server name as AoR domain */
+	domain_portion = call_info.sca_uri;
     } else {
-	/* Contact user and To/From user mismatch */
-	if ( sca_aor_create_from_info( c_aor, c_uri.type,
-		&c_uri.user, &tf->parsed_uri.host,
-		&tf->parsed_uri.port ) < 0 ) {
-	    LM_ERR( "sca_create_canonical_aor: failed to create AoR from "
-		    "Contact <%.*s> and URI <%.*s>",
-		    STR_FMT( &contact_uri ), STR_FMT( &tf_aor ));
-	    goto done;
-	}
+	/* Use To/From domain */
+	domain_portion = tf->parsed_uri.host;
+	port_portion = tf->parsed_uri.port;
+    }
+
+    if ( sca_aor_create_from_info( c_aor, c_uri.type, &user_portion, &domain_portion, &port_portion ) < 0 ) {
+	LM_ERR( "sca_create_canonical_aor: failed to create canonical AoR "
+	    "user: <%.*s>, domain: <%.*s>", STR_FMT( &user_portion ), STR_FMT( &domain_portion ));
+	goto done;
     }
 
     rc = 1;
-- 
1.8.4




More information about the sr-dev mailing list