📄 proxy.java
字号:
package gov.nist.sip.proxy;import java.util.*;import javax.sip.*;import javax.sip.message.*;import javax.sip.header.*;import javax.sip.address.*;import org.apache.log4j.FileAppender;import org.apache.log4j.Level;import org.apache.log4j.Logger;import org.apache.log4j.SimpleLayout;import gov.nist.sip.proxy.registrar.*;import java.text.ParseException;import java.io.IOException;import gov.nist.sip.proxy.authentication.*;import gov.nist.sip.proxy.presenceserver.*;/** * Proxy Entry point. * * @version JAIN-SIP-1.2 * * @author Olivier Deruelle <deruelle@nist.gov> , M. Ranganathan, Henrik Leion * */public class Proxy implements SipListener { private static Logger logger = Logger.getLogger(Proxy.class); protected LinkedList listeningPoints; // Map the server transactions with the client transactions protected SipStack sipStack; protected SipProvider defaultProvider; protected MessageFactory messageFactory; protected HeaderFactory headerFactory; protected AddressFactory addressFactory; protected Configuration configuration; protected PresenceServer presenceServer; protected Registrar registrar; protected ProxyUtilities proxyUtilities; protected Authentication authentication; protected RequestForwarding requestForwarding; protected ResponseForwarding responseForwarding; public RequestForwarding getRequestForwarding() { return requestForwarding; } public ResponseForwarding getResponseForwarding() { return responseForwarding; } public AddressFactory getAddressFactory() { return addressFactory; } public MessageFactory getMessageFactory() { return messageFactory; } public HeaderFactory getHeaderFactory() { return headerFactory; } public Registrar getRegistrar() { return registrar; } public boolean isPresenceServer() { return configuration.enablePresenceServer; } public PresenceServer getPresenceServer() { return presenceServer; } public ProxyUtilities getProxyUtilities() { return proxyUtilities; } public SipStack getSipStack() { return sipStack; } public Configuration getConfiguration() { return configuration; } /** * get the first allocated provider. */ public SipProvider getSipProvider() { return this.defaultProvider; } public Authentication getAuthentication() { return authentication; } public boolean managesDomain(String domainAddress) { return configuration.hasDomain(domainAddress) || registrar.hasRegistration("sip:" + domainAddress); } /** Creates new Proxy */ public Proxy(String confFile) throws Exception { this.listeningPoints = new LinkedList(); if (confFile == null) { logger.fatal("ERROR: Set the configuration file flag: " + "USE: -cf configuration_file_location.xml"); } else { try { // First, let's parse the configuration file. ProxyConfigurationHandler handler = new ProxyConfigurationHandler( confFile); configuration = handler.getConfiguration(); if (configuration == null || !configuration.isValidConfiguration()) { logger .fatal("ERROR: the configuration file is not correct!" + " Correct the errors first."); throw new Exception( "ERROR: the configuration file is not correct!" + " Correct the errors first."); } else { proxyUtilities = new ProxyUtilities(this); presenceServer = new PresenceServer(this); registrar = new Registrar(this); requestForwarding = new RequestForwarding(this); responseForwarding = new ResponseForwarding(this); } } catch (Exception ex) { logger .fatal("ERROR: exception raised while initializing the proxy"); ex.printStackTrace(); throw new Exception( "ERROR: exception raised while initializing the proxy"); } } } /** * This is a listener method. */ public void processRequest(RequestEvent requestEvent) { Request request = requestEvent.getRequest(); SipProvider sipProvider = (SipProvider) requestEvent.getSource(); ServerTransaction serverTransaction = requestEvent .getServerTransaction(); try { if (logger.isDebugEnabled()) logger .debug("\n****************************************************" + "\nRequest " + request.getMethod() + " received:\n" + request.toString()); if (logger.isDebugEnabled()) ProxyUtilities.printTransaction(serverTransaction); /* * RFC 3261: 16.2: For all new requests, including any with unknown * methods, an element intending to proxy the request MUST: * * 1. Validate the request (Section 16.3) * * 2. Preprocess routing information (Section 16.4) * * 3. Determine target(s) for the request (Section 16.5) * * 4. Forward the request to each target (Section 16.6) * * 5. Process all responses (Section 16.7) */ /* * Before an element can proxy a request, it MUST verify the * message's validity */ RequestValidation requestValidation = new RequestValidation(this); if (!requestValidation.validateRequest(sipProvider, request, serverTransaction)) { // An appropriate response has been sent back by the request // validation step, so we just return. The request has been // processed! if (logger.isDebugEnabled()) logger .debug("Proxy, processRequest(), the request has not been" + " validated, so the request is discarded " + " (an error code has normally been" + " sent back)"); return; } // Let's check if the ACK is for the proxy: if there is no Route // header: it is mandatory for the ACK to be forwarded if (request.getMethod().equals(Request.ACK)) { ListIterator routes = request.getHeaders(RouteHeader.NAME); if (routes == null || !routes.hasNext()) { if (logger.isDebugEnabled()) logger.debug("Proxy, processRequest(), " + "the request is an ACK" + " targeted for the proxy, we ignore it"); return; } } if (serverTransaction == null) { String method = request.getMethod(); // Methods that creates dialogs, so that can // generate transactions try { serverTransaction = sipProvider .getNewServerTransaction(request); TransactionsMapping transactionsMapping = (TransactionsMapping) serverTransaction .getApplicationData(); if (transactionsMapping == null) { transactionsMapping = new TransactionsMapping(); serverTransaction .setApplicationData(transactionsMapping); } } catch (TransactionAlreadyExistsException e) { if (logger.isDebugEnabled()) logger.error("Proxy, processRequest(), this request" + " is a retransmission, we drop it!"); } } /** ************************************************************************ */ /** * **** 2. Preprocess routing information (Section 16.4) * ****************** */ /** ************************************************************************ */ /* * The proxy MUST inspect the Request-URI of the request. If the * Request-URI of the request contains a value this proxy previously * placed into a Record-Route header field (see Section 16.6 item * 4), the proxy MUST replace the Request-URI in the request with * the last value from the Route header field, and remove that value * from the Route header field. The proxy MUST then proceed as if it * received this modified request. ..... (idem to below:) 16.12. 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). */ ListIterator routes = request.getHeaders(RouteHeader.NAME); if (routes != null) { if (routes.hasNext()) { RouteHeader routeHeader = (RouteHeader) routes.next(); Address routeAddress = routeHeader.getAddress(); SipURI routeSipURI = (SipURI) routeAddress.getURI(); String host = routeSipURI.getHost(); int port = routeSipURI.getPort(); if (sipStack.getIPAddress().equals(host)) { Iterator lps = sipStack.getListeningPoints(); while (lps != null && lps.hasNext()) { ListeningPoint lp = (ListeningPoint) lps.next(); if (lp.getPort() == port) { if (logger.isDebugEnabled()) logger .debug("Proxy, processRequest()," + " we remove the first route form " + " the RouteHeader;" + " it matches the proxy"); routes.remove(); break; } } } } } /* * If the Request-URI contains a maddr parameter, the proxy MUST * check to see if its value is in the set of addresses or domains * the proxy is configured to be responsible for. If the Request-URI * has a maddr parameter with a value the proxy is responsible for, * and the request was received using the port and transport * indicated (explicitly or by default) in the Request-URI, the * proxy MUST strip the maddr and any non-default port or transport * parameter and continue processing as if those values had not been * present in the request. */ URI requestURI = request.getRequestURI(); if (requestURI.isSipURI()) { SipURI requestSipURI = (SipURI) requestURI; if (requestSipURI.getMAddrParam() != null) { // The domain the proxy is configured to be responsible for // is defined // by stack_domain parameter in the configuration file: if (configuration.hasDomain(requestSipURI.getMAddrParam())) { if (logger.isDebugEnabled()) logger .debug("Proxy, processRequest()," + " The maddr contains a domain we are responsible for," + " we remove the mAddr parameter from the original" + " request"); // We have to strip the madr parameter: requestSipURI.removeParameter("maddr"); // We have to strip the port parameter: if (requestSipURI.getPort() != 5060 && requestSipURI.getPort() != -1) { requestSipURI.setPort(5060); } // We have to strip the transport parameter: requestSipURI.removeParameter("transport"); } else { // The Maddr parameter is not a domain we have to take // care of, we pass this check... } } else { // No Maddr parameter, we pass this check... } } else { // No SipURI, so no Maddr parameter, we pass this check... } /** *************************************************************************** */ /** * *********** 3. Determine target(s) for the request (Section 16.5) * ********* */ /** ************************************************************************** */ /* * The set of targets will either be predetermined by the contents * of the request or will be obtained from an abstract location * service. Each target in the set is represented as a URI. */ Vector targetURIList = new Vector(); URI targetURI; /* * If the Request-URI of the request contains an maddr parameter, * the Request-URI MUST be placed into the target set as the only * target URI, and the proxy MUST proceed to Section 16.6. */ if (requestURI.isSipURI()) { SipURI requestSipURI = (SipURI) requestURI; if (requestSipURI.getMAddrParam() != null) { targetURI = requestURI; targetURIList.addElement(targetURI);
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -