Start line:  
End line:  

Snippet Preview

Snippet HTML Code

Stack Overflow Questions
   /*
    * Conditions Of Use
    *
    * This software was developed by employees of the National Institute of
    * Standards and Technology (NIST), an agency of the Federal Government.
    * Pursuant to title 15 Untied States Code Section 105, works of NIST
    * employees are not subject to copyright protection in the United States
    * and are considered to be in the public domain.  As a result, a formal
    * license is not needed to use the software.
   *
   * This software is provided by NIST as a service and is expressly
   * provided "AS IS."  NIST MAKES NO WARRANTY OF ANY KIND, EXPRESS, IMPLIED
   * OR STATUTORY, INCLUDING, WITHOUT LIMITATION, THE IMPLIED WARRANTY OF
   * MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE, NON-INFRINGEMENT
   * AND DATA ACCURACY.  NIST does not warrant or make any representations
   * regarding the use of the software or the results thereof, including but
   * not limited to the correctness, accuracy, reliability or usefulness of
   * the software.
   *
   * Permission to use this software is contingent upon your acceptance
   * of the terms of this agreement
   *
   * .
   *
   */
  package gov.nist.javax.sip;
  
  
  import java.util.List;
  
Implementation of SipStack. The JAIN-SIP stack is initialized by a set of properties (see the JAIN SIP documentation for an explanation of these properties javax.sip.SipStack ). For NIST SIP stack all properties can also be passed as JVM system properties from the command line as -D arguments. In addition to these, the following are meaningful properties for the NIST SIP stack (specify these in the property array when you create the JAIN-SIP statck):
  • gov.nist.javax.sip.TRACE_LEVEL = integer
    Use of this property is still supported but deprecated. Please use gov.nist.javax.sip.STACK_LOGGER and gov.nist.javax.sip.SERVER_LOGGER for integration with logging frameworks and for custom formatting of log records. This property is used by the built in log4j based logger. You can use the standard log4j level names here (i.e. ERROR, INFO, WARNING, OFF, DEBUG, TRACE) If this is set to INFO or above, then incoming valid messages are logged in SERVER_LOG. If you set this to 32 and specify a DEBUG_LOG then vast amounts of trace information will be dumped in to the specified DEBUG_LOG. The server log accumulates the signaling trace. This can be viewed using the trace viewer tool . Please send us both the server log and debug log when reporting non-obvious problems. You can also use the strings DEBUG or INFO for level 32 and 16 respectively. If the value of this property is set to LOG4J, then the effective log levels are determined from the log4j settings file (e.g. log4j.properties). The logger name for the stack is specified using the gov.nist.javax.sip.LOG4J_LOGGER_NAME property. By default log4j logger name for the stack is the same as the stack name. For example, properties.setProperty("gov.nist.javax.sip.TRACE_LEVEL", "LOG4J"); properties.setProperty("gov.nist.javax.sip.LOG4J_LOGGER_NAME", "SIPStackLogger"); allows you to now control logging in the stack entirely using log4j facilities.
  • gov.nist.javax.sip.LOG_FACTORY = classpath Use of this property is still supported but deprecated. Please use gov.nist.javax.sip.STACK_LOGGER and gov.nist.javax.sip.SERVER_LOGGER for integration with logging frameworks and for custom formatting of log records.
    The fully qualified classpath for an implementation of the MessageLogFactory. The stack calls the MessageLogFactory functions to format the log for messages that are received or sent. This function allows you to log auxiliary information related to the application or environmental conditions into the log stream. The log factory must have a default constructor.
  • gov.nist.javax.sip.SERVER_LOG = fileName
    Use of this property is still supported but deprecated. Please use gov.nist.javax.sip.STACK_LOGGER and gov.nist.javax.sip.SERVER_LOGGER for integration with logging frameworks and for custom formatting of log records. Log valid incoming messages here. If this is left null AND the TRACE_LEVEL is above INFO (or TRACE) then the messages are printed to stdout. Otherwise messages are logged in a format that can later be viewed using the trace viewer application which is located in the tools/tracesviewer directory. Mail this to us with bug reports.
  • gov.nist.javax.sip.DEBUG_LOG = fileName Use of this property is still supported but deprecated. Please use gov.nist.javax.sip.STACK_LOGGER and gov.nist.javax.sip.SERVER_LOGGER for integration with logging frameworks and for custom formatting of log records.
    Where the debug log goes. Mail this to us with bug reports.
  • gov.nist.javax.sip.LOG_MESSAGE_CONTENT = true|false
    Set true if you want to capture content into the log. Default is false. A bad idea to log content if you are using SIP to push a lot of bytes through TCP.
  • gov.nist.javax.sip.LOG_STACK_TRACE_ON_MESSAGE_SEND = true|false
    Set true if you want to to log a stack trace at INFO level for each message send. This is really handy for debugging.
  • gov.nist.javax.sip.STACK_LOGGER = full path name to the class implementing gov.nist.core.StackLogger interface
    If this property is defined the sip stack will try to instantiate it through a no arg constructor. This allows to use different logging implementations than the ones provided by default to log what happens within the stack while processing SIP messages. If this property is not defined, the default sip stack LogWriter will be used for logging
  • gov.nist.javax.sip.SERVER_LOGGER = full path name to the class implementing gov.nist.core.ServerLogger interface
    If this property is defined the sip stack will try to instantiate it through a no arg constructor. This allows to use different logging implementations than the ones provided by default to log sent/received messages by the sip stack. If this property is not defined, the default sip stack ServerLog will be used for logging
  • gov.nist.javax.sip.AUTOMATIC_DIALOG_ERROR_HANDLING = [true|false]
    Default is <it>true</it>. This is also settable on a per-provider basis. This flag is set to true by default. When set to <it>false</it> the following behaviors are enabled:
    • Turn off Merged requests Loop Detection:
      The following behavior is turned off: If the request has no tag in the To header field, the UAS core MUST check the request against ongoing transactions. If the From tag, Call-ID, and CSeq exactly match those associated with an ongoing transaction, but the request does not match that transaction (based on the matching rules in Section 17.2.3), the UAS core SHOULD generate a 482 (Loop Detected) response and pass it to the server transaction.
  • gov.nist.javax.sip.IS_BACK_TO_BACK_USER_AGENT = [true|false]
    Default is <it>false</it> This property controls a setting on the Dialog objects that the stack manages. Pure B2BUA applications should set this flag to <it>true</it>. This property can also be set on a per-dialog basis. Setting this to <it>true</it> imposes serialization on re-INVITE and makes the sending of re-INVITEs asynchronous. The sending of re-INVITE is controlled as follows : If the previous in-DIALOG request was an invite ClientTransaction then the next re-INVITEs that uses the dialog will wait till an ACK has been sent before admitting the new re-INVITE. If the previous in-DIALOG transaction was a INVITE ServerTransaction then Dialog waits for ACK before re-INVITE is allowed to be sent. If a dialog is not ACKed within 32 seconds, then the dialog is torn down and a BYE sent to the peer.
  • gov.nist.javax.sip.MAX_MESSAGE_SIZE = integer
    Maximum size of content that a TCP connection can read. Must be at least 4K. Default is "infinity" -- ie. no limit. This is to prevent DOS attacks launched by writing to a TCP connection until the server chokes.
  • gov.nist.javax.sip.DELIVER_TERMINATED_EVENT_FOR_NULL_DIALOG = [true|false]
    If set to false (the default), the application does NOT get notified when a Dialog in the NULL state is terminated. ( Dialogs in the NULL state are not associated with an actual SIP Dialog. They are a programming convenience. A Dialog is in the NULL state before the first response for the Dialog forming Transaction). If set to true, the SipListener will get a DialogTerminatedEvent when a Dialog in the NULL state is terminated.
  • gov.nist.javax.sip.CACHE_SERVER_CONNECTIONS = [true|false]
    Default value is true. Setting this to false makes the Stack close the server socket after a Server Transaction goes to the TERMINATED state. This allows a server to protectect against TCP based Denial of Service attacks launched by clients (ie. initiate hundreds of client transactions). If true (default action), the stack will keep the socket open so as to maximize performance at the expense of Thread and memory resources - leaving itself open to DOS attacks.
  • gov.nist.javax.sip.CACHE_CLIENT_CONNECTIONS = [true|false]
    Default value is true. Setting this to false makes the Stack close the server socket after a Client Transaction goes to the TERMINATED state. This allows a client release any buffers threads and socket connections associated with a client transaction after the transaction has terminated at the expense of performance.
  • gov.nist.javax.sip.THREAD_POOL_SIZE = integer
    Concurrency control for number of simultaneous active threads. If unspecificed, the default is "infinity". This feature is useful if you are trying to build a container.
    • If this is not specified, and the listener is re-entrant, each event delivered to the listener is run in the context of a new thread.
    • If this is specified and the listener is re-entrant, then the stack will run the listener using a thread from the thread pool. This allows you to manage the level of concurrency to a fixed maximum. Threads are pre-allocated when the stack is instantiated.
    • If this is specified and the listener is not re-entrant, then the stack will use the thread pool thread from this pool to parse and manage the state machine but will run the listener in its own thread.
  • gov.nist.javax.sip.REENTRANT_LISTENER = true|false
    Default is false. Set to true if the listener is re-entrant. If the listener is re-entrant then the stack manages a thread pool and synchronously calls the listener from the same thread which read the message. Multiple transactions may concurrently receive messages and this will result in multiple threads being active in the listener at the same time. The listener has to be written with this in mind. If you want good performance on a multithreaded machine write your listener to be re-entrant and set this property to be true
  • gov.nist.javax.sip.MAX_CONNECTIONS = integer
    Max number of simultaneous TCP connections handled by stack.
  • gov.nist.javax.sip.MAX_SERVER_TRANSACTIONS = integer
    Maximum size of server transaction table. The low water mark is 80% of the high water mark. Requests are selectively dropped in the lowater mark to highwater mark range. Requests are unconditionally accepted if the table is smaller than the low water mark. The default highwater mark is 5000
  • gov.nist.javax.sip.MAX_CLIENT_TRANSACTIONS = integer
    Max number of active client transactions before the caller blocks and waits for the number to drop below a threshold. Default is unlimited, i.e. the caller never blocks and waits for a client transaction to become available (i.e. it does its own resource management in the application).
  • gov.nist.javax.sip.PASS_INVITE_NON_2XX_ACK_TO_LISTENER = true|false
    If true then the listener will see the ACK for non-2xx responses for server transactions. This is not standard behavior per RFC 3261 (INVITE server transaction state machine) but this is a useful flag for testing. The TCK uses this flag for example.
  • gov.nist.javax.sip.MAX_LISTENER_RESPONSE_TIME = Integer
    Max time (seconds) before sending a response to a server transaction. If a response is not sent within this time period, the transaction will be deleted by the stack. Default time is "infinity" - i.e. if the listener never responds, the stack will hang on to a reference for the transaction and result in a memory leak.
  • gov.nist.javax.sip.DELIVER_TERMINATED_EVENT_FOR_ACK = [true|false]
    Default is <it>false</it>. ACK Server Transaction is a Pseuedo-transaction. If you want termination notification on ACK transactions (so all server transactions can be handled uniformly in user code during cleanup), then set this flag to <it>true</it>.
  • gov.nist.javax.sip.READ_TIMEOUT = integer
    This is relevant for incoming TCP connections to prevent starvation at the server. This defines the timeout in miliseconds between successive reads after the first byte of a SIP message is read by the stack. All the sip headers must be delivered in this interval and each successive buffer must be of the content delivered in this interval. Default value is -1 (ie. the stack is wide open to starvation attacks) and the client can be as slow as it wants to be.
  • gov.nist.javax.sip.NETWORK_LAYER = classpath
    This is an EXPERIMENTAL property (still under active devlopment). Defines a network layer that allows a client to have control over socket allocations and monitoring of socket activity. A network layer should implement gov.nist.core.net.NetworkLayer. The default implementation simply acts as a wrapper for the standard java.net socket layer. This functionality is still under active development (may be extended to support security and other features).
  • gov.nist.javax.sip.ADDRESS_RESOLVER = classpath
    The fully qualified class path for an implementation of the AddressResolver interface. The AddressResolver allows you to support lookup schemes for addresses that are not directly resolvable to IP adresses using getHostByName. Specifying your own address resolver allows you to customize address lookup. The default address resolver is a pass-through address resolver (i.e. just returns the input string without doing a resolution). See gov.nist.javax.sip.DefaultAddressResolver.
  • gov.nist.javax.sip.AUTO_GENERATE_TIMESTAMP= [true| false]
    (default is false) Automatically generate a getTimeOfDay timestamp for a retransmitted request if the original request contained a timestamp. This is useful for profiling.
  • gov.nist.javax.sip.THREAD_AUDIT_INTERVAL_IN_MILLISECS = long
    Defines how often the application intends to audit the SIP Stack about the health of its internal threads (the property specifies the time in miliseconds between successive audits). The audit allows the application to detect catastrophic failures like an internal thread terminating because of an exception or getting stuck in a deadlock condition. Events like these will make the stack inoperable and therefore require immediate action from the application layer (e.g., alarms, traps, reboot, failover, etc.) Thread audits are disabled by default. If this property is not specified, audits will remain disabled. An example of how to use this property is in src/examples/threadaudit.
  • gov.nist.javax.sip.COMPUTE_CONTENT_LENGTH_FROM_MESSAGE_BODY = [true|false]
    Default is <it>false</it> If set to <it>true</it>, when you are creating a message from a <it>String</it>, the MessageFactory will compute the content length from the message content and ignore the provided content length parameter in the Message. Otherwise, it will use the content length supplied and generate a parse exception if the content is truncated.
  • gov.nist.javax.sip.CANCEL_CLIENT_TRANSACTION_CHECKED = [true|false]
    Default is <it>true</it>. This flag is added in support of load balancers or failover managers where you may want to cancel ongoing transactions from a different stack than the original stack. If set to <it>false</it> then the CANCEL client transaction is not checked for the existence of the INVITE or the state of INVITE when you send the CANCEL request. Hence you can CANCEL an INVITE from a different stack than the INVITE. You can also create a CANCEL client transaction late and send it out after the INVITE server transaction has been Terminated. Clearly this will result in protocol errors. Setting the flag to true ( default ) enables you to avoid common protocol errors.
  • gov.nist.javax.sip.IS_BACK_TO_BACK_USER_AGENT = [true|false]
    Default is <it>false</it> This property controls a setting on the Dialog objects that the stack manages. Pure B2BUA applications should set this flag to <it>true</it>. This property can also be set on a per-dialog basis. Setting this to <it>true</it> imposes serialization on re-INVITE and makes the sending of re-INVITEs asynchronous. The sending of re-INVITE is controlled as follows : If the previous in-DIALOG request was an invite ClientTransaction then the next re-INVITEs that uses the dialog will wait till an ACK has been sent before admitting the new re-INVITE. If the previous in-DIALOG transaction was a INVITE ServerTransaction then Dialog waits for ACK before re-INVITE is allowed to be sent. If a dialog is not ACKed within 32 seconds, then the dialog is torn down and a BYE sent to the peer.
  • gov.nist.javax.sip.RECEIVE_UDP_BUFFER_SIZE = int
    Default is <it>8*1024</it>. This property control the size of the UDP buffer used for SIP messages. Under load, if the buffer capacity is overflown the messages are dropped causing retransmissions, further increasing the load and causing even more retransmissions. Good values to this property for servers is a big number in the order of 8*8*1024.
  • gov.nist.javax.sip.SEND_UDP_BUFFER_SIZE = int
    Default is <it>8*1024</it>. This property control the size of the UDP buffer used for SIP messages. Under load, if the buffer capacity is overflown the messages are dropped causing retransmissions, further increasing the load and causing even more retransmissions. Good values to this property for servers is a big number in the order of 8*8*1024 or higher.
  • gov.nist.javax.sip.CONGESTION_CONTROL_TIMEOUT = int How much time messages are allowed to wait in queue before being dropped due to stack being too slow to respond. Default value is 8000 ms. The value is in milliseconds
  • gov.nist.javax.sip.TCP_POST_PARSING_THREAD_POOL_SIZE = integer Use 0 or do not set this option to disable it. When using TCP your phones/clients usually connect independently creating their own TCP sockets. Sometimes however SIP devices are allowed to tunnel multiple calls over a single socket. This can also be simulated with SIPP by running "sipp -t t1". In the stack each TCP socket has it's own thread. When all calls are using the same socket they all use a single thread, which leads to severe performance penalty, especially on multi-core machines. This option instructs the SIP stack to use a thread pool and split the CPU load between many threads. The number of the threads is specified in this parameter. The processing is split immediately after the parsing of the message. It cannot be split before the parsing because in TCP the SIP message size is in the Content-Length header of the message and the access to the TCP network stream has to be synchronized. Additionally in TCP the message size can be larger. This causes most of the parsing for all calls to occur in a single thread, which may have impact on the performance in trivial applications using a single socket for all calls. In most applications it doesn't have performance impact. If the phones/clients use separate TCP sockets for each call this option doesn't have much impact, except the slightly increased memory footprint caused by the thread pool. It is recommended to disable this option in this case by setting it 0 or not setting it at all. You can simulate multi-socket mode with "sipp -t t0". With this option also we avoid closing the TCP socket when something fails, because we must keep processing other messages for other calls. Note: This option relies on accurate Content-Length headers in the SIP messages. It cannot recover once a malformed message is processed, because the stream iterator will not be aligned any more. Eventually the connection will be closed.
  • gov.nist.javax.sip.DELIVER_UNSOLICITED_NOTIFY = [true|false]
    Default is <it>false</it>. This flag is added to allow Sip Listeners to receive all NOTIFY requests including those that are not part of a valid dialog.
  • gov.nist.javax.sip.REJECT_STRAY_RESPONSES = [true|false] Default is <it>false</it> A flag that checks responses to test whether the response corresponds to a via header that was previously generated by us. Note that setting this flag implies that the stack will take control over setting the VIA header for Sip Requests sent through the stack. The stack will attach a suffix to the VIA header branch and check any response arriving at the stack to see if that response suffix is present. If it is not present, then the stack will silently drop the response.
  • gov.nist.javax.sip.MAX_FORK_TIME_SECONDS = integer Maximum time for which the original transaction for which a forked response is received is tracked. This property is only relevant to Dialog Stateful applications ( User Agents or B2BUA). When a forked response is received in this time interval from when the original INVITE client transaction was sent, the stack will place the original INVITE client transction in the ResponseEventExt and deliver that to the application. The event handler can get the original transaction from this event.
  • gov.nist.javax.sip.EARLY_DIALOG_TIMEOUT_SECONDS=integer Maximum time for which a dialog can remain in early state. This is defaulted to 3 minutes ( 180 seconds).
  • gov.nist.javax.sip.THREAD_PRIORITY=integer Control the priority of the threads started by the stack.
  • gov.nist.javax.sip.MESSAGE_PARSER_FACTORY = name of the class implementing gov.nist.javax.sip.parser.MessageParserFactory This factory allows pluggable implementations of the MessageParser that will take care of parsing the incoming messages. By example one could plug a lazy parser through this factory.
  • gov.nist.javax.sip.MESSAGE_PROCESSOR_FACTORY = name of the class implementing gov.nist.javax.sip.parser.MessageProcessorFactory This factory allows pluggable implementations of the MessageProcessor that will take care of incoming messages. By example one could plug a NIO Processor through this factory.
  • gov.nist.javax.sip.TIMER_CLASS_NAME = name of the class implementing gov.nist.javax.sip.stack.timers.SipTimer interface This allows pluggable implementations of the Timer that will take care of scheduling the various SIP Timers. By example one could plug a regular timer, a scheduled thread pool executor.
  • gov.nist.javax.sip.DELIVER_RETRANSMITTED_ACK_TO_LISTENER=boolean A testing property that allows application to see the ACK for retransmitted 200 OK requests. Note that this is for test purposes only
  • *
  • gov.nist.javax.sip.AGGRESSIVE_CLEANUP=boolean A property that will cleanup Dialog, and Transaction structures agrressively to improve memroy usage and performance (up to 50% gain). However one needs to be careful in its code on how and when it accesses transaction and dialog data since it cleans up aggressively when transactions changes state to COMPLETED or TERMINATED and for Dialog once the ACK is received/sent
  • gov.nist.javax.sip.MIN_KEEPALIVE_TIME_SECONDS = integer Minimum time between keep alive pings (CRLF CRLF) from clients. If pings arrive with less than this frequency they will be replied with CRLF CRLF if greater they will be rejected. The default is -1 (i.e. do not respond to CRLF CRLF).
  • gov.nist.javax.sip.DIALOG_TIMEOUT_FACTOR= integer Default to 64. The number of ticks before a dialog that does not receive an ACK receives a Timeout notification. Note that this is only relevant if the registered SipListener is of type SipListenerExt
  • gov.nist.javax.sip.SIP_MESSAGE_VALVE= String Default to null. The class name of your custom valve component. An instance of this class will be created and the SIPMessageValve.processRequest/Response() methods will be called for every message before any long-lived SIP Stack resources are allocated (no transactions, no dialogs). From within the processRequest callback implementation you can drop messages, send a response statelessly or otherwise transform/pre-process the message before it reaches the next steps of the pipeline. Similarly from processResponse() you can manipulate a response or drop it silently, but dropping responses is not recommended, because the transaction already exists when the request for the response was sent.
  • gov.nist.javax.sip.SIP_EVENT_INTERCEPTOR Default to null. The class name of your custom interceptor object. An instance of this object will be created at initialization of the stack. You must implement the interface gov.nist.javax.sip.stack.SIPEventInterceptor and handle the lifecycle callbacks. This interface is the solution for https://jain-sip.dev.java.net/issues/show_bug.cgi?id=337 . It allows to wrap the JSIP pipeline and execute custom analysis logic as SIP messages advance through the pipeline checkpoints. One example implementation of this interceptor is gov.nist.javax.sip.stack.CallAnalysisInterceptor, which will periodically check for requests stuck in the JAIN SIP threads and if some request is taking too long it will log the stack traces for all threads. The logging can occur only on certain events, so it will not overwhelm the CPU. The overall performance penalty by using this class in production under load is only 2% peak on average laptop machine. There is minimal locking inside. One known limitation of this feature is that you must use gov.nist.javax.sip.REENTRANT_LISTENER=true to ensure that the request will be processed in the original thread completely for UDP.
  • gov.nist.javax.sip.TLS_CLIENT_PROTOCOLS = String Comma-separated list of protocols to use when creating outgoing TLS connections. The default is "SSLv3, SSLv2Hello, TLSv1". Some servers do not support SSLv2Hello, so override to "SSLv3, TLSv1".
  • gov.nist.javax.sip.TLS_SECURITY_POLICY = String The fully qualified path name of a TLS Security Policy implementation that is consulted for certificate verification of outbund TLS connections.
  • gov.nist.javax.sip.TLS_CLIENT_AUTH_TYPE = String Valid values are Default (backward compatible with previous versions) , Enabled, Want or Disabled. Set to Enabled if you want the SSL stack to require a valid certificate chain from the client before accepting a connection. Set to Want if you want the SSL stack to request a client Certificate, but not fail if one isn't presented. A Disabled value will not require a certificate chain.
  • javax.net.ssl.keyStore = fileName
    Default is <it>NULL</it>. If left undefined the keyStore and trustStore will be left to the java runtime defaults. If defined, any TLS sockets created (client and server) will use the key store provided in the fileName. The trust store will default to the same store file. A password must be provided to access the keyStore using the following property:
    properties.setProperty("javax.net.ssl.keyStorePassword", "<password>");
    The trust store can be changed, to a separate file with the following setting:
    properties.setProperty("javax.net.ssl.trustStore", "<trustStoreFileName location>");
    If the trust store property is provided the password on the trust store must be the same as the key store.

