/// <summary> /// This method is called when new request is received. /// </summary> /// <param name="e">Request event arguments.</param> private void OnRequestReceived(SIP_RequestReceivedEventArgs e) { SIP_Request request = e.Request; try{ #region Statefull // Statefull if ((m_ProxyMode & SIP_ProxyMode.Statefull) != 0) { // Statefull proxy is transaction statefull proxy only, // what don't create dialogs and keep dialog state. /* RFC 3261 16.10. * StateFull proxy: * If a matching response context is found, the element MUST * immediately return a 200 (OK) response to the CANCEL request. * * If a response context is not found, the element does not have any * knowledge of the request to apply the CANCEL to. It MUST statelessly * forward the CANCEL request (it may have statelessly forwarded the * associated request previously). */ if (e.Request.RequestLine.Method == SIP_Methods.CANCEL) { // Don't do server transaction before we get CANCEL matching transaction. SIP_ServerTransaction trToCancel = m_pStack.TransactionLayer.MatchCancelToTransaction(e.Request); if (trToCancel != null) { trToCancel.Cancel(); e.ServerTransaction.SendResponse(m_pStack.CreateResponse(SIP_ResponseCodes.x200_Ok, request)); } else { ForwardRequest(false, e, true); } } // ACK never creates transaction, it's always passed directly to transport layer. else if (e.Request.RequestLine.Method == SIP_Methods.ACK) { ForwardRequest(false, e, true); } else { ForwardRequest(true, e, true); } } #endregion #region B2BUA // B2BUA else if ((m_ProxyMode & SIP_ProxyMode.B2BUA) != 0) { m_pB2BUA.OnRequestReceived(e); } #endregion #region Stateless // Stateless else if ((m_ProxyMode & SIP_ProxyMode.Stateless) != 0) { // Stateless proxy don't do transaction, just forwards all. ForwardRequest(false, e, true); } #endregion #region Proxy won't accept command else { e.ServerTransaction.SendResponse(m_pStack.CreateResponse(SIP_ResponseCodes.x501_Not_Implemented, request)); } #endregion } catch (Exception x) { try{ m_pStack.TransportLayer.SendResponse(m_pStack.CreateResponse(SIP_ResponseCodes.x500_Server_Internal_Error + ": " + x.Message, e.Request)); } catch { // Skip transport layer exception if send fails. } // Don't raise OnError for transport errors. if (!(x is SIP_TransportException)) { m_pStack.OnError(x); } } }
/// <summary> /// This method is called when new request is received. /// </summary> /// <param name="e">Request event arguments.</param> private void OnRequestReceived(SIP_RequestReceivedEventArgs e) { /* RFC 3261 16.12. ????????? Forward does all thse steps. * 1. The proxy will inspect the Request-URI. If it indicates a * resource owned by this proxy, the proxy will replace it with * the results of running a location service. Otherwise, the * proxy will not change the Request-URI. * * 2. The proxy will inspect the URI in the topmost Route header * field value. If it indicates this proxy, the proxy removes it * from the Route header field (this route node has been reached). * * 3. The proxy will forward the request to the resource indicated * by the URI in the topmost Route header field value or in the * Request-URI if no Route header field is present. The proxy * determines the address, port and transport to use when * forwarding the request by applying the procedures in [4] to that URI. */ SIP_Request request = e.Request; try { #region Registrar // Registrar if ((m_ProxyMode & SIP_ProxyMode.Registrar) != 0 && request.RequestLine.Method == SIP_Methods.REGISTER) { m_pRegistrar.Register(e); } #endregion #region Presence /* * // Presence * else if((m_ProxyMode & SIP_ProxyMode.Presence) != 0 && (request.Method == "SUBSCRIBE" || request.Method == "NOTIFY")){ * * } */ #endregion #region Statefull // Statefull else if ((m_ProxyMode & SIP_ProxyMode.Statefull) != 0) { // Statefull proxy is transaction statefull proxy only, // what don't create dialogs and keep dialog state. /* RFC 3261 16.10. * StateFull proxy: * If a matching response context is found, the element MUST * immediately return a 200 (OK) response to the CANCEL request. * * If a response context is not found, the element does not have any * knowledge of the request to apply the CANCEL to. It MUST statelessly * forward the CANCEL request (it may have statelessly forwarded the * associated request previously). */ if (e.Request.RequestLine.Method == SIP_Methods.CANCEL) { // Don't do server transaction before we get CANCEL matching transaction. SIP_ServerTransaction trToCancel = m_pStack.TransactionLayer.MatchCancelToTransaction(e.Request); if (trToCancel != null) { trToCancel.Cancel(); e.ServerTransaction.SendResponse(m_pStack.CreateResponse( SIP_ResponseCodes.x200_Ok, request)); } else { ForwardRequest(false, e); } } // ACK never creates transaction, it's always passed directly to transport layer. else if (e.Request.RequestLine.Method == SIP_Methods.ACK) { ForwardRequest(false, e); } else { ForwardRequest(true, e); } } #endregion #region B2BUA // B2BUA else if ((m_ProxyMode & SIP_ProxyMode.B2BUA) != 0) { m_pB2BUA.OnRequestReceived(e); } #endregion #region Stateless // Stateless else if ((m_ProxyMode & SIP_ProxyMode.Stateless) != 0) { // Stateless proxy don't do transaction, just forwards all. ForwardRequest(false, e); } #endregion #region Proxy won't accept command else { e.ServerTransaction.SendResponse( m_pStack.CreateResponse(SIP_ResponseCodes.x501_Not_Implemented, request)); } #endregion } catch (Exception x) { try { m_pStack.TransportLayer.SendResponse( m_pStack.CreateResponse( SIP_ResponseCodes.x500_Server_Internal_Error + ": " + x.Message, e.Request)); } catch { // Skip transport layer exception if send fails. } // Don't raise OnError for transport errors. if (!(x is SIP_TransportException)) { m_pStack.OnError(x); } } }