Package com.ericsson.ssa.sip

Source Code of com.ericsson.ssa.sip.RecordRouteResolver

/*
* DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS HEADER.
*
* Copyright 1997-2009 Sun Microsystems, Inc. All rights reserved.
* Copyright (c) Ericsson AB, 2004-2008. All rights reserved.
*
* The contents of this file are subject to the terms of either the GNU
* General Public License Version 2 only ("GPL") or the Common Development
* and Distribution License("CDDL") (collectively, the "License").  You
* may not use this file except in compliance with the License. You can obtain
* a copy of the License at https://glassfish.dev.java.net/public/CDDL+GPL.html
* or glassfish/bootstrap/legal/LICENSE.txt.  See the License for the specific
* language governing permissions and limitations under the License.
*
* When distributing the software, include this License Parameterable Notice in each
* file and include the License file at glassfish/bootstrap/legal/LICENSE.txt.
* Sun designates this particular file as subject to the "Classpath" exception
* as provided by Sun in the GPL Version 2 section of the License file that
* accompanied this code.  If applicable, add the following below the License
* Parameterable, with the fields enclosed by brackets [] replaced by your own
* identifying information: "Portions Copyrighted [year]
* [name of copyright owner]"
*
* Contributor(s):
*
* If you wish your version of this file to be governed by only the CDDL or
* only the GPL Version 2, indicate your decision by adding "[Contributor]
* elects to include this software in this distribution under the [CDDL or GPL
* Version 2] license."  If you don't indicate a single choice of license, a
* recipient has the option to distribute your version of this file under
* either the CDDL, the GPL Version 2 or to extend the choice of license to
* its licensees as provided above.  However, if you add GPL Version 2 code
* and therefore, elected the GPL Version 2 license, then the option applies
* only if the new code is made subject to such option by the copyright
* holder.
*/
package com.ericsson.ssa.sip;

import com.ericsson.ssa.config.ConvergedContext;
import com.ericsson.ssa.container.OutboundFlowManager;
import com.ericsson.ssa.sip.dns.SipTransports;
import com.ericsson.ssa.sip.dns.TargetTuple;
import java.util.ListIterator;
import java.util.logging.Level;
import java.util.logging.Logger;
import javax.servlet.sip.Address;
import javax.servlet.sip.SipURI;
import javax.servlet.sip.TooManyHopsException;
import org.jvnet.glassfish.comms.util.LogUtil;

/**
* UAC (TCP) -------- Proxy (sailfin) ----------- UAS (UDP)
* In the scenarios like above, the record-route inserted by
* the server should be according to the different ends of the
* proxy.
*
* The design is to allow developer to add a property in
* sun-sip.xml to indicate what kind of policy should be adopted
* for electing the transport of the record-route.
*
* Besides static TCP or UDP, the other policy supported is "rewrite".
* It indicate that the transport is rewritten according to the
* ends of the proxy.
*
* Eg: sun-sip.xml element.
* <sip-app>
*    <property name="record-route-policy" value="rewrite"/>
* </sip-app>
*
* In the future, "double record routing" can also be supported as
* a policy, especially to handle multihome scenarios.
*
* Transport of the RR is rewritten for all outgoing requests and
* responses of the proxy, if the sun-sip.xml contains the policy
* parameter.
*
* @author binod
*/
public class RecordRouteResolver {

   
    private static Logger logger = LogUtil.SIP_LOGGER.getLogger();
   
    /**
     * This is invoked typically for out-going requests and is
     * invoked from TargetResolver.
     *
     * @param req
     * @param tt
     */
    public static void resolveTransport(SipServletRequestImpl req,
    TargetTuple tt) {
        try {
            if (req.isContactIndicated() || !req.isRecordRouteIndicated()) {
                return;
            }

            OutboundFlowManager ofm = OutboundFlowManager.getInstance();
            ofm.addFlowOnRecordRoute(req);
      
            String sp = getPolicyFromApp(req);
            if (sp.equals("")) {               
                return;
            }

            Address rrHeader = req.getAddressHeaderImpl(Header.RECORD_ROUTE);

            if (rrHeader == null) {
                if (logger.isLoggable(Level.FINE)) {
                    logger.log(Level.FINE, "Record-Route is null. Returning");
                }               
                return;
            }

            SipURI uri = null;
            if (rrHeader.getURI().isSipURI()) {
                uri = (SipURI) rrHeader.getURI();
            }

            if (uri == null) {               
                if (logger.isLoggable(Level.FINER)) {
                    logger.log(Level.FINER, "Record-Route URI is not SIP?");
                }  
                return;
            }

            RecordRoutePolicy policy = getPolicy(sp);

            switch (policy) {               
                case TCP:
                    uri.setTransportParam("tcp");
                    break;
                case UDP:
                    uri.setTransportParam("udp");
                    break;
                case REWRITE:
                    String transport = getTransport(tt);
                    if (transport != null) {
                        uri.setTransportParam(transport);
                    }
                    break;
            }
            if (logger.isLoggable(Level.FINE)) {
                logger.log(Level.FINE,
                "Resolved out-going reqest's Record-Route :" + uri);
            }
        } catch (Throwable t) {
            logger.log(Level.WARNING, t.getMessage(), t);
        }
    }
   