Note that the stack supports the extensions that are defined in SipStackExt. These will be supported in the next release of JAIN-SIP. You should only use the extensions that are defined in this class.

Author(s):
M. Ranganathan
Version:
1.2 $Revision: 1.143 $ $Date: 2010-12-02 22:04:18 $
 
 public class SipStackImpl extends SIPTransactionStack implements
 	private static StackLogger logger = CommonLogger.getLogger(SipStackImpl.class);
 
 
Max datagram size.
 
 	public static final Integer MAX_DATAGRAM_SIZE = 64 * 1024;
 
 	// Flag to indicate that the listener is re-entrant and hence
 	// Use this flag with caution.
 	private boolean reEntrantListener;
 
 
 	// Stack semaphore (global lock).
 	private Semaphore stackSemaphore = new Semaphore(1);
 
 	// RFC3261: TLS_RSA_WITH_AES_128_CBC_SHA MUST be supported
 	// RFC3261: TLS_RSA_WITH_3DES_EDE_CBC_SHA SHOULD be supported for backwards
 	// compat
 	private String[] cipherSuites = {
 			"TLS_RSA_WITH_AES_128_CBC_SHA"// AES difficult to get with
 											// c++/Windows
 			// "TLS_RSA_WITH_3DES_EDE_CBC_SHA", // Unsupported by Sun impl,
 			"SSL_RSA_WITH_3DES_EDE_CBC_SHA"// For backwards comp., C++
 
 			// JvB: patch from Sebastien Mazy, issue with mismatching
 			// ciphersuites
 			"TLS_DH_anon_WITH_AES_128_CBC_SHA",
 			"SSL_DH_anon_WITH_3DES_EDE_CBC_SHA", };
 
 	// Supported protocols for TLS client: can be overridden by application
 	private String[] enabledProtocols = {
 			"SSLv3",
 			"SSLv2Hello",
 			"TLSv1"
 	};
 
