• Home
  • Line#
  • Scopes#
  • Navigate#
  • Raw
  • Download
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 
MessageProcessor( String transport )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      */
MessageProcessor( InetAddress ipAddress, int port, String transport, SIPTransactionStack transactionStack )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      */
initialize( InetAddress ipAddress, int port, SIPTransactionStack transactionStack )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      */
getTransport()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      */
getPort()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      */
getViaHeader()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     }
getListeningPoint()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 
setListeningPoint(ListeningPointImpl lp)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      */
getSavedIpAddress()213     public String getSavedIpAddress() {
214         return this.savedIpAddress;
215     }
216     /**
217      * @return the ip address for this message processor.
218      */
getIpAddress()219     public InetAddress getIpAddress() {
220           return this.ipAddress;
221     }
222     /**
223      * @param ipAddress the ipAddress to set
224      */
setIpAddress(InetAddress ipAddress)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      */
setSentBy(String sentBy)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      */
getSentBy()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      */
getSIPStack()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      */
createMessageChannel(HostPort targetHostPort)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      */
createMessageChannel(InetAddress targetHost, int port)292     public abstract MessageChannel createMessageChannel(InetAddress targetHost,
293             int port) throws IOException;
294 
295 
296     /**
297      * Start our thread.
298      */
start()299     public abstract void start() throws IOException;
300 
301     /**
302      * Stop method.
303      */
stop()304     public abstract void stop();
305 
306     /**
307      * Default target port used by this processor. This is 5060 for TCP / UDP
308      */
getDefaultTargetPort()309     public abstract int getDefaultTargetPort();
310 
311     /**
312      * Flags whether this processor is secure or not.
313      */
isSecure()314     public abstract boolean isSecure();
315 
316     /**
317      * Maximum number of bytes that this processor can handle.
318      */
getMaximumMessageSize()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      */
inUse()325     public abstract boolean inUse();
326 
327 
328 
329     /**
330      * Run method.
331      */
run()332     public abstract void run();
333 
334     /**
335      * @return Returns the sentBySet.
336      */
isSentBySet()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 
getDefaultPort(String transport)349     public static int getDefaultPort(String transport) {
350 
351         return transport.equalsIgnoreCase("TLS")?5061:5060;
352     }
353 
354 
355 
356 }
357