Sun GlassFish Communications Server 1.5 Release Notes

SIP Container

SIP container unable to handle a CANCEL when it has sent a 100 response (Issue 712)

Description

The SIP container cannot handle a CANCEL request when a 100 response has been sent.

Solution

The application needs to send a provisional response (such as 1xx), so that the remote side is able to CANCEL the INVITE request.

SIP sessions and HTTP sessions do not apply the same session expiration time model (Issue 1180)

Description

The session expiration model of SIP sessions is different from the HTTP expiration time logic. In HTTP, the session is automatically extended, outside of the control of the application, whenever a new HTTP request is received in that HTTP session.

With SIP sessions, the application is in control over the duration of the SipApplicationSession (SAS), subject to approval by the SIP container. Applications can use the setExpires method to indicate when the SAS should expire. setExpires defines an expiration time relative to the moment the setExpires method is called. The container can modify, reject, or accept the duration indicated in setExpires. If the session is not invalidated, then the sessionExpired callback is performed at the time defined by setExpires . In this callback, the application can try to extend the duration of the SAS by invoking a new setExpires, again subject to modification, rejection, or acceptance by the container.

For this reason, converged applications that start out with the same expiration time of the SipApplicationSession (SAS) and on the HTTP session will notice that the SAS times out before the HTTP session if new requests were received on the HTTP session.

Solution

The best way to deal with the different expiration time handling of the SIP and the HTTP session is to start with a large enough SAS expiration time, which is the total time that the application session is expected to live (including several HTTP requests). The SAS lifetime could even be set to infinite, specifically if invalidateWhenReady semantics are used, in which case, the SipApplicationSession is invalidated when the last protocol child session becomes invalidated. The initial expiration time for the SAS can be configured in the deployment descriptor.

If the maximum total duration can be estimated in advance, no further code is needed, as it is then appropriate to invalidate both the Sip session and the HTTP session when the SAS expires. If the maximum duration cannot be estimated in advance, then the SipApplicationSession can be extended when it expires, as shown in the code snippet below.

In the SipApplicationSessionListener implementation, you can do something like this:

public void sessionExpired(SipApplicationSessionEvent sasEvent) {
                // check if the SAS needs to be extended first, if so:
		int granted = sasEvent.getApplicationSession().setExpires(2);
		if (granted <= 0) {
			System.out.println("extension rejected");
		} else if (granted < 2) {
			System.out.println("extension granted with lower value " + granted);
		} // else allowed 
	}

SIP session lives on after container callback to sessionExpired (Issue 1265)

Description

This is an intermittent issue. The SIP container intermittently responds with a 500 Server internal error message instead of a 481 Call/Transaction does not exist message when there is a race condition between the 200 for NOTIFY indicating that the session has been removed, and the SUBSCRIBE sent by the client when receiving that NOTIFY.

Solution

The client needs to the refresh SUBSCRIBE much before the subscription expires.

Communications Server first acts as a UAS, then as a proxy, and generates NOP (Issue 1432)

Description

When it receives an INVITE request, Communications Server first acts as UAS, replies to this request with 1XX, and then proxies this INVITE request to another instance, which replies with 200 OK. The 1xx creates an internal virtual branch while the 200 message creates a real branch. Upon reception of 200 OK from B the internal virtual branch should be cancelled

Solution

This exception trace does not affect the functionality of the virtual proxy branch.

getLastAccessedTime method does not provide accurate results (Issue 1351)

Description

The getLastAccessedTime method of a SIP session does not provide accurate results.

Solution

Applications that need to keep accurate track of the lastAccessedTime must store it themselves into the SipApplicationSession.

synchronized (sas) {
	Long last = (Long) sas.getAttribute("myLastAccessedTime");
	if (last == null) {last = 0};
	// do something with the last one
	// and...
	// set the new one.
	sas.setAttribute("myLastAccessedTime", System.currentTimeMillis());
}

SIP listener remains active for a certain duration after it is deleted (Issue 1294)

Description

After a SIP listener configured for TCP and UDP requests is deleted, the listener remains active for a certain duration. UDP requests that are sent to the listener could receive a response from the listener.

Solution

No known solution. The SIP listener stops listening to UDP requests after a certain duration. This problem does not impact TCP requests.

Communications Server throws exception when it receives a Contact header without “<>” (Issue 1489)

Description

Communications Server throws exception when it receives a Contact header without “<>”. According to SIP RFC 3261, it is not mandatory to have the “<>” in the address. This could lead to interoperability problems with other SIP-compliant devices.

Solution

Use “<>” in the Contact header.

Communications Server throws exception at an invalid UUID value (Issue 1494)

Description

Communications Server throws exception at an invalid UUID value instead of returning a 400 Bad Request. The UUID value resides in the SIP contact header's sip.instance value

Solution

No known solution.

Windows: Sometimes, UDP messages are not received by Communications Server (No id)

Description

This problem is intermittently seen only on Windows. UDP messages are not received by Communications Server.

Solution

Set the following JVM option as follows, and restart Communications Server.

org.jvnet.glassfish.comms.disableUDPSourcePort=true