The SIPRoute class is used to represent both Route and Record-Route headers.
The Route and Record-Route headers only have parameters, no headers. Parameters of from ...;name=value;name2=value2 There are no specific parameters.
 public void AddBottomRoute(SIPRoute route)
 {
     m_sipRoutes.Insert(m_sipRoutes.Count, route);
 }
 public void SetAt(int index, SIPRoute sipRoute)
 {
     m_sipRoutes[index] = sipRoute;
 }
 public void PushRoute(SIPRoute route)
 {
     m_sipRoutes.Insert(0, route);
 }
			public void MissingBracketsRouteTest()
			{
				Console.WriteLine("--> " + System.Reflection.MethodBase.GetCurrentMethod().Name);

				SIPRoute newRoute = new SIPRoute("sip:127.0.0.1:5060");

                Console.WriteLine(newRoute.ToString());

                Assert.IsTrue(newRoute.URI.ToString() == "sip:127.0.0.1:5060", "The Route header URI was not correctly parsed.");
			}
        public static SIPRoute ParseSIPRoute(string route)
        {
            if (route.IsNullOrBlank())
            {
                throw new SIPValidationException(SIPValidationFieldsEnum.RouteHeader, "Cannot create a Route from an blank string.");
            }

            try
            {
                SIPRoute sipRoute = new SIPRoute();
                sipRoute.m_userField = SIPUserField.ParseSIPUserField(route);

                return sipRoute;
            }
            catch (Exception excp)
            {
                throw new SIPValidationException(SIPValidationFieldsEnum.RouteHeader, excp.Message);
            }
        }
