Start line:  
End line:  

Snippet Preview

Snippet HTML Code

Stack Overflow Questions
  /*
   * Conditions Of Use
   *
   * This software was developed by employees of the National Institute of
   * Standards and Technology (NIST), an agency of the Federal Government.
   * Pursuant to title 15 Untied States Code Section 105, works of NIST
   * employees are not subject to copyright protection in the United States
   * and are considered to be in the public domain.  As a result, a formal
   * license is not needed to use the software.
  *
  * This software is provided by NIST as a service and is expressly
  * provided "AS IS."  NIST MAKES NO WARRANTY OF ANY KIND, EXPRESS, IMPLIED
  * OR STATUTORY, INCLUDING, WITHOUT LIMITATION, THE IMPLIED WARRANTY OF
  * MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE, NON-INFRINGEMENT
  * AND DATA ACCURACY.  NIST does not warrant or make any representations
  * regarding the use of the software or the results thereof, including but
  * not limited to the correctness, accuracy, reliability or usefulness of
  * the software.
  *
  * Permission to use this software is contingent upon your acceptance
  * of the terms of this agreement
  *
  * .
  *
  */
Product of NIST/ITL Advanced Networking Technologies Division (ANTD). * /
 
 package gov.nist.javax.sip.stack;
 
 
 import javax.sip.*;
 
 
 /*
  * Bug reported by Will Scullin -- maddr was being ignored when routing
  * requests. Bug reported by Antonis Karydas - the RequestURI can be a non-sip
  * URI Jiang He - use address in route header. Significant changes to conform to
  * RFC 3261 made by Jeroen van Bemmel. Hagai Sela contributed a bug fix to the
  * strict route post processing code.
  *
  */

This is the default router. When the implementation wants to forward a request and had run out of othe options, then it calls this method to figure out where to send the request. The default router implements a simple "default routing algorithm" which just forwards to the configured proxy address.

When javax.sip.USE_ROUTER_FOR_ALL_URIS is set to false, the next hop is determined according to the following algorithm:

  • If the request contains one or more Route headers, use the URI of the topmost Route header as next hop, possibly modifying the request in the process if the topmost Route header contains no lr parameter(*)
  • Else, if the property javax.sip.OUTBOUND_PROXY is set, use its value as the next hop
  • Otherwise, use the request URI as next hop. If the request URI is not a SIP URI, call javax.sip.address.Router.getNextHop(javax.sip.message.Request) provided by the application.

(*)Note that in case the topmost Route header contains no 'lr' parameter (which means the next hop is a strict router), the implementation will perform 'Route Information Postprocessing' as described in RFC3261 section 16.6 step 6 (also known as "Route header popping"). That is, the following modifications will be made to the request:

  1. The implementation places the Request-URI into the Route header field as the last value.
  2. The implementation then places the first Route header field value into the Request-URI and removes that value from the Route header field.
Subsequently, the request URI will be used as next hop target

