@ -508,7 +508,7 @@ static int mwi_expiry = DEFAULT_MWI_EXPIRY;
# define SIP_MAX_HEADERS 64 /*!< Max amount of SIP headers to read */
# define SIP_MAX_HEADERS 64 /*!< Max amount of SIP headers to read */
# define SIP_MAX_LINES 64 /*!< Max amount of lines in SIP attachment (like SDP) */
# define SIP_MAX_LINES 64 /*!< Max amount of lines in SIP attachment (like SDP) */
# define SIP_MIN_PACKET 102 4 /*!< Initialize size of memory to allocate for packets */
# define SIP_MIN_PACKET 4096 /*!< Initialize size of memory to allocate for packets */
# define INITIAL_CSEQ 101 /*!< Our initial sip sequence number */
# define INITIAL_CSEQ 101 /*!< Our initial sip sequence number */
@ -2031,8 +2031,6 @@ static void temp_pvt_cleanup(void *);
/*! \brief A per-thread temporary pvt structure */
/*! \brief A per-thread temporary pvt structure */
AST_THREADSTORAGE_CUSTOM ( ts_temp_pvt , temp_pvt_init , temp_pvt_cleanup ) ;
AST_THREADSTORAGE_CUSTOM ( ts_temp_pvt , temp_pvt_init , temp_pvt_cleanup ) ;
AST_THREADSTORAGE ( transmit_state_buffer ) ;
AST_THREADSTORAGE ( mailbox_buffer ) ;
# ifdef LOW_MEMORY
# ifdef LOW_MEMORY
static void ts_ast_rtp_destroy ( void * ) ;
static void ts_ast_rtp_destroy ( void * ) ;
@ -2263,7 +2261,7 @@ static int reload_config(enum channelreloadreason reason);
static int expire_register ( const void * data ) ;
static int expire_register ( const void * data ) ;
static void * do_monitor ( void * data ) ;
static void * do_monitor ( void * data ) ;
static int restart_monitor ( void ) ;
static int restart_monitor ( void ) ;
static char * peer_mailboxes_to_str ( struct ast_str * * mailbox_str , struct sip_peer * peer ) ;
static void peer_mailboxes_to_str ( struct ast_str * * mailbox_str , struct sip_peer * peer ) ;
/* static int sip_addrcmp(char *name, struct sockaddr_in *sin); Support for peer matching */
/* static int sip_addrcmp(char *name, struct sockaddr_in *sin); Support for peer matching */
static int sip_refer_allocate ( struct sip_pvt * p ) ;
static int sip_refer_allocate ( struct sip_pvt * p ) ;
static void ast_quiet_chan ( struct ast_channel * chan ) ;
static void ast_quiet_chan ( struct ast_channel * chan ) ;
@ -2709,7 +2707,7 @@ static void *_sip_tcp_helper_thread(struct sip_pvt *pvt, struct ast_tcptls_sessi
}
}
/* Read in headers one line at a time */
/* Read in headers one line at a time */
while ( req . len < 4 | | strncmp ( ast_str_buffer ( req . data ) + req . len - 4 , " \r \n \r \n " , 4 ) ) {
while ( req . len < 4 | | strncmp ( ( char * ) & req . data - > str + req . len - 4 , " \r \n \r \n " , 4 ) ) {
ast_mutex_lock ( & tcptls_session - > lock ) ;
ast_mutex_lock ( & tcptls_session - > lock ) ;
if ( ! fgets ( buf , sizeof ( buf ) , tcptls_session - > f ) ) {
if ( ! fgets ( buf , sizeof ( buf ) , tcptls_session - > f ) ) {
ast_mutex_unlock ( & tcptls_session - > lock ) ;
ast_mutex_unlock ( & tcptls_session - > lock ) ;
@ -2718,8 +2716,8 @@ static void *_sip_tcp_helper_thread(struct sip_pvt *pvt, struct ast_tcptls_sessi
ast_mutex_unlock ( & tcptls_session - > lock ) ;
ast_mutex_unlock ( & tcptls_session - > lock ) ;
if ( me - > stop )
if ( me - > stop )
goto cleanup ;
goto cleanup ;
ast_str_append ( & req . data , - 1 , " %s " , buf ) ;
ast_str_append ( & req . data , 0 , " %s " , buf ) ;
req . len = ast_str_strlen ( req . data ) ;
req . len = req . data - > used ;
}
}
copy_request ( & reqcpy , & req ) ;
copy_request ( & reqcpy , & req ) ;
parse_request ( & reqcpy ) ;
parse_request ( & reqcpy ) ;
@ -2735,8 +2733,8 @@ static void *_sip_tcp_helper_thread(struct sip_pvt *pvt, struct ast_tcptls_sessi
if ( me - > stop )
if ( me - > stop )
goto cleanup ;
goto cleanup ;
cl - = strlen ( buf ) ;
cl - = strlen ( buf ) ;
ast_str_append ( & req . data , - 1 , " %s " , buf ) ;
ast_str_append ( & req . data , 0 , " %s " , buf ) ;
req . len = ast_str_strlen ( req . data ) ;
req . len = req . data - > used ;
}
}
}
}
/*! \todo XXX If there's no Content-Length or if the content-length and what
/*! \todo XXX If there's no Content-Length or if the content-length and what
@ -3165,24 +3163,21 @@ static int __sip_xmit(struct sip_pvt *p, struct ast_str *data, int len)
int res = 0 ;
int res = 0 ;
const struct sockaddr_in * dst = sip_real_dst ( p ) ;
const struct sockaddr_in * dst = sip_real_dst ( p ) ;
ast_debug ( 2 , " Trying to put '%.10s' onto %s socket destined for %s:%d \n " , ast_str_buffer ( data ) , get_transport_pvt ( p ) , ast_inet_ntoa ( dst - > sin_addr ) , htons ( dst - > sin_port ) ) ;
ast_debug ( 2 , " Trying to put '%.10s' onto %s socket destined for %s:%d \n " , data - > str , get_transport_pvt ( p ) , ast_inet_ntoa ( dst - > sin_addr ) , htons ( dst - > sin_port ) ) ;
if ( sip_prepare_socket ( p ) < 0 ) {
if ( sip_prepare_socket ( p ) < 0 )
return XMIT_ERROR ;
return XMIT_ERROR ;
}
if ( p - > socket . tcptls_session ) {
if ( p - > socket . tcptls_session )
ast_mutex_lock ( & p - > socket . tcptls_session - > lock ) ;
ast_mutex_lock ( & p - > socket . tcptls_session - > lock ) ;
}
if ( p - > socket . type & SIP_TRANSPORT_UDP ) {
if ( p - > socket . type & SIP_TRANSPORT_UDP )
res = sendto ( p - > socket . fd , ast_str_buffer ( data ) , len , 0 , ( const struct sockaddr * ) dst , sizeof ( struct sockaddr_in ) ) ;
res = sendto ( p - > socket . fd , data - > str , len , 0 , ( const struct sockaddr * ) dst , sizeof ( struct sockaddr_in ) ) ;
} else {
else {
if ( p - > socket . tcptls_session - > f ) {
if ( p - > socket . tcptls_session - > f )
res = ast_tcptls_server_write ( p - > socket . tcptls_session , ast_str_buffer ( data ) , len ) ;
res = ast_tcptls_server_write ( p - > socket . tcptls_session , data - > str , len ) ;
} else {
else
ast_debug ( 2 , " No p->socket.tcptls_session->f len=%d \n " , len ) ;
ast_debug ( 2 , " No p->socket.tcptls_session->f len=%d \n " , len ) ;
}
}
}
if ( p - > socket . tcptls_session )
if ( p - > socket . tcptls_session )
@ -3198,9 +3193,8 @@ static int __sip_xmit(struct sip_pvt *p, struct ast_str *data, int len)
res = XMIT_ERROR ; /* Don't bother with trying to transmit again */
res = XMIT_ERROR ; /* Don't bother with trying to transmit again */
}
}
}
}
if ( res ! = len ) {
if ( res ! = len )
ast_log ( LOG_WARNING , " sip_xmit of %p (len %d) to %s:%d returned %d: %s \n " , data , len , ast_inet_ntoa ( dst - > sin_addr ) , ntohs ( dst - > sin_port ) , res , strerror ( errno ) ) ;
ast_log ( LOG_WARNING , " sip_xmit of %p (len %d) to %s:%d returned %d: %s \n " , data , len , ast_inet_ntoa ( dst - > sin_addr ) , ntohs ( dst - > sin_port ) , res , strerror ( errno ) ) ;
}
return res ;
return res ;
}
}
@ -3360,10 +3354,10 @@ static int retrans_pkt(const void *data)
ast_verbose ( " Retransmitting #%d (%s) to %s:%d: \n %s \n --- \n " ,
ast_verbose ( " Retransmitting #%d (%s) to %s:%d: \n %s \n --- \n " ,
pkt - > retrans , sip_nat_mode ( pkt - > owner ) ,
pkt - > retrans , sip_nat_mode ( pkt - > owner ) ,
ast_inet_ntoa ( dst - > sin_addr ) ,
ast_inet_ntoa ( dst - > sin_addr ) ,
ntohs ( dst - > sin_port ) , ast_str_buffer ( pkt - > data ) ) ;
ntohs ( dst - > sin_port ) , pkt - > data - > str ) ;
}
}
append_history ( pkt - > owner , " ReTx " , " %d %s " , reschedule , ast_str_buffer ( pkt - > data ) ) ;
append_history ( pkt - > owner , " ReTx " , " %d %s " , reschedule , pkt - > data - > str ) ;
xmitres = __sip_xmit ( pkt - > owner , pkt - > data , pkt - > packetlen ) ;
xmitres = __sip_xmit ( pkt - > owner , pkt - > data , pkt - > packetlen ) ;
sip_pvt_unlock ( pkt - > owner ) ;
sip_pvt_unlock ( pkt - > owner ) ;
if ( xmitres = = XMIT_ERROR )
if ( xmitres = = XMIT_ERROR )
@ -3478,7 +3472,7 @@ static enum sip_result __sip_reliable_xmit(struct sip_pvt *p, int seqno, int res
ast_free ( pkt ) ;
ast_free ( pkt ) ;
return AST_FAILURE ;
return AST_FAILURE ;
}
}
ast_str_set ( & pkt - > data , 0 , " %s " , ast_str_buffer ( data ) ) ;
ast_str_set ( & pkt - > data , 0 , " %s %s" , data - > str , " \0 " ) ;
pkt - > packetlen = len ;
pkt - > packetlen = len ;
/* copy other parameters from the caller */
/* copy other parameters from the caller */
pkt - > method = sipmethod ;
pkt - > method = sipmethod ;
@ -3680,7 +3674,7 @@ static void __sip_pretend_ack(struct sip_pvt *p)
return ;
return ;
}
}
cur = p - > packets ;
cur = p - > packets ;
method = ( cur - > method ) ? cur - > method : find_sip_method ( ast_str_buffer ( cur - > data ) ) ;
method = ( cur - > method ) ? cur - > method : find_sip_method ( cur - > data - > str ) ;
__sip_ack ( p , cur - > seqno , cur - > is_resp , method ) ;
__sip_ack ( p , cur - > seqno , cur - > is_resp , method ) ;
}
}
}
}
@ -3693,7 +3687,7 @@ static int __sip_semi_ack(struct sip_pvt *p, int seqno, int resp, int sipmethod)
for ( cur = p - > packets ; cur ; cur = cur - > next ) {
for ( cur = p - > packets ; cur ; cur = cur - > next ) {
if ( cur - > seqno = = seqno & & cur - > is_resp = = resp & &
if ( cur - > seqno = = seqno & & cur - > is_resp = = resp & &
( cur - > is_resp | | method_match ( sipmethod , ast_str_buffer ( cur - > data ) ) ) ) {
( cur - > is_resp | | method_match ( sipmethod , cur - > data - > str ) ) ) {
/* this is our baby */
/* this is our baby */
if ( cur - > retransid > - 1 ) {
if ( cur - > retransid > - 1 ) {
if ( sipdebug )
if ( sipdebug )
@ -3722,7 +3716,7 @@ static void add_blank(struct sip_request *req)
if ( ! req - > lines ) {
if ( ! req - > lines ) {
/* Add extra empty return. add_header() reserves 4 bytes so cannot be truncated */
/* Add extra empty return. add_header() reserves 4 bytes so cannot be truncated */
ast_str_append ( & req - > data , 0 , " \r \n " ) ;
ast_str_append ( & req - > data , 0 , " \r \n " ) ;
req - > len = ast_str_strlen ( req - > data ) ;
req - > len = req - > data - > used ;
}
}
}
}
@ -3738,12 +3732,12 @@ static int send_response(struct sip_pvt *p, struct sip_request *req, enum xmitty
ast_verbose ( " \n <--- %sTransmitting (%s) to %s:%d ---> \n %s \n <------------> \n " ,
ast_verbose ( " \n <--- %sTransmitting (%s) to %s:%d ---> \n %s \n <------------> \n " ,
reliable ? " Reliably " : " " , sip_nat_mode ( p ) ,
reliable ? " Reliably " : " " , sip_nat_mode ( p ) ,
ast_inet_ntoa ( dst - > sin_addr ) ,
ast_inet_ntoa ( dst - > sin_addr ) ,
ntohs ( dst - > sin_port ) , ast_str_buffer ( req - > data ) ) ;
ntohs ( dst - > sin_port ) , req - > data - > str ) ;
}
}
if ( p - > do_history ) {
if ( p - > do_history ) {
struct sip_request tmp = { . rlPart1 = NULL , } ;
struct sip_request tmp = { . rlPart1 = NULL , } ;
parse_copy ( & tmp , req ) ;
parse_copy ( & tmp , req ) ;
append_history ( p , reliable ? " TxRespRel " : " TxResp " , " %s / %s - %s " , ast_str_buffer ( tmp . data ) , get_header ( & tmp , " CSeq " ) ,
append_history ( p , reliable ? " TxRespRel " : " TxResp " , " %s / %s - %s " , tmp . data - > str , get_header ( & tmp , " CSeq " ) ,
( tmp . method = = SIP_RESPONSE | | tmp . method = = SIP_UNKNOWN ) ? tmp . rlPart2 : sip_methods [ tmp . method ] . text ) ;
( tmp . method = = SIP_RESPONSE | | tmp . method = = SIP_UNKNOWN ) ? tmp . rlPart2 : sip_methods [ tmp . method ] . text ) ;
ast_free ( tmp . data ) ;
ast_free ( tmp . data ) ;
}
}
@ -3771,16 +3765,15 @@ static int send_request(struct sip_pvt *p, struct sip_request *req, enum xmittyp
add_blank ( req ) ;
add_blank ( req ) ;
if ( sip_debug_test_pvt ( p ) ) {
if ( sip_debug_test_pvt ( p ) ) {
if ( ast_test_flag ( & p - > flags [ 0 ] , SIP_NAT_ROUTE ) ) {
if ( ast_test_flag ( & p - > flags [ 0 ] , SIP_NAT_ROUTE ) )
ast_verbose ( " %sTransmitting (NAT) to %s:%d: \n %s \n --- \n " , reliable ? " Reliably " : " " , ast_inet_ntoa ( p - > recv . sin_addr ) , ntohs ( p - > recv . sin_port ) , ast_str_buffer ( req - > data ) ) ;
ast_verbose ( " %sTransmitting (NAT) to %s:%d: \n %s \n --- \n " , reliable ? " Reliably " : " " , ast_inet_ntoa ( p - > recv . sin_addr ) , ntohs ( p - > recv . sin_port ) , req - > data - > str ) ;
} else {
else
ast_verbose ( " %sTransmitting (no NAT) to %s:%d: \n %s \n --- \n " , reliable ? " Reliably " : " " , ast_inet_ntoa ( p - > sa . sin_addr ) , ntohs ( p - > sa . sin_port ) , ast_str_buffer ( req - > data ) ) ;
ast_verbose ( " %sTransmitting (no NAT) to %s:%d: \n %s \n --- \n " , reliable ? " Reliably " : " " , ast_inet_ntoa ( p - > sa . sin_addr ) , ntohs ( p - > sa . sin_port ) , req - > data - > str ) ;
}
}
}
if ( p - > do_history ) {
if ( p - > do_history ) {
struct sip_request tmp = { . rlPart1 = NULL , } ;
struct sip_request tmp = { . rlPart1 = NULL , } ;
parse_copy ( & tmp , req ) ;
parse_copy ( & tmp , req ) ;
append_history ( p , reliable ? " TxReqRel " : " TxReq " , " %s / %s - %s " , ast_str_buffer ( tmp . data ) , get_header ( & tmp , " CSeq " ) , sip_methods [ tmp . method ] . text ) ;
append_history ( p , reliable ? " TxReqRel " : " TxReq " , " %s / %s - %s " , tmp . data - > str , get_header ( & tmp , " CSeq " ) , sip_methods [ tmp . method ] . text ) ;
ast_free ( tmp . data ) ;
ast_free ( tmp . data ) ;
}
}
res = ( reliable ) ?
res = ( reliable ) ?
@ -5511,7 +5504,7 @@ static int sip_hangup(struct ast_channel *ast)
sip_scheddestroy ( p , DEFAULT_TRANS_TIMEOUT ) ;
sip_scheddestroy ( p , DEFAULT_TRANS_TIMEOUT ) ;
/* Start the process if it's not already started */
/* Start the process if it's not already started */
if ( ! p - > alreadygone & & p - > initreq . data & & ast_str _str len( p - > initreq . data ) ) {
if ( ! p - > alreadygone & & p - > initreq . data & & ! ast_str len_zero ( p - > initreq . data - > str ) ) {
if ( needcancel ) { /* Outgoing call, not up */
if ( needcancel ) { /* Outgoing call, not up */
if ( ast_test_flag ( & p - > flags [ 0 ] , SIP_OUTGOING ) ) {
if ( ast_test_flag ( & p - > flags [ 0 ] , SIP_OUTGOING ) ) {
/* stop retransmitting an INVITE that has not received a response */
/* stop retransmitting an INVITE that has not received a response */
@ -7024,7 +7017,7 @@ static int lws2sws(char *msgbuf, int len)
*/
*/
static int parse_request ( struct sip_request * req )
static int parse_request ( struct sip_request * req )
{
{
char * c = ast_str_buffer ( req - > data ) , * * dst = req - > header ;
char * c = req - > data - > str , * * dst = req - > header ;
int i = 0 , lim = SIP_MAX_HEADERS - 1 ;
int i = 0 , lim = SIP_MAX_HEADERS - 1 ;
unsigned int skipping_headers = 0 ;
unsigned int skipping_headers = 0 ;
@ -7922,7 +7915,7 @@ static int process_sdp(struct sip_pvt *p, struct sip_request *req, int t38action
/* Activate a re-invite */
/* Activate a re-invite */
ast_queue_frame ( p - > owner , & ast_null_frame ) ;
ast_queue_frame ( p - > owner , & ast_null_frame ) ;
/* Queue Manager Unhold event */
/* Queue Manager Unhold event */
append_history ( p , " Unhold " , " %s " , ast_str_buffer ( req - > data ) ) ;
append_history ( p , " Unhold " , " %s " , req - > data - > str ) ;
if ( sip_cfg . callevents )
if ( sip_cfg . callevents )
manager_event ( EVENT_FLAG_CALL , " Hold " ,
manager_event ( EVENT_FLAG_CALL , " Hold " ,
" Status: Off \r \n "
" Status: Off \r \n "
@ -7944,7 +7937,7 @@ static int process_sdp(struct sip_pvt *p, struct sip_request *req, int t38action
/* Activate a re-invite */
/* Activate a re-invite */
ast_queue_frame ( p - > owner , & ast_null_frame ) ;
ast_queue_frame ( p - > owner , & ast_null_frame ) ;
/* Queue Manager Hold event */
/* Queue Manager Hold event */
append_history ( p , " Hold " , " %s " , ast_str_buffer ( req - > data ) ) ;
append_history ( p , " Hold " , " %s " , req - > data - > str ) ;
if ( sip_cfg . callevents & & ! ast_test_flag ( & p - > flags [ 1 ] , SIP_PAGE2_CALL_ONHOLD ) ) {
if ( sip_cfg . callevents & & ! ast_test_flag ( & p - > flags [ 1 ] , SIP_PAGE2_CALL_ONHOLD ) ) {
manager_event ( EVENT_FLAG_CALL , " Hold " ,
manager_event ( EVENT_FLAG_CALL , " Hold " ,
" Status: On \r \n "
" Status: On \r \n "
@ -7987,8 +7980,8 @@ static int add_header(struct sip_request *req, const char *var, const char *valu
return - 1 ;
return - 1 ;
}
}
ast_str_append ( & req - > data , - 1 , " %s: %s \r \n " , var , value ) ;
ast_str_append ( & req - > data , 0 , " %s: %s \r \n " , var , value ) ;
req - > header [ req - > headers ] = ast_str_buffer ( req - > data ) + req - > len ;
req - > header [ req - > headers ] = req - > data - > str + req - > len ;
if ( sip_cfg . compactheaders )
if ( sip_cfg . compactheaders )
var = find_alias ( var , var ) ;
var = find_alias ( var , var ) ;
@ -8014,12 +8007,16 @@ static int add_line(struct sip_request *req, const char *line)
ast_log ( LOG_WARNING , " Out of SIP line space \n " ) ;
ast_log ( LOG_WARNING , " Out of SIP line space \n " ) ;
return - 1 ;
return - 1 ;
}
}
if ( ! req - > lines ) {
if ( ! req - > lines )
/* Add extra empty return */
/* Add extra empty return */
req - > len + = ast_str_append ( & req - > data , - 1 , " \r \n " ) ;
req - > len + = ast_str_append ( & req - > data , 0 , " \r \n " ) ;
if ( req - > len > = sizeof ( req - > data - > str ) - 4 ) {
ast_log ( LOG_WARNING , " Out of space, can't add anymore \n " ) ;
return - 1 ;
}
}
req - > line [ req - > lines ] = ast_str_buffer ( req - > data ) + ast_str_strlen ( req - > data ) ;
req - > line [ req - > lines ] = req - > data - > str + req - > len ;
req - > len + = ast_str_append ( & req - > data , - 1 , " %s " , line ) ;
ast_str_append ( & req - > data , 0 , " %s " , line ) ;
req - > len + = strlen ( req - > line [ req - > lines ] ) ;
req - > lines + + ;
req - > lines + + ;
return 0 ;
return 0 ;
}
}
@ -8083,7 +8080,7 @@ static int copy_via_headers(struct sip_pvt *p, struct sip_request *req, const st
/* Find ;rport; (empty request) */
/* Find ;rport; (empty request) */
rport = strstr ( leftmost , " ;rport " ) ;
rport = strstr ( leftmost , " ;rport " ) ;
if ( rport & & * ( rport + 6 ) = = ' = ' )
if ( rport & & * ( rport + 6 ) = = ' = ' )
rport = NULL ; /* We already have a parameter to rport */
rport = NULL ; /* We already have a parameter to rport */
/* Check rport if NAT=yes or NAT=rfc3581 (which is the default setting) */
/* Check rport if NAT=yes or NAT=rfc3581 (which is the default setting) */
@ -8235,9 +8232,9 @@ static int init_resp(struct sip_request *resp, const char *msg)
resp - > method = SIP_RESPONSE ;
resp - > method = SIP_RESPONSE ;
if ( ! ( resp - > data = ast_str_create ( SIP_MIN_PACKET ) ) )
if ( ! ( resp - > data = ast_str_create ( SIP_MIN_PACKET ) ) )
return - 1 ;
return - 1 ;
ast_str_set ( & resp - > data , - 1 , " SIP/2.0 %s \r \n " , msg ) ;
resp - > header [ 0 ] = resp - > data - > str ;
resp - > header [ 0 ] = ast_str_buffer ( resp - > data ) ;
ast_str_set ( & resp - > data , 0 , " SIP/2.0 %s \r \n " , msg ) ;
resp - > len = ast_str_ strlen( resp - > data ) ;
resp - > len = strlen( resp - > header[ 0 ] ) ;
resp - > headers + + ;
resp - > headers + + ;
return 0 ;
return 0 ;
}
}
@ -8250,9 +8247,9 @@ static int init_req(struct sip_request *req, int sipmethod, const char *recip)
if ( ! ( req - > data = ast_str_create ( SIP_MIN_PACKET ) ) )
if ( ! ( req - > data = ast_str_create ( SIP_MIN_PACKET ) ) )
return - 1 ;
return - 1 ;
req - > method = sipmethod ;
req - > method = sipmethod ;
ast_str_set ( & req - > data , - 1 , " %s %s SIP/2.0 \r \n " , sip_methods [ sipmethod ] . text , recip ) ;
req - > header [ 0 ] = req - > data - > str ;
req - > header [ 0 ] = ast_str_buffer ( req - > data ) ;
ast_str_set ( & req - > data , 0 , " %s %s SIP/2.0 \r \n " , sip_methods [ sipmethod ] . text , recip ) ;
req - > len = ast_str_ strlen( req - > data ) ;
req - > len = strlen( req - > header[ 0 ] ) ;
req - > headers + + ;
req - > headers + + ;
return 0 ;
return 0 ;
}
}
@ -8899,11 +8896,11 @@ static int add_t38_sdp(struct sip_request *resp, struct sip_pvt *p)
ast_str_append ( & a_modem , 0 , " a=T38FaxMaxDatagram:%d \r \n " , x ) ;
ast_str_append ( & a_modem , 0 , " a=T38FaxMaxDatagram:%d \r \n " , x ) ;
if ( p - > t38 . jointcapability ! = T38FAX_UDP_EC_NONE )
if ( p - > t38 . jointcapability ! = T38FAX_UDP_EC_NONE )
ast_str_append ( & a_modem , 0 , " a=T38FaxUdpEC:%s \r \n " , ( p - > t38 . jointcapability & T38FAX_UDP_EC_REDUNDANCY ) ? " t38UDPRedundancy " : " t38UDPFEC " ) ;
ast_str_append ( & a_modem , 0 , " a=T38FaxUdpEC:%s \r \n " , ( p - > t38 . jointcapability & T38FAX_UDP_EC_REDUNDANCY ) ? " t38UDPRedundancy " : " t38UDPFEC " ) ;
len = ast_str_strlen ( m_modem ) + ast_str_strlen ( a_modem ) ;
len = m_modem - > used + a_modem - > used ;
add_header ( resp , " Content-Type " , " application/sdp " ) ;
add_header ( resp , " Content-Type " , " application/sdp " ) ;
add_header_contentLength ( resp , len ) ;
add_header_contentLength ( resp , len ) ;
add_line ( resp , ast_str_buffer ( m_modem ) ) ;
add_line ( resp , m_modem - > str ) ;
add_line ( resp , ast_str_buffer ( a_modem ) ) ;
add_line ( resp , a_modem - > str ) ;
/* Update lastrtprx when we send our SDP */
/* Update lastrtprx when we send our SDP */
p - > lastrtprx = p - > lastrtptx = time ( NULL ) ;
p - > lastrtprx = p - > lastrtptx = time ( NULL ) ;
@ -8941,12 +8938,10 @@ static void get_our_media_address(struct sip_pvt *p, int needvideo,
{
{
/* First, get our address */
/* First, get our address */
ast_rtp_get_us ( p - > rtp , sin ) ;
ast_rtp_get_us ( p - > rtp , sin ) ;
if ( p - > vrtp ) {
if ( p - > vrtp )
ast_rtp_get_us ( p - > vrtp , vsin ) ;
ast_rtp_get_us ( p - > vrtp , vsin ) ;
}
if ( p - > trtp )
if ( p - > trtp ) {
ast_rtp_get_us ( p - > trtp , tsin ) ;
ast_rtp_get_us ( p - > trtp , tsin ) ;
}
/* Now, try to figure out where we want them to send data */
/* Now, try to figure out where we want them to send data */
/* Is this a re-invite to move the media out, then use the original offer from caller */
/* Is this a re-invite to move the media out, then use the original offer from caller */
@ -8996,12 +8991,12 @@ static enum sip_result add_sdp(struct sip_request *resp, struct sip_pvt *p, int
struct sockaddr_in tdest = { 0 , } ;
struct sockaddr_in tdest = { 0 , } ;
/* SDP fields */
/* SDP fields */
char * version = " v=0 \r \n " ; /* Protocol version */
char * version = " v=0 \r \n " ; /* Protocol version */
char subject [ 256 ] ; /* Subject of the session */
char subject [ 256 ] ; /* Subject of the session */
char owner [ 256 ] ; /* Session owner/creator */
char owner [ 256 ] ; /* Session owner/creator */
char connection [ 256 ] ; /* Connection data */
char connection [ 256 ] ; /* Connection data */
char * session_time = " t=0 0 \r \n " ; /* Time the session is active */
char * session_time = " t=0 0 \r \n " ; /* Time the session is active */
char bandwidth [ 256 ] = " " ; /* Max bitrate */
char bandwidth [ 256 ] = " " ; /* Max bitrate */
char * hold ;
char * hold ;
struct ast_str * m_audio = ast_str_alloca ( 256 ) ; /* Media declaration line for audio */
struct ast_str * m_audio = ast_str_alloca ( 256 ) ; /* Media declaration line for audio */
struct ast_str * m_video = ast_str_alloca ( 256 ) ; /* Media declaration line for video */
struct ast_str * m_video = ast_str_alloca ( 256 ) ; /* Media declaration line for video */
@ -9035,12 +9030,11 @@ static enum sip_result add_sdp(struct sip_request *resp, struct sip_pvt *p, int
/* Set RTP Session ID and version */
/* Set RTP Session ID and version */
if ( ! p - > sessionid ) {
if ( ! p - > sessionid ) {
p - > sessionid = ( int ) ast_random ( ) ;
p - > sessionid = ( int ) ast_random ( ) ;
p - > sessionversion = p - > sessionid ;
p - > sessionversion = p - > sessionid ;
} else {
} else {
if ( oldsdp = = FALSE ) {
if ( oldsdp = = FALSE )
p - > sessionversion + + ;
p - > sessionversion + + ;
}
}
}
capability = p - > jointcapability ;
capability = p - > jointcapability ;
@ -9058,26 +9052,23 @@ static enum sip_result add_sdp(struct sip_request *resp, struct sip_pvt *p, int
# endif
# endif
/* Check if we need audio */
/* Check if we need audio */
if ( capability & AST_FORMAT_AUDIO_MASK ) {
if ( capability & AST_FORMAT_AUDIO_MASK )
needaudio = TRUE ;
needaudio = TRUE ;
}
/* Check if we need video in this call */
/* Check if we need video in this call */
if ( ( capability & AST_FORMAT_VIDEO_MASK ) & & ! p - > novideo ) {
if ( ( capability & AST_FORMAT_VIDEO_MASK ) & & ! p - > novideo ) {
if ( p - > vrtp ) {
if ( p - > vrtp ) {
needvideo = TRUE ;
needvideo = TRUE ;
ast_debug ( 2 , " This call needs video offers! \n " ) ;
ast_debug ( 2 , " This call needs video offers! \n " ) ;
} else {
} else
ast_debug ( 2 , " This call needs video offers, but there's no video support enabled! \n " ) ;
ast_debug ( 2 , " This call needs video offers, but there's no video support enabled! \n " ) ;
}
}
}
/* Get our media addresses */
/* Get our media addresses */
get_our_media_address ( p , needvideo , & sin , & vsin , & tsin , & dest , & vdest ) ;
get_our_media_address ( p , needvideo , & sin , & vsin , & tsin , & dest , & vdest ) ;
if ( debug ) {
if ( debug )
ast_verbose ( " Audio is at %s port %d \n " , ast_inet_ntoa ( p - > ourip . sin_addr ) , ntohs ( sin . sin_port ) ) ;
ast_verbose ( " Audio is at %s port %d \n " , ast_inet_ntoa ( p - > ourip . sin_addr ) , ntohs ( sin . sin_port ) ) ;
}
/* Ok, we need video. Let's add what we need for video and set codecs.
/* Ok, we need video. Let's add what we need for video and set codecs.
Video is handled differently than audio since we can not transcode . */
Video is handled differently than audio since we can not transcode . */
@ -9085,36 +9076,30 @@ static enum sip_result add_sdp(struct sip_request *resp, struct sip_pvt *p, int
ast_str_append ( & m_video , 0 , " m=video %d RTP/AVP " , ntohs ( vdest . sin_port ) ) ;
ast_str_append ( & m_video , 0 , " m=video %d RTP/AVP " , ntohs ( vdest . sin_port ) ) ;
/* Build max bitrate string */
/* Build max bitrate string */
if ( p - > maxcallbitrate ) {
if ( p - > maxcallbitrate )
snprintf ( bandwidth , sizeof ( bandwidth ) , " b=CT:%d \r \n " , p - > maxcallbitrate ) ;
snprintf ( bandwidth , sizeof ( bandwidth ) , " b=CT:%d \r \n " , p - > maxcallbitrate ) ;
}
if ( debug )
if ( debug ) {
ast_verbose ( " Video is at %s port %d \n " , ast_inet_ntoa ( p - > ourip . sin_addr ) , ntohs ( vsin . sin_port ) ) ;
ast_verbose ( " Video is at %s port %d \n " , ast_inet_ntoa ( p - > ourip . sin_addr ) , ntohs ( vsin . sin_port ) ) ;
}
}
}
/* Check if we need text in this call */
/* Check if we need text in this call */
if ( ( capability & AST_FORMAT_TEXT_MASK ) & & ! p - > notext ) {
if ( ( capability & AST_FORMAT_TEXT_MASK ) & & ! p - > notext ) {
if ( sipdebug_text ) {
if ( sipdebug_text )
ast_verbose ( " We think we can do text \n " ) ;
ast_verbose ( " We think we can do text \n " ) ;
}
if ( p - > trtp ) {
if ( p - > trtp ) {
if ( sipdebug_text ) {
if ( sipdebug_text )
ast_verbose ( " And we have a text rtp object \n " ) ;
ast_verbose ( " And we have a text rtp object \n " ) ;
}
needtext = TRUE ;
needtext = TRUE ;
ast_debug ( 2 , " This call needs text offers! \n " ) ;
ast_debug ( 2 , " This call needs text offers! \n " ) ;
} else {
} else
ast_debug ( 2 , " This call needs text offers, but there's no text support enabled ! \n " ) ;
ast_debug ( 2 , " This call needs text offers, but there's no text support enabled ! \n " ) ;
}
}
}
/* Ok, we need text. Let's add what we need for text and set codecs.
/* Ok, we need text. Let's add what we need for text and set codecs.
Text is handled differently than audio since we can not transcode . */
Text is handled differently than audio since we can not transcode . */
if ( needtext ) {
if ( needtext ) {
if ( sipdebug_text ) {
if ( sipdebug_text )
ast_verbose ( " Lets set up the text sdp \n " ) ;
ast_verbose ( " Lets set up the text sdp \n " ) ;
}
/* Determine text destination */
/* Determine text destination */
if ( p - > tredirip . sin_addr . s_addr ) {
if ( p - > tredirip . sin_addr . s_addr ) {
tdest . sin_addr = p - > tredirip . sin_addr ;
tdest . sin_addr = p - > tredirip . sin_addr ;
@ -9125,9 +9110,9 @@ static enum sip_result add_sdp(struct sip_request *resp, struct sip_pvt *p, int
}
}
ast_str_append ( & m_text , 0 , " m=text %d RTP/AVP " , ntohs ( tdest . sin_port ) ) ;
ast_str_append ( & m_text , 0 , " m=text %d RTP/AVP " , ntohs ( tdest . sin_port ) ) ;
if ( debug ) { /* XXX should I use tdest below ? */
if ( debug ) /* XXX should I use tdest below ? */
ast_verbose ( " Text is at %s port %d \n " , ast_inet_ntoa ( p - > ourip . sin_addr ) , ntohs ( tsin . sin_port ) ) ;
ast_verbose ( " Text is at %s port %d \n " , ast_inet_ntoa ( p - > ourip . sin_addr ) , ntohs ( tsin . sin_port ) ) ;
}
}
}
/* Start building generic SDP headers */
/* Start building generic SDP headers */
@ -9139,13 +9124,12 @@ static enum sip_result add_sdp(struct sip_request *resp, struct sip_pvt *p, int
snprintf ( connection , sizeof ( connection ) , " c=IN IP4 %s \r \n " , ast_inet_ntoa ( dest . sin_addr ) ) ;
snprintf ( connection , sizeof ( connection ) , " c=IN IP4 %s \r \n " , ast_inet_ntoa ( dest . sin_addr ) ) ;
ast_str_append ( & m_audio , 0 , " m=audio %d RTP/AVP " , ntohs ( dest . sin_port ) ) ;
ast_str_append ( & m_audio , 0 , " m=audio %d RTP/AVP " , ntohs ( dest . sin_port ) ) ;
if ( ast_test_flag ( & p - > flags [ 1 ] , SIP_PAGE2_CALL_ONHOLD ) = = SIP_PAGE2_CALL_ONHOLD_ONEDIR ) {
if ( ast_test_flag ( & p - > flags [ 1 ] , SIP_PAGE2_CALL_ONHOLD ) = = SIP_PAGE2_CALL_ONHOLD_ONEDIR )
hold = " a=recvonly \r \n " ;
hold = " a=recvonly \r \n " ;
} else if ( ast_test_flag ( & p - > flags [ 1 ] , SIP_PAGE2_CALL_ONHOLD ) = = SIP_PAGE2_CALL_ONHOLD_INACTIVE ) {
else if ( ast_test_flag ( & p - > flags [ 1 ] , SIP_PAGE2_CALL_ONHOLD ) = = SIP_PAGE2_CALL_ONHOLD_INACTIVE )
hold = " a=inactive \r \n " ;
hold = " a=inactive \r \n " ;
} else {
else
hold = " a=sendrecv \r \n " ;
hold = " a=sendrecv \r \n " ;
}
/* Now, start adding audio codecs. These are added in this order:
/* Now, start adding audio codecs. These are added in this order:
- First what was requested by the calling channel
- First what was requested by the calling channel
@ -9169,15 +9153,14 @@ static enum sip_result add_sdp(struct sip_request *resp, struct sip_pvt *p, int
for ( x = 0 ; x < 32 ; x + + ) {
for ( x = 0 ; x < 32 ; x + + ) {
int codec ;
int codec ;
if ( ! ( codec = ast_codec_pref_index ( & p - > prefs , x ) ) ) {
if ( ! ( codec = ast_codec_pref_index ( & p - > prefs , x ) ) )
break ;
break ;
}
if ( ! ( capability & codec ) ) {
if ( ! ( capability & codec ) )
continue ;
continue ;
}
if ( alreadysent & codec ) {
if ( alreadysent & codec )
continue ;
continue ;
}
add_codec_to_sdp ( p , codec , SDP_SAMPLE_RATE ( codec ) ,
add_codec_to_sdp ( p , codec , SDP_SAMPLE_RATE ( codec ) ,
& m_audio , & a_audio ,
& m_audio , & a_audio ,
@ -9187,85 +9170,67 @@ static enum sip_result add_sdp(struct sip_request *resp, struct sip_pvt *p, int
/* Now send any other common audio and video codecs, and non-codec formats: */
/* Now send any other common audio and video codecs, and non-codec formats: */
for ( x = 1 ; x < = ( needtext ? AST_FORMAT_TEXT_MASK : ( needvideo ? AST_FORMAT_VIDEO_MASK : AST_FORMAT_AUDIO_MASK ) ) ; x < < = 1 ) {
for ( x = 1 ; x < = ( needtext ? AST_FORMAT_TEXT_MASK : ( needvideo ? AST_FORMAT_VIDEO_MASK : AST_FORMAT_AUDIO_MASK ) ) ; x < < = 1 ) {
if ( ! ( capability & x ) ) { /* Codec not requested */
if ( ! ( capability & x ) ) /* Codec not requested */
continue ;
continue ;
}
if ( alreadysent & x ) { /* Already added to SDP */
if ( alreadysent & x ) /* Already added to SDP */
continue ;
continue ;
}
if ( x & AST_FORMAT_AUDIO_MASK ) {
if ( x & AST_FORMAT_AUDIO_MASK )
add_codec_to_sdp ( p , x , SDP_SAMPLE_RATE ( x ) ,
add_codec_to_sdp ( p , x , SDP_SAMPLE_RATE ( x ) ,
& m_audio , & a_audio , debug , & min_audio_packet_size ) ;
& m_audio , & a_audio , debug , & min_audio_packet_size ) ;
} else if ( x & AST_FORMAT_VIDEO_MASK ) {
else if ( x & AST_FORMAT_VIDEO_MASK )
add_vcodec_to_sdp ( p , x , 90000 ,
add_vcodec_to_sdp ( p , x , 90000 ,
& m_video , & a_video , debug , & min_video_packet_size ) ;
& m_video , & a_video , debug , & min_video_packet_size ) ;
} else if ( x & AST_FORMAT_TEXT_MASK ) {
else if ( x & AST_FORMAT_TEXT_MASK )
add_tcodec_to_sdp ( p , x , 1000 ,
add_tcodec_to_sdp ( p , x , 1000 ,
& m_text , & a_text , debug , & min_text_packet_size ) ;
& m_text , & a_text , debug , & min_text_packet_size ) ;
}
}
}
/* Now add DTMF RFC2833 telephony-event as a codec */
/* Now add DTMF RFC2833 telephony-event as a codec */
for ( x = 1 ; x < = AST_RTP_MAX ; x < < = 1 ) {
for ( x = 1 ; x < = AST_RTP_MAX ; x < < = 1 ) {
if ( ! ( p - > jointnoncodeccapability & x ) ) {
if ( ! ( p - > jointnoncodeccapability & x ) )
continue ;
continue ;
}
add_noncodec_to_sdp ( p , x , 8000 , & m_audio , & a_audio , debug ) ;
add_noncodec_to_sdp ( p , x , 8000 , & m_audio , & a_audio , debug ) ;
}
}
ast_debug ( 3 , " -- Done with adding codecs to SDP \n " ) ;
ast_debug ( 3 , " -- Done with adding codecs to SDP \n " ) ;
if ( ! p - > owner | | ! ast_internal_timing_enabled ( p - > owner ) ) {
if ( ! p - > owner | | ! ast_internal_timing_enabled ( p - > owner ) )
ast_str_append ( & a_audio , 0 , " a=silenceSupp:off - - - - \r \n " ) ;
ast_str_append ( & a_audio , 0 , " a=silenceSupp:off - - - - \r \n " ) ;
}
if ( min_audio_packet_size ) {
if ( min_audio_packet_size )
ast_str_append ( & a_audio , 0 , " a=ptime:%d \r \n " , min_audio_packet_size ) ;
ast_str_append ( & a_audio , 0 , " a=ptime:%d \r \n " , min_audio_packet_size ) ;
}
/* XXX don't think you can have ptime for video */
/* XXX don't think you can have ptime for video */
if ( min_video_packet_size ) {
if ( min_video_packet_size )
ast_str_append ( & a_video , 0 , " a=ptime:%d \r \n " , min_video_packet_size ) ;
ast_str_append ( & a_video , 0 , " a=ptime:%d \r \n " , min_video_packet_size ) ;
}
/* XXX don't think you can have ptime for text */
/* XXX don't think you can have ptime for text */
if ( min_text_packet_size ) {
if ( min_text_packet_size )
ast_str_append ( & a_text , 0 , " a=ptime:%d \r \n " , min_text_packet_size ) ;
ast_str_append ( & a_text , 0 , " a=ptime:%d \r \n " , min_text_packet_size ) ;
}
if ( ast_str_size ( m_audio ) - ast_str_strlen ( m_audio ) < 2 | |
if ( m_audio - > len - m_audio - > used < 2 | | m_video - > len - m_video - > used < 2 | |
ast_str_size ( m_video ) - ast_str_strlen ( m_video ) < 2 | |
m_text - > len - m_text - > used < 2 | | a_text - > len - a_text - > used < 2 | |
ast_str_size ( m_text ) - ast_str_strlen ( m_text ) < 2 | |
a_audio - > len - a_audio - > used < 2 | | a_video - > len - a_video - > used < 2 )
ast_str_size ( a_text ) - ast_str_strlen ( a_text ) < 2 | |
ast_str_size ( a_audio ) - ast_str_strlen ( a_audio ) < 2 | |
ast_str_size ( a_video ) - ast_str_strlen ( a_video ) < 2 ) {
ast_log ( LOG_WARNING , " SIP SDP may be truncated due to undersized buffer!! \n " ) ;
ast_log ( LOG_WARNING , " SIP SDP may be truncated due to undersized buffer!! \n " ) ;
}
if ( needaudio ) {
if ( needaudio )
ast_str_append ( & m_audio , 0 , " \r \n " ) ;
ast_str_append ( & m_audio , 0 , " \r \n " ) ;
}
if ( needvideo )
if ( needvideo ) {
ast_str_append ( & m_video , 0 , " \r \n " ) ;
ast_str_append ( & m_video , 0 , " \r \n " ) ;
}
if ( needtext )
if ( needtext ) {
ast_str_append ( & m_text , 0 , " \r \n " ) ;
ast_str_append ( & m_text , 0 , " \r \n " ) ;
}
len = strlen ( version ) + strlen ( subject ) + strlen ( owner ) +
len = strlen ( version ) + strlen ( subject ) + strlen ( owner ) +
strlen ( connection ) + strlen ( session_time ) ;
strlen ( connection ) + strlen ( session_time ) ;
if ( needaudio ) {
if ( needaudio )
len + = ast_str_strlen ( m_audio ) + ast_str_strlen ( a_audio ) + strlen ( hold ) ;
len + = m_audio - > used + a_audio - > used + strlen ( hold ) ;
}
if ( needvideo ) /* only if video response is appropriate */
if ( needvideo ) { /* only if video response is appropriate */
len + = m_video - > used + a_video - > used + strlen ( bandwidth ) + strlen ( hold ) ;
len + = ast_str_strlen ( m_video ) + ast_str_strlen ( a_video ) + strlen ( bandwidth ) + strlen ( hold ) ;
if ( needtext ) /* only if text response is appropriate */
}
len + = m_text - > used + a_text - > used + strlen ( hold ) ;
if ( needtext ) { /* only if text response is appropriate */
len + = ast_str_strlen ( m_text ) + ast_str_strlen ( a_text ) + strlen ( hold ) ;
}
add_header ( resp , " Content-Type " , " application/sdp " ) ;
add_header ( resp , " Content-Type " , " application/sdp " ) ;
add_header_contentLength ( resp , len ) ;
add_header_contentLength ( resp , len ) ;
@ -9273,23 +9238,22 @@ static enum sip_result add_sdp(struct sip_request *resp, struct sip_pvt *p, int
add_line ( resp , owner ) ;
add_line ( resp , owner ) ;
add_line ( resp , subject ) ;
add_line ( resp , subject ) ;
add_line ( resp , connection ) ;
add_line ( resp , connection ) ;
if ( needvideo ) { /* only if video response is appropriate */
if ( needvideo ) /* only if video response is appropriate */
add_line ( resp , bandwidth ) ;
add_line ( resp , bandwidth ) ;
}
add_line ( resp , session_time ) ;
add_line ( resp , session_time ) ;
if ( needaudio ) {
if ( needaudio ) {
add_line ( resp , ast_str_buffer ( m_audio ) ) ;
add_line ( resp , m_audio - > str ) ;
add_line ( resp , ast_str_buffer ( a_audio ) ) ;
add_line ( resp , a_audio - > str ) ;
add_line ( resp , hold ) ;
add_line ( resp , hold ) ;
}
}
if ( needvideo ) { /* only if video response is appropriate */
if ( needvideo ) { /* only if video response is appropriate */
add_line ( resp , ast_str_buffer ( m_video ) ) ;
add_line ( resp , m_video - > str ) ;
add_line ( resp , ast_str_buffer ( a_video ) ) ;
add_line ( resp , a_video - > str ) ;
add_line ( resp , hold ) ; /* Repeat hold for the video stream */
add_line ( resp , hold ) ; /* Repeat hold for the video stream */
}
}
if ( needtext ) { /* only if text response is appropriate */
if ( needtext ) { /* only if text response is appropriate */
add_line ( resp , ast_str_buffer ( m_text ) ) ;
add_line ( resp , m_text - > str ) ;
add_line ( resp , ast_str_buffer ( a_text ) ) ;
add_line ( resp , a_text - > str ) ;
add_line ( resp , hold ) ; /* Repeat hold for the text stream */
add_line ( resp , hold ) ; /* Repeat hold for the text stream */
}
}
@ -9339,13 +9303,14 @@ static void copy_request(struct sip_request *dst, const struct sip_request *src)
* the place and so a memcpy is the only way to accurately copy the string
* the place and so a memcpy is the only way to accurately copy the string
*/
*/
if ( ! dst - > data & & ! ( dst - > data = ast_str_create ( ast_str_strlen ( src - > data ) + 1 ) ) )
if ( ! dst - > data & & ! ( dst - > data = ast_str_create ( src - > data - > used + 1 ) ) )
return ;
return ;
else if ( ast_str_size ( dst - > data ) < ast_str_strlen ( src - > data ) + 1 )
else if ( dst - > data - > len < src - > data - > used + 1 )
ast_str_make_space ( & dst - > data , ast_str_strlen ( src - > data ) + 1 ) ;
ast_str_make_space ( & dst - > data , src - > data - > used + 1 ) ;
ast_str_set ( & dst - > data , 0 , " %s " , ast_str_buffer ( src - > data ) ) ;
memcpy ( dst - > data - > str , src - > data - > str , src - > data - > used + 1 ) ;
offset = ( ( void * ) ast_str_buffer ( dst - > data ) ) - ( ( void * ) ast_str_buffer ( src - > data ) ) ;
dst - > data - > used = src - > data - > used ;
offset = ( ( void * ) dst - > data - > str ) - ( ( void * ) src - > data - > str ) ;
/* Now fix pointer arithmetic */
/* Now fix pointer arithmetic */
for ( x = 0 ; x < src - > headers ; x + + )
for ( x = 0 ; x < src - > headers ; x + + )
dst - > header [ x ] + = offset ;
dst - > header [ x ] + = offset ;
@ -9694,7 +9659,7 @@ static void initreqprep(struct sip_request *req, struct sip_pvt *p, int sipmetho
/* This is the request URI, which is the next hop of the call
/* This is the request URI, which is the next hop of the call
which may or may not be the destination of the call
which may or may not be the destination of the call
*/
*/
ast_string_field_set ( p , uri , ast_str_buffer ( invite ) ) ;
ast_string_field_set ( p , uri , invite - > str ) ;
if ( ! ast_strlen_zero ( p - > todnid ) ) {
if ( ! ast_strlen_zero ( p - > todnid ) ) {
/*! \todo Need to add back the VXML URL here at some point, possibly use build_string for all this junk */
/*! \todo Need to add back the VXML URL here at some point, possibly use build_string for all this junk */
@ -9977,8 +9942,8 @@ static int find_calling_channel(struct ast_channel *c, void *data) {
/*! \brief Used in the SUBSCRIBE notification subsystem (RFC3265) */
/*! \brief Used in the SUBSCRIBE notification subsystem (RFC3265) */
static int transmit_state_notify ( struct sip_pvt * p , int state , int full , int timeout )
static int transmit_state_notify ( struct sip_pvt * p , int state , int full , int timeout )
{
{
struct ast_str * tmp = ast_str_ thread_get( & transmit_state_buffer , 4000 ) ;
struct ast_str * tmp = ast_str_ alloca( 4000 ) ;
char from [ 256 ] = " " , to [ 256 ] = " " ;
char from [ 256 ] , to [ 256 ] ;
char * c , * mfrom , * mto ;
char * c , * mfrom , * mto ;
struct sip_request req ;
struct sip_request req ;
char hint [ AST_MAX_EXTENSION ] ;
char hint [ AST_MAX_EXTENSION ] ;
@ -9988,6 +9953,9 @@ static int transmit_state_notify(struct sip_pvt *p, int state, int full, int tim
char * pidfstate = " -- " ;
char * pidfstate = " -- " ;
char * pidfnote = " Ready " ;
char * pidfnote = " Ready " ;
memset ( from , 0 , sizeof ( from ) ) ;
memset ( to , 0 , sizeof ( to ) ) ;
switch ( state ) {
switch ( state ) {
case ( AST_EXTENSION_RINGING | AST_EXTENSION_INUSE ) :
case ( AST_EXTENSION_RINGING | AST_EXTENSION_INUSE ) :
statestring = ( global_notifyringing ) ? " early " : " confirmed " ;
statestring = ( global_notifyringing ) ? " early " : " confirmed " ;
@ -10177,8 +10145,8 @@ static int transmit_state_notify(struct sip_pvt *p, int state, int full, int tim
break ;
break ;
}
}
add_header_contentLength ( & req , ast_str_strlen ( tmp ) ) ;
add_header_contentLength ( & req , tmp - > used ) ;
add_line ( & req , ast_str_buffer ( tmp ) ) ;
add_line ( & req , tmp - > str ) ;
p - > pendinginvite = p - > ocseq ; /* Remember that we have a pending NOTIFY in order not to confuse the NOTIFY subsystem */
p - > pendinginvite = p - > ocseq ; /* Remember that we have a pending NOTIFY in order not to confuse the NOTIFY subsystem */
@ -10216,8 +10184,8 @@ static int transmit_notify_with_mwi(struct sip_pvt *p, int newmsgs, int oldmsgs,
add_header ( & req , " Subscription-State " , " terminated;reason=timeout " ) ;
add_header ( & req , " Subscription-State " , " terminated;reason=timeout " ) ;
}
}
add_header_contentLength ( & req , ast_str_strlen ( out ) ) ;
add_header_contentLength ( & req , out - > used ) ;
add_line ( & req , ast_str_buffer ( out ) ) ;
add_line ( & req , out - > str ) ;
if ( ! p - > initreq . headers )
if ( ! p - > initreq . headers )
initialize_initreq ( p , & req ) ;
initialize_initreq ( p , & req ) ;
@ -11484,7 +11452,7 @@ static enum check_auth_result check_auth(struct sip_pvt *p, struct sip_request *
if ( res = = AST_DYNSTR_BUILD_FAILED )
if ( res = = AST_DYNSTR_BUILD_FAILED )
return AUTH_SECRET_FAILED ; /*! XXX \todo need a better return code here */
return AUTH_SECRET_FAILED ; /*! XXX \todo need a better return code here */
c = ast_str_buffer ( buf ) ;
c = buf - > str ;
while ( c & & * ( c = ast_skip_blanks ( c ) ) ) { /* lookup for keys */
while ( c & & * ( c = ast_skip_blanks ( c ) ) ) { /* lookup for keys */
for ( i = keys ; i - > key ! = NULL ; i + + ) {
for ( i = keys ; i - > key ! = NULL ; i + + ) {
@ -13975,7 +13943,7 @@ static char *sip_qualify_peer(struct ast_cli_entry *e, int cmd, struct ast_cli_a
}
}
/*! \brief list peer mailboxes to CLI */
/*! \brief list peer mailboxes to CLI */
static char * peer_mailboxes_to_str ( struct ast_str * * mailbox_str , struct sip_peer * peer )
static void peer_mailboxes_to_str ( struct ast_str * * mailbox_str , struct sip_peer * peer )
{
{
struct sip_mailbox * mailbox ;
struct sip_mailbox * mailbox ;
@ -13986,7 +13954,6 @@ static char *peer_mailboxes_to_str(struct ast_str **mailbox_str, struct sip_peer
S_OR ( mailbox - > context , " " ) ,
S_OR ( mailbox - > context , " " ) ,
AST_LIST_NEXT ( mailbox , entry ) ? " , " : " " ) ;
AST_LIST_NEXT ( mailbox , entry ) ? " , " : " " ) ;
}
}
return ast_str_buffer ( * mailbox_str ) ;
}
}
/*! \brief Show one peer in detail (main function) */
/*! \brief Show one peer in detail (main function) */
@ -14023,7 +13990,7 @@ static char *_sip_show_peer(int type, int fd, struct mansession *s, const struct
}
}
}
}
if ( peer & & type = = 0 ) { /* Normal listing */
if ( peer & & type = = 0 ) { /* Normal listing */
struct ast_str * mailbox_str = ast_str_ thread_get( & mailbox_buffer , 16 ) ;
struct ast_str * mailbox_str = ast_str_ alloca( 512 ) ;
ast_cli ( fd , " \n \n " ) ;
ast_cli ( fd , " \n \n " ) ;
ast_cli ( fd , " * Name : %s \n " , peer - > name ) ;
ast_cli ( fd , " * Name : %s \n " , peer - > name ) ;
if ( realtimepeers ) { /* Realtime is enabled */
if ( realtimepeers ) { /* Realtime is enabled */
@ -14052,7 +14019,8 @@ static char *_sip_show_peer(int type, int fd, struct mansession *s, const struct
print_group ( fd , peer - > callgroup , 0 ) ;
print_group ( fd , peer - > callgroup , 0 ) ;
ast_cli ( fd , " Pickupgroup : " ) ;
ast_cli ( fd , " Pickupgroup : " ) ;
print_group ( fd , peer - > pickupgroup , 0 ) ;
print_group ( fd , peer - > pickupgroup , 0 ) ;
ast_cli ( fd , " Mailbox : %s \n " , peer_mailboxes_to_str ( & mailbox_str , peer ) ) ;
peer_mailboxes_to_str ( & mailbox_str , peer ) ;
ast_cli ( fd , " Mailbox : %s \n " , mailbox_str - > str ) ;
ast_cli ( fd , " VM Extension : %s \n " , peer - > vmexten ) ;
ast_cli ( fd , " VM Extension : %s \n " , peer - > vmexten ) ;
ast_cli ( fd , " LastMsgsSent : %d/%d \n " , ( peer - > lastmsgssent & 0x7fff0000 ) > > 16 , peer - > lastmsgssent & 0xffff ) ;
ast_cli ( fd , " LastMsgsSent : %d/%d \n " , ( peer - > lastmsgssent & 0x7fff0000 ) > > 16 , peer - > lastmsgssent & 0xffff ) ;
ast_cli ( fd , " Call limit : %d \n " , peer - > call_limit ) ;
ast_cli ( fd , " Call limit : %d \n " , peer - > call_limit ) ;
@ -14138,7 +14106,7 @@ static char *_sip_show_peer(int type, int fd, struct mansession *s, const struct
peer = unref_peer ( peer , " sip_show_peer: unref_peer: done with peer ptr " ) ;
peer = unref_peer ( peer , " sip_show_peer: unref_peer: done with peer ptr " ) ;
} else if ( peer & & type = = 1 ) { /* manager listing */
} else if ( peer & & type = = 1 ) { /* manager listing */
char buffer [ 256 ] ;
char buffer [ 256 ] ;
struct ast_str * mailbox_str = ast_str_ thread_get( & mailbox_buffer , 16 ) ;
struct ast_str * mailbox_str = ast_str_ alloca( 512 ) ;
astman_append ( s , " Channeltype: SIP \r \n " ) ;
astman_append ( s , " Channeltype: SIP \r \n " ) ;
astman_append ( s , " ObjectName: %s \r \n " , peer - > name ) ;
astman_append ( s , " ObjectName: %s \r \n " , peer - > name ) ;
astman_append ( s , " ChanObjectType: peer \r \n " ) ;
astman_append ( s , " ChanObjectType: peer \r \n " ) ;
@ -14159,7 +14127,8 @@ static char *_sip_show_peer(int type, int fd, struct mansession *s, const struct
astman_append ( s , " %s \r \n " , ast_print_group ( buffer , sizeof ( buffer ) , peer - > callgroup ) ) ;
astman_append ( s , " %s \r \n " , ast_print_group ( buffer , sizeof ( buffer ) , peer - > callgroup ) ) ;
astman_append ( s , " Pickupgroup: " ) ;
astman_append ( s , " Pickupgroup: " ) ;
astman_append ( s , " %s \r \n " , ast_print_group ( buffer , sizeof ( buffer ) , peer - > pickupgroup ) ) ;
astman_append ( s , " %s \r \n " , ast_print_group ( buffer , sizeof ( buffer ) , peer - > pickupgroup ) ) ;
astman_append ( s , " VoiceMailbox: %s \r \n " , peer_mailboxes_to_str ( & mailbox_str , peer ) ) ;
peer_mailboxes_to_str ( & mailbox_str , peer ) ;
astman_append ( s , " VoiceMailbox: %s \r \n " , mailbox_str - > str ) ;
astman_append ( s , " TransferMode: %s \r \n " , transfermode2str ( peer - > allowtransfer ) ) ;
astman_append ( s , " TransferMode: %s \r \n " , transfermode2str ( peer - > allowtransfer ) ) ;
astman_append ( s , " LastMsgsSent: %d \r \n " , peer - > lastmsgssent ) ;
astman_append ( s , " LastMsgsSent: %d \r \n " , peer - > lastmsgssent ) ;
astman_append ( s , " Call-limit: %d \r \n " , peer - > call_limit ) ;
astman_append ( s , " Call-limit: %d \r \n " , peer - > call_limit ) ;
@ -14726,7 +14695,7 @@ static int show_channels_cb(void *__cur, void *__arg, int flags)
arg - > numchans + + ;
arg - > numchans + + ;
}
}
if ( cur - > subscribed ! = NONE & & arg - > subscriptions ) {
if ( cur - > subscribed ! = NONE & & arg - > subscriptions ) {
struct ast_str * mailbox_str = ast_str_ thread_get( & mailbox_buffer , 16 ) ;
struct ast_str * mailbox_str = ast_str_ alloca( 512 ) ;
if ( cur - > subscribed = = MWI_NOTIFICATION & & cur - > relatedpeer )
if ( cur - > subscribed = = MWI_NOTIFICATION & & cur - > relatedpeer )
peer_mailboxes_to_str ( & mailbox_str , cur - > relatedpeer ) ;
peer_mailboxes_to_str ( & mailbox_str , cur - > relatedpeer ) ;
ast_cli ( arg - > fd , FORMAT4 , ast_inet_ntoa ( dst - > sin_addr ) ,
ast_cli ( arg - > fd , FORMAT4 , ast_inet_ntoa ( dst - > sin_addr ) ,
@ -14736,7 +14705,7 @@ static int show_channels_cb(void *__cur, void *__arg, int flags)
cur - > subscribed = = MWI_NOTIFICATION ? " -- " : cur - > subscribeuri ,
cur - > subscribed = = MWI_NOTIFICATION ? " -- " : cur - > subscribeuri ,
cur - > subscribed = = MWI_NOTIFICATION ? " <none> " : ast_extension_state2str ( cur - > laststate ) ,
cur - > subscribed = = MWI_NOTIFICATION ? " <none> " : ast_extension_state2str ( cur - > laststate ) ,
subscription_type2str ( cur - > subscribed ) ,
subscription_type2str ( cur - > subscribed ) ,
cur - > subscribed = = MWI_NOTIFICATION ? A S_OR( mailbox_ str, " <none> " ) : " <none> " ,
cur - > subscribed = = MWI_NOTIFICATION ? S_OR( mailbox_ str- > str, " <none> " ) : " <none> " ,
cur - > expiry
cur - > expiry
) ;
) ;
arg - > numchans + + ;
arg - > numchans + + ;
@ -15822,8 +15791,9 @@ static int function_sippeer(struct ast_channel *chan, const char *cmd, char *dat
} else if ( ! strcasecmp ( colname , " useragent " ) ) {
} else if ( ! strcasecmp ( colname , " useragent " ) ) {
ast_copy_string ( buf , peer - > useragent , len ) ;
ast_copy_string ( buf , peer - > useragent , len ) ;
} else if ( ! strcasecmp ( colname , " mailbox " ) ) {
} else if ( ! strcasecmp ( colname , " mailbox " ) ) {
struct ast_str * mailbox_str = ast_str_thread_get ( & mailbox_buffer , 16 ) ;
struct ast_str * mailbox_str = ast_str_alloca ( 512 ) ;
ast_copy_string ( buf , peer_mailboxes_to_str ( & mailbox_str , peer ) , len ) ;
peer_mailboxes_to_str ( & mailbox_str , peer ) ;
ast_copy_string ( buf , mailbox_str - > str , len ) ;
} else if ( ! strcasecmp ( colname , " context " ) ) {
} else if ( ! strcasecmp ( colname , " context " ) ) {
ast_copy_string ( buf , peer - > context , len ) ;
ast_copy_string ( buf , peer - > context , len ) ;
} else if ( ! strcasecmp ( colname , " expire " ) ) {
} else if ( ! strcasecmp ( colname , " expire " ) ) {
@ -18122,12 +18092,12 @@ static int do_magic_pickup(struct ast_channel *channel, const char *extension, c
ast_str_set ( & str , 0 , " %s@%s " , extension , context ) ;
ast_str_set ( & str , 0 , " %s@%s " , extension , context ) ;
ast_debug ( 2 , " About to call Pickup(%s) \n " , ast_str_buffer ( str ) ) ;
ast_debug ( 2 , " About to call Pickup(%s) \n " , str - > str ) ;
/* There is no point in capturing the return value since pickup_exec
/* There is no point in capturing the return value since pickup_exec
doesn ' t return anything meaningful unless the passed data is an empty
doesn ' t return anything meaningful unless the passed data is an empty
string ( which in our case it will not be ) */
string ( which in our case it will not be ) */
pbx_exec ( channel , pickup , ast_str_buffer ( str ) ) ;
pbx_exec ( channel , pickup , str - > str ) ;
return 0 ;
return 0 ;
}
}
@ -20229,7 +20199,7 @@ static int sipsock_read(int *id, int fd, short events, void *ignore)
return 1 ;
return 1 ;
}
}
if ( ast_str_set ( & req . data , - 1 , " %s " , readbuf ) = = AST_DYNSTR_BUILD_FAILED ) {
if ( ast_str_set ( & req . data , 0 , " %s " , readbuf ) = = AST_DYNSTR_BUILD_FAILED ) {
return - 1 ;
return - 1 ;
}
}
@ -20262,11 +20232,11 @@ static int handle_request_do(struct sip_request *req, struct sockaddr_in *sin)
if ( sip_debug_test_addr ( sin ) ) /* Set the debug flag early on packet level */
if ( sip_debug_test_addr ( sin ) ) /* Set the debug flag early on packet level */
req - > debug = 1 ;
req - > debug = 1 ;
if ( sip_cfg . pedanticsipchecking )
if ( sip_cfg . pedanticsipchecking )
req - > len = lws2sws ( ast_str_buffer ( req - > data ) , req - > len ) ; /* Fix multiline headers */
req - > len = lws2sws ( req - > data - > str , req - > len ) ; /* Fix multiline headers */
if ( req - > debug ) {
if ( req - > debug ) {
ast_verbose ( " \n <--- SIP read from %s:%s:%d ---> \n %s \n <-------------> \n " ,
ast_verbose ( " \n <--- SIP read from %s:%s:%d ---> \n %s \n <-------------> \n " ,
get_transport ( req - > socket . type ) , ast_inet_ntoa ( sin - > sin_addr ) ,
get_transport ( req - > socket . type ) , ast_inet_ntoa ( sin - > sin_addr ) ,
ntohs ( sin - > sin_port ) , ast_str_buffer ( req - > data ) ) ;
ntohs ( sin - > sin_port ) , req - > data - > str ) ;
}
}
if ( parse_request ( req ) = = - 1 ) { /* Bad packet, can't parse */
if ( parse_request ( req ) = = - 1 ) { /* Bad packet, can't parse */
@ -20313,7 +20283,7 @@ static int handle_request_do(struct sip_request *req, struct sockaddr_in *sin)
p - > recv = * sin ;
p - > recv = * sin ;
if ( p - > do_history ) /* This is a request or response, note what it was for */
if ( p - > do_history ) /* This is a request or response, note what it was for */
append_history ( p , " Rx " , " %s / %s / %s " , ast_str_buffer ( req - > data ) , get_header ( req , " CSeq " ) , req - > rlPart2 ) ;
append_history ( p , " Rx " , " %s / %s / %s " , req - > data - > str , get_header ( req , " CSeq " ) , req - > rlPart2 ) ;
if ( ! lockretry ) {
if ( ! lockretry ) {
if ( p - > owner )
if ( p - > owner )
@ -20558,8 +20528,9 @@ static int sip_send_mwi_to_peer(struct sip_peer *peer, const struct ast_event *e
} else if ( cache_only ) {
} else if ( cache_only ) {
return 0 ;
return 0 ;
} else { /* Fall back to manually checking the mailbox */
} else { /* Fall back to manually checking the mailbox */
struct ast_str * mailbox_str = ast_str_thread_get ( & mailbox_buffer , 16 ) ;
struct ast_str * mailbox_str = ast_str_alloca ( 512 ) ;
ast_app_inboxcount ( peer_mailboxes_to_str ( & mailbox_str , peer ) , & newmsgs , & oldmsgs ) ;
peer_mailboxes_to_str ( & mailbox_str , peer ) ;
ast_app_inboxcount ( mailbox_str - > str , & newmsgs , & oldmsgs ) ;
}
}
if ( peer - > mwipvt ) {
if ( peer - > mwipvt ) {
@ -22003,7 +21974,7 @@ static struct sip_peer *build_peer(const char *name, struct ast_variable *v, str
ast_copy_string ( peer - > name , v - > value , sizeof ( peer - > name ) ) ;
ast_copy_string ( peer - > name , v - > value , sizeof ( peer - > name ) ) ;
else if ( realtime & & ! strcasecmp ( v - > name , " fullcontact " ) ) {
else if ( realtime & & ! strcasecmp ( v - > name , " fullcontact " ) ) {
/* Reconstruct field, because realtime separates our value at the ';' */
/* Reconstruct field, because realtime separates our value at the ';' */
if ( ast_str_strlen ( fullcontact ) > 0 ) {
if ( fullcontact - > used > 0 ) {
ast_str_append ( & fullcontact , 0 , " ;%s " , v - > value ) ;
ast_str_append ( & fullcontact , 0 , " ;%s " , v - > value ) ;
} else {
} else {
ast_str_set ( & fullcontact , 0 , " %s " , v - > value ) ;
ast_str_set ( & fullcontact , 0 , " %s " , v - > value ) ;
@ -22285,8 +22256,8 @@ static struct sip_peer *build_peer(const char *name, struct ast_variable *v, str
peer - > socket . type = default_primary_transport ;
peer - > socket . type = default_primary_transport ;
}
}
if ( ast_str_strlen ( fullcontact ) > 0 ) {
if ( fullcontact - > used > 0 ) {
ast_string_field_set ( peer , fullcontact , ast_str_buffer ( fullcontact ) ) ;
ast_string_field_set ( peer , fullcontact , fullcontact - > str ) ;
peer - > rt_fromcontact = TRUE ;
peer - > rt_fromcontact = TRUE ;
/* We have a hostname in the fullcontact, but if we don't have an
/* We have a hostname in the fullcontact, but if we don't have an
* address listed on the entry ( or if it ' s ' dynamic ' ) , then we need to
* address listed on the entry ( or if it ' s ' dynamic ' ) , then we need to
@ -22295,7 +22266,7 @@ static struct sip_peer *build_peer(const char *name, struct ast_variable *v, str
* register once again ) . */
* register once again ) . */
/* XXX May need to revisit the final argument; does the realtime DB store whether
/* XXX May need to revisit the final argument; does the realtime DB store whether
* the original contact was over TLS or not ? XXX */
* the original contact was over TLS or not ? XXX */
__set_address_from_contact ( ast_str_buffer ( fullcontact ) , & peer - > addr , 0 ) ;
__set_address_from_contact ( fullcontact - > str , & peer - > addr , 0 ) ;
}
}
if ( srvlookup & & peer - > dnsmgr = = NULL ) {
if ( srvlookup & & peer - > dnsmgr = = NULL ) {