Beispiel #6
0
        /// <summary>
        /// This function performs processing on a request to handle any actions that need to be taken based on the Route header.
        /// </summary>
        /// <remarks>
        /// The main sections in the RFC3261 dealing with Route header processing are sections 12.2.1.1 for request processing and
        /// 16.4 for proxy processing.
        /// The steps to process requests for Route headers are:
        ///  1. If route set is empty no further action is required, forward to destination resolved from request URI,
        ///  2. If the request URI is identified as a value that was previously set as a Route by this SIP agent it means the
        ///     previous hop was a strict router. Replace the reqest URI with the last Route header and go to next step,
        ///  3. If the top most route header was set by this SIP agent then remove it and go to next step,
        ///  4. If the top most route set does contain the lr parameter then forward to the destination resolved by it,
        ///  5. If the top most route header does NOT contain the lr parameter is must be popped and inserted as the request URI
        ///     and the original request URI must be added to the end of the route set, forward to destination resolved from request URI,
        /// </remarks>
        public void PreProcessRouteInfo(SIPRequest sipRequest)
        {
            // If there are no routes defined then there is nothing to do.
            if (sipRequest.Header.Routes != null && sipRequest.Header.Routes.Length > 0)
            {
                // If this stack's route URI is being used as the request URI then it will have the loose route parameter (see remarks step 2).
                if (sipRequest.URI.Parameters.Has(m_looseRouteParameter))
                {
                    foreach (SIPChannel sipChannel in m_sipChannels.Values)
                    {
                        if (sipRequest.URI.ToSIPEndPoint() == sipChannel.SIPChannelEndPoint)
                        {
                            // The request URI was this router's address so it was set by a strict router.
                            // Replace the URI with the original SIP URI that is stored at the end of the route header.
                            sipRequest.URI = sipRequest.Header.Routes.BottomRoute.URI;
                            sipRequest.Header.Routes.RemoveBottomRoute();
                        }
                    }
                }

                // The possibility of a strict router on the previous hop has now been handled.
                if (sipRequest.Header.Routes != null && sipRequest.Header.Routes.Length > 0)
                {
                    // Check whether the top route header belongs to this proxy (see remarks step 3).
                    if (!sipRequest.Header.Routes.TopRoute.IsStrictRouter)
                    {
                        foreach (SIPChannel sipChannel in m_sipChannels.Values)
                        {
                            if (sipRequest.Header.Routes.TopRoute.ToSIPEndPoint() == sipChannel.SIPChannelEndPoint)
                            {
                                // Remove the top route as it belongs to this proxy.
                                sipRequest.ReceivedRoute = sipRequest.Header.Routes.PopRoute();
                                break;
                            }
                        }
                    }

                    // Check whether the top route header is a strict router and if so adjust the request accordingly (see remarks step 5).
                    if (sipRequest.Header.Routes != null && sipRequest.Header.Routes.Length > 0)
                    {
                        if (sipRequest.Header.Routes.TopRoute.IsStrictRouter)
                        {
                            // Put the strict router's uri into the request URI and place the original request URI at the end of the route set.
                            SIPRoute strictRoute = sipRequest.Header.Routes.PopRoute();
                            SIPRoute uriRoute = new SIPRoute(sipRequest.URI);
                            sipRequest.Header.Routes.AddBottomRoute(uriRoute);
                            sipRequest.URI = strictRoute.URI;
                        }
                    }
                }
            }
        }
        private SIPRequest GetRegistrationRequest(SIPProvider sipProvider, SIPProviderBinding binding, SIPEndPoint localSIPEndPoint, int expiry, SIPEndPoint registrarEndPoint)
        {
            try
            {
                if (!binding.BindingSIPURI.Parameters.Has(m_regAgentContactId))
                {
                    binding.BindingSIPURI.Parameters.Set(m_regAgentContactId, Crypto.GetRandomString(6));
                }

                string realm = binding.RegistrarRealm;

                SIPURI registerURI = SIPURI.ParseSIPURIRelaxed(realm);
                SIPURI regUserURI = SIPURI.ParseSIPURIRelaxed(sipProvider.ProviderUsername + "@" + realm);

                SIPFromHeader fromHeader = new SIPFromHeader(null, regUserURI, CallProperties.CreateNewTag());
                SIPToHeader toHeader = new SIPToHeader(null, regUserURI, null);
                SIPContactHeader contactHeader = new SIPContactHeader(null, binding.BindingSIPURI);
                //contactHeader.Expires = binding.BindingExpiry;
                string callId = binding.Id.ToString();
                int cseq = ++binding.CSeq;

                SIPRequest registerRequest = new SIPRequest(SIPMethodsEnum.REGISTER, registerURI);
                registerRequest.LocalSIPEndPoint = localSIPEndPoint;
                SIPHeader header = new SIPHeader(contactHeader, fromHeader, toHeader, cseq, callId);
                header.CSeqMethod = SIPMethodsEnum.REGISTER;
                header.UserAgent = m_userAgentString;
                header.Expires = binding.BindingExpiry;

                SIPViaHeader viaHeader = new SIPViaHeader(localSIPEndPoint, CallProperties.CreateBranchId());
                header.Vias.PushViaHeader(viaHeader);

                SIPRoute registrarRoute = new SIPRoute(new SIPURI(binding.RegistrarServer.Scheme, registrarEndPoint), true);
                header.Routes.PushRoute(registrarRoute);

                if (sipProvider != null && !sipProvider.CustomHeaders.IsNullOrBlank())
                {
                    string[] customerHeadersList = sipProvider.CustomHeaders.Split(SIPProvider.CUSTOM_HEADERS_SEPARATOR);

                    if (customerHeadersList != null && customerHeadersList.Length > 0)
                    {
                        foreach (string customHeader in customerHeadersList)
                        {
                            if (customHeader.IndexOf(':') == -1)
                            {
                                logger.Debug("Skipping custom header due to missing colon, " + customHeader + ".");
                                continue;
                            }
                            else
                            {
                                string headerName = customHeader.Substring(0, customHeader.IndexOf(':'));
                                if (headerName != null && Regex.Match(headerName.Trim(), "(Via|From|To|Contact|CSeq|Call-ID|Max-Forwards|Content)", RegexOptions.IgnoreCase).Success)
                                {
                                    logger.Debug("Skipping custom header due to an non-permitted string in header name, " + customHeader + ".");
                                    continue;
                                }
                                else
                                {
                                    if (headerName == SIPConstants.SIP_USERAGENT_STRING)
                                    {
                                        header.UserAgent = customHeader.Substring(customHeader.IndexOf(':') + 1);
                                    }
                                    else
                                    {
                                        header.UnknownHeaders.Add(customHeader.Trim());
                                    }
                                }
                            }
                        }
                    }
                }

                registerRequest.Header = header;
                return registerRequest;
            }
            catch (Exception excp)
            {
                logger.Error("Exception GetRegistrationRequest. " + excp.Message);
                throw excp;
            }
        }
 public void SetServiceRoute(SIPRoute serviceRoute)
 {
     m_serviceRoute = serviceRoute;
 }