Frequently Asked Questions / JAIN-SIP HOWTO

  1. Who owns NIST-SIP ?
  2. What are the restrictions on its use?
  3. What is its intended use?
  4. Show me a quick how-to.
  5. Why do I see a lot of strange exceptions in the log file?
  6. Why is there only superficial resemblance between JAIN SIP 1.0 and
  7. How involved is it to port applications between JAIN-SIP 1.0 and JAIN-SIP 1.1 JAIN SIP 1.1?
  8. Does the RI support Re-Invite and how do I issue a re-invite?
  9. Is JAIN-SIP 1.2 Stateful/Stateless or DialogStateful ?
  10. Why does my application get a null ServerTransaction for INVITE transactions?
  11. Who manages From/To tags ?
  12. Why Dialog.sendRequest but no Dialog.sendResponse ?
  13. Does the SIP Communicator Softphone work on Linux?
  14. How do I cancel a transaction ?
  15. What is the difference between Transaction.sendRequest, Dialog.sendRequest and SipProvider.sendRequest ?
  16. What does the javax.sip.Router interface do?
  17. How much compatibility with RFC 2543 do you support?
  18. What is the difference between sending ack for a transaction and Dialog.sendRequest(Request.ACK)?
  19. What is the Provider method for creating dialogs?
  20. I am constructing a stateful proxy/B2BUA. I forward the request after modifying it and then respond statefully. Why are the tags/headers/something else modified in the response ?
  21. How to set up MSN messenger for SIP?
  22. Does NIST-SIP do eager or lazy parsing? I see no parse exceptions on get methods. What happened to all the JAIN SIP lazy parsing stuff?
  23. What support is provided for sending out-of-dialog requests?
  24. How do I communicate with the Router from the application?
  25. How are IO Exceptions reported to the Application?
  26. Why is the Transacton Request returned from transaction.getRequest() set to null?
  27. How do you identify the listening point for an incoming server transaction in the case where you are supporting multiple listening points?
  28. Why is my application getting Server Transaction timeouts even after I send response?
  29. Why am I getting a "Transaction not available" sip execption on an incoming INVITE?
  30. How do you remove log4j for logging?
  31. I see a SIP message headed for my machine on Ethereal but my application (Listener) does not see it. Why ?
  32. How do I ensure that the stack closes TCP connections after transaction completion?
  33. How do I limit the maximum size of messages that the stack will accept?
  34. While sending ACK request for 200 OK should I use transaction.createAck() or Dialog.createRequest(Request.ACK)?
  35. Can I run the stack in an applet?
  36. I want to be able to send SIP packets to different SIP servers using different local identities. Any tips on how this is best handled with this stack?
  37. The stack seems a bit slow. Can you do something to improve performance?
  38. I downloaded a version some time ago and worked long and hard to fix bugs and customize it. It now works but lately I noticed some strange bug. I am afraid of your changes so can you help me fix that vintage version?
  39. How can I take advantage of my multi-processor mutli-threaded machine with dual headed monitors to get better performance out of NIST-SIP?
  40. What dialog support is provided by JAIN SIP ?
  41. How do you make shootist shoot somewhere else (at another machine) ?
  42. How do you find out which IP address a SIP Message arrived on?
  43. How do you use the STUN support?
  44. Can you delay sending responses to after the Listener runs ?
  45. How do you build it under the ibm java implementation?
  46. What happens to Terminated Transactions ?
  47. How many Calls Per Second can NIST-SIP Handle ?
  48. I'm writing a SIP user agent to connect to various SIP resources, and I'm having an issue where my SipListener is receiving unexpected DialogTerminatedEvent's via processDialogTerminated (..). These appear to happen almost exactly 40 seconds after an INVITE is processed, so I'm assuming there's some sort of timeout issue at work here. I am even sending an ACK for the Dialog. Dear Abby, please tell me what is wrong with my application.
  49. I really like my Router implementation and want to send subliminal suggestions
  50. to him. How do I communicate with the Router
  51. I want to loosen up on the parsing of headers. However, I cannot extend your Header implementation classes. If I supply my own implementation of a header, I get ClassCastException. Why not let me extend the implementation classes?
  52. I have some questionable questions. Where do I look?


  1. Who owns NIST-SIP?
    NIST owns it and has released it to the public domain as required by act of U.S. Congress. This includes the stack (gov.nist....) the SDP implementation, the proxy, the trace viewer tool IM client and the TCK. Specific copyrights apply everything else. These are noted in the code and copyright statements included with the documents.


  2. What are the restrictions on its use?
    Do whatever you want with it but just dont demand support. If you do use it in your product or project, be aware that it is experimental code and is therefore subject to frequent changes. Do acknowledge that your code was derived from NIST-SIP. It helps us keep the project alive.


  3. What is its intended use?
    JAIN-SIP/ NIST-SIP is meant for SIP developers. As such it is not a stand-alone product. Its primary use is for integrating SIP into your applications. If you have an applicaton already and wish to SIP-enable it, JAIN-SIP/NIST-SIP is a reasonable choice.


  4. Show me a quick how-to
    See examples/shootist. We'll be working several examples as time permits.


  5. Why do I see a lot of strange exceptions in the log file?
    These are just for stack tracing (ok there are better ways to do this under 1.4.2 but we want to be 1.3.1 and above compatible). The implementation does new Exception().printStack trace and captures the execution trace in a file for later use.


  6. Why is there only superficial resemblance between JAIN SIP 1.0 and JAIN SIP 1.1?


  7. How involved is it to port applications between JAIN-SIP 1.0 and JAIN-SIP 1.1
    It is not difficult but it is not trivial. Anecdotal evidence indicates several hours or maybe a day or two of effort.


  8. Does the RI support Re-Invite and how do I issue a re-invite?
    Request inviteRequest = dialog.createRequest(Request.INVITE);
    ClientTransaction ct = sipProvider.getNewClientTransaction(inviteRequest);
    dialog.sendRequest(ct);
    

  9. Is JAIN-SIP 1.2 Stateful/Stateless or DialogStateful?
    Your application can choose its desired behavior. You have the option to create a dialog for the first (dialog creating) transaction. Once a dialog is created, however, all incoming requests that belong to the dialog are automatically given a server transaction and are hence handled statefully. You can also create dialogs under program control and associate it with the Server or Client Transaction ( new feature added for JAIN-SIP-1.2)


  10. Why does my application get a null ServerTransaction for INVITE transactions ?
    In order to support both statefull and stateless modes of operation, the INIVITE request gets delivered to your application with a null ServerTransaction. You can choose to create a ServerTransacton and associated dialog using provider.getNewServerTransaction(inviteRequest)


  11. Who manages From/To tags
    From the client side, for the initial outgoing transaction, the application needs to specify a From tag. From the server side, the application specifies the initial To tag when responding to the request. After that, the stack manages things. Transactions are assigned to dialogs based on tags in requests/respomses.


  12. Why Dialog.sendRequest but no Dialog.sendResponse
    Dialog.sendRequest uses route set and other dialog specific information. Responses take all the information they need from the transaction.


  13. Does the Softphone work on Linux?
    Yes. You need a 2.4 Kernel and the latest version of the Java Media Framework.


  14. How do I cancel a transaction.
    Request cancelRequest = originalClientTransaction.createCancel();
    ClientTransaction ct = sipProvider.getNewClientTransaction(cancelRequest);
    ct.sendRequest();
    

  15. What is the difference between Transaction.sendRequest, Dialog.sendRequest and SipProvider.sendRequest
    Dialog.sendRequest stamps the outgoing request with dialog state. This includes the local sequence number, Request URI and Route set. For requests within a dialog you should use Dialog.sendRequest. For sending request for a transaction that is not associated with a Dialog, you should use Transaction.sendRequest. For sending requests statelessly, you should use SipProvider.sendRequest. Stateless requests do not result in the creation of a new Transaction or Dialog.


  16. What does the javax.sip.Router do?
    The router routes requests outside a dialog. This would be a good place to add customizations like looking up in a location database or registry for forwarding requests out of dialog.


  17. How much backward compatibility with 2543 do you support
    We do not guarantee complete backward compatibility with RFC 2543. We support it to the extent that the implementation does not break. If there is a life threatening conflict between RFC 2543 and RFC 3261, then RFC 3261 wins.


  18. What is the difference between sending ACK for a transaction and Dialog.sendRequest(Request.ACK) ?
    The latter includes dialog state and places a fresh branch id in the Via. This ensures it will not match any transaction on the server. Use this when ACKing 2xx responses and the former when ACKing error directed towards a transction (3xx) and the like.


  19. What is the Provider method for creating dialogs?
    One of the new features added to JSIP-1.2 is to allow applications the ability to have control over dialog creation. To enable, you have to set AUTOMATIC_DIALOG_SUPPORT="off" when you create the stack. You may also disable automatic dialog support on a per-provider basis. Then use the method. SipProvider.getNewDialog(tansaction) to create a dialog.

    Under the stack configuration parameter, AUTOMATIC_DIALOG_SUPPORT="on" , Dialog creation and destruction is managed by the stack. When the client transcaction is created, a Dialog is associated with it but not mapped (its state is null). When you complete the transaction successfully it actually gets mapped and a valid state is assigned to it. On the server side, when you get the request, provided the method of the request has the ability to create a Dialog, you can elect to create a Dialog by creating a new Server Transaction at which point the stack automatically creates a Dialog for transaction but defers actually mapping it until a final response is sent out.



  20. I am constructing a stateful proxy/B2BUA. I forward the request after modifying it and then respond statefully. Why are the tags/headers/something else modified in the response ?
    NIST-SIP does not copy the request when it hands it over to the listener. This is for efficiency. If you want to modify an outgoing request (for example if you are building a stateful proxy server or B2BUA) clone it. JAIN-SIP specifies a Deep cloning operation for this purpose.


  21. How to set up MSN messenger for SIP?
    MSN Messenger 4.7 (on windows XP) supports SIP but SIP support is not working well on MSN 5.0 (on Win2K). Enable communications services in Accounts tab. Go to Advanced and set your proxy from there.


  22. Does NIST-SIP do eager or lazy parsing? I see no parse exceptions on get methods. What happened to all the JAIN SIP lazy parsing stuff?
    The new JAIN Spec does not specify the type of parser to be employed. An implementation may employ lazy parsing. Parse failures are silent. If something parsing fails then the header is silently added to the uparseable header list and null is returned to the application. The application can later retrieve it as a String as an Unparseable header. This can happen either lazily or eagerly; however, Lazy/eager parsing is not exposed at the API level. NIST-SIP employs an eager strategy (mostly because of implementation ease). This is likely to be revised but your app does not get affected.


  23. What support is provided for sending out-of-dialog requests?
    Use clientTransaction.sendRequest(). This will get the next hop from the Router and use that to send the request. If you use dialog.sendRequest, the next hop is obtained from the Dialog route set if one exists.


  24. How do I communicate with the Router from the application?
    This issue may arise when you want to use Loose or Strict routing. Only the Application knows whether to use Loose or Strict Routing but the Router needs to decide the Next Hops. Thus we need to communicate with the router. Currently, it is a bit hacky. Use an extension header and place it in the Request then examine it in the Router. For example, use a header like IS-STRICT-ROUTE which the router will see as an extension header and strip off before deciding the next hop set.


  25. How are IO Exceptions reported to the Application?
    For JAIN-SIP 1.2, there is a new listener method for reporting IO Exceptions to applications. Additionally, the Tranaction for which the IO Exception is delivered will be immediately terminated.


  26.  Why is the Transacton Request returned from transaction.getRequest() set to null?
    The client transaction is only obliged to hold a reference to the Request until the transaction goes to COMPLETED state. After that, the reference to the Request is nulled out to save heap space and ehance scalability of the implementation. If you want to hold a long term reference to the request, then please do this in your application.


  27. How do you identify the listening point for an incoming server transaction in the case where you are supporting multiple listening points?
    SipProvider sipProvider = (SipProvider) sipEvent.getSource();
    ListeningPoint lp = sipProvider.getListeningPoint();
    

  28. Why is my application getting Server Transaction timeouts even after I send response?
    If the stack configuration property javax.sip.RETRANSMISSION_FILTER is "false" or "off", for INVITE Transactions, your application is alerted to send response periodically until ACK is received from the client side. This happens through the mechanism of your application fielding a Timeout Event.


  29. Why am I getting a "Transaction not available" sip execption on an incoming INVITE?
    Check your application to see if you cloned the request before you requested the server transaction. A Server transaction can only be created for the incoming request that is identitically equal to the incoming request that was received by the stack and not for a cloned request. Further, you cannot cache the request and ask that a server transaction be created at some future time. You must create the server transaction synchronously when the request is delivered to your application and not later.


  30. How do you remove log4j for logging?
    Because log4j is configured by default to log to a file, you may want to remove it from the implementaton. Doing this is quite simple - modify gov.nist.core.LogWriter.java. You can change its behavior to log to a network connection or remove it entirely and convert to println.



  31. I see a SIP message headed for my machine on Ethereal but my application (Listener) does not see it. Why ?
    There could be one of several things going on:

  32. How do I ensure that the stack closes TCP connections after transaction completion?
    The following two configuration parameters instruct the stack to close TCP connections after a linger period:

    gov.nist.javax.sip.CACHE_SERVER_CONNECTIONS=false

    Default is true. Does reference counting for server transactions if false and releases resources after refcount goes to 0.

    gov.nist.javax.sip.CACHE_CLIENT_CONNECTIONS=false

    Default is true. Does reference counting for client transactions and releases socket and thread resources after refcount goes to 0. Setting to false will close the connection and release any threads and buffers after all transactions that use the connection have terminated and a keepalive period (currently 32 sec) has expired. In some circumstances (eg. if you are supporting NAT via tcp, then it may be appropriate not to close server connections). Defaults for these are true - which may be appropriate to do if you are burrowing through firewalls using tcp.


  33. How do I limit the size of messages that the stack will accept?
    For UDP this is not an issue. For TCP,
    gov.nist.javax.sip.MAX_MESSAGE_SIZE=number
    default for this property is inifinity (no limit).

  34. While sending ACK request for 200 OK should I use transaction.createAck() or Dialog.createRequest(Request.ACK)?
    Use the following when ACKing final responses
    Request ackRequest = dialog.createRequest(Request.ACK);
    dialog.sendAck(ackRequest);
    

  35. Can I run the stack in an applet?
    Yes - take a look at jain-sip-applet-phone.dev.java.net. If your server caches connections, you can use TCP sip transactions to transport chunks of binary data and thereby construct an applet phone.
  36. I want to be able to send SIP packets to different SIP servers using different local identities. Any tips on how this is best handled with this stack?
    The way to do this through the router. Note that you can specify a Router class implementation when the stack is created. The Router sets up the path to the next hop. In your Router, look at the user trying to set up the call and return the Hop implementation corresponding to the gateway to which that user should be pointed to. Note also that the Router is only used to route requests out of dialog - which is to say it is used for pre-dialog establishment, requests that dont belong to any particular dialog and stateless requests.

  37. The stack seems to be slow. Can you do something to improve performance?
    This is a reference implementation. As such, the emphasis is on clarity not performance. In its current state, the RI performs reasonably well and is suited for client applications. You may need to do some work by way of performance tuning to get it to work well in a high performance server setting. In particular, you may wish to fine tune object allocation, transaction location (searching for a transaction that corresponds to an incoming message) and other such details.

  38. I downloaded a version of NIST-SIP some time ago and worked long and hard to fix bugs and customize it. It now works but lately I noticed a strange bug. I am afraid of your changes so can you help me fix that vintage version?
    This one's easy. NO. I do not have the time for this and even if I did, I would consider it a waste of time. Please use cvs if you want to customize your code and make sure you are up to date with the latest version before you post bug reports. I cannot fix back level code.

  39. How can I take advantage of my multi-processor mutli-threaded machine with dual headed monitors to get better performance out of NIST-SIP?

    This may be of use when you are building a high performance server software component. Inform the stack that your listener is re-entrant using the gov.nist.javax.sip.stack.REENTRANT_LISTENER=true configuration property. Manage the thread pool size to suit your needs. See the gov.nist.javax.sip.stack.THREAD_POOL_SIZE=number configuration property. Be careful that your listener is indeed re-entrant. The stack will parse, manage the transaction state machine and call your listener code in the same thread avoiding queueing.

  40. What dialog support is provided in JAIN-SIP?
    JAIN-SIP allows for stateless or dialog stateful processing. Under dialog stateful processing. Dialog support is provided to facilitate in-dialog request generation, maintenance of route sets, maintenance of sequence numbers and other dialog functionality that is specified in Chapter 12 of the SIP RFC. Additionally, the dialog layer will shield your application from out of sequence messages and generate appropriate error responses when necessary. ( An implementation may choose to buffer early arriving messages and deliver to the application at a later time.) No dialog support is provided for authentication. This is an application responsibility. In dialog requests are delvered to the application in strict sequentially increasing order as specified in Chapter 12 of the RFC 3261.
  41. How do you make shootist shoot somewhere else (at another machine) ?
    Change the variable peerHostPort in Shootist.java to whatever host and port you want to shoot at (ie. where the shootme resides will be a wise choice). Change change Shootme.java likewise. You can also leave out the RouterImpl and HopImpl and just use the default (just dont specify the stack configuration property for ROUTER_PATH ). The example router was provided to show you how you can write your own router (to look up DNS records for example).

  42. How do you find out which IP address and port a SIP Message arrived on?
    From the Listening Point on which the message was received, retrieve the IP Address and Port.

  43. How do you enable/use the STUN support?
    set the gov.nist.javax.sip.STUN_SERVER to point to stun_server_ip_address[:port] where your stun server resides. The stack will return mapped address when you getIpAddress() from the stack and getPort() from the listening point. With stun, if you have a NAT box, these will in general be different from the IP address and port used to create the LP. Your application needs to use these in setting up the contact address and SDP parameters as appropriate. The stack is not responsible for this.

  44. Can you delay sending responses to requests until after the Listener runs ?
    You cannot do this. You must respond to the request when the listener is invoked. You must do this synchronously (not from another thread). This is because housekeeping functions are performed after the listener completes invocation.

  45. How do you build under IBM java implementation ?
    A user sent in the following helpful tip: I needed to tell eclipse that the files were "US-ASCII" rather than UTF-8. Then I edited my build-config and added "-encoding US-ASCII" to the end of the line that defines JAVAC for OS other than Windows_NT. Then "make ri" completed without incident.
  46. What happens to Terminated Transactions ?
    Once the Transaction is terminated, it is done and the server discards records of it. Thus you can well see the following behavior:
    1. Other party sends INVITE, times out and retransmits several times
    2. The SipListener finally sees the first transmission and, being busy, responds "503 service unavailable"
    3. Later, the SipListener sees one of the retransmissions. The SipListener does not keep track of terminated calls, and since it now has resources, it responds "200 OK"
    4. The other party ignores the "200 OK" since it already has seen the 503
    5. Eventually, the server INVITE transaction times out.

  47. How many calls per second can NIST-SIP handle?
    NIST-SIP is suitable for most User Agent Applications. It can handle roughly 75 Calls/Second. Thats usually enough for your average desktop phone unless you are an extremely busy person. Proxy server type applications requiring higher thruput are best built as stateless applications (ie. no transactions or dialogs are allocated). There are several optimizations possible including the use of NIO and lazy parsing. These will be implemented as time permits.

  48. I'm writing a SIP user agent to connect to various SIP resources, and I'm having an issue where my SipListener is receiving unexpected DialogTerminatedEvent's via processDialogTerminated (..). These appear to happen almost exactly 40 seconds after an INVITE is processed, so I'm assuming there's some sort of timeout issue at work here. I am even sending an ACK for the Dialog. Dear Abby, please tell me what is wrong with my application?
    Check to see if you are using Dialog.sendAck in your application. You should use Dialog.sendAck to send out the Ack if you have created a Dialog. Otherwise the Dialog will time out after a period of time has expired.

  49. I really like my Router implementation and want to send subliminal suggestions to him. How do I communicate with the Router
  50. Specify your Router implementation as a property when you create the stack. Then access the created object using
    Router myRouter  = (MyRouter)sipStack.getRouter();
    
    Now send your subliminal message to the Router using
    
    myRouter.sendSubliminalMessage()
    
    

  51. I want to loosen up on the parsing of headers. However, I cannot extend your Header implementation classes. If I supply my own implementation of a header to setHeader, I get ClassCastException. Why not let me extend the implementation classes or supply my own Header implementation classes?
    The point behind JAIN is to try to make your application portable across different implementations of the standard. This includes Native code implementations of the stack, Headers etc. If we allowed for applications to be able to pass in their own implementations of Header objects, this would not be possible. Hence, to simplify implementation headaches, and ensure portability, a conscious decision was made to not necessitate a requirement that a given provider be able to recognize Header implementations other than those created by its own factory. If you want to modify the way in which Headers are parsed etc. the simplest thing to do would be to hack the source code.

Frequently Questionable Questions (List likely to grow in time)

We have provided links to external web pages in this section because it has information that may be of interest to our users. NIST does not necessarily endorse the views expressed or the facts presented on these sites. Further, NIST does not endorse any commercial products that may be advertised or available on these sites.

M. Ranganathan and Jeroen van Bemmel