Merged revisions 203116 via svnmerge from

https://origsvn.digium.com/svn/asterisk/trunk

................
  r203116 | russell | 2009-06-25 11:04:10 -0500 (Thu, 25 Jun 2009) | 18 lines
  
  Merged revisions 203115 via svnmerge from 
  https://origsvn.digium.com/svn/asterisk/branches/1.4
  
  ........
    r203115 | russell | 2009-06-25 11:02:16 -0500 (Thu, 25 Jun 2009) | 11 lines
    
    Resolve a crash related to a T.38 reinvite race condition.
    
    This change resolves a crash observed locally during some T.38 testing.
    A call was set up using a call file, and when the T.38 reinvite came in,
    the channel state was still AST_STATE_DOWN.  The reason is explained by
    a comment in the code that previously lived in the handling of
    AST_STATE_RINGING.  This change modifies the logic to handle the same
    race condition for any channel state that is not UP.
    
    (closes ABE-1895)
  ........
................


git-svn-id: https://origsvn.digium.com/svn/asterisk/branches/1.6.2@203119 65c4cc65-6c06-0410-ace0-fbb531ad65f3
1.6.2
Russell Bryant 17 years ago
parent 70d80ebe62
commit b3e3e5add6

@ -19519,7 +19519,23 @@ static int handle_request_invite(struct sip_pvt *p, struct sip_request *req, int
if (c) { /* We have a call -either a new call or an old one (RE-INVITE) */
switch(c->_state) {
enum ast_channel_state c_state = c->_state;
if (c_state != AST_STATE_UP && reinvite &&
(p->invitestate == INV_TERMINATED || p->invitestate == INV_CONFIRMED)) {
/* If these conditions are true, and the channel is still in the 'ringing'
* state, then this likely means that we have a situation where the initial
* INVITE transaction has completed *but* the channel's state has not yet been
* changed to UP. The reason this could happen is if the reinvite is received
* on the SIP socket prior to an application calling ast_read on this channel
* to read the answer frame we earlier queued on it. In this case, the reinvite
* is completely legitimate so we need to handle this the same as if the channel
* were already UP. Thus we are purposely falling through to the AST_STATE_UP case.
*/
c_state = AST_STATE_UP;
}
switch(c_state) {
case AST_STATE_DOWN:
ast_debug(2, "%s: New call is still down.... Trying... \n", c->name);
transmit_response(p, "100 Trying", req);
@ -19581,21 +19597,9 @@ static int handle_request_invite(struct sip_pvt *p, struct sip_request *req, int
p->invitestate = INV_PROCEEDING;
break;
case AST_STATE_RINGING:
if (reinvite && (p->invitestate == INV_TERMINATED || p->invitestate == INV_CONFIRMED)) {
/* If these conditions are true, and the channel is still in the 'ringing'
* state, then this likely means that we have a situation where the initial
* INVITE transaction has completed *but* the channel's state has not yet been
* changed to UP. The reason this could happen is if the reinvite is received
* on the SIP socket prior to an application calling ast_read on this channel
* to read the answer frame we earlier queued on it. In this case, the reinvite
* is completely legitimate so we need to handle this the same as if the channel
* were already UP. Thus we are purposely falling through to the AST_STATE_UP case.
*/
} else {
transmit_response(p, "180 Ringing", req);
p->invitestate = INV_PROCEEDING;
break;
}
transmit_response(p, "180 Ringing", req);
p->invitestate = INV_PROCEEDING;
break;
case AST_STATE_UP:
ast_debug(2, "%s: This call is UP.... \n", c->name);

Loading…
Cancel
Save