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 */
26package gov.nist.javax.sip;
27
28import gov.nist.core.ServerLogger;
29import gov.nist.core.StackLogger;
30import gov.nist.core.net.AddressResolver;
31import gov.nist.core.net.NetworkLayer;
32import gov.nist.core.net.SslNetworkLayer;
33import gov.nist.javax.sip.clientauthutils.AccountManager;
34import gov.nist.javax.sip.clientauthutils.AuthenticationHelper;
35import gov.nist.javax.sip.clientauthutils.AuthenticationHelperImpl;
36import gov.nist.javax.sip.clientauthutils.SecureAccountManager;
37import gov.nist.javax.sip.parser.StringMsgParser;
38import gov.nist.javax.sip.stack.DefaultMessageLogFactory;
39import gov.nist.javax.sip.stack.DefaultRouter;
40import gov.nist.javax.sip.stack.MessageProcessor;
41import gov.nist.javax.sip.stack.SIPTransactionStack;
42
43import java.io.BufferedReader;
44import java.io.IOException;
45import java.io.InputStream;
46import java.io.InputStreamReader;
47import java.lang.reflect.Constructor;
48import java.lang.reflect.InvocationTargetException;
49import java.net.InetAddress;
50import java.util.Hashtable;
51import java.util.LinkedList;
52import java.util.Properties;
53import java.util.StringTokenizer;
54import java.util.concurrent.Semaphore;
55import java.util.concurrent.TimeUnit;
56
57import javax.sip.InvalidArgumentException;
58import javax.sip.ListeningPoint;
59import javax.sip.ObjectInUseException;
60import javax.sip.PeerUnavailableException;
61import javax.sip.ProviderDoesNotExistException;
62import javax.sip.SipException;
63import javax.sip.SipListener;
64import javax.sip.SipProvider;
65import javax.sip.SipStack;
66import javax.sip.TransportNotSupportedException;
67import javax.sip.address.Router;
68import javax.sip.header.HeaderFactory;
69import javax.sip.message.Request;
70
71/**
72 * Implementation of SipStack.
73 *
74 * The JAIN-SIP stack is initialized by a set of properties (see the JAIN SIP
75 * documentation for an explanation of these properties
76 * {@link javax.sip.SipStack} ). In addition to these, the following are
77 * meaningful properties for the NIST SIP stack (specify these in the property
78 * array when you create the JAIN-SIP statck):
79 * <ul>
80 *
81 * <li><b>gov.nist.javax.sip.TRACE_LEVEL = integer </b><br/>
82 * <b> Use of this property is still supported but deprecated. Please use
83 * gov.nist.javax.sip.STACK_LOGGER and gov.nist.javax.sip.SERVER_LOGGER for
84 * integration with logging frameworks and for custom formatting of log records.
85 * </b> This property is used by the built in log4j based logger. You can use
86 * the standard log4j level names here (i.e. ERROR, INFO, WARNING, OFF, DEBUG,
87 * TRACE) If this is set to INFO or above, then incoming valid messages are
88 * logged in SERVER_LOG. If you set this to 32 and specify a DEBUG_LOG then vast
89 * amounts of trace information will be dumped in to the specified DEBUG_LOG.
90 * The server log accumulates the signaling trace. <a href="{@docRoot}
91 * /tools/tracesviewer/tracesviewer.html"> This can be viewed using the trace
92 * viewer tool .</a> Please send us both the server log and debug log when
93 * reporting non-obvious problems. You can also use the strings DEBUG or INFO
94 * for level 32 and 16 respectively. If the value of this property is set to
95 * LOG4J, then the effective log levels are determined from the log4j settings
96 * file (e.g. log4j.properties). The logger name for the stack is specified
97 * using the gov.nist.javax.sip.LOG4J_LOGGER_NAME property. By default log4j
98 * logger name for the stack is the same as the stack name. For example, <code>
99 * properties.setProperty("gov.nist.javax.sip.TRACE_LEVEL", "LOG4J");
100 * properties.setProperty("gov.nist.javax.sip.LOG4J_LOGGER_NAME", "SIPStackLogger");
101 * </code> allows you to now control logging in the stack entirely using log4j
102 * facilities.</li>
103 *
104 * <li><b>gov.nist.javax.sip.LOG_FACTORY = classpath </b> <b> Use of this
105 * property is still supported but deprecated. Please use
106 * gov.nist.javax.sip.STACK_LOGGER and gov.nist.javax.sip.SERVER_LOGGER for
107 * integration with logging frameworks and for custom formatting of log records.
108 * </b> <br/>
109 * The fully qualified classpath for an implementation of the MessageLogFactory.
110 * The stack calls the MessageLogFactory functions to format the log for
111 * messages that are received or sent. This function allows you to log auxiliary
112 * information related to the application or environmental conditions into the
113 * log stream. The log factory must have a default constructor.</li>
114 *
115 * <li><b>gov.nist.javax.sip.SERVER_LOG = fileName </b><br/>
116 * <b> Use of this property is still supported but deprecated. Please use
117 * gov.nist.javax.sip.STACK_LOGGER and gov.nist.javax.sip.SERVER_LOGGER for
118 * integration with logging frameworks and for custom formatting of log records.
119 * </b> Log valid incoming messages here. If this is left null AND the
120 * TRACE_LEVEL is above INFO (or TRACE) then the messages are printed to stdout.
121 * Otherwise messages are logged in a format that can later be viewed using the
122 * trace viewer application which is located in the tools/tracesviewer
123 * directory. <font color=red> Mail this to us with bug reports. </font></li>
124 *
125 * <li><b>gov.nist.javax.sip.DEBUG_LOG = fileName </b> <b> Use of this property
126 * is still supported but deprecated. Please use gov.nist.javax.sip.STACK_LOGGER
127 * and gov.nist.javax.sip.SERVER_LOGGER for integration with logging frameworks
128 * and for custom formatting of log records. </b> <br/>
129 * Where the debug log goes. <font color=red> Mail this to us with bug reports.
130 * </font></li>
131 *
132 * <li><b>gov.nist.javax.sip.LOG_MESSAGE_CONTENT = true|false </b><br/>
133 * Set true if you want to capture content into the log. Default is false. A bad
134 * idea to log content if you are using SIP to push a lot of bytes through TCP.</li>
135 *
136 * <li><b>gov.nist.javax.sip.LOG_STACK_TRACE_ON_MESSAGE_SEND = true|false </b><br/>
137 * Set true if you want to to log a stack trace at INFO level for each message
138 * send. This is really handy for debugging.</li>
139 *
140 * <li><b>gov.nist.javax.sip.STACK_LOGGER = full path name to the class
141 * implementing gov.nist.core.StackLogger interface</b><br/>
142 * If this property is defined the sip stack will try to instantiate it through
143 * a no arg constructor. This allows to use different logging implementations
144 * than the ones provided by default to log what happens within the stack while
145 * processing SIP messages. If this property is not defined, the default sip
146 * stack LogWriter will be used for logging</li>
147 *
148 * <li><b>gov.nist.javax.sip.SERVER_LOGGER = full path name to the class
149 * implementing gov.nist.core.ServerLogger interface</b><br/>
150 * If this property is defined the sip stack will try to instantiate it through
151 * a no arg constructor. This allows to use different logging implementations
152 * than the ones provided by default to log sent/received messages by the sip
153 * stack. If this property is not defined, the default sip stack ServerLog will
154 * be used for logging</li>
155 *
156 * <li><b>gov.nist.javax.sip.AUTOMATIC_DIALOG_ERROR_HANDLING = [true|false] </b>
157 * <br/>
158 * Default is <it>true</it>. This is also settable on a per-provider basis. This
159 * flag is set to true by default. When set
160 * to <it>false</it> the following behaviors are enabled:
161 *
162 *
163 * <li>Turn off Merged requests Loop Detection: The following behavior is turned off
164 * : If the request has no tag in the To header field, the UAS core MUST check
165 * the request against ongoing transactions. If the From tag, Call-ID, and CSeq
166 * exactly match those associated with an ongoing transaction, but the request
167 * does not match that transaction (based on the matching rules in Section
168 * 17.2.3), the UAS core SHOULD generate a 482 (Loop Detected) response and pass
169 * it to the server transaction.
170 *
171 * </ul>
172 *
173 * <li><b>gov.nist.javax.sip.IS_BACK_TO_BACK_USER_AGENT = [true|false] </b> <br/>
174 * Default is <it>false</it> This property controls a setting on the Dialog
175 * objects that the stack manages. Pure B2BUA applications should set this flag
176 * to <it>true</it>. This property can also be set on a per-dialog basis.
177 * Setting this to <it>true</it> imposes serialization on re-INVITE and makes
178 * the sending of re-INVITEs asynchronous. The sending of re-INVITE is
179 * controlled as follows : If the previous in-DIALOG request was an invite
180 * ClientTransaction then the next re-INVITEs that uses the dialog will wait
181 * till an ACK has been sent before admitting the new re-INVITE. If the previous
182 * in-DIALOG transaction was a INVITE ServerTransaction then Dialog waits for
183 * ACK before re-INVITE is allowed to be sent. If a dialog is not ACKed within
184 * 32 seconds, then the dialog is torn down and a BYE sent to the peer.</li>
185 * <li><b>gov.nist.javax.sip.MAX_MESSAGE_SIZE = integer</b> <br/>
186 * Maximum size of content that a TCP connection can read. Must be at least 4K.
187 * Default is "infinity" -- ie. no limit. This is to prevent DOS attacks
188 * launched by writing to a TCP connection until the server chokes.</li>
189 *
190 * <li><b>gov.nist.javax.sip.DELIVER_TERMINATED_EVENT_FOR_NULL_DIALOG = [true|false] </b><br/>
191 * If set to false (the default), the application does NOT get notified when a Dialog in the
192 * NULL state is terminated. ( Dialogs in the NULL state are not associated with an actual SIP Dialog.
193 * They are a programming convenience. A Dialog is in the NULL state before the first response for the
194 * Dialog forming Transaction). If set to true, the SipListener will get a DialogTerminatedEvent
195 * when a Dialog in the NULL state is terminated.
196 * </li>
197 *
198 * <li><b>gov.nist.javax.sip.CACHE_SERVER_CONNECTIONS = [true|false] </b> <br/>
199 * Default value is true. Setting this to false makes the Stack close the server
200 * socket after a Server Transaction goes to the TERMINATED state. This allows a
201 * server to protectect against TCP based Denial of Service attacks launched by
202 * clients (ie. initiate hundreds of client transactions). If true (default
203 * action), the stack will keep the socket open so as to maximize performance at
204 * the expense of Thread and memory resources - leaving itself open to DOS
205 * attacks.</li>
206 *
207 *
208 * <li><b>gov.nist.javax.sip.CACHE_CLIENT_CONNECTIONS = [true|false] </b> <br/>
209 * Default value is true. Setting this to false makes the Stack close the server
210 * socket after a Client Transaction goes to the TERMINATED state. This allows a
211 * client release any buffers threads and socket connections associated with a
212 * client transaction after the transaction has terminated at the expense of
213 * performance.</li>
214 *
215 * <li><b>gov.nist.javax.sip.THREAD_POOL_SIZE = integer </b> <br/>
216 * Concurrency control for number of simultaneous active threads. If
217 * unspecificed, the default is "infinity". This feature is useful if you are
218 * trying to build a container.
219 * <ul>
220 * <li>
221 * <li>If this is not specified, <b> and the listener is re-entrant</b>, each
222 * event delivered to the listener is run in the context of a new thread.</li>
223 * <li>If this is specified and the listener is re-entrant, then the stack will
224 * run the listener using a thread from the thread pool. This allows you to
225 * manage the level of concurrency to a fixed maximum. Threads are pre-allocated
226 * when the stack is instantiated.</li>
227 * <li>If this is specified and the listener is not re-entrant, then the stack
228 * will use the thread pool thread from this pool to parse and manage the state
229 * machine but will run the listener in its own thread.</li>
230 * </ul>
231 *
232 * <li><b>gov.nist.javax.sip.REENTRANT_LISTENER = true|false </b> <br/>
233 * Default is false. Set to true if the listener is re-entrant. If the listener
234 * is re-entrant then the stack manages a thread pool and synchronously calls
235 * the listener from the same thread which read the message. Multiple
236 * transactions may concurrently receive messages and this will result in
237 * multiple threads being active in the listener at the same time. The listener
238 * has to be written with this in mind. <b> If you want good performance on a
239 * multithreaded machine write your listener to be re-entrant and set this
240 * property to be true </b></li>
241 *
242 * <li><b>gov.nist.javax.sip.MAX_CONNECTIONS = integer </b> <br/>
243 * Max number of simultaneous TCP connections handled by stack.</li>
244 *
245 * <li><b>gov.nist.javax.sip.MAX_SERVER_TRANSACTIONS = integer </b> <br/>
246 * Maximum size of server transaction table. The low water mark is 80% of the
247 * high water mark. Requests are selectively dropped in the lowater mark to
248 * highwater mark range. Requests are unconditionally accepted if the table is
249 * smaller than the low water mark. The default highwater mark is 5000</li>
250 *
251 * <li><b>gov.nist.javax.sip.MAX_CLIENT_TRANSACTIONS = integer </b> <br/>
252 * Max number of active client transactions before the caller blocks and waits
253 * for the number to drop below a threshold. Default is unlimited, i.e. the
254 * caller never blocks and waits for a client transaction to become available
255 * (i.e. it does its own resource management in the application).</li>
256 *
257 * <li><b>gov.nist.javax.sip.PASS_INVITE_NON_2XX_ACK_TO_LISTENER = true|false
258 * </b> <br/>
259 * If true then the listener will see the ACK for non-2xx responses for server
260 * transactions. This is not standard behavior per RFC 3261 (INVITE server
261 * transaction state machine) but this is a useful flag for testing. The TCK
262 * uses this flag for example.</li>
263 *
264 * <li><b>gov.nist.javax.sip.MAX_LISTENER_RESPONSE_TIME = Integer </b> <br/>
265 * Max time (seconds) before sending a response to a server transaction. If a
266 * response is not sent within this time period, the transaction will be deleted
267 * by the stack. Default time is "infinity" - i.e. if the listener never
268 * responds, the stack will hang on to a reference for the transaction and
269 * result in a memory leak.
270 *
271 * <li><b>gov.nist.javax.sip.DELIVER_TERMINATED_EVENT_FOR_ACK = [true|false]</b>
272 * <br/>
273 * Default is <it>false</it>. ACK Server Transaction is a Pseuedo-transaction.
274 * If you want termination notification on ACK transactions (so all server
275 * transactions can be handled uniformly in user code during cleanup), then set
276 * this flag to <it>true</it>.</li>
277 *
278 * <li><b>gov.nist.javax.sip.READ_TIMEOUT = integer </b> <br/>
279 * This is relevant for incoming TCP connections to prevent starvation at the
280 * server. This defines the timeout in miliseconds between successive reads
281 * after the first byte of a SIP message is read by the stack. All the sip
282 * headers must be delivered in this interval and each successive buffer must be
283 * of the content delivered in this interval. Default value is -1 (ie. the stack
284 * is wide open to starvation attacks) and the client can be as slow as it wants
285 * to be.</li>
286 *
287 * <li><b>gov.nist.javax.sip.NETWORK_LAYER = classpath </b> <br/>
288 * This is an EXPERIMENTAL property (still under active devlopment). Defines a
289 * network layer that allows a client to have control over socket allocations
290 * and monitoring of socket activity. A network layer should implement
291 * gov.nist.core.net.NetworkLayer. The default implementation simply acts as a
292 * wrapper for the standard java.net socket layer. This functionality is still
293 * under active development (may be extended to support security and other
294 * features).</li>
295 *
296 * <li><b>gov.nist.javax.sip.ADDRESS_RESOLVER = classpath </b><br/>
297 * The fully qualified class path for an implementation of the AddressResolver
298 * interface. The AddressResolver allows you to support lookup schemes for
299 * addresses that are not directly resolvable to IP adresses using
300 * getHostByName. Specifying your own address resolver allows you to customize
301 * address lookup. The default address resolver is a pass-through address
302 * resolver (i.e. just returns the input string without doing a resolution). See
303 * gov.nist.javax.sip.DefaultAddressResolver.</li>
304 *
305 * <li><b>gov.nist.javax.sip.AUTO_GENERATE_TIMESTAMP= [true| false] </b><br/>
306 * (default is false) Automatically generate a getTimeOfDay timestamp for a
307 * retransmitted request if the original request contained a timestamp. This is
308 * useful for profiling.</li>
309 *
310 * <li><b>gov.nist.javax.sip.THREAD_AUDIT_INTERVAL_IN_MILLISECS = long </b> <br/>
311 * Defines how often the application intends to audit the SIP Stack about the
312 * health of its internal threads (the property specifies the time in
313 * miliseconds between successive audits). The audit allows the application to
314 * detect catastrophic failures like an internal thread terminating because of
315 * an exception or getting stuck in a deadlock condition. Events like these will
316 * make the stack inoperable and therefore require immediate action from the
317 * application layer (e.g., alarms, traps, reboot, failover, etc.) Thread audits
318 * are disabled by default. If this property is not specified, audits will
319 * remain disabled. An example of how to use this property is in
320 * src/examples/threadaudit.</li>
321 *
322 *
323 *
324 * <li><b>gov.nist.javax.sip.COMPUTE_CONTENT_LENGTH_FROM_MESSAGE_BODY =
325 * [true|false] </b> <br/>
326 * Default is <it>false</it> If set to <it>true</it>, when you are creating a
327 * message from a <it>String</it>, the MessageFactory will compute the content
328 * length from the message content and ignore the provided content length
329 * parameter in the Message. Otherwise, it will use the content length supplied
330 * and generate a parse exception if the content is truncated.
331 *
332 * <li><b>gov.nist.javax.sip.CANCEL_CLIENT_TRANSACTION_CHECKED = [true|false]
333 * </b> <br/>
334 * Default is <it>true</it>. This flag is added in support of load balancers or
335 * failover managers where you may want to cancel ongoing transactions from a
336 * different stack than the original stack. If set to <it>false</it> then the
337 * CANCEL client transaction is not checked for the existence of the INVITE or
338 * the state of INVITE when you send the CANCEL request. Hence you can CANCEL an
339 * INVITE from a different stack than the INVITE. You can also create a CANCEL
340 * client transaction late and send it out after the INVITE server transaction
341 * has been Terminated. Clearly this will result in protocol errors. Setting the
342 * flag to true ( default ) enables you to avoid common protocol errors.</li>
343 *
344 * <li><b>gov.nist.javax.sip.IS_BACK_TO_BACK_USER_AGENT = [true|false] </b> <br/>
345 * Default is <it>false</it> This property controls a setting on the Dialog
346 * objects that the stack manages. Pure B2BUA applications should set this flag
347 * to <it>true</it>. This property can also be set on a per-dialog basis.
348 * Setting this to <it>true</it> imposes serialization on re-INVITE and makes
349 * the sending of re-INVITEs asynchronous. The sending of re-INVITE is
350 * controlled as follows : If the previous in-DIALOG request was an invite
351 * ClientTransaction then the next re-INVITEs that uses the dialog will wait
352 * till an ACK has been sent before admitting the new re-INVITE. If the previous
353 * in-DIALOG transaction was a INVITE ServerTransaction then Dialog waits for
354 * ACK before re-INVITE is allowed to be sent. If a dialog is not ACKed within
355 * 32 seconds, then the dialog is torn down and a BYE sent to the peer.</li>
356 *
357 *
358 * <li><b>gov.nist.javax.sip.RECEIVE_UDP_BUFFER_SIZE = int </b> <br/>
359 * Default is <it>8*1024</it>. This property control the size of the UDP buffer
360 * used for SIP messages. Under load, if the buffer capacity is overflown the
361 * messages are dropped causing retransmissions, further increasing the load and
362 * causing even more retransmissions. Good values to this property for servers
363 * is a big number in the order of 8*8*1024.</li>
364 *
365 * <li><b>gov.nist.javax.sip.SEND_UDP_BUFFER_SIZE = int </b> <br/>
366 * Default is <it>8*1024</it>. This property control the size of the UDP buffer
367 * used for SIP messages. Under load, if the buffer capacity is overflown the
368 * messages are dropped causing retransmissions, further increasing the load and
369 * causing even more retransmissions. Good values to this property for servers
370 * is a big number in the order of 8*8*1024 or higher.</li>
371 *
372 * <li><b>gov.nist.javax.sip.CONGESTION_CONTROL_ENABLED = boolean </b> Defailt
373 * is true. If set to true stack will enforce queue length limitation for UDP.
374 * The Max queue size is 5000 messages. The minimum queue size is 2500 messages.
375 * </li>
376 *
377 * <li><b>gov.nist.javax.sip.DELIVER_UNSOLICITED_NOTIFY = [true|false] </b> <br/>
378 * Default is <it>false</it>. This flag is added to allow Sip Listeners to
379 * receive all NOTIFY requests including those that are not part of a valid
380 * dialog.</li>
381 *
382 * <li><b>gov.nist.javax.sip.REJECT_STRAY_RESPONSES = [true|false] </b> Default
383 * is <it>false</it> A flag that checks responses to test whether the response
384 * corresponds to a via header that was previously generated by us. Note that
385 * setting this flag implies that the stack will take control over setting the
386 * VIA header for Sip Requests sent through the stack. The stack will attach a
387 * suffix to the VIA header branch and check any response arriving at the stack
388 * to see if that response suffix is present. If it is not present, then the
389 * stack will silently drop the response.</li>
390 *
391 * <li><b>gov.nist.javax.sip.MAX_FORK_TIME_SECONDS = integer </b> Maximum time for which the original
392 * transaction for which a forked response is received is tracked. This property
393 * is only relevant to Dialog Stateful applications ( User Agents or B2BUA).
394 * When a forked response is received in this time interval from when the original
395 * INVITE client transaction was sent, the stack will place the original INVITE
396 * client transction in the ResponseEventExt and deliver that to the application.
397 * The event handler can get the original transaction from this event. </li>
398 *
399 *  * <li><b>gov.nist.javax.sip.TLS_CLIENT_PROTOCOLS = String </b>
400 *  Comma-separated list of protocols to use when creating outgoing TLS connections.
401 *  The default is "SSLv3, SSLv2Hello, TLSv1".
402 *  Some servers do not support SSLv2Hello, so override to "SSLv3, TLSv1".
403 * </li>
404
405 * <li><b>javax.net.ssl.keyStore = fileName </b> <br/>
406 * Default is <it>NULL</it>. If left undefined the keyStore and trustStore will
407 * be left to the java runtime defaults. If defined, any TLS sockets created
408 * (client and server) will use the key store provided in the fileName. The
409 * trust store will default to the same store file. A password must be provided
410 * to access the keyStore using the following property: <br>
411 * <code>
412 * properties.setProperty("javax.net.ssl.keyStorePassword", "&lt;password&gt;");
413 * </code> <br>
414 * The trust store can be changed, to a separate file with the following
415 * setting: <br>
416 * <code>
417 * properties.setProperty("javax.net.ssl.trustStore", "&lt;trustStoreFileName location&gt;");
418 * </code> <br>
419 * If the trust store property is provided the password on the trust store must
420 * be the same as the key store. <br>
421 * <br>
422 * <b> Note that the stack supports the extensions that are defined in
423 * SipStackExt. These will be supported in the next release of JAIN-SIP. You
424 * should only use the extensions that are defined in this class. </b>
425 *
426 *
427 * @version 1.2 $Revision: 1.115 $ $Date: 2010/01/10 00:13:14 $
428 *
429 * @author M. Ranganathan <br/>
430 *
431 *
432 *
433 *
434 */
435public class SipStackImpl extends SIPTransactionStack implements
436		javax.sip.SipStack, SipStackExt {
437
438	private EventScanner eventScanner;
439
440	private Hashtable<String, ListeningPointImpl> listeningPoints;
441
442	private LinkedList<SipProviderImpl> sipProviders;
443
444	/**
445	 * Max datagram size.
446	 */
447	public static final Integer MAX_DATAGRAM_SIZE = 8 * 1024;
448
449	// Flag to indicate that the listener is re-entrant and hence
450	// Use this flag with caution.
451	boolean reEntrantListener;
452
453	SipListener sipListener;
454
455	// If set to true then a transaction terminated event is
456	// delivered for ACK transactions.
457	boolean deliverTerminatedEventForAck = false;
458
459	// If set to true then the application want to receive
460	// unsolicited NOTIFYs, ie NOTIFYs that don't match any dialog
461	boolean deliverUnsolicitedNotify = false;
462
463	// Stack semaphore (global lock).
464	private Semaphore stackSemaphore = new Semaphore(1);
465
466	// RFC3261: TLS_RSA_WITH_AES_128_CBC_SHA MUST be supported
467	// RFC3261: TLS_RSA_WITH_3DES_EDE_CBC_SHA SHOULD be supported for backwards
468	// compat
469	private String[] cipherSuites = {
470			"TLS_RSA_WITH_AES_128_CBC_SHA", // AES difficult to get with
471											// c++/Windows
472			// "TLS_RSA_WITH_3DES_EDE_CBC_SHA", // Unsupported by Sun impl,
473			"SSL_RSA_WITH_3DES_EDE_CBC_SHA", // For backwards comp., C++
474
475			// JvB: patch from Sebastien Mazy, issue with mismatching
476			// ciphersuites
477			"TLS_DH_anon_WITH_AES_128_CBC_SHA",
478			"SSL_DH_anon_WITH_3DES_EDE_CBC_SHA", };
479
480	// Supported protocols for TLS client: can be overridden by application
481	private String[] enabledProtocols = {
482			"SSLv3",
483			"SSLv2Hello",
484			"TLSv1"
485	};
486
487	/**
488	 * Creates a new instance of SipStackImpl.
489	 */
490
491	protected SipStackImpl() {
492		super();
493		NistSipMessageFactoryImpl msgFactory = new NistSipMessageFactoryImpl(
494				this);
495		super.setMessageFactory(msgFactory);
496		this.eventScanner = new EventScanner(this);
497		this.listeningPoints = new Hashtable<String, ListeningPointImpl>();
498		this.sipProviders = new LinkedList<SipProviderImpl>();
499
500	}
501
502	/**
503	 * ReInitialize the stack instance.
504	 */
505	private void reInitialize() {
506		super.reInit();
507		this.eventScanner = new EventScanner(this);
508		this.listeningPoints = new Hashtable<String, ListeningPointImpl>();
509		this.sipProviders = new LinkedList<SipProviderImpl>();
510		this.sipListener = null;
511
512	}
513
514	/**
515	 * Return true if automatic dialog support is enabled for this stack.
516	 *
517	 * @return boolean, true if automatic dialog support is enabled for this
518	 *         stack
519	 */
520	boolean isAutomaticDialogSupportEnabled() {
521		return super.isAutomaticDialogSupportEnabled;
522	}
523
524	/**
525	 * Constructor for the stack.
526	 *
527	 * @param configurationProperties
528	 *            -- stack configuration properties including NIST-specific
529	 *            extensions.
530	 * @throws PeerUnavailableException
531	 */
532	public SipStackImpl(Properties configurationProperties)
533			throws PeerUnavailableException {
534		this();
535		String address = configurationProperties
536				.getProperty("javax.sip.IP_ADDRESS");
537		try {
538			/** Retrieve the stack IP address */
539			if (address != null) {
540				// In version 1.2 of the spec the IP address is
541				// associated with the listening point and
542				// is not madatory.
543				super.setHostAddress(address);
544
545			}
546		} catch (java.net.UnknownHostException ex) {
547			throw new PeerUnavailableException("bad address " + address);
548		}
549
550		/** Retrieve the stack name */
551		String name = configurationProperties
552				.getProperty("javax.sip.STACK_NAME");
553		if (name == null)
554			throw new PeerUnavailableException("stack name is missing");
555		super.setStackName(name);
556		String stackLoggerClassName = configurationProperties
557				.getProperty("gov.nist.javax.sip.STACK_LOGGER");
558		// To log debug messages.
559		if (stackLoggerClassName == null)
560			stackLoggerClassName = "gov.nist.core.LogWriter";
561			try {
562				Class<?> stackLoggerClass = Class.forName(stackLoggerClassName);
563				Class<?>[] constructorArgs = new Class[0];
564				Constructor<?> cons = stackLoggerClass
565						.getConstructor(constructorArgs);
566				Object[] args = new Object[0];
567				StackLogger stackLogger = (StackLogger) cons.newInstance(args);
568				stackLogger.setStackProperties(configurationProperties);
569				super.setStackLogger(stackLogger);
570			} catch (InvocationTargetException ex1) {
571				throw new IllegalArgumentException(
572						"Cound not instantiate stack logger "
573								+ stackLoggerClassName
574								+ "- check that it is present on the classpath and that there is a no-args constructor defined",
575						ex1);
576			} catch (Exception ex) {
577				throw new IllegalArgumentException(
578						"Cound not instantiate stack logger "
579								+ stackLoggerClassName
580								+ "- check that it is present on the classpath and that there is a no-args constructor defined",
581						ex);
582			}
583
584		String serverLoggerClassName = configurationProperties
585				.getProperty("gov.nist.javax.sip.SERVER_LOGGER");
586		// To log debug messages.
587		if (serverLoggerClassName == null)
588			serverLoggerClassName = "gov.nist.javax.sip.stack.ServerLog";
589			try {
590				Class<?> serverLoggerClass = Class
591						.forName(serverLoggerClassName);
592				Class<?>[] constructorArgs = new Class[0];
593				Constructor<?> cons = serverLoggerClass
594						.getConstructor(constructorArgs);
595				Object[] args = new Object[0];
596				this.serverLogger = (ServerLogger) cons.newInstance(args);
597				serverLogger.setSipStack(this);
598				serverLogger.setStackProperties(configurationProperties);
599			} catch (InvocationTargetException ex1) {
600				throw new IllegalArgumentException(
601						"Cound not instantiate server logger "
602								+ stackLoggerClassName
603								+ "- check that it is present on the classpath and that there is a no-args constructor defined",
604						ex1);
605			} catch (Exception ex) {
606				throw new IllegalArgumentException(
607						"Cound not instantiate server logger "
608								+ stackLoggerClassName
609								+ "- check that it is present on the classpath and that there is a no-args constructor defined",
610						ex);
611			}
612
613		// Default router -- use this for routing SIP URIs.
614		// Our router does not do DNS lookups.
615		this.outboundProxy = configurationProperties
616				.getProperty("javax.sip.OUTBOUND_PROXY");
617
618		this.defaultRouter = new DefaultRouter(this, outboundProxy);
619
620		/** Retrieve the router path */
621		String routerPath = configurationProperties
622				.getProperty("javax.sip.ROUTER_PATH");
623		if (routerPath == null)
624			routerPath = "gov.nist.javax.sip.stack.DefaultRouter";
625
626		try {
627			Class<?> routerClass = Class.forName(routerPath);
628			Class<?>[] constructorArgs = new Class[2];
629			constructorArgs[0] = javax.sip.SipStack.class;
630			constructorArgs[1] = String.class;
631			Constructor<?> cons = routerClass.getConstructor(constructorArgs);
632			Object[] args = new Object[2];
633			args[0] = (SipStack) this;
634			args[1] = outboundProxy;
635			Router router = (Router) cons.newInstance(args);
636			super.setRouter(router);
637		} catch (InvocationTargetException ex1) {
638			getStackLogger()
639					.logError(
640							"could not instantiate router -- invocation target problem",
641							(Exception) ex1.getCause());
642			throw new PeerUnavailableException(
643					"Cound not instantiate router - check constructor", ex1);
644		} catch (Exception ex) {
645			getStackLogger().logError("could not instantiate router",
646					(Exception) ex.getCause());
647			throw new PeerUnavailableException("Could not instantiate router",
648					ex);
649		}
650
651		// The flag that indicates that the default router is to be ignored.
652		String useRouterForAll = configurationProperties
653				.getProperty("javax.sip.USE_ROUTER_FOR_ALL_URIS");
654		this.useRouterForAll = true;
655		if (useRouterForAll != null) {
656			this.useRouterForAll = "true".equalsIgnoreCase(useRouterForAll);
657		}
658
659		/*
660		 * Retrieve the EXTENSION Methods. These are used for instantiation of
661		 * Dialogs.
662		 */
663		String extensionMethods = configurationProperties
664				.getProperty("javax.sip.EXTENSION_METHODS");
665
666		if (extensionMethods != null) {
667			java.util.StringTokenizer st = new java.util.StringTokenizer(
668					extensionMethods);
669			while (st.hasMoreTokens()) {
670				String em = st.nextToken(":");
671				if (em.equalsIgnoreCase(Request.BYE)
672						|| em.equalsIgnoreCase(Request.INVITE)
673						|| em.equalsIgnoreCase(Request.SUBSCRIBE)
674						|| em.equalsIgnoreCase(Request.NOTIFY)
675						|| em.equalsIgnoreCase(Request.ACK)
676						|| em.equalsIgnoreCase(Request.OPTIONS))
677					throw new PeerUnavailableException("Bad extension method "
678							+ em);
679				else
680					this.addExtensionMethod(em);
681			}
682		}
683		String keyStoreFile = configurationProperties
684				.getProperty("javax.net.ssl.keyStore");
685		String trustStoreFile = configurationProperties
686				.getProperty("javax.net.ssl.trustStore");
687		if (keyStoreFile != null) {
688			if (trustStoreFile == null) {
689				trustStoreFile = keyStoreFile;
690			}
691			String keyStorePassword = configurationProperties
692					.getProperty("javax.net.ssl.keyStorePassword");
693			try {
694				this.networkLayer = new SslNetworkLayer(trustStoreFile,
695						keyStoreFile, keyStorePassword.toCharArray(),
696						configurationProperties
697								.getProperty("javax.net.ssl.keyStoreType"));
698			} catch (Exception e1) {
699				getStackLogger().logError(
700						"could not instantiate SSL networking", e1);
701			}
702		}
703
704		// Set the auto dialog support flag.
705		super.isAutomaticDialogSupportEnabled = configurationProperties
706				.getProperty("javax.sip.AUTOMATIC_DIALOG_SUPPORT", "on")
707				.equalsIgnoreCase("on");
708
709		super.isAutomaticDialogErrorHandlingEnabled = configurationProperties
710					.getProperty("gov.nist.javax.sip.AUTOMATIC_DIALOG_ERROR_HANDLING","true")
711					.equals(Boolean.TRUE.toString());
712		if ( super.isAutomaticDialogSupportEnabled ) {
713			super.isAutomaticDialogErrorHandlingEnabled = true;
714		}
715
716		if (configurationProperties
717				.getProperty("gov.nist.javax.sip.MAX_LISTENER_RESPONSE_TIME") != null) {
718			super.maxListenerResponseTime = Integer
719					.parseInt(configurationProperties
720							.getProperty("gov.nist.javax.sip.MAX_LISTENER_RESPONSE_TIME"));
721			if (super.maxListenerResponseTime <= 0)
722				throw new PeerUnavailableException(
723						"Bad configuration parameter gov.nist.javax.sip.MAX_LISTENER_RESPONSE_TIME : should be positive");
724		} else {
725			super.maxListenerResponseTime = -1;
726		}
727
728
729
730		this.deliverTerminatedEventForAck = configurationProperties
731				.getProperty(
732						"gov.nist.javax.sip.DELIVER_TERMINATED_EVENT_FOR_ACK",
733						"false").equalsIgnoreCase("true");
734
735		this.deliverUnsolicitedNotify = configurationProperties.getProperty(
736				"gov.nist.javax.sip.DELIVER_UNSOLICITED_NOTIFY", "false")
737				.equalsIgnoreCase("true");
738
739		String forkedSubscriptions = configurationProperties
740				.getProperty("javax.sip.FORKABLE_EVENTS");
741		if (forkedSubscriptions != null) {
742			StringTokenizer st = new StringTokenizer(forkedSubscriptions);
743			while (st.hasMoreTokens()) {
744				String nextEvent = st.nextToken();
745				this.forkedEvents.add(nextEvent);
746			}
747		}
748
749		// The following features are unique to the NIST implementation.
750
751		/*
752		 * gets the NetworkLayer implementation, if any. Note that this is a
753		 * NIST only feature.
754		 */
755
756		final String NETWORK_LAYER_KEY = "gov.nist.javax.sip.NETWORK_LAYER";
757
758		if (configurationProperties.containsKey(NETWORK_LAYER_KEY)) {
759			String path = configurationProperties
760					.getProperty(NETWORK_LAYER_KEY);
761			try {
762				Class<?> clazz = Class.forName(path);
763				Constructor<?> c = clazz.getConstructor(new Class[0]);
764				networkLayer = (NetworkLayer) c.newInstance(new Object[0]);
765			} catch (Exception e) {
766				throw new PeerUnavailableException(
767						"can't find or instantiate NetworkLayer implementation: "
768								+ path);
769			}
770		}
771
772		final String ADDRESS_RESOLVER_KEY = "gov.nist.javax.sip.ADDRESS_RESOLVER";
773
774		if (configurationProperties.containsKey(ADDRESS_RESOLVER_KEY)) {
775			String path = configurationProperties
776					.getProperty(ADDRESS_RESOLVER_KEY);
777			try {
778				Class<?> clazz = Class.forName(path);
779				Constructor<?> c = clazz.getConstructor(new Class[0]);
780				this.addressResolver = (AddressResolver) c
781						.newInstance(new Object[0]);
782			} catch (Exception e) {
783				throw new PeerUnavailableException(
784						"can't find or instantiate AddressResolver implementation: "
785								+ path);
786			}
787		}
788
789		String maxConnections = configurationProperties
790				.getProperty("gov.nist.javax.sip.MAX_CONNECTIONS");
791		if (maxConnections != null) {
792			try {
793				this.maxConnections = new Integer(maxConnections).intValue();
794			} catch (NumberFormatException ex) {
795				if (isLoggingEnabled())
796					getStackLogger().logError(
797						"max connections - bad value " + ex.getMessage());
798			}
799		}
800
801		String threadPoolSize = configurationProperties
802				.getProperty("gov.nist.javax.sip.THREAD_POOL_SIZE");
803		if (threadPoolSize != null) {
804			try {
805				this.threadPoolSize = new Integer(threadPoolSize).intValue();
806			} catch (NumberFormatException ex) {
807				if (isLoggingEnabled())
808					this.getStackLogger().logError(
809						"thread pool size - bad value " + ex.getMessage());
810			}
811		}
812
813		String serverTransactionTableSize = configurationProperties
814				.getProperty("gov.nist.javax.sip.MAX_SERVER_TRANSACTIONS");
815		if (serverTransactionTableSize != null) {
816			try {
817				this.serverTransactionTableHighwaterMark = new Integer(
818						serverTransactionTableSize).intValue();
819				this.serverTransactionTableLowaterMark = this.serverTransactionTableHighwaterMark * 80 / 100;
820				// Lowater is 80% of highwater
821			} catch (NumberFormatException ex) {
822				if (isLoggingEnabled())
823					this.getStackLogger()
824						.logError(
825								"transaction table size - bad value "
826										+ ex.getMessage());
827			}
828		} else {
829			// Issue 256 : consistent with MAX_CLIENT_TRANSACTIONS, if the MAX_SERVER_TRANSACTIONS is not set
830			// we assume the transaction table size can grow unlimited
831			this.unlimitedServerTransactionTableSize = true;
832		}
833
834		String clientTransactionTableSize = configurationProperties
835				.getProperty("gov.nist.javax.sip.MAX_CLIENT_TRANSACTIONS");
836		if (clientTransactionTableSize != null) {
837			try {
838				this.clientTransactionTableHiwaterMark = new Integer(
839						clientTransactionTableSize).intValue();
840				this.clientTransactionTableLowaterMark = this.clientTransactionTableLowaterMark * 80 / 100;
841				// Lowater is 80% of highwater
842			} catch (NumberFormatException ex) {
843				if (isLoggingEnabled())
844					this.getStackLogger()
845						.logError(
846								"transaction table size - bad value "
847										+ ex.getMessage());
848			}
849		} else {
850			this.unlimitedClientTransactionTableSize = true;
851		}
852
853		super.cacheServerConnections = true;
854		String flag = configurationProperties
855				.getProperty("gov.nist.javax.sip.CACHE_SERVER_CONNECTIONS");
856
857		if (flag != null && "false".equalsIgnoreCase(flag.trim())) {
858			super.cacheServerConnections = false;
859		}
860
861		super.cacheClientConnections = true;
862		String cacheflag = configurationProperties
863				.getProperty("gov.nist.javax.sip.CACHE_CLIENT_CONNECTIONS");
864
865		if (cacheflag != null && "false".equalsIgnoreCase(cacheflag.trim())) {
866			super.cacheClientConnections = false;
867		}
868
869		String readTimeout = configurationProperties
870				.getProperty("gov.nist.javax.sip.READ_TIMEOUT");
871		if (readTimeout != null) {
872			try {
873
874				int rt = Integer.parseInt(readTimeout);
875				if (rt >= 100) {
876					super.readTimeout = rt;
877				} else {
878					System.err.println("Value too low " + readTimeout);
879				}
880			} catch (NumberFormatException nfe) {
881				// Ignore.
882				if (isLoggingEnabled())
883					getStackLogger().logError("Bad read timeout " + readTimeout);
884			}
885		}
886
887		// Get the address of the stun server.
888
889		String stunAddr = configurationProperties
890				.getProperty("gov.nist.javax.sip.STUN_SERVER");
891
892		if (stunAddr != null)
893			this.getStackLogger().logWarning(
894					"Ignoring obsolete property "
895							+ "gov.nist.javax.sip.STUN_SERVER");
896
897		String maxMsgSize = configurationProperties
898				.getProperty("gov.nist.javax.sip.MAX_MESSAGE_SIZE");
899
900		try {
901			if (maxMsgSize != null) {
902				super.maxMessageSize = new Integer(maxMsgSize).intValue();
903				if (super.maxMessageSize < 4096)
904					super.maxMessageSize = 4096;
905			} else {
906				// Allow for "infinite" size of message
907				super.maxMessageSize = 0;
908			}
909		} catch (NumberFormatException ex) {
910			if (isLoggingEnabled())
911				getStackLogger().logError(
912					"maxMessageSize - bad value " + ex.getMessage());
913		}
914
915		String rel = configurationProperties
916				.getProperty("gov.nist.javax.sip.REENTRANT_LISTENER");
917		this.reEntrantListener = (rel != null && "true".equalsIgnoreCase(rel));
918
919		// Check if a thread audit interval is specified
920		String interval = configurationProperties
921				.getProperty("gov.nist.javax.sip.THREAD_AUDIT_INTERVAL_IN_MILLISECS");
922		if (interval != null) {
923			try {
924				// Make the monitored threads ping the auditor twice as fast as
925				// the audits
926				getThreadAuditor().setPingIntervalInMillisecs(
927						Long.valueOf(interval).longValue() / 2);
928			} catch (NumberFormatException ex) {
929				if (isLoggingEnabled())
930					getStackLogger().logError(
931						"THREAD_AUDIT_INTERVAL_IN_MILLISECS - bad value ["
932								+ interval + "] " + ex.getMessage());
933			}
934		}
935
936		// JvB: added property for testing
937		this
938				.setNon2XXAckPassedToListener(Boolean
939						.valueOf(
940								configurationProperties
941										.getProperty(
942												"gov.nist.javax.sip.PASS_INVITE_NON_2XX_ACK_TO_LISTENER",
943												"false")).booleanValue());
944
945		this.generateTimeStampHeader = Boolean.valueOf(
946				configurationProperties.getProperty(
947						"gov.nist.javax.sip.AUTO_GENERATE_TIMESTAMP", "false"))
948				.booleanValue();
949
950		String messageLogFactoryClasspath = configurationProperties
951				.getProperty("gov.nist.javax.sip.LOG_FACTORY");
952		if (messageLogFactoryClasspath != null) {
953			try {
954				Class<?> clazz = Class.forName(messageLogFactoryClasspath);
955				Constructor<?> c = clazz.getConstructor(new Class[0]);
956				this.logRecordFactory = (LogRecordFactory) c
957						.newInstance(new Object[0]);
958			} catch (Exception ex) {
959				if (isLoggingEnabled())
960					getStackLogger()
961						.logError(
962								"Bad configuration value for LOG_FACTORY -- using default logger");
963				this.logRecordFactory = new DefaultMessageLogFactory();
964			}
965
966		} else {
967			this.logRecordFactory = new DefaultMessageLogFactory();
968		}
969
970		boolean computeContentLength = configurationProperties.getProperty(
971				"gov.nist.javax.sip.COMPUTE_CONTENT_LENGTH_FROM_MESSAGE_BODY",
972				"false").equalsIgnoreCase("true");
973		StringMsgParser
974				.setComputeContentLengthFromMessage(computeContentLength);
975
976		String tlsClientProtocols = configurationProperties.getProperty(
977				"gov.nist.javax.sip.TLS_CLIENT_PROTOCOLS");
978		if (tlsClientProtocols != null)
979		{
980			StringTokenizer st = new StringTokenizer(tlsClientProtocols, " ,");
981			String[] protocols = new String[st.countTokens()];
982
983			int i=0;
984			while (st.hasMoreTokens()) {
985				protocols[i++] = st.nextToken();
986			}
987			this.enabledProtocols = protocols;
988		}
989
990		super.rfc2543Supported = configurationProperties.getProperty(
991				"gov.nist.javax.sip.RFC_2543_SUPPORT_ENABLED", "true")
992				.equalsIgnoreCase("true");
993
994		super.cancelClientTransactionChecked = configurationProperties
995				.getProperty(
996						"gov.nist.javax.sip.CANCEL_CLIENT_TRANSACTION_CHECKED",
997						"true").equalsIgnoreCase("true");
998		super.logStackTraceOnMessageSend = configurationProperties.getProperty(
999				"gov.nist.javax.sip.LOG_STACK_TRACE_ON_MESSAGE_SEND", "false")
1000				.equalsIgnoreCase("true");
1001		if (isLoggingEnabled())
1002			getStackLogger().logDebug(
1003				"created Sip stack. Properties = " + configurationProperties);
1004		InputStream in = getClass().getResourceAsStream("/TIMESTAMP");
1005		if (in != null) {
1006			BufferedReader streamReader = new BufferedReader(
1007					new InputStreamReader(in));
1008
1009			try {
1010				String buildTimeStamp = streamReader.readLine();
1011				if (in != null) {
1012					in.close();
1013				}
1014				getStackLogger().setBuildTimeStamp(buildTimeStamp);
1015			} catch (IOException ex) {
1016				getStackLogger().logError("Could not open build timestamp.");
1017			}
1018		}
1019
1020		String bufferSize = configurationProperties.getProperty(
1021				"gov.nist.javax.sip.RECEIVE_UDP_BUFFER_SIZE", MAX_DATAGRAM_SIZE
1022						.toString());
1023		int bufferSizeInteger = new Integer(bufferSize).intValue();
1024		super.setReceiveUdpBufferSize(bufferSizeInteger);
1025
1026		bufferSize = configurationProperties.getProperty(
1027				"gov.nist.javax.sip.SEND_UDP_BUFFER_SIZE", MAX_DATAGRAM_SIZE
1028						.toString());
1029		bufferSizeInteger = new Integer(bufferSize).intValue();
1030		super.setSendUdpBufferSize(bufferSizeInteger);
1031
1032		boolean congetstionControlEnabled = Boolean
1033				.parseBoolean(configurationProperties.getProperty(
1034						"gov.nist.javax.sip.CONGESTION_CONTROL_ENABLED",
1035						Boolean.TRUE.toString()));
1036		super.stackDoesCongestionControl = congetstionControlEnabled;
1037
1038		super.isBackToBackUserAgent = Boolean
1039				.parseBoolean(configurationProperties.getProperty(
1040						"gov.nist.javax.sip.IS_BACK_TO_BACK_USER_AGENT",
1041						Boolean.FALSE.toString()));
1042		super.checkBranchId = Boolean.parseBoolean(configurationProperties
1043				.getProperty("gov.nist.javax.sip.REJECT_STRAY_RESPONSES",
1044						Boolean.FALSE.toString()));
1045
1046		super.isDialogTerminatedEventDeliveredForNullDialog = (Boolean.parseBoolean(configurationProperties.getProperty("gov.nist.javax.sip.DELIVER_TERMINATED_EVENT_FOR_NULL_DIALOG",
1047		        Boolean.FALSE.toString())));
1048
1049
1050		super.maxForkTime = Integer.parseInt(
1051		        configurationProperties.getProperty("gov.nist.javax.sip.MAX_FORK_TIME_SECONDS","0"));
1052
1053	}
1054
1055	/*
1056	 * (non-Javadoc)
1057	 *
1058	 * @see javax.sip.SipStack#createListeningPoint(java.lang.String, int,
1059	 * java.lang.String)
1060	 */
1061	public synchronized ListeningPoint createListeningPoint(String address,
1062			int port, String transport) throws TransportNotSupportedException,
1063			InvalidArgumentException {
1064		if (isLoggingEnabled())
1065			getStackLogger().logDebug(
1066				"createListeningPoint : address = " + address + " port = "
1067						+ port + " transport = " + transport);
1068
1069		if (address == null)
1070			throw new NullPointerException(
1071					"Address for listening point is null!");
1072		if (transport == null)
1073			throw new NullPointerException("null transport");
1074		if (port <= 0)
1075			throw new InvalidArgumentException("bad port");
1076
1077		if (!transport.equalsIgnoreCase("UDP")
1078				&& !transport.equalsIgnoreCase("TLS")
1079				&& !transport.equalsIgnoreCase("TCP")
1080				&& !transport.equalsIgnoreCase("SCTP"))
1081			throw new TransportNotSupportedException("bad transport "
1082					+ transport);
1083
1084		/** Reusing an old stack instance */
1085		if (!this.isAlive()) {
1086			this.toExit = false;
1087			this.reInitialize();
1088		}
1089
1090		String key = ListeningPointImpl.makeKey(address, port, transport);
1091
1092		ListeningPointImpl lip = (ListeningPointImpl) listeningPoints.get(key);
1093		if (lip != null) {
1094			return lip;
1095		} else {
1096			try {
1097				InetAddress inetAddr = InetAddress.getByName(address);
1098				MessageProcessor messageProcessor = this
1099						.createMessageProcessor(inetAddr, port, transport);
1100				if (this.isLoggingEnabled()) {
1101					this.getStackLogger().logDebug(
1102							"Created Message Processor: " + address
1103									+ " port = " + port + " transport = "
1104									+ transport);
1105				}
1106				lip = new ListeningPointImpl(this, port, transport);
1107				lip.messageProcessor = messageProcessor;
1108				messageProcessor.setListeningPoint(lip);
1109				this.listeningPoints.put(key, lip);
1110				// start processing messages.
1111				messageProcessor.start();
1112				return (ListeningPoint) lip;
1113			} catch (java.io.IOException ex) {
1114				if (isLoggingEnabled())
1115					getStackLogger().logError(
1116						"Invalid argument address = " + address + " port = "
1117								+ port + " transport = " + transport);
1118				throw new InvalidArgumentException(ex.getMessage(), ex);
1119			}
1120		}
1121	}
1122
1123	/*
1124	 * (non-Javadoc)
1125	 *
1126	 * @see javax.sip.SipStack#createSipProvider(javax.sip.ListeningPoint)
1127	 */
1128	public SipProvider createSipProvider(ListeningPoint listeningPoint)
1129			throws ObjectInUseException {
1130		if (listeningPoint == null)
1131			throw new NullPointerException("null listeningPoint");
1132		if (this.isLoggingEnabled())
1133			this.getStackLogger().logDebug(
1134					"createSipProvider: " + listeningPoint);
1135		ListeningPointImpl listeningPointImpl = (ListeningPointImpl) listeningPoint;
1136		if (listeningPointImpl.sipProvider != null)
1137			throw new ObjectInUseException("Provider already attached!");
1138
1139		SipProviderImpl provider = new SipProviderImpl(this);
1140
1141		provider.setListeningPoint(listeningPointImpl);
1142		listeningPointImpl.sipProvider = provider;
1143		this.sipProviders.add(provider);
1144		return provider;
1145	}
1146
1147	/*
1148	 * (non-Javadoc)
1149	 *
1150	 * @see javax.sip.SipStack#deleteListeningPoint(javax.sip.ListeningPoint)
1151	 */
1152	public void deleteListeningPoint(ListeningPoint listeningPoint)
1153			throws ObjectInUseException {
1154		if (listeningPoint == null)
1155			throw new NullPointerException("null listeningPoint arg");
1156		ListeningPointImpl lip = (ListeningPointImpl) listeningPoint;
1157		// Stop the message processing thread in the listening point.
1158		super.removeMessageProcessor(lip.messageProcessor);
1159		String key = lip.getKey();
1160		this.listeningPoints.remove(key);
1161
1162	}
1163
1164	/*
1165	 * (non-Javadoc)
1166	 *
1167	 * @see javax.sip.SipStack#deleteSipProvider(javax.sip.SipProvider)
1168	 */
1169	public void deleteSipProvider(SipProvider sipProvider)
1170			throws ObjectInUseException {
1171
1172		if (sipProvider == null)
1173			throw new NullPointerException("null provider arg");
1174		SipProviderImpl sipProviderImpl = (SipProviderImpl) sipProvider;
1175
1176		// JvB: API doc is not clear, but in_use ==
1177		// sipProviderImpl.sipListener!=null
1178		// so we should throw if app did not call removeSipListener
1179		// sipProviderImpl.sipListener = null;
1180		if (sipProviderImpl.getSipListener() != null) {
1181			throw new ObjectInUseException(
1182					"SipProvider still has an associated SipListener!");
1183		}
1184
1185		sipProviderImpl.removeListeningPoints();
1186
1187		// Bug reported by Rafael Barriuso
1188		sipProviderImpl.stop();
1189		sipProviders.remove(sipProvider);
1190		if (sipProviders.isEmpty()) {
1191			this.stopStack();
1192		}
1193	}
1194
1195	/**
1196	 * Get the IP Address of the stack.
1197	 *
1198	 * @see javax.sip.SipStack#getIPAddress()
1199	 * @deprecated
1200	 */
1201	public String getIPAddress() {
1202		return super.getHostAddress();
1203	}
1204
1205	/*
1206	 * (non-Javadoc)
1207	 *
1208	 * @see javax.sip.SipStack#getListeningPoints()
1209	 */
1210	public java.util.Iterator getListeningPoints() {
1211		return this.listeningPoints.values().iterator();
1212	}
1213
1214	/**
1215	 * Return true if retransmission filter is active.
1216	 *
1217	 * @see javax.sip.SipStack#isRetransmissionFilterActive()
1218	 * @deprecated
1219	 */
1220	public boolean isRetransmissionFilterActive() {
1221		return true;
1222	}
1223
1224	/*
1225	 * (non-Javadoc)
1226	 *
1227	 * @see javax.sip.SipStack#getSipProviders()
1228	 */
1229	public java.util.Iterator<SipProviderImpl> getSipProviders() {
1230		return this.sipProviders.iterator();
1231	}
1232
1233	/*
1234	 * (non-Javadoc)
1235	 *
1236	 * @see javax.sip.SipStack#getStackName()
1237	 */
1238	public String getStackName() {
1239		return this.stackName;
1240	}
1241
1242	/**
1243	 * Finalization -- stop the stack on finalization. Exit the transaction
1244	 * scanner and release all resources.
1245	 *
1246	 * @see java.lang.Object#finalize()
1247	 */
1248	protected void finalize() {
1249		this.stopStack();
1250	}
1251
1252	/**
1253	 * This uses the default stack address to create a listening point.
1254	 *
1255	 * @see javax.sip.SipStack#createListeningPoint(java.lang.String, int,
1256	 *      java.lang.String)
1257	 * @deprecated
1258	 */
1259	public ListeningPoint createListeningPoint(int port, String transport)
1260			throws TransportNotSupportedException, InvalidArgumentException {
1261		if (super.stackAddress == null)
1262			throw new NullPointerException(
1263					"Stack does not have a default IP Address!");
1264		return this.createListeningPoint(super.stackAddress, port, transport);
1265	}
1266
1267	/*
1268	 * (non-Javadoc)
1269	 *
1270	 * @see javax.sip.SipStack#stop()
1271	 */
1272	public void stop() {
1273		if (isLoggingEnabled()) {
1274			getStackLogger().logDebug("stopStack -- stoppping the stack");
1275		}
1276		this.stopStack();
1277		this.sipProviders = new LinkedList<SipProviderImpl>();
1278		this.listeningPoints = new Hashtable<String, ListeningPointImpl>();
1279		/*
1280		 * Check for presence of an event scanner ( may happen if stack is
1281		 * stopped before listener is attached ).
1282		 */
1283		if (this.eventScanner != null)
1284			this.eventScanner.forceStop();
1285		this.eventScanner = null;
1286
1287	}
1288
1289	/*
1290	 * (non-Javadoc)
1291	 *
1292	 * @see javax.sip.SipStack#start()
1293	 */
1294	public void start() throws ProviderDoesNotExistException, SipException {
1295		// Start a new event scanner if one does not exist.
1296		if (this.eventScanner == null) {
1297			this.eventScanner = new EventScanner(this);
1298		}
1299
1300	}
1301
1302	/**
1303	 * Get the listener for the stack. A stack can have only one listener. To
1304	 * get an event from a provider, the listener has to be registered with the
1305	 * provider. The SipListener is application code.
1306	 *
1307	 * @return -- the stack SipListener
1308	 *
1309	 */
1310	public SipListener getSipListener() {
1311		return this.sipListener;
1312	}
1313
1314	/**
1315	 * Get the message log factory registered with the stack.
1316	 *
1317	 * @return -- the messageLogFactory of the stack.
1318	 */
1319	public LogRecordFactory getLogRecordFactory() {
1320		return super.logRecordFactory;
1321	}
1322
1323	/**
1324	 * Set the log appender ( this is useful if you want to specify a particular
1325	 * log format or log to something other than a file for example). This method
1326	 * is will be removed May 11, 2010 or shortly there after.
1327	 *
1328	 * @param Appender
1329	 *            - the log4j appender to add.
1330	 * @deprecated TODO: remove this method May 11, 2010.
1331	 */
1332        // BEGIN android-deleted
1333	/*
1334        @Deprecated
1335	public void addLogAppender(org.apache.log4j.Appender appender) {
1336		if (this.getStackLogger() instanceof gov.nist.core.LogWriter) {
1337			((gov.nist.core.LogWriter) this.getStackLogger()).addAppender(appender);
1338		}
1339	}
1340        */
1341        // END android-deleted
1342
1343	/**
1344	 * Get the log4j logger ( for log stream integration ).
1345	 * This method will be removed May 11, 2010 or shortly there after.
1346	 *
1347	 * @return  the log4j logger.
1348	 * @deprecated TODO: This method will be removed May 11, 2010.
1349	 */
1350	@Deprecated
1351        // BEGIN andoird-deleted
1352        /*
1353	public org.apache.log4j.Logger getLogger() {
1354		if (this.getStackLogger() instanceof gov.nist.core.LogWriter) {
1355			return ((gov.nist.core.LogWriter) this.getStackLogger()).getLogger();
1356		}
1357		return null;
1358	}
1359        */
1360        // END android-deleted
1361
1362	public EventScanner getEventScanner() {
1363		return eventScanner;
1364	}
1365
1366	/*
1367	 * (non-Javadoc)
1368	 *
1369	 * @see
1370	 * gov.nist.javax.sip.SipStackExt#getAuthenticationHelper(gov.nist.javax
1371	 * .sip.clientauthutils.AccountManager, javax.sip.header.HeaderFactory)
1372	 */
1373	public AuthenticationHelper getAuthenticationHelper(
1374			AccountManager accountManager, HeaderFactory headerFactory) {
1375		return new AuthenticationHelperImpl(this, accountManager, headerFactory);
1376	}
1377
1378	/*
1379	 * (non-Javadoc)
1380	 *
1381	 * @see
1382	 * gov.nist.javax.sip.SipStackExt#getAuthenticationHelper(gov.nist.javax
1383	 * .sip.clientauthutils.AccountManager, javax.sip.header.HeaderFactory)
1384	 */
1385	public AuthenticationHelper getSecureAuthenticationHelper(
1386			SecureAccountManager accountManager, HeaderFactory headerFactory) {
1387		return new AuthenticationHelperImpl(this, accountManager, headerFactory);
1388	}
1389
1390	/**
1391	 * Set the list of cipher suites supported by the stack. A stack can have
1392	 * only one set of suites. These are not validated against the supported
1393	 * cipher suites of the java runtime, so specifying a cipher here does not
1394	 * guarantee that it will work.<br>
1395	 * The stack has a default cipher suite of:
1396	 * <ul>
1397	 * <li>TLS_RSA_WITH_AES_128_CBC_SHA</li>
1398	 * <li>SSL_RSA_WITH_3DES_EDE_CBC_SHA</li>
1399	 * <li>TLS_DH_anon_WITH_AES_128_CBC_SHA</li>
1400	 * <li>SSL_DH_anon_WITH_3DES_EDE_CBC_SHA</li>
1401	 * </ul>
1402	 *
1403	 * <b>NOTE: This function must be called before adding a TLS listener</b>
1404	 *
1405	 * @param String
1406	 *            [] The new set of ciphers to support.
1407	 * @return
1408	 *
1409	 */
1410	public void setEnabledCipherSuites(String[] newCipherSuites) {
1411		cipherSuites = newCipherSuites;
1412	}
1413
1414	/**
1415	 * Return the currently enabled cipher suites of the Stack.
1416	 *
1417	 * @return The currently enabled cipher suites.
1418	 */
1419	public String[] getEnabledCipherSuites() {
1420		return cipherSuites;
1421	}
1422
1423	/**
1424	 * Set the list of protocols supported by the stack for outgoing TLS connections.
1425	 * A stack can have only one set of protocols.
1426	 * These are not validated against the supported
1427	 * protocols of the java runtime, so specifying a protocol here does not
1428	 * guarantee that it will work.<br>
1429	 * The stack has a default protocol suite of:
1430	 * <ul>
1431	 * <li>SSLv3</li>
1432	 * <li>SSLv2Hello</li>
1433	 * <li>TLSv1</li>
1434	 * </ul>
1435	 *
1436	 * <b>NOTE: This function must be called before creating a TLSMessageChannel.</b>
1437	 *
1438	 * @param String
1439	 *            [] The new set of protocols to use for outgoing TLS connections.
1440	 * @return
1441	 *
1442	 */
1443	public void setEnabledProtocols(String[] newProtocols) {
1444		enabledProtocols = newProtocols;
1445	}
1446
1447	/**
1448	 * Return the currently enabled protocols to use when creating TLS connection.
1449	 *
1450	 * @return The currently enabled protocols.
1451	 */
1452	public String[] getEnabledProtocols() {
1453		return enabledProtocols;
1454	}
1455
1456	/**
1457	 * Set the "back to back User Agent" flag.
1458	 *
1459	 * @param flag
1460	 *            - boolean flag to set.
1461	 *
1462	 */
1463	public void setIsBackToBackUserAgent(boolean flag) {
1464		super.isBackToBackUserAgent = flag;
1465	}
1466
1467	/**
1468	 * Get the "back to back User Agent" flag.
1469	 *
1470	 * return the value of the flag
1471	 *
1472	 */
1473	public boolean isBackToBackUserAgent() {
1474		return super.isBackToBackUserAgent;
1475	}
1476
1477	public boolean isAutomaticDialogErrorHandlingEnabled() {
1478		return super.isAutomaticDialogErrorHandlingEnabled;
1479	}
1480
1481    public boolean acquireSem() {
1482        try {
1483            return this.stackSemaphore.tryAcquire(10, TimeUnit.SECONDS);
1484        } catch ( InterruptedException ex) {
1485            return false;
1486        }
1487    }
1488
1489    public void releaseSem() {
1490        this.stackSemaphore.release();
1491    }
1492
1493
1494
1495
1496}
1497