Details
-
Type:
Bug
-
Status:
Closed
-
Priority:
Minor
-
Resolution: Fixed
-
Affects Version/s: None
-
Fix Version/s: None
-
Component/s: None
-
Labels:None
-
Platform:Linux x86/gcc
-
CPU Info:
-
FreeSWITCH GIT Revision:0e4fa9e23bd0bc2f3c639e47ee764552f6384755
-
Reproduced with GIT HEAD?:yes
Description
A call is negotiated and bridged with bypass_media mode between two peers that then both try to re-invite each other with new SDP (t.38 fax, but that is not relevant as we're in bypass_media mode).
If one leg reinvites far enough ahead of the other, the other's reinvite is rejected with a 491 and it is then sent a reinvite, and the call proceeds.
If, however, the two peers manage to pretty much simultaneously reinvite each other, there is a race between the sofia endpoints accepting the incoming invites and the internal messages between the two legs of the bridge to pass across the new invites and SDP and call do_invite/nua_invite on the other end.
One leg's sofia endpoint receives a reinvite with new SDP. This queues a sofia event that triggers the sending of a message to the other leg that causes do_invite/nua_invite to be called on the other leg's sofia endpoint.
However, if that other endpoint receives its own reinvite whilst the other leg's event and message are in flight, then the call to nua_invite will silently fail as the endpoint is in the wrong callstate to send an invite, leaving the first leg expecting a reply that will never happen.
In addition, the message sent in the other direction will result in a call to nua_invite that will ALSO silently fail as its endpoint is also not in a state to send invites. Both legs thus sit there doing nothing until the peers give up and hangup the call.
The manner in which nua_invite fails does not appear to generate any sort of sofia event, and there appears to be no way of programmatically extracting a hint that it has failed from the nua handle, even though nua will happily write a log message indicating that it rejected the invite, if you turn the logging up to full(!)
So the only way to detect the failure is to remember that a nua_invite was attempted and then notice if the state machine moves into a state that is not consistent with having sent an invite.
The attached patch creates a new TFLAG_REINVITED that is set on receipt of an incoming reinvite event from sofia, *provided that the other leg of the bridge has not already set that flag itself*. If a leg finds itself to have lost the invite race, a 491 is sent, allowing the nua_invite that is about to happen to succeed.
If, from the state the losing leg finds itself in, it can infer that a message has already been sent and nua_invite has already failed, a 491 is sent, followed by a retry of the call to do_invite.
If one leg reinvites far enough ahead of the other, the other's reinvite is rejected with a 491 and it is then sent a reinvite, and the call proceeds.
If, however, the two peers manage to pretty much simultaneously reinvite each other, there is a race between the sofia endpoints accepting the incoming invites and the internal messages between the two legs of the bridge to pass across the new invites and SDP and call do_invite/nua_invite on the other end.
One leg's sofia endpoint receives a reinvite with new SDP. This queues a sofia event that triggers the sending of a message to the other leg that causes do_invite/nua_invite to be called on the other leg's sofia endpoint.
However, if that other endpoint receives its own reinvite whilst the other leg's event and message are in flight, then the call to nua_invite will silently fail as the endpoint is in the wrong callstate to send an invite, leaving the first leg expecting a reply that will never happen.
In addition, the message sent in the other direction will result in a call to nua_invite that will ALSO silently fail as its endpoint is also not in a state to send invites. Both legs thus sit there doing nothing until the peers give up and hangup the call.
The manner in which nua_invite fails does not appear to generate any sort of sofia event, and there appears to be no way of programmatically extracting a hint that it has failed from the nua handle, even though nua will happily write a log message indicating that it rejected the invite, if you turn the logging up to full(!)
So the only way to detect the failure is to remember that a nua_invite was attempted and then notice if the state machine moves into a state that is not consistent with having sent an invite.
The attached patch creates a new TFLAG_REINVITED that is set on receipt of an incoming reinvite event from sofia, *provided that the other leg of the bridge has not already set that flag itself*. If a leg finds itself to have lost the invite race, a 491 is sent, allowing the nua_invite that is about to happen to succeed.
If, from the state the losing leg finds itself in, it can infer that a message has already been sent and nua_invite has already failed, a 491 is sent, followed by a retry of the call to do_invite.
Branch: refs/heads/master
Commit: 8203475 http://fisheye.freeswitch.org/changelog/freeswitch.git/?cs=8203475
Closed By: anthm@freeswitch.org
Comment:
FS-4148--resolve note: see switch_core_session_get_partnerFreeSWITCH Support Contracts and Consulting Services available!
Contact us:
Email: consulting@freeswitch.org
Web: http://www.freeswitch.org
Phone: +1-918-420-9266
Tollfree: +1-877-742-2583
Fax: +1-918-420-9267
iNum: +883 5100 1420 9266
Come To ClueCon in August to learn more about FreeSWITCH and Internet Telephony!
http://www.cluecon.com