Author(s):
M. Ranganathan
Version:
1.2 $Revision: 1.18.2.1 $ $Date: 2010-11-23 19:23:11 $
 
 public class DefaultRouter implements Router {
    private SIPTransactionStack sipStack;
    private Hop defaultRoute;
    private DefaultRouter() {
    }

    
Constructor.
    public DefaultRouter(SipStack sipStackString defaultRoute) {
        this. = (SIPTransactionStacksipStack;
        if (defaultRoute != null) {
            try {
                this. = (Hopthis..getAddressResolver()
                        .resolveAddress((Hop) (new HopImpl(defaultRoute)));
            } catch (IllegalArgumentException ex) {
                // The outbound proxy is optional. If specified it should be host:port/transport.
                ((SIPTransactionStacksipStack)
                        .getStackLogger()
                        .logError(
                                "Invalid default route specification - need host:port/transport");
                throw ex;
            }
        }
    }

    
Return addresses for default proxy to forward the request to. The list is organized in the following priority. If the requestURI refers directly to a host, the host and port information are extracted from it and made the next hop on the list. If the default route has been specified, then it is used to construct the next element of the list. RouteHeader firstRoute = (RouteHeader) req.getHeader( RouteHeader.NAME ); if (firstRoute!=null) { URI uri = firstRoute.getAddress().getURI(); if (uri.isSIPUri()) { SipURI nextHop = (SipURI) uri; if ( nextHop.hasLrParam() ) { // OK, use it } else { nextHop = fixStrictRouting( req ); <--- Here, make the modifications as per RFC3261 } } else { // error: non-SIP URI not allowed in Route headers throw new SipException( "Request has Route header with non-SIP URI" ); } } else if (outboundProxy!=null) { // use outbound proxy for nextHop } else if ( req.getRequestURI().isSipURI() ) { // use request URI for nextHop }

Parameters:
request is the sip request to route.
    public Hop getNextHop(Request requestthrows SipException {
        SIPRequest sipRequest = (SIPRequestrequest;
        RequestLine requestLine = sipRequest.getRequestLine();
        if (requestLine == null) {
            return ;
        }
        javax.sip.address.URI requestURI = requestLine.getUri();
        if (requestURI == null)
            throw new IllegalArgumentException("Bad message: Null requestURI");
        RouteList routes = sipRequest.getRouteHeaders();
        /*
         * In case the topmost Route header contains no 'lr' parameter (which
         * means the next hop is a strict router), the implementation will
         * perform 'Route Information Postprocessing' as described in RFC3261
         * section 16.6 step 6 (also known as "Route header popping"). That is,
         * the following modifications will be made to the request:
         *
         * The implementation places the Request-URI into the Route header field
         * as the last value.
         *
         * The implementation then places the first Route header field value
         * into the Request-URI and removes that value from the Route header
         * field.
         *
         * Subsequently, the request URI will be used as next hop target
         */
        if (routes != null) {
            // to send the request through a specified hop the application is
            // supposed to prepend the appropriate Route header which.
            Route route = (Routeroutes.getFirst();
            URI uri = route.getAddress().getURI();
            if (uri.isSipURI()) {
                SipURI sipUri = (SipURIuri;
                if (!sipUri.hasLrParam()) {
                    fixStrictRouting(sipRequest);
                    if (.isLoggingEnabled(.))
                        .getStackLogger()
                                .logDebug("Route post processing fixed strict routing");
                }
                Hop hop = createHop(sipUri,request);
                if (.isLoggingEnabled(.))
                    .getStackLogger()
                            .logDebug("NextHop based on Route:" + hop);
                return hop;
            } else {
                throw new SipException("First Route not a SIP URI");
            }
        } else if (requestURI.isSipURI()
                && ((SipURIrequestURI).getMAddrParam() != null) {
            Hop hop = createHop((SipURIrequestURI,request);
            if (.isLoggingEnabled(.))
                .getStackLogger()
                        .logDebug("Using request URI maddr to route the request = "
                                + hop.toString());
            // JvB: don't remove it!
            // ((SipURI) requestURI).removeParameter("maddr");
            return hop;
        } else if ( != null) {
            if (.isLoggingEnabled(.))
                .getStackLogger()
                        .logDebug("Using outbound proxy to route the request = "
                                + .toString());
            return ;
        } else if (requestURI.isSipURI()) {
            Hop hop = createHop((SipURIrequestURI,request);
            if (hop != null && .isLoggingEnabled(.))
                .getStackLogger().logDebug("Used request-URI for nextHop = "
                        + hop.toString());
            else if (.isLoggingEnabled(.)) {
                .getStackLogger()
                        .logDebug("returning null hop -- loop detected");
            }
            return hop;
        } else {
            // The internal router should never be consulted for non-sip URIs.
            InternalErrorHandler.handleException("Unexpected non-sip URI",
                    this..getStackLogger());
            return null;
        }
    }

    
Performs strict router fix according to RFC3261 section 16.6 step 6 pre: top route header in request has no 'lr' parameter in URI post: request-URI added as last route header, new req-URI = top-route-URI
    public void fixStrictRouting(SIPRequest req) {
        RouteList routes = req.getRouteHeaders();
        Route first = (Routeroutes.getFirst();
        SipUri firstUri = (SipUrifirst.getAddress().getURI();
        routes.removeFirst();
        // Add request-URI as last Route entry
        AddressImpl addr = new AddressImpl();
        addr.setAddess(req.getRequestURI()); // don't clone it
        Route route = new Route(addr);
        routes.add(route); // as last one
        req.setRequestURI(firstUri);
            .getStackLogger().logDebug("post: fixStrictRouting" + req);
        }
    }

    
Utility method to create a hop from a SIP URI

Parameters:
sipUri
Returns:
    private final Hop createHop(SipURI sipUriRequest request) {
        // always use TLS when secure
        String transport = sipUri.isSecure() ? . : sipUri
                .getTransportParam();
        if (transport == null) {
            //@see issue 131
            ViaHeader via = (ViaHeaderrequest.getHeader(.);
            transport = via.getTransport();
        }
        // sipUri.removeParameter("transport");
        int port;
        if (sipUri.getPort() != -1) {
            port = sipUri.getPort();
        } else {
            if (transport.equalsIgnoreCase(.))
                port = 5061;
            else
                port = 5060; // TCP or UDP
        }
        String host = sipUri.getMAddrParam() != null ? sipUri.getMAddrParam()
                : sipUri.getHost();
        AddressResolver addressResolver = this..getAddressResolver();
        return addressResolver
                .resolveAddress(new HopImpl(hostporttransport));
    }

    
Get the default hop.

Returns:
defaultRoute is the default route. public java.util.Iterator getDefaultRoute(Request request) { return this.getNextHops((SIPRequest)request); }
    public javax.sip.address.Hop getOutboundProxy() {
        return this.;
    }
    /*
     * (non-Javadoc)
     *
     * @see javax.sip.address.Router#getNextHop(javax.sip.message.Request)
     */
    public ListIterator getNextHops(Request request) {
        try {
            LinkedList llist = new LinkedList();
            llist.add(this.getNextHop(request));
            return llist.listIterator();
        } catch (SipException ex) {
            return null;
        }
    }
New to GrepCode? Check out our FAQ X