@ -1446,7 +1446,7 @@ static int copy_via_headers(struct sip_pvt *p, struct sip_request *req, const st
static void set_destination ( struct sip_pvt * p , const char * uri ) ;
static void set_destination ( struct sip_pvt * p , const char * uri ) ;
static void add_date ( struct sip_request * req ) ;
static void add_date ( struct sip_request * req ) ;
static void add_expires ( struct sip_request * req , int expires ) ;
static void add_expires ( struct sip_request * req , int expires ) ;
static void build_contact ( struct sip_pvt * p );
static void build_contact ( struct sip_pvt * p , struct sip_request * req , int incoming );
/*------Request handling functions */
/*------Request handling functions */
static int handle_incoming ( struct sip_pvt * p , struct sip_request * req , struct ast_sockaddr * addr , int * recount , int * nounlock ) ;
static int handle_incoming ( struct sip_pvt * p , struct sip_request * req , struct ast_sockaddr * addr , int * recount , int * nounlock ) ;
@ -13838,22 +13838,110 @@ static void extract_uri(struct sip_pvt *p, struct sip_request *req)
if ( ! ast_strlen_zero ( c ) ) {
if ( ! ast_strlen_zero ( c ) ) {
ast_string_field_set ( p , uri , c ) ;
ast_string_field_set ( p , uri , c ) ;
}
}
}
/*!
* \ brief Determine if , as a UAS , we need to use a SIPS Contact .
*
* This uses the rules defined in RFC 3261 section 12.1 .1 to
* determine if a SIPS URI should be used as the Contact header
* when responding to incoming SIP requests .
*
* \ param req The incoming SIP request
* \ retval 0 SIPS is not required
* \ retval 1 SIPS is required
*/
static int uas_sips_contact ( struct sip_request * req )
{
const char * record_route = sip_get_header ( req , " Record-Route " ) ;
if ( ! strncmp ( REQ_OFFSET_TO_STR ( req , rlpart2 ) , " sips: " , 5 ) ) {
return 1 ;
}
if ( record_route ) {
char * record_route_uri = get_in_brackets ( ast_strdupa ( record_route ) ) ;
if ( ! strncmp ( record_route_uri , " sips: " , 5 ) ) {
return 1 ;
}
} else {
const char * contact = sip_get_header ( req , " Contact " ) ;
char * contact_uri = get_in_brackets ( ast_strdupa ( contact ) ) ;
if ( ! strncmp ( contact_uri , " sips: " , 5 ) ) {
return 1 ;
}
}
return 0 ;
}
/*!
* \ brief Determine if , as a UAC , we need to use a SIPS Contact .
*
* This uses the rules defined in RFC 3621 section 8.1 .1 .8 to
* determine if a SIPS URI should be used as the Contact header
* on our outgoing request .
*
* \ param req The outgoing SIP request
* \ retval 0 SIPS is not required
* \ retval 1 SIPS is required
*/
static int uac_sips_contact ( struct sip_request * req )
{
const char * route = sip_get_header ( req , " Route " ) ;
if ( ! strncmp ( REQ_OFFSET_TO_STR ( req , rlpart2 ) , " sips: " , 5 ) ) {
return 1 ;
}
if ( route ) {
char * route_uri = get_in_brackets ( ast_strdupa ( route ) ) ;
if ( ! strncmp ( route_uri , " sips: " , 5 ) ) {
return 1 ;
}
}
return 0 ;
}
}
/*! \brief Build contact header - the contact header we send out */
/*!
static void build_contact ( struct sip_pvt * p )
* \ brief Build contact header
*
* This is the Contact header that we send out in SIP requests and responses
* involving this sip_pvt .
*
* The incoming parameter is used to tell if we are building the request parameter
* is an incoming SIP request that we are building the Contact header in response to ,
* or if the req parameter is an outbound SIP request that we will later be adding
* the Contact header to .
*
* \ param p The sip_pvt where the built Contact will be saved .
* \ param req The request that triggered the creation of a Contact header .
* \ param incoming Indicates if the Contact header is being created for a response to an incoming request
*/
static void build_contact ( struct sip_pvt * p , struct sip_request * req , int incoming )
{
{
char tmp [ SIPBUFSIZE ] ;
char tmp [ SIPBUFSIZE ] ;
char * user = ast_uri_encode ( p - > exten , tmp , sizeof ( tmp ) , ast_uri_sip_user ) ;
char * user = ast_uri_encode ( p - > exten , tmp , sizeof ( tmp ) , ast_uri_sip_user ) ;
int use_sips ;
if ( incoming ) {
use_sips = uas_sips_contact ( req ) ;
} else {
use_sips = uac_sips_contact ( req ) ;
}
if ( p - > socket . type = = AST_TRANSPORT_UDP ) {
if ( p - > socket . type = = AST_TRANSPORT_UDP ) {
ast_string_field_build ( p , our_contact , " <sip:%s%s%s> " , user ,
ast_string_field_build ( p , our_contact , " <%s:%s%s%s> " , use_sips ? " sips " : " sip " ,
ast_strlen_zero ( user ) ? " " : " @ " , ast_sockaddr_stringify_remote ( & p - > ourip ) ) ;
user , ast_strlen_zero ( user ) ? " " : " @ " ,
ast_sockaddr_stringify_remote ( & p - > ourip ) ) ;
} else {
} else {
ast_string_field_build ( p , our_contact , " <sip:%s%s%s;transport=%s> " , user ,
ast_string_field_build ( p , our_contact , " < % s:%s%s%s;transport=%s>" ,
ast_strlen_zero ( user ) ? " " : " @ " , ast_sockaddr_stringify_remote ( & p - > ourip ) ,
use_sips ? " sips " : " sip " , user , ast_strlen_zero ( user ) ? " " : " @ " ,
sip_get_transport ( p - > socket . type ) ) ;
ast_sockaddr_stringify_remote( & p - > ourip ) , sip_get_transport( p - > socket . type ) ) ;
}
}
}
}
@ -14049,7 +14137,7 @@ static void initreqprep(struct sip_request *req, struct sip_pvt *p, int sipmetho
add_header ( req , " From " , from ) ;
add_header ( req , " From " , from ) ;
add_header ( req , " To " , to ) ;
add_header ( req , " To " , to ) ;
ast_string_field_set ( p , exten , l ) ;
ast_string_field_set ( p , exten , l ) ;
build_contact ( p );
build_contact ( p , req , 0 );
add_header ( req , " Contact " , p - > our_contact ) ;
add_header ( req , " Contact " , p - > our_contact ) ;
add_header ( req , " Call-ID " , p - > callid ) ;
add_header ( req , " Call-ID " , p - > callid ) ;
add_header ( req , " CSeq " , tmp_n ) ;
add_header ( req , " CSeq " , tmp_n ) ;
@ -14478,7 +14566,6 @@ static int __sip_subscribe_mwi_do(struct sip_subscription_mwi *mwi)
set_socket_transport ( & mwi - > call - > socket , mwi - > transport ) ;
set_socket_transport ( & mwi - > call - > socket , mwi - > transport ) ;
mwi - > call - > socket . port = htons ( mwi - > portno ) ;
mwi - > call - > socket . port = htons ( mwi - > portno ) ;
ast_sip_ouraddrfor ( & mwi - > call - > sa , & mwi - > call - > ourip , mwi - > call ) ;
ast_sip_ouraddrfor ( & mwi - > call - > sa , & mwi - > call - > ourip , mwi - > call ) ;
build_contact ( mwi - > call ) ;
build_via ( mwi - > call ) ;
build_via ( mwi - > call ) ;
/* Change the dialog callid. */
/* Change the dialog callid. */
@ -15446,7 +15533,6 @@ static int transmit_register(struct sip_registry *r, int sipmethod, const char *
internal network so we can register through nat
internal network so we can register through nat
*/
*/
ast_sip_ouraddrfor ( & p - > sa , & p - > ourip , p ) ;
ast_sip_ouraddrfor ( & p - > sa , & p - > ourip , p ) ;
build_contact ( p ) ;
}
}
/* set up a timeout */
/* set up a timeout */
@ -15526,6 +15612,7 @@ static int transmit_register(struct sip_registry *r, int sipmethod, const char *
}
}
add_expires ( & req , r - > expiry ) ;
add_expires ( & req , r - > expiry ) ;
build_contact ( p , & req , 0 ) ;
add_header ( & req , " Contact " , p - > our_contact ) ;
add_header ( & req , " Contact " , p - > our_contact ) ;
initialize_initreq ( p , & req ) ;
initialize_initreq ( p , & req ) ;
@ -17055,7 +17142,7 @@ static enum check_auth_result register_verify(struct sip_pvt *p, struct ast_sock
}
}
ast_string_field_set ( p , exten , name ) ;
ast_string_field_set ( p , exten , name ) ;
build_contact ( p );
build_contact ( p , req , 1 );
if ( req - > ignore ) {
if ( req - > ignore ) {
/* Expires is a special case, where we only want to load the peer if this isn't a deregistration attempt */
/* Expires is a special case, where we only want to load the peer if this isn't a deregistration attempt */
const char * expires = sip_get_header ( req , " Expires " ) ;
const char * expires = sip_get_header ( req , " Expires " ) ;
@ -18601,8 +18688,9 @@ static enum check_auth_result check_user_full(struct sip_pvt *p, struct sip_requ
if ( t )
if ( t )
* t = ' \0 ' ;
* t = ' \0 ' ;
if ( ast_strlen_zero ( p - > our_contact ) )
if ( ast_strlen_zero ( p - > our_contact ) ) {
build_contact ( p ) ;
build_contact ( p , req , 1 ) ;
}
}
}
of = get_in_brackets ( of ) ;
of = get_in_brackets ( of ) ;
@ -24747,7 +24835,7 @@ static int handle_request_options(struct sip_pvt *p, struct sip_request *req, st
/* must go through authentication before getting here */
/* must go through authentication before getting here */
gotdest = get_destination ( p , req , NULL ) ;
gotdest = get_destination ( p , req , NULL ) ;
build_contact ( p );
build_contact ( p , req , 1 );
if ( ast_strlen_zero ( p - > context ) )
if ( ast_strlen_zero ( p - > context ) )
ast_string_field_set ( p , context , sip_cfg . default_context ) ;
ast_string_field_set ( p , context , sip_cfg . default_context ) ;
@ -25514,7 +25602,7 @@ static int handle_request_invite(struct sip_pvt *p, struct sip_request *req, str
}
}
gotdest = get_destination ( p , NULL , & cc_recall_core_id ) ; /* Get destination right away */
gotdest = get_destination ( p , NULL , & cc_recall_core_id ) ; /* Get destination right away */
extract_uri ( p , req ) ; /* Get the Contact URI */
extract_uri ( p , req ) ; /* Get the Contact URI */
build_contact ( p ); /* Build our contact header */
build_contact ( p , req , 1 ) ; /* Build our contact header */
if ( p - > rtp ) {
if ( p - > rtp ) {
ast_rtp_instance_set_prop ( p - > rtp , AST_RTP_PROPERTY_DTMF , ast_test_flag ( & p - > flags [ 0 ] , SIP_DTMF ) = = SIP_DTMF_RFC2833 ) ;
ast_rtp_instance_set_prop ( p - > rtp , AST_RTP_PROPERTY_DTMF , ast_test_flag ( & p - > flags [ 0 ] , SIP_DTMF ) = = SIP_DTMF_RFC2833 ) ;
@ -27422,7 +27510,7 @@ static int handle_request_subscribe(struct sip_pvt *p, struct sip_request *req,
/* Get full contact header - this needs to be used as a request URI in NOTIFY's */
/* Get full contact header - this needs to be used as a request URI in NOTIFY's */
parse_ok_contact ( p , req ) ;
parse_ok_contact ( p , req ) ;
build_contact ( p );
build_contact ( p , req , 1 );
/* Initialize tag for new subscriptions */
/* Initialize tag for new subscriptions */
if ( ast_strlen_zero ( p - > tag ) ) {
if ( ast_strlen_zero ( p - > tag ) ) {