    /**
     * This is invoked for outgoing responses. It is invoked from
     * SipBindingResolver.
     *
     * @param resp
     */
    public static void resolveTransport(SipServletResponseImpl resp) {       
        try {           
            SipServletRequestImpl req = resp.getRequestImpl();
            if (req == null || !isProxy(req)) {
                return;
            }
           
            TargetTuple tt = req.getInitialRemote();
            if (!tt.getProtocol().name().equals(SipTransports.UDP_PROT.name())) {               
                resolveTransport(resp, tt);
            } else {
                logger.log(Level.FINER, "UDP transport. RR will be resolved " +
                " from TargetResolver");
            }
        } catch (Throwable t) {
            logger.log(Level.WARNING, t.getMessage(), t);
        }
    }
   
    private static boolean isProxy(SipServletRequestImpl req)
    throws TooManyHopsException {
        return req !=null && req.getProxyContext() != null;
    }

    /**
     * This is invoked for outgoing responses. It is invoked from
     * TargetResolver. Normally for UDP path, resolution happens.
     * So, this is needed.
     *
     * @param resp
     */
    public static void resolveTransport(SipServletResponseImpl resp,
    TargetTuple tt) {
                       
        try {
            SipServletRequestImpl req = resp.getRequestImpl();           
            if (req == null || !isProxy(req)) {                
                return;
            }
           
            String sp = getPolicyFromApp(resp);
            if (sp.equals("")) {               
                return;
            }                       
           
            ListIterator<Address> rrs =
            resp.getAddressHeaders(Header.RECORD_ROUTE);
            while (rrs.hasNext()) {
                AddressImpl a = (AddressImpl) rrs.next();
                if (a.isContainerAddress()) { // Should we also check fid
                    SipURI uri = (SipURI) a.getURI();                   
                    RecordRoutePolicy policy = getPolicy(sp);

                    switch (policy) {                       
                        case TCP:
                            uri.setTransportParam("tcp");
                            break;
                        case UDP:
                            uri.setTransportParam("udp");
                            break;
                        case REWRITE:
                            String transport = getTransport(tt);
                            if (transport != null) {                               
                                uri.setTransportParam(transport);                               
                            }
                            break;
                    }
                    if (logger.isLoggable(Level.FINE)) {
                        logger.log(Level.FINE,
                        "Resolved out-going response' Record-Route :" + uri);
                    }
                   
                    return;
                }
            }
        } catch (Throwable t) {
            logger.log(Level.WARNING, t.getMessage(), t);
        }
    }
   
    enum RecordRoutePolicy {
         TCP, UDP, REWRITE, DOUBLERR
    }
   
    static String getTransport(TargetTuple tt) {       
        if (tt.getProtocol().name().equals("udp")) {
            return "udp";
        } else {
            return "tcp";
        }
        //For TLS transport would be tcp.
    }
   
    private static String getPolicyFromApp(SipServletMessageImpl msg) {
        try {
            SipApplicationSessionImpl sas = msg.getApplicationSessionImpl();
            SipSessionManager ssm = sas.getSipSessionManager();
            ConvergedContext ctx = ssm.getContext();

            return ctx.getSipApplication().getRecordRoutePolicy();
        } catch (Throwable t) {
            return "";
        }
    }
   
    //Extract the policy from sun-sip.xml
    private static RecordRoutePolicy getPolicy(String policy) {       
        if (logger.isLoggable(Level.FINER)) {
            logger.log(Level.FINER,
            "Record-Route Policy in the sun-sip.xml is :" + policy);
        }
               
        return RecordRoutePolicy.valueOf(policy.toUpperCase());                       
    }
}
TOP

Related Classes of com.ericsson.ssa.sip.RecordRouteResolver

TOP
Copyright © 2018 www.massapi.com. All rights reserved.
All source code are property of their respective owners. Java is a trademark of Sun Microsystems, Inc and owned by ORACLE Inc. Contact coftware#gmail.com.