Creates a new instance of SipStackImpl.
 
 
 	protected SipStackImpl() {
 		super();
 				this);
 		super.setMessageFactory(msgFactory);
 		this. = new EventScanner(this);
 
 	}

ReInitialize the stack instance.
 
 	private void reInitialize() {
 		super.reInit();
 		this. = new EventScanner(this);
 		this. = null;
 		if(!getTimer().isStarted()) {			
 			String defaultTimerName = .getProperty("gov.nist.javax.sip.TIMER_CLASS_NAME",DefaultSipTimer.class.getName());
 			try {				
 				setTimer((SipTimer)Class.forName(defaultTimerName).newInstance());
 		            // Start monitoring the timer thread
 		            getTimer().schedule(new PingTimer(null), 0);
 		        }
 			} catch (Exception e) {
 							"Bad configuration value for gov.nist.javax.sip.TIMER_CLASS_NAME"e);			
 			}
 		}
 	}

Return true if automatic dialog support is enabled for this stack.

Returns:
boolean, true if automatic dialog support is enabled for this stack
 
 	}

Constructor for the stack.

Parameters:
configurationProperties -- stack configuration properties including NIST-specific extensions.
Throws:
javax.sip.PeerUnavailableException
 
 	public SipStackImpl(Properties configurationProperties)
 		this();
 		configurationProperties = new MergedSystemProperties(configurationProperties);
 		this. = configurationProperties;
 		String address = configurationProperties
 				.getProperty("javax.sip.IP_ADDRESS");
 		try {
Retrieve the stack IP address
 
 			if (address != null) {
 				// In version 1.2 of the spec the IP address is
 				// associated with the listening point and
 				// is not madatory.
 				super.setHostAddress(address);
 
 			}
 		} catch (java.net.UnknownHostException ex) {
 			throw new PeerUnavailableException("bad address " + address);
 		}

