@ -98,14 +98,14 @@ sip_trans* trans_bucket::match_request(sip_msg* msg)
}
if ( msg - > u . request - > method ! = ( * it ) - > msg - > u . request - > method ) {
if ( ( * it ) - > msg - > u . request - > method = = sip_request : : INVITE ) {
if ( msg - > u . request - > method = = sip_request : : ACK ) {
if ( ( t = match_200_ack ( * it , msg ) ) )
break ;
} else if ( msg - > u . request - > method = = sip_request : : PR ACK) {
if ( ( t = match_1xx_pr ack( * it , msg ) ) )
break ;
}
// ACK is the only request that should match an existing
// transaction without being a re-transmission
if ( ( ( * it ) - > msg - > u . request - > method = = sip_request : : INVITE )
& & ( msg - > u . request - > method = = sip_request : : ACK)
& & ( t = match_200_ ack( * it , msg ) ) ) {
break ;
}
continue ;
@ -335,48 +335,63 @@ sip_trans* trans_bucket::match_200_ack(sip_trans* t, sip_msg* msg)
return t ;
}
sip_trans * trans_bucket : : match_1xx_prack ( sip_ trans* t , sip_ msg* msg )
sip_trans * trans_bucket : : match_1xx_prack ( sip_ msg* msg )
{
/* first, check quickly if lenghts match (From tag, To tag, Call-ID) */
sip_from_to * from = dynamic_cast < sip_from_to * > ( msg - > from - > p ) ;
sip_from_to * t_from = dynamic_cast < sip_from_to * > ( t - > msg - > from - > p ) ;
if ( from - > tag . len ! = t_from - > tag . len )
return 0 ;
sip_from_to * to = dynamic_cast < sip_from_to * > ( msg - > to - > p ) ;
if ( to - > tag . len ! = t - > to_tag . len )
return 0 ;
if ( msg - > callid - > value . len ! = t - > msg - > callid - > value . len )
return 0 ;
DBG ( " Matching %.*s request \n " ,
msg - > u . request - > method_str . len ,
msg - > u . request - > method_str . s ) ;
sip_rack * rack = dynamic_cast < sip_rack * > ( msg - > rack - > p ) ;
sip_cseq * t_cseq = dynamic_cast < sip_cseq * > ( t - > msg - > cseq - > p ) ;
if ( rack - > cseq ! = t_cseq - > num )
return 0 ;
if ( elmts . empty ( ) )
return NULL ;
trans_list : : iterator it = elmts . begin ( ) ;
for ( ; it ! = elmts . end ( ) ; + + it ) {
if ( ( * it ) - > msg - > type ! = SIP_REQUEST ) {
continue ;
}
sip_trans * t = * it ;
if ( rack - > rseq ! = t - > last_rseq )
return 0 ;
/* first, check quickly if lenghts match (From tag, To tag, Call-ID) */
if ( rack - > method ! = t - > msg - > u . request - > method )
return 0 ;
sip_from_to * from = dynamic_cast < sip_from_to * > ( msg - > from - > p ) ;
sip_from_to * t_from = dynamic_cast < sip_from_to * > ( t - > msg - > from - > p ) ;
if ( from - > tag . len ! = t_from - > tag . len )
continue ;
sip_from_to * to = dynamic_cast < sip_from_to * > ( msg - > to - > p ) ;
if ( to - > tag . len ! = t - > to_tag . len )
continue ;
if ( msg - > callid - > value . len ! = t - > msg - > callid - > value . len )
continue ;
/* numbers fit, try content */
sip_rack * rack = dynamic_cast < sip_rack * > ( msg - > rack - > p ) ;
sip_cseq * t_cseq = dynamic_cast < sip_cseq * > ( t - > msg - > cseq - > p ) ;
if ( rack - > cseq ! = t_cseq - > num )
continue ;
if ( rack - > rseq ! = t - > last_rseq )
continue ;
if ( rack - > method ! = t - > msg - > u . request - > method )
continue ;
/* numbers fit, try content */
if ( memcmp ( from - > tag . s , t_from - > tag . s , from - > tag . len ) )
continue ;
if ( memcmp ( msg - > callid - > value . s , t - > msg - > callid - > value . s ,
msg - > callid - > value . len ) )
continue ;
if ( memcmp ( to - > tag . s , t - > to_tag . s , to - > tag . len ) )
continue ;
if ( memcmp ( from - > tag . s , t_from - > tag . s , from - > tag . len ) )
return NULL ;
return t ;
}
if ( memcmp ( msg - > callid - > value . s , t - > msg - > callid - > value . s ,
msg - > callid - > value . len ) )
return NULL ;
if ( memcmp ( to - > tag . s , t - > to_tag . s , to - > tag . len ) )
return NULL ;
return t ;
return NULL ;
}
sip_trans * trans_bucket : : add_trans ( sip_msg * msg , int ttype )