Beispiel #1
0
        private void NatKeepAliveChannelMessageReceived(SIPChannel sipChannel, SIPEndPoint remoteEndPoint, byte[] buffer)
        {
            try
            {
                NATKeepAliveMessage keepAliveMessage = NATKeepAliveMessage.ParseNATKeepAliveMessage(buffer);

                if (keepAliveMessage != null)
                {
                    if (keepAliveMessage.LocalSIPEndPoint.Protocol == SIPProtocolsEnum.udp)
                    {
                        FireSIPMonitorLogEvent(new SIPMonitorConsoleEvent(SIPMonitorServerTypesEnum.NATKeepAlive, SIPMonitorEventTypesEnum.NATKeepAliveRelay, "Relaying NAT keep-alive from proxy socket " + keepAliveMessage.LocalSIPEndPoint + " to " + keepAliveMessage.RemoteEndPoint + ".", null));
                        m_sipTransport.SendRaw(keepAliveMessage.LocalSIPEndPoint, new SIPEndPoint(keepAliveMessage.RemoteEndPoint), m_sendBuffer);
                    }
                    else
                    {
                        // For connection oriented protocols check whether a connection exists. NAT keep alives shouldn't cause a connection to be initiated.
                        SIPChannel sendFromChannel = m_sipTransport.FindSIPChannel(keepAliveMessage.LocalSIPEndPoint);
                        if (sendFromChannel != null && sendFromChannel.IsConnectionEstablished(keepAliveMessage.RemoteEndPoint))
                        {
                            FireSIPMonitorLogEvent(new SIPMonitorConsoleEvent(SIPMonitorServerTypesEnum.NATKeepAlive, SIPMonitorEventTypesEnum.NATKeepAliveRelay, "Relaying NAT keep-alive from proxy socket " + keepAliveMessage.LocalSIPEndPoint + " to " + keepAliveMessage.RemoteEndPoint + ".", null));
                            m_sipTransport.SendRaw(keepAliveMessage.LocalSIPEndPoint, new SIPEndPoint(keepAliveMessage.RemoteEndPoint), m_sendBuffer);
                        }
                        else
                        {
                            FireSIPMonitorLogEvent(new SIPMonitorConsoleEvent(SIPMonitorServerTypesEnum.NATKeepAlive, SIPMonitorEventTypesEnum.NATKeepAliveRelay, "No established connection was found to relay NAT keep-alive from proxy socket " + keepAliveMessage.LocalSIPEndPoint + " to " + keepAliveMessage.RemoteEndPoint + ".", null));
                        }
                    }
                }
            }
            catch (Exception excp)
            {
                logger.Error("Exception NatKeepAliveChannelMessageReceived. " + excp.Message);
            }
        }
        /// <summary>
        /// Used to send a request from an internal server agent to an external SIP user agent. The difference between this method and
        /// the SendTransparent method is that this one will set Via headers in accordance with RFC3261.
        /// </summary>
        /// <param name="receivedOnEP">The proxy SIP end point the request was received on.</param>
        /// <param name="dstSocket">The SIP end point the request is being sent to.</param>
        /// <param name="sipRequest">The SIP request to send.</param>
        /// <param name="proxyBranch">The branch parameter for the top Via header that has been pre-calculated by the proxy core.</param>
        /// <param name="sendFromSocket">The proxy SIP end point to send this request from. If the SIP request has its ProxySendFrom header
        /// value set that will overrule this parameter.</param>
        public void SendExternal(SIPEndPoint receivedOnEP, SIPEndPoint dstSIPEndPoint, SIPRequest sipRequest, string proxyBranch, IPAddress publicIPAddress)
        {
            try
            {
                if (!IsDestinationValid(sipRequest, dstSIPEndPoint))
                {
                    logger.Debug("SendExternal failed destination check.");
                    return;
                }

                // Determine the external SIP endpoint that the proxy will use to send this request.
                SIPEndPoint localSIPEndPoint = m_sipTransport.GetDefaultSIPEndPoint(dstSIPEndPoint);
                if (!sipRequest.Header.ProxySendFrom.IsNullOrBlank())
                {
                    SIPChannel proxyChannel = m_sipTransport.FindSIPChannel(SIPEndPoint.ParseSIPEndPoint(sipRequest.Header.ProxySendFrom));
                    if (proxyChannel == null)
                    {
                        logger.Warn("No SIP channel could be found for\n" + sipRequest.ToString());
                    }
                    localSIPEndPoint = (proxyChannel != null) ? proxyChannel.SIPChannelEndPoint : localSIPEndPoint;
                }

                if (receivedOnEP != localSIPEndPoint)
                {
                    // The proxy is being requested to send the request on a different socket to the one it was received on.
                    // A second Via header is added to ensure the response can navigate back the same path. The calculated branch
                    // parameter needs to go on the top Via header so that whichever internal socket the request is being sent to can
                    // determine re-transmits.
                    SIPViaHeader via = new SIPViaHeader(receivedOnEP, CallProperties.CreateBranchId());
                    sipRequest.Header.Vias.PushViaHeader(via);

                    SIPViaHeader externalVia = new SIPViaHeader(localSIPEndPoint, proxyBranch);
                    sipRequest.Header.Vias.PushViaHeader(externalVia);
                }
                else
                {
                    // Only a single Via header is required as any response to this request will be sent from the same socket it gets received on.
                    SIPViaHeader via = new SIPViaHeader(localSIPEndPoint, proxyBranch);
                    sipRequest.Header.Vias.PushViaHeader(via);
                }

                if (sipRequest.Method != SIPMethodsEnum.REGISTER)
                {
                    AdjustContactHeader(sipRequest.Header, localSIPEndPoint, publicIPAddress);
                }

                sipRequest.LocalSIPEndPoint = localSIPEndPoint;

                // Proxy sepecific headers that don't need to be seen by external UAs.
                sipRequest.Header.ProxyReceivedOn   = null;
                sipRequest.Header.ProxyReceivedFrom = null;
                sipRequest.Header.ProxySendFrom     = null;

                m_sipTransport.SendRequest(dstSIPEndPoint, sipRequest);
            }
            catch (Exception excp)
            {
                logger.Error("Exception SIPRequest SendExternal. " + excp.Message);
                logger.Error(sipRequest.ToString());
                throw;
            }
        }