Retrieve the stack name
 
 		String name = configurationProperties
 				.getProperty("javax.sip.STACK_NAME");
 		if (name == null)
 			throw new PeerUnavailableException("stack name is missing");
 		super.setStackName(name);
 		String stackLoggerClassName = configurationProperties
 				.getProperty("gov.nist.javax.sip.STACK_LOGGER");
 		// To log debug messages.
 		if (stackLoggerClassName == null)
 			stackLoggerClassName = "gov.nist.core.LogWriter";
 			try {
 				Class<?> stackLoggerClass = Class.forName(stackLoggerClassName);
 				Class<?>[] constructorArgs = new Class[0];
 				Constructor<?> cons = stackLoggerClass
 						.getConstructor(constructorArgs);
 				Object[] args = new Object[0];
 				StackLogger stackLogger = (StackLoggercons.newInstance(args);
 				. = stackLogger;
 				stackLogger.setStackProperties(configurationProperties);
 			} catch (InvocationTargetException ex1) {
 						"Cound not instantiate stack logger "
 								+ stackLoggerClassName
 								+ "- check that it is present on the classpath and that there is a no-args constructor defined",
 						ex1);
 			} catch (Exception ex) {
 						"Cound not instantiate stack logger "
 								+ stackLoggerClassName
 								+ "- check that it is present on the classpath and that there is a no-args constructor defined",
 						ex);
 			}
 
 		String serverLoggerClassName = configurationProperties
 				.getProperty("gov.nist.javax.sip.SERVER_LOGGER");
 		// To log debug messages.
 		if (serverLoggerClassName == null)
 			serverLoggerClassName = "gov.nist.javax.sip.stack.ServerLog";
 			try {
 				Class<?> serverLoggerClass = Class
 						.forName(serverLoggerClassName);
 				Class<?>[] constructorArgs = new Class[0];
 				Constructor<?> cons = serverLoggerClass
 						.getConstructor(constructorArgs);
 				Object[] args = new Object[0];
 				this. = (ServerLoggercons.newInstance(args);
 				.setStackProperties(configurationProperties);
 			} catch (InvocationTargetException ex1) {
 						"Cound not instantiate server logger "
 								+ stackLoggerClassName
 								+ "- check that it is present on the classpath and that there is a no-args constructor defined",
 						ex1);
 			} catch (Exception ex) {
 						"Cound not instantiate server logger "
 								+ stackLoggerClassName
 								+ "- check that it is present on the classpath and that there is a no-args constructor defined",
 						ex);
 			}
 
 		super.setThreadPriority(Integer.parseInt(
 			        configurationProperties.getProperty("gov.nist.javax.sip.THREAD_PRIORITY","" + .)));
 			
 		// Default router -- use this for routing SIP URIs.
 		// Our router does not do DNS lookups.
 		this. = configurationProperties
 				.getProperty("javax.sip.OUTBOUND_PROXY");
 
 		this. = new DefaultRouter(this);

