Example #1
0
  /**
   * Performs strict router fix according to RFC3261 section 16.6 step 6
   *
   * <p>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 = (Route) routes.getFirst();
    SipUri firstUri = (SipUri) first.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);
    if (sipStack.isLoggingEnabled()) {
      sipStack.getStackLogger().logDebug("post: fixStrictRouting" + req);
    }
  }
Example #2
0
  /**
   * 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. <code>
   * 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
   * }
   *
   * </code>
   *
   * @param request is the sip request to route.
   */
  public Hop getNextHop(Request request) throws SipException {

    SIPRequest sipRequest = (SIPRequest) request;

    RequestLine requestLine = sipRequest.getRequestLine();
    if (requestLine == null) {
      return defaultRoute;
    }
    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 = (Route) routes.getFirst();
      URI uri = route.getAddress().getURI();
      if (uri.isSipURI()) {
        SipURI sipUri = (SipURI) uri;
        if (!sipUri.hasLrParam()) {

          fixStrictRouting(sipRequest);
          if (sipStack.isLoggingEnabled())
            sipStack.getStackLogger().logDebug("Route post processing fixed strict routing");
        }

        Hop hop = createHop(sipUri, request);
        if (sipStack.isLoggingEnabled())
          sipStack.getStackLogger().logDebug("NextHop based on Route:" + hop);
        return hop;
      } else {
        throw new SipException("First Route not a SIP URI");
      }

    } else if (requestURI.isSipURI() && ((SipURI) requestURI).getMAddrParam() != null) {
      Hop hop = createHop((SipURI) requestURI, request);
      if (sipStack.isLoggingEnabled())
        sipStack
            .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 (defaultRoute != null) {
      if (sipStack.isLoggingEnabled())
        sipStack
            .getStackLogger()
            .logDebug("Using outbound proxy to route the request = " + defaultRoute.toString());
      return defaultRoute;
    } else if (requestURI.isSipURI()) {
      Hop hop = createHop((SipURI) requestURI, request);
      if (hop != null && sipStack.isLoggingEnabled())
        sipStack.getStackLogger().logDebug("Used request-URI for nextHop = " + hop.toString());
      else if (sipStack.isLoggingEnabled()) {
        sipStack.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.sipStack.getStackLogger());
      return null;
    }
  }