private void UACInviteTransaction_TransactionFinalResponseReceived(SIPEndPoint localSIPEndPoint, SIPEndPoint remoteEndPoint, SIPTransaction sipTransaction, SIPResponse sipResponse)
{
try
{
// BranchId for 2xx responses needs to be a new one, non-2xx final responses use same one as original request.
SIPRequest ackRequest = null;
if (sipResponse.StatusCode >= 200 && sipResponse.StatusCode < 299)
{
if (sipResponse.Header.To != null)
{
m_remoteTag = sipResponse.Header.To.ToTag;
}
SIPURI ackURI = m_transactionRequest.URI;
if (sipResponse.Header.Contact != null && sipResponse.Header.Contact.Count > 0)
{
ackURI = sipResponse.Header.Contact[0].ContactURI;
// Don't mangle private contacts if there is a Record-Route header. If a proxy is putting private IP's in a Record-Route header that's its problem.
if ((sipResponse.Header.RecordRoutes == null || sipResponse.Header.RecordRoutes.Length == 0)
&& IPSocket.IsPrivateAddress(ackURI.Host) && !sipResponse.Header.ProxyReceivedFrom.IsNullOrBlank())
{
// Setting the Proxy-ReceivedOn header is how an upstream proxy will let an agent know it should mangle the contact.
SIPEndPoint remoteUASSIPEndPoint = SIPEndPoint.ParseSIPEndPoint(sipResponse.Header.ProxyReceivedFrom);
ackURI.Host = remoteUASSIPEndPoint.GetIPEndPoint().ToString();
}
}
// ACK for 2xx response needs to be a new transaction and gets routed based on SIP request fields.
ackRequest = GetNewTransactionACKRequest(sipResponse, ackURI, LocalSIPEndPoint);
base.SendRequest(ackRequest);
}
else
{
// ACK for non 2xx response is part of the INVITE transaction and gets routed to the same endpoint as the INVITE.
ackRequest = GetInTransactionACKRequest(sipResponse, m_transactionRequest.URI, LocalSIPEndPoint);
base.SendRequest(RemoteEndPoint, ackRequest);
}
if (UACInviteTransactionFinalResponseReceived != null)
{
UACInviteTransactionFinalResponseReceived(localSIPEndPoint, remoteEndPoint, sipTransaction, sipResponse);
}
if (CDR != null)
{
SIPEndPoint localEP = SIPEndPoint.TryParse(sipResponse.Header.ProxyReceivedOn) ?? localSIPEndPoint;
SIPEndPoint remoteEP = SIPEndPoint.TryParse(sipResponse.Header.ProxyReceivedFrom) ?? remoteEndPoint;
CDR.Answered(sipResponse.StatusCode, sipResponse.Status, sipResponse.ReasonPhrase, localEP, remoteEP);
}
}
catch (Exception excp)
{
logger.Error("Exception UACInviteTransaction_TransactionFinalResponseReceived. " + excp.Message);
}
}