Home | History | Annotate | Download | only in sip
      1 /*
      2  * Conditions Of Use
      3  *
      4  * This software was developed by employees of the National Institute of
      5  * Standards and Technology (NIST), an agency of the Federal Government.
      6  * Pursuant to title 15 Untied States Code Section 105, works of NIST
      7  * employees are not subject to copyright protection in the United States
      8  * and are considered to be in the public domain.  As a result, a formal
      9  * license is not needed to use the software.
     10  *
     11  * This software is provided by NIST as a service and is expressly
     12  * provided "AS IS."  NIST MAKES NO WARRANTY OF ANY KIND, EXPRESS, IMPLIED
     13  * OR STATUTORY, INCLUDING, WITHOUT LIMITATION, THE IMPLIED WARRANTY OF
     14  * MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE, NON-INFRINGEMENT
     15  * AND DATA ACCURACY.  NIST does not warrant or make any representations
     16  * regarding the use of the software or the results thereof, including but
     17  * not limited to the correctness, accuracy, reliability or usefulness of
     18  * the software.
     19  *
     20  * Permission to use this software is contingent upon your acceptance
     21  * of the terms of this agreement
     22  *
     23  * .
     24  *
     25  */
     26 package gov.nist.javax.sip;
     27 
     28 import gov.nist.core.ServerLogger;
     29 import gov.nist.core.StackLogger;
     30 import gov.nist.core.net.AddressResolver;
     31 import gov.nist.core.net.NetworkLayer;
     32 import gov.nist.core.net.SslNetworkLayer;
     33 import gov.nist.javax.sip.clientauthutils.AccountManager;
     34 import gov.nist.javax.sip.clientauthutils.AuthenticationHelper;
     35 import gov.nist.javax.sip.clientauthutils.AuthenticationHelperImpl;
     36 import gov.nist.javax.sip.clientauthutils.SecureAccountManager;
     37 import gov.nist.javax.sip.parser.StringMsgParser;
     38 import gov.nist.javax.sip.stack.DefaultMessageLogFactory;
     39 import gov.nist.javax.sip.stack.DefaultRouter;
     40 import gov.nist.javax.sip.stack.MessageProcessor;
     41 import gov.nist.javax.sip.stack.SIPTransactionStack;
     42 
     43 import java.io.BufferedReader;
     44 import java.io.IOException;
     45 import java.io.InputStream;
     46 import java.io.InputStreamReader;
     47 import java.lang.reflect.Constructor;
     48 import java.lang.reflect.InvocationTargetException;
     49 import java.net.InetAddress;
     50 import java.util.Hashtable;
     51 import java.util.LinkedList;
     52 import java.util.Properties;
     53 import java.util.StringTokenizer;
     54 import java.util.concurrent.Semaphore;
     55 import java.util.concurrent.TimeUnit;
     56 
     57 import javax.sip.InvalidArgumentException;
     58 import javax.sip.ListeningPoint;
     59 import javax.sip.ObjectInUseException;
     60 import javax.sip.PeerUnavailableException;
     61 import javax.sip.ProviderDoesNotExistException;
     62 import javax.sip.SipException;
     63 import javax.sip.SipListener;
     64 import javax.sip.SipProvider;
     65 import javax.sip.SipStack;
     66 import javax.sip.TransportNotSupportedException;
     67 import javax.sip.address.Router;
     68 import javax.sip.header.HeaderFactory;
     69 import 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  */
    435 public 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