Home | History | Annotate | Download | only in stack
      1 /*
      2 * Conditions Of Use
      3 *
      4 * This software was developed by employees of the National Institute of
      5 * Standards and Technology (NIST), an agency of the Federal Government.
      6 * Pursuant to title 15 Untied States Code Section 105, works of NIST
      7 * employees are not subject to copyright protection in the United States
      8 * and are considered to be in the public domain.  As a result, a formal
      9 * license is not needed to use the software.
     10 *
     11 * This software is provided by NIST as a service and is expressly
     12 * provided "AS IS."  NIST MAKES NO WARRANTY OF ANY KIND, EXPRESS, IMPLIED
     13 * OR STATUTORY, INCLUDING, WITHOUT LIMITATION, THE IMPLIED WARRANTY OF
     14 * MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE, NON-INFRINGEMENT
     15 * AND DATA ACCURACY.  NIST does not warrant or make any representations
     16 * regarding the use of the software or the results thereof, including but
     17 * not limited to the correctness, accuracy, reliability or usefulness of
     18 * the software.
     19 *
     20 * Permission to use this software is contingent upon your acceptance
     21 * of the terms of this agreement
     22 *
     23 * .
     24 *
     25 */
     26 package gov.nist.javax.sip.stack;
     27 
     28 import gov.nist.core.Host;
     29 import gov.nist.core.HostPort;
     30 import gov.nist.core.InternalErrorHandler;
     31 import gov.nist.javax.sip.ListeningPointImpl;
     32 import gov.nist.javax.sip.header.Via;
     33 
     34 import java.io.IOException;
     35 import java.net.InetAddress;
     36 import java.text.ParseException;
     37 
     38 import javax.sip.InvalidArgumentException;
     39 
     40 /**
     41  * This is the Stack abstraction for the active object that waits for messages
     42  * to appear on the wire and processes these messages by calling the
     43  * MessageFactory interface to create a ServerRequest or ServerResponse object.
     44  * The main job of the message processor is to instantiate message channels for
     45  * the given transport.
     46  *
     47  * @version 1.2 $Revision: 1.18 $ $Date: 2009/10/16 22:58:41 $
     48  *
     49  * @author M. Ranganathan <br/>
     50  *
     51  */
     52 public abstract class MessageProcessor implements Runnable {
     53     /**
     54      * A string containing the 0.0.0.0 IPv4 ANY address.
     55      */
     56     protected static final String IN_ADDR_ANY = "0.0.0.0";
     57 
     58     /**
     59      * A string containing the ::0 IPv6 ANY address.
     60      */
     61     protected static final String IN6_ADDR_ANY = "::0";
     62     /**
     63      * My Sent by string ( which I use to set the outgoing via header)
     64      */
     65     private  String sentBy;
     66 
     67     private HostPort sentByHostPort;
     68 
     69     /*
     70      * The IP Address that was originally assigned ( Can be ANY )
     71      */
     72 
     73     private String savedIpAddress;
     74 
     75     /**
     76      * The IP address where I am listening.
     77      */
     78     private InetAddress ipAddress;
     79 
     80     /**
     81      * The port where I am listening
     82      */
     83     private int port;
     84 
     85     /**
     86      * The transport where I am listening
     87      */
     88     protected String transport;
     89 
     90     /**
     91      * The Listening Point to which I am assigned.
     92      */
     93     private ListeningPointImpl listeningPoint;
     94 
     95     private boolean sentBySet;
     96 
     97     /**
     98      * Our stack (that created us).
     99      */
    100     protected SIPTransactionStack sipStack;
    101 
    102     protected MessageProcessor( String transport ) {
    103     	this.transport = transport;
    104     }
    105 
    106     /**
    107      * Constructor
    108      *
    109      * @param ipAddress -- ip address where I am listening for incoming requests.
    110      * @param port -- port where i am listening for incoming requests.
    111      * @param transport -- transport to use for the message processor (UDP/TCP/TLS).
    112      */
    113     protected MessageProcessor( InetAddress ipAddress, int port, String transport,
    114     							SIPTransactionStack transactionStack ) {
    115     	this( transport );
    116     	this.initialize(ipAddress, port, transactionStack);
    117     }
    118 
    119     /**
    120      * Initializes this MessageProcessor. Needed for extensions
    121      * that use classloading
    122      *
    123      * @param ipAddress2
    124      * @param transactionStack
    125      * @param port2
    126      */
    127 	public final void initialize( InetAddress ipAddress, int port,
    128 			SIPTransactionStack transactionStack ) {
    129 
    130 		this.sipStack = transactionStack;
    131         this.savedIpAddress = ipAddress.getHostAddress();
    132         this.ipAddress = ipAddress;
    133         this.port = port;
    134         this.sentByHostPort = new HostPort();
    135         this.sentByHostPort.setHost(new Host(ipAddress.getHostAddress()));
    136         this.sentByHostPort.setPort(port);
    137 	}
    138 
    139     /**
    140      * Get the transport string.
    141      *
    142      * @return A string that indicates the transport. (i.e. "tcp" or "udp")
    143      */
    144     public String getTransport() {
    145         return this.transport;
    146     }
    147 
    148     /**
    149      * Get the port identifier.
    150      *
    151      * @return the port for this message processor. This is where you receive
    152      *         messages.
    153      */
    154     public int getPort() {
    155         return this.port;
    156     }
    157 
    158     /**
    159      * Get the Via header to assign for this message processor. The topmost via
    160      * header of the outoging messages use this.
    161      *
    162      * @return the ViaHeader to be used by the messages sent via this message processor.
    163      */
    164     public Via getViaHeader() {
    165         try {
    166             Via via = new Via();
    167             if (this.sentByHostPort != null) {
    168                 via.setSentBy(sentByHostPort);
    169                 via.setTransport(this.getTransport());
    170             } else {
    171                 Host host = new Host();
    172                 host.setHostname(this.getIpAddress().getHostAddress());
    173                 via.setHost(host);
    174                 via.setPort(this.getPort());
    175                 via.setTransport(this.getTransport());
    176             }
    177             return via;
    178         } catch (ParseException ex) {
    179             ex.printStackTrace();
    180             return null;
    181         } catch (InvalidArgumentException ex) {
    182             ex.printStackTrace();
    183             return null;
    184         }
    185     }
    186     public ListeningPointImpl getListeningPoint() {
    187         if ( listeningPoint == null )  {
    188             if ( this.getSIPStack().isLoggingEnabled()) {
    189                 this.getSIPStack().getStackLogger().logError("getListeningPoint" + this +
    190                         " returning null listeningpoint");
    191 
    192             }
    193         }
    194         return listeningPoint;
    195     }
    196 
    197     public void setListeningPoint(ListeningPointImpl lp) {
    198         if ( this.getSIPStack().isLoggingEnabled()) {
    199             this.getSIPStack().getStackLogger().logDebug("setListeningPoint" + this +
    200                     " listeningPoint = " + lp);
    201 
    202         }
    203         if ( lp.getPort() != this.getPort())
    204             InternalErrorHandler.handleException
    205             ("lp mismatch with provider",getSIPStack().getStackLogger());
    206         this.listeningPoint = lp;
    207 
    208     }
    209 
    210     /**
    211      * Get the saved IP Address.
    212      */
    213     public String getSavedIpAddress() {
    214         return this.savedIpAddress;
    215     }
    216     /**
    217      * @return the ip address for this message processor.
    218      */
    219     public InetAddress getIpAddress() {
    220           return this.ipAddress;
    221     }
    222     /**
    223      * @param ipAddress the ipAddress to set
    224      */
    225     protected void setIpAddress(InetAddress ipAddress) {
    226         this.sentByHostPort.setHost( new Host(ipAddress.getHostAddress()));
    227         this.ipAddress = ipAddress;
    228     }
    229 
    230     /**
    231      * Set the sentby string. This is used for stamping outgoing messages sent
    232      * from this listening point.
    233      *
    234      * @param sentBy
    235      */
    236     public void setSentBy(String sentBy) throws ParseException {
    237 
    238         int ind = sentBy.indexOf(":");
    239         if (ind == -1) {
    240             this.sentByHostPort = new HostPort();
    241             this.sentByHostPort.setHost(new Host(sentBy));
    242         } else {
    243             this.sentByHostPort = new HostPort();
    244             this.sentByHostPort.setHost(new Host(sentBy.substring(0, ind)));
    245             String portStr = sentBy.substring(ind + 1);
    246             try {
    247                 int port = Integer.parseInt(portStr);
    248                 this.sentByHostPort.setPort(port);
    249             } catch (NumberFormatException ex) {
    250                 throw new ParseException("Bad format encountered at ", ind);
    251             }
    252         }
    253         this.sentBySet = true;
    254         this.sentBy = sentBy;
    255 
    256     }
    257 
    258     /**
    259      * Get the sentby string.
    260      *
    261      */
    262     public String getSentBy() {
    263         if ( this.sentBy == null && this.sentByHostPort != null) {
    264             this.sentBy = this.sentByHostPort.toString();
    265         }
    266         return this.sentBy;
    267     }
    268 
    269     ////////////////////////////////////////////////////////////////////////////////////////
    270     // Abstract methods
    271     ///////////////////////////////////////////////////////////////////////////////////////
    272     /**
    273      * Get the SIP Stack.
    274      *
    275      * @return the sip stack.
    276      */
    277     public abstract SIPTransactionStack getSIPStack();
    278 
    279     /**
    280      * Create a message channel for the specified host/port.
    281      *
    282      * @return New MessageChannel for this processor.
    283      */
    284     public abstract MessageChannel createMessageChannel(HostPort targetHostPort)
    285             throws IOException;
    286 
    287     /**
    288      * Create a message channel for the specified host/port.
    289      *
    290      * @return New MessageChannel for this processor.
    291      */
    292     public abstract MessageChannel createMessageChannel(InetAddress targetHost,
    293             int port) throws IOException;
    294 
    295 
    296     /**
    297      * Start our thread.
    298      */
    299     public abstract void start() throws IOException;
    300 
    301     /**
    302      * Stop method.
    303      */
    304     public abstract void stop();
    305 
    306     /**
    307      * Default target port used by this processor. This is 5060 for TCP / UDP
    308      */
    309     public abstract int getDefaultTargetPort();
    310 
    311     /**
    312      * Flags whether this processor is secure or not.
    313      */
    314     public abstract boolean isSecure();
    315 
    316     /**
    317      * Maximum number of bytes that this processor can handle.
    318      */
    319     public abstract int getMaximumMessageSize();
    320 
    321     /**
    322      * Return true if there are pending messages to be processed (which prevents
    323      * the message channel from being closed).
    324      */
    325     public abstract boolean inUse();
    326 
    327 
    328 
    329     /**
    330      * Run method.
    331      */
    332     public abstract void run();
    333 
    334     /**
    335      * @return Returns the sentBySet.
    336      */
    337     public boolean isSentBySet() {
    338         return sentBySet;
    339     }
    340 
    341 
    342     /**
    343      * Get the defalt port for the message processor.
    344      *
    345      * @param transport
    346      * @return -- the default port for the message processor.
    347      */
    348 
    349     public static int getDefaultPort(String transport) {
    350 
    351         return transport.equalsIgnoreCase("TLS")?5061:5060;
    352     }
    353 
    354 
    355 
    356 }
    357