예제 #1
0
        /// <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);
                }
            }
        }
예제 #2
0
        /// <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);
                }
            }
        }