Retrieve the router path
 
 		String routerPath = configurationProperties
 				.getProperty("javax.sip.ROUTER_PATH");
 		if (routerPath == null)
 			routerPath = "gov.nist.javax.sip.stack.DefaultRouter";
 
 		try {
 			Class<?> routerClass = Class.forName(routerPath);
 			Class<?>[] constructorArgs = new Class[2];
 			constructorArgs[0] = javax.sip.SipStack.class;
 			constructorArgs[1] = String.class;
 			Constructor<?> cons = routerClass.getConstructor(constructorArgs);
 			Object[] args = new Object[2];
 			args[0] = (SipStackthis;
 			args[1] = ;
 			Router router = (Routercons.newInstance(args);
 			super.setRouter(router);
 		} catch (InvocationTargetException ex1) {
 							"could not instantiate router -- invocation target problem",
 							(Exceptionex1.getCause());
 					"Cound not instantiate router - check constructor"ex1);
 		} catch (Exception ex) {
 			.logError("could not instantiate router",
 					(Exceptionex.getCause());
 			throw new PeerUnavailableException("Could not instantiate router",
 					ex);
 		}
 
 		// The flag that indicates that the default router is to be ignored.
 		String useRouterForAll = configurationProperties
 				.getProperty("javax.sip.USE_ROUTER_FOR_ALL_URIS");
 		this. = true;
 		if (useRouterForAll != null) {
 			this. = "true".equalsIgnoreCase(useRouterForAll);
 		}
 
 		/*
 		 * Retrieve the EXTENSION Methods. These are used for instantiation of
 		 * Dialogs.
 		 */
 		String extensionMethods = configurationProperties
 				.getProperty("javax.sip.EXTENSION_METHODS");
 
 		if (extensionMethods != null) {
 					extensionMethods);
 			while (st.hasMoreTokens()) {
 				String em = st.nextToken(":");
 					throw new PeerUnavailableException("Bad extension method "
 							+ em);
 				else
 			}
 		}
 		String keyStoreFile = configurationProperties
 				.getProperty("javax.net.ssl.keyStore");
 		String trustStoreFile = configurationProperties
 				.getProperty("javax.net.ssl.trustStore");
 		if (keyStoreFile != null) {
 			if (trustStoreFile == null) {
 				trustStoreFile = keyStoreFile;
 			}
 			String keyStorePassword = configurationProperties
 					.getProperty("javax.net.ssl.keyStorePassword");
 			try {
 				this. = new SslNetworkLayer(trustStoreFile,
 						keyStoreFile,
 						keyStorePassword != null ?
 						    keyStorePassword.toCharArray() : null,
 						configurationProperties
 								.getProperty("javax.net.ssl.keyStoreType"));
 			} catch (Exception e1) {
 						"could not instantiate SSL networking"e1);
 			}
 		}
 
 		// Set the auto dialog support flag.
 		super. = configurationProperties
 				.getProperty("javax.sip.AUTOMATIC_DIALOG_SUPPORT""on")
 
 		super. = configurationProperties
 					.getProperty("gov.nist.javax.sip.AUTOMATIC_DIALOG_ERROR_HANDLING","true")
 		}
 	
 		if (configurationProperties
 				.getProperty("gov.nist.javax.sip.MAX_LISTENER_RESPONSE_TIME") != null) {
 			super. = Integer
 					.parseInt(configurationProperties
 							.getProperty("gov.nist.javax.sip.MAX_LISTENER_RESPONSE_TIME"));
 			if (super. <= 0)
 						"Bad configuration parameter gov.nist.javax.sip.MAX_LISTENER_RESPONSE_TIME : should be positive");
 		} else {
 		}
 
 		
 
 		this.setDeliverTerminatedEventForAck(configurationProperties
 						"gov.nist.javax.sip.DELIVER_TERMINATED_EVENT_FOR_ACK",
 						"false").equalsIgnoreCase("true"));
 
 		super.setDeliverUnsolicitedNotify(Boolean.parseBooleanconfigurationProperties.getProperty(
 				"gov.nist.javax.sip.DELIVER_UNSOLICITED_NOTIFY""false")));
 				
 
 		String forkedSubscriptions = configurationProperties
 				.getProperty("javax.sip.FORKABLE_EVENTS");
 		if (forkedSubscriptions != null) {
 			StringTokenizer st = new StringTokenizer(forkedSubscriptions);
 			while (st.hasMoreTokens()) {
 				String nextEvent = st.nextToken();
 				this..add(nextEvent);
 			}
 		}
 
 		// Allow application to hook in a TLS Security Policy implementation
 		String tlsPolicyPath = configurationProperties.getProperty("gov.nist.javax.sip.TLS_SECURITY_POLICY");
 		if (tlsPolicyPath == null) {
 			tlsPolicyPath = "gov.nist.javax.sip.stack.DefaultTlsSecurityPolicy";
 			.logWarning("using default tls security policy");
 		}
 		try {
 			Class< ? > tlsPolicyClass = Class.forName(tlsPolicyPath);
 			Class< ? >[] constructorArgs = new Class[0];
 			Constructor< ? > cons = tlsPolicyClass.getConstructor(constructorArgs);
 			Object[] args = new Object[0];
 		} catch (InvocationTargetException ex1) {
 			throw new IllegalArgumentException("Cound not instantiate TLS security policy " + tlsPolicyPath
 					+ "- check that it is present on the classpath and that there is a no-args constructor defined",
 					ex1);
 		} catch (Exception ex) {
 			throw new IllegalArgumentException("Cound not instantiate TLS security policy " + tlsPolicyPath
 					+ "- check that it is present on the classpath and that there is a no-args constructor defined",
 					ex);
 		}
 		
 		// Allow application to choose the tls client auth policy on the socket
         String clientAuthType = configurationProperties.getProperty("gov.nist.javax.sip.TLS_CLIENT_AUTH_TYPE");
         if (clientAuthType != null) {
             super. = ClientAuthType.valueOf(clientAuthType);
             .logInfo("using " + clientAuthType + " tls auth policy");
         }
 
 		// The following features are unique to the NIST implementation.
 
 		/*
 		 * gets the NetworkLayer implementation, if any. Note that this is a
 		 * NIST only feature.
 		 */
 
 		final String NETWORK_LAYER_KEY = "gov.nist.javax.sip.NETWORK_LAYER";
 
 		if (configurationProperties.containsKey(NETWORK_LAYER_KEY)) {
 			String path = configurationProperties
 					.getProperty(NETWORK_LAYER_KEY);
 			try {
 				Class<?> clazz = Class.forName(path);
 				Constructor<?> c = clazz.getConstructor(new Class[0]);
 			} catch (Exception e) {
 						"can't find or instantiate NetworkLayer implementation: "
 								+ pathe);
 			}
 		}
 
 		final String ADDRESS_RESOLVER_KEY = "gov.nist.javax.sip.ADDRESS_RESOLVER";
 
 		if (configurationProperties.containsKey(ADDRESS_RESOLVER_KEY)) {
 			String path = configurationProperties
 					.getProperty(ADDRESS_RESOLVER_KEY);
 			try {
 				Class<?> clazz = Class.forName(path);
 				Constructor<?> c = clazz.getConstructor(new Class[0]);
 						.newInstance(new Object[0]);
 			} catch (Exception e) {
 						"can't find or instantiate AddressResolver implementation: "
 								+ pathe);
 			}
 		}
 
 		String maxConnections = configurationProperties
 				.getProperty("gov.nist.javax.sip.MAX_CONNECTIONS");
 		if (maxConnections != null) {
 			try {
 				this. = new Integer(maxConnections).intValue();
 			} catch (NumberFormatException ex) {
 						"max connections - bad value " + ex.getMessage());
 			}
 		}
 
 		String threadPoolSize = configurationProperties
 				.getProperty("gov.nist.javax.sip.THREAD_POOL_SIZE");
 		if (threadPoolSize != null) {
 			try {
 				this. = new Integer(threadPoolSize).intValue();
 			} catch (NumberFormatException ex) {
 						"thread pool size - bad value " + ex.getMessage());
 			}
 		}
 
 		int congetstionControlTimeout = Integer
 		.parseInt(configurationProperties.getProperty(
 				"gov.nist.javax.sip.CONGESTION_CONTROL_TIMEOUT",
 		"8000"));
 		super. = congetstionControlTimeout;
 
 		String tcpTreadPoolSize = configurationProperties
 		.getProperty("gov.nist.javax.sip.TCP_POST_PARSING_THREAD_POOL_SIZE");
 		if (tcpTreadPoolSize != null) {
 			try {
 				int threads = new Integer(tcpTreadPoolSize).intValue();
 				PipelinedMsgParser.setPostParseExcutorSize(threadscongetstionControlTimeout);
 			} catch (NumberFormatException ex) {
 							"TCP post-parse thread pool size - bad value " + tcpTreadPoolSize + " : " + ex.getMessage());
 			}
		String serverTransactionTableSize = configurationProperties
				.getProperty("gov.nist.javax.sip.MAX_SERVER_TRANSACTIONS");
		if (serverTransactionTableSize != null) {
			try {
						serverTransactionTableSize).intValue();
				// Lowater is 80% of highwater
catch (NumberFormatException ex) {
								"transaction table size - bad value "
ex.getMessage());
else {
			// Issue 256 : consistent with MAX_CLIENT_TRANSACTIONS, if the MAX_SERVER_TRANSACTIONS is not set
			// we assume the transaction table size can grow unlimited
		String clientTransactionTableSize = configurationProperties
				.getProperty("gov.nist.javax.sip.MAX_CLIENT_TRANSACTIONS");
		if (clientTransactionTableSize != null) {
			try {
						clientTransactionTableSize).intValue();
				// Lowater is 80% of highwater
catch (NumberFormatException ex) {
								"transaction table size - bad value "
ex.getMessage());
else {
		String flag = configurationProperties
				.getProperty("gov.nist.javax.sip.CACHE_SERVER_CONNECTIONS");
		if (flag != null && "false".equalsIgnoreCase(flag.trim())) {
			super. = false;
		String cacheflag = configurationProperties
				.getProperty("gov.nist.javax.sip.CACHE_CLIENT_CONNECTIONS");
		if (cacheflag != null && "false".equalsIgnoreCase(cacheflag.trim())) {
			super. = false;
		String readTimeout = configurationProperties
				.getProperty("gov.nist.javax.sip.READ_TIMEOUT");
		if (readTimeout != null) {
			try {
				int rt = Integer.parseInt(readTimeout);
				if (rt >= 100) {
					super. = rt;
else {
					..println("Value too low " + readTimeout);
catch (NumberFormatException nfe) {
				// Ignore.
					.logError("Bad read timeout " + readTimeout);
		// Get the address of the stun server.
		String stunAddr = configurationProperties
				.getProperty("gov.nist.javax.sip.STUN_SERVER");
		if (stunAddr != null)
					"Ignoring obsolete property "
"gov.nist.javax.sip.STUN_SERVER");
		String maxMsgSize = configurationProperties
				.getProperty("gov.nist.javax.sip.MAX_MESSAGE_SIZE");
		try {
			if (maxMsgSize != null) {
				super. = new Integer(maxMsgSize).intValue();
				if (super. < 4096)
					super. = 4096;
else {
				// Allow for "infinite" size of message
				super. = 0;
catch (NumberFormatException ex) {
					"maxMessageSize - bad value " + ex.getMessage());
		String rel = configurationProperties
				.getProperty("gov.nist.javax.sip.REENTRANT_LISTENER");
		this. = (rel != null && "true".equalsIgnoreCase(rel));
		// Check if a thread audit interval is specified
		String interval = configurationProperties
				.getProperty("gov.nist.javax.sip.THREAD_AUDIT_INTERVAL_IN_MILLISECS");
		if (interval != null) {
			try {
				// Make the monitored threads ping the auditor twice as fast as
				// the audits
						Long.valueOf(interval).longValue() / 2);
catch (NumberFormatException ex) {
						"THREAD_AUDIT_INTERVAL_IN_MILLISECS - bad value ["
interval + "] " + ex.getMessage());
		// JvB: added property for testing
		this
								configurationProperties
												"gov.nist.javax.sip.PASS_INVITE_NON_2XX_ACK_TO_LISTENER",
												"false")).booleanValue());
				configurationProperties.getProperty(
						"gov.nist.javax.sip.AUTO_GENERATE_TIMESTAMP""false"))
		String messageLogFactoryClasspath = configurationProperties
				.getProperty("gov.nist.javax.sip.LOG_FACTORY");
		if (messageLogFactoryClasspath != null) {
			try {
				Class<?> clazz = Class.forName(messageLogFactoryClasspath);
				Constructor<?> c = clazz.getConstructor(new Class[0]);
catch (Exception ex) {
								"Bad configuration value for LOG_FACTORY -- using default logger");
else {
		boolean computeContentLength = configurationProperties.getProperty(
				"gov.nist.javax.sip.COMPUTE_CONTENT_LENGTH_FROM_MESSAGE_BODY",
				"false").equalsIgnoreCase("true");
		StringMsgParser
		String tlsClientProtocols = configurationProperties.getProperty(
				"gov.nist.javax.sip.TLS_CLIENT_PROTOCOLS");
		if (tlsClientProtocols != null)
			StringTokenizer st = new StringTokenizer(tlsClientProtocols" ,");
			String[] protocols = new String[st.countTokens()];
			int i=0;
			while (st.hasMoreTokens()) {
				protocols[i++] = st.nextToken();
			this. = protocols;
		super. = configurationProperties.getProperty(
				"gov.nist.javax.sip.RFC_2543_SUPPORT_ENABLED""true")
		super. = configurationProperties
						"gov.nist.javax.sip.CANCEL_CLIENT_TRANSACTION_CHECKED",
						"true").equalsIgnoreCase("true");
		super. = configurationProperties.getProperty(
				"gov.nist.javax.sip.LOG_STACK_TRACE_ON_MESSAGE_SEND""false")
				"created Sip stack. Properties = " + configurationProperties);
		InputStream in = getClass().getResourceAsStream("/TIMESTAMP");
		if (in != null) {
			BufferedReader streamReader = new BufferedReader(
			try {
				String buildTimeStamp = streamReader.readLine();
				if (in != null) {
					in.close();
				.setBuildTimeStamp(buildTimeStamp);
catch (IOException ex) {
				.logError("Could not open build timestamp.");
		String bufferSize = configurationProperties.getProperty(
				"gov.nist.javax.sip.RECEIVE_UDP_BUFFER_SIZE"
		int bufferSizeInteger = new Integer(bufferSize).intValue();
		super.setReceiveUdpBufferSize(bufferSizeInteger);
		bufferSize = configurationProperties.getProperty(
				"gov.nist.javax.sip.SEND_UDP_BUFFER_SIZE"
		bufferSizeInteger = new Integer(bufferSize).intValue();
		super.setSendUdpBufferSize(bufferSizeInteger);
		super. = Boolean
				.parseBoolean(configurationProperties.getProperty(
						"gov.nist.javax.sip.IS_BACK_TO_BACK_USER_AGENT",
		super. = Boolean.parseBoolean(configurationProperties
				.getProperty("gov.nist.javax.sip.REJECT_STRAY_RESPONSES",
		super. = (Boolean.parseBoolean(configurationProperties.getProperty("gov.nist.javax.sip.DELIVER_TERMINATED_EVENT_FOR_NULL_DIALOG",
		        ..toString())));
		super. = Integer.parseInt(
		        configurationProperties.getProperty("gov.nist.javax.sip.MAX_FORK_TIME_SECONDS","0"));
		super. = Integer.parseInt(
                configurationProperties.getProperty("gov.nist.javax.sip.EARLY_DIALOG_TIMEOUT_SECONDS","180"));				
		super. = Integer.parseInt(configurationProperties.getProperty("gov.nist.javax.sip.MIN_KEEPALIVE_TIME_SECONDS","-1"));
		super. = Boolean.parseBoolean(configurationProperties.getProperty
				("gov.nist.javax.sip.DELIVER_RETRANSMITTED_ACK_TO_LISTENER","false"));
		super. = Integer.parseInt(configurationProperties.getProperty("gov.nist.javax.sip.DIALOG_TIMEOUT_FACTOR","64"));
		String messageParserFactoryName = configurationProperties.getProperty("gov.nist.javax.sip.MESSAGE_PARSER_FACTORY",StringMsgParserFactory.class.getName());
		try {
			super. = (MessageParserFactory) Class.forName(messageParserFactoryName).newInstance();
catch (Exception e) {
						"Bad configuration value for gov.nist.javax.sip.MESSAGE_PARSER_FACTORY"e);			
		String messageProcessorFactoryName = configurationProperties.getProperty("gov.nist.javax.sip.MESSAGE_PROCESSOR_FACTORY",OIOMessageProcessorFactory.class.getName());
		try {
			super. = (MessageProcessorFactory) Class.forName(messageProcessorFactoryName).newInstance();
catch (Exception e) {
						"Bad configuration value for gov.nist.javax.sip.MESSAGE_PROCESSOR_FACTORY"e);			
		String defaultTimerName = configurationProperties.getProperty("gov.nist.javax.sip.TIMER_CLASS_NAME",DefaultSipTimer.class.getName());
		try {
			setTimer((SipTimer)Class.forName(defaultTimerName).newInstance());
			getTimer().start(thisconfigurationProperties);
	            // Start monitoring the timer thread
	            getTimer().schedule(new PingTimer(null), 0);
	        }
catch (Exception e) {
						"Bad configuration value for gov.nist.javax.sip.TIMER_CLASS_NAME"e);			
		super. = Boolean.parseBoolean(configurationProperties
				.getProperty("gov.nist.javax.sip.AGGRESSIVE_CLEANUP",
		String valveClassName = configurationProperties.getProperty("gov.nist.javax.sip.SIP_MESSAGE_VALVE"null);
		if(valveClassName != null && !valveClassName.equals("")) {
			try {
				super. = (SIPMessageValve) Class.forName(valveClassName).newInstance();
				final SipStack thisStack = this;
				try {
					Thread.sleep(100);
catch (Exception e) {
					.logError("Error intializing SIPMessageValve"e);
catch (Exception e) {
						"Bad configuration value for gov.nist.javax.sip.SIP_MESSAGE_VALVE"e);			
		String interceptorClassName = configurationProperties.getProperty("gov.nist.javax.sip.SIP_EVENT_INTERCEPTOR"null);
		if(interceptorClassName != null && !interceptorClassName.equals("")) {
			try {
				super. = (SIPEventInterceptor) Class.forName(interceptorClassName).newInstance();
				final SipStack thisStack = this;
				new Thread() {
					public void run() {
						try {
							Thread.sleep(100);
catch (Exception e) {
							.logError("Error intializing SIPEventInterceptor"e);
				}.start();
catch (Exception e) {
							"Bad configuration value for gov.nist.javax.sip.SIP_EVENT_INTERCEPTOR"e);			
	/*
	 * (non-Javadoc)
	 * 
	 * @see javax.sip.SipStack#createListeningPoint(java.lang.String, int,
	 * java.lang.String)
	 */
	public synchronized ListeningPoint createListeningPoint(String address,
			int portString transportthrows TransportNotSupportedException,
				"createListeningPoint : address = " + address + " port = "
port + " transport = " + transport);
		if (address == null)
					"Address for listening point is null!");
		if (transport == null)
			throw new NullPointerException("null transport");
		if (port <= 0)
			throw new InvalidArgumentException("bad port");
		if (!transport.equalsIgnoreCase("UDP")
				&& !transport.equalsIgnoreCase("TLS")
				&& !transport.equalsIgnoreCase("TCP")
				&& !transport.equalsIgnoreCase("SCTP"))
			throw new TransportNotSupportedException("bad transport "
transport);

Reusing an old stack instance
		if (!this.isAlive()) {
			this. = false;
		String key = ListeningPointImpl.makeKey(addressporttransport);
		if (lip != null) {
			return lip;
else {
			try {
				InetAddress inetAddr = InetAddress.getByName(address);
				MessageProcessor messageProcessor = this
						.createMessageProcessor(inetAddrporttransport);
							"Created Message Processor: " + address
" port = " + port + " transport = "
transport);
				lip = new ListeningPointImpl(thisporttransport);
				lip.messageProcessor = messageProcessor;
				messageProcessor.setListeningPoint(lip);
				this..put(keylip);
				// start processing messages.
				messageProcessor.start();
				return (ListeningPointlip;
catch (java.io.IOException ex) {
						"Invalid argument address = " + address + " port = "
port + " transport = " + transport);
				throw new InvalidArgumentException(ex.getMessage(), ex);
	/*
	 * (non-Javadoc)
	 * 
	 * @see javax.sip.SipStack#createSipProvider(javax.sip.ListeningPoint)
	 */
		if (listeningPoint == null)
			throw new NullPointerException("null listeningPoint");
					"createSipProvider: " + listeningPoint);
		ListeningPointImpl listeningPointImpl = (ListeningPointImpllisteningPoint;
		if (listeningPointImpl.sipProvider != null)
			throw new ObjectInUseException("Provider already attached!");
		SipProviderImpl provider = new SipProviderImpl(this);
		provider.setListeningPoint(listeningPointImpl);
		listeningPointImpl.sipProvider = provider;
		this..add(provider);
		return provider;
	/*
	 * (non-Javadoc)
	 * 
	 * @see javax.sip.SipStack#deleteListeningPoint(javax.sip.ListeningPoint)
	 */
	public void deleteListeningPoint(ListeningPoint listeningPoint)
		if (listeningPoint == null)
			throw new NullPointerException("null listeningPoint arg");
		ListeningPointImpl lip = (ListeningPointImpllisteningPoint;
		// Stop the message processing thread in the listening point.
		super.removeMessageProcessor(lip.messageProcessor);
		String key = lip.getKey();
	/*
	 * (non-Javadoc)
	 * 
	 * @see javax.sip.SipStack#deleteSipProvider(javax.sip.SipProvider)
	 */
	public void deleteSipProvider(SipProvider sipProvider)
		if (sipProvider == null)
			throw new NullPointerException("null provider arg");
		SipProviderImpl sipProviderImpl = (SipProviderImplsipProvider;
		// JvB: API doc is not clear, but in_use ==
		// sipProviderImpl.sipListener!=null
		// so we should throw if app did not call removeSipListener
		// sipProviderImpl.sipListener = null;
		if (sipProviderImpl.getSipListener() != null) {
					"SipProvider still has an associated SipListener!");
		sipProviderImpl.removeListeningPoints();
		// Bug reported by Rafael Barriuso
		sipProviderImpl.stop();
		.remove(sipProvider);
			this.stopStack();
	}

Get the IP Address of the stack.

Deprecated:
See also:
javax.sip.SipStack.getIPAddress()
	public String getIPAddress() {
		return super.getHostAddress();
	/*
	 * (non-Javadoc)
	 * 
	 * @see javax.sip.SipStack#getListeningPoints()
	 */
	}

Return true if retransmission filter is active.

	public boolean isRetransmissionFilterActive() {
		return true;
	/*
	 * (non-Javadoc)
	 * 
	 * @see javax.sip.SipStack#getSipProviders()
	 */
		return this..iterator();
	/*
	 * (non-Javadoc)
	 * 
	 * @see javax.sip.SipStack#getStackName()
	 */
	public String getStackName() {
		return this.;
	}

Finalization -- stop the stack on finalization. Exit the transaction scanner and release all resources.

	protected void finalize() {
		this.stopStack();
	}

This uses the default stack address to create a listening point.

	public ListeningPoint createListeningPoint(int portString transport)
		if (super. == null)
					"Stack does not have a default IP Address!");
		return this.createListeningPoint(super.porttransport);
	/*
	 * (non-Javadoc)
	 * 
	 * @see javax.sip.SipStack#stop()
	 */
	public void stop() {
			.logDebug("stopStack -- stoppping the stack");
		this.stopStack();
		if(super. != null
		if(super. != null
		/*
		 * Check for presence of an event scanner ( may happen if stack is
		 * stopped before listener is attached ).
		 */
		if (this. != null)
		this. = null;
		PipelinedMsgParser.shutdownTcpThreadpool();
	/*
	 * (non-Javadoc)
	 * 
	 * @see javax.sip.SipStack#start()
	 */
		// Start a new event scanner if one does not exist.
		if (this. == null) {
			this. = new EventScanner(this);
	}

Get the listener for the stack. A stack can have only one listener. To get an event from a provider, the listener has to be registered with the provider. The SipListener is application code.

Returns:
-- the stack SipListener
		return this.;
	}

Get the TLS Security Policy implementation for the stack. The TlsSecurityPolicy is application code.

Returns:
-- the TLS Security Policy implementation
		return this.;
	}

Get the message log factory registered with the stack.

Returns:
-- the messageLogFactory of the stack.
		return super.;
	}

Set the log appender ( this is useful if you want to specify a particular log format or log to something other than a file for example). This method is will be removed May 11, 2010 or shortly there after.

Deprecated:
TODO: remove this method May 11, 2010.
Parameters:
Appender - the log4j appender to add.
	public void addLogAppender(org.apache.log4j.Appender appender) {
		if (this. instanceof gov.nist.core.LogWriter) {
	}

Get the log4j logger ( for log stream integration ). This method will be removed May 11, 2010 or shortly there after.

Deprecated:
TODO: This method will be removed May 11, 2010.
Returns:
the log4j logger.