Tuesday Sep 29, 2009

Sip Message Inspection in SailFin

SipMessageInspection(SMI) feature is intended as a way of troubleshooting Sip traffic through SailFin. SMI in SailFin is implemented as logging of requests and responses in the server log. Together with the contextual log information in the server logs, Sip messages helps in tracing and debugging. SMI was first introduced in SailFin 1.0, but it had few limitations such as outgoing requests and responses are not accounted for.

SMI is enhanced in SailFin 2.0 to overcome the short comings in 1.0 and in addition, ability to add user defined message adapters is provided to customize the information logged as part of SMI.

SailFin's sip stack is based on layered architecture and by default SMI logs messages at network layer and application dispatcher/servlet dispatcher, reasoning behind these two are that they are important interception points both from the application and infrastructure developer point of views. Logging at network layer will take care of incoming and outgoing messages from the container and logging at servlet dispatcher takes care of incoming and outgoing messages from or to the applications, which includes the messages generated in the container and stayed back in the container, for example application composition. Users could configure the log message adapters at each layer.

SMI can be configured with the help of properties under sip-service element in the domain.xml and they can be set either using admin GUI or asadmin command line.

By default an adapter is configured at GrizzlyNetworkManager layer and one for servlet invocation on application dispatcher. Users could configure their adapters using on of the following three properties: smiServletAdapter, smiLayerAdapter, smiNetworkManagerAdapter and their values should be in the following format:
(specified class should be available with container class loader)
(specified class should be available at supplied external class root)

User defined adapters should implement org.jvnet.glassfish.comms.admin.reporter.SMILogMessageAdapter interface.

For the default adapters, it is possible to control the amount of records logged by setting smi log level ( e.g. server-config.log-service.module-log-levels.property.smi=FINE ).

When smi log level is

FINE: messages are logged at SERVLET interception in the Application Dispatcher layer

FINER: SERVLET interception and NetworkManager from/to cluster (i.e excluding Loadbalancer network hops)

FINEST:SERVLET interception and NetworkManager including Loadbalancer network hops

If the intent is to log messages only at NetworkManager thus bypassing messages at servlet invocation, there is a work around to achieve the same. There is a NullAdapter implementation in SailFin, which can be set as an adapter implementation for smiServletAdapter property.

Access logging, where SIP messages are logged into a different file is implemented on top of SMI.

Cut and paster from the server logs to when a simple invite UAS application is run:

[#|2009-09-27T23:21:03.509+0530|FINE|sun-glassfish-comms-server2.0|javax.enterprise.system.container.sip.smi|_ThreadID=16;_ThreadName=SipContainer-serversWorkerThread-5060-9;ClassName=org.jvnet.glassfish.comms.admin.reporter.SMIBaseReporter;MethodName=log;_RequestID=fc6596b6-87ec-4304-b423-76425085c98c;|SMI -->IN Request INVITE At: inviteuas/TestSipServlet -->

INVITE sip:sailfin-AT-inviteuas-DOT-com;transport=UDP SIP/2.0

Content-Length: 127

Max-Forwards: 70

From: "sipp";tag=10460SIPpTag001

Cseq: 1 INVITE


Subject: inviteuas Test

To: "sailfin"

Content-Type: application/sdp

Test-Type: uas

Call-Id: 1-10460-AT-127.0.0-DOT-1

Via: SIP/2.0/UDP 127.0.0-DOT-1:5090;branch=z9hG4bK-10460-1-0


o=user1 53655765 2353687637 IN IP4 127.0.0-DOT-1


c=IN IP4 127.0.0-DOT-1

t=0 0

m=audio 6000 RTP/AVP 0

a=rtpmap:0 PCMU/8000|#]

[#|2009-09-27T23:21:03.533+0530|FINE|sun-glassfish-comms-server2.0|javax.enterprise.system.container.sip.smi|_ThreadID=16;_ThreadName=SipContainer-serversWorkerThread-5060-9;ClassName=org.jvnet.glassfish.comms.admin.reporter.SMIBaseReporter;MethodName=log;_RequestID=fc6596b6-87ec-4304-b423-76425085c98c;|SMI <--OUT Response 200 (INVITE) At: inviteuas/TestSipServlet -->

SIP/2.0 200 OK

From: "sipp";tag=10460SIPpTag001

Cseq: 1 INVITE


To: "sailfin";tag=g043761z-1

Server: Glassfish_SIP_2.0.0

Call-Id: 1-10460-AT-127.0.0-DOT-1

Via: SIP/2.0/UDP 127.0.0-DOT-1:5090;branch=z9hG4bK-10460-1-0

[#|2009-09-27T23:21:03.578+0530|FINE|sun-glassfish-comms-server2.0|javax.enterprise.system.container.sip.smi|_ThreadID=17;_ThreadName=SipContainer-serversWorkerThread-5060-7;ClassName=org.jvnet.glassfish.comms.admin.reporter.SMIBaseReporter;MethodName=log;_RequestID=6dd574b5-0f5a-4857-8e85-0a805d6e02e8;|SMI -->IN Request ACK At: inviteuas/TestSipServlet -->

ACK sip:sailfin-AT-inviteuas-DOT-com;transport=UDP;fid=server_1 SIP/2.0

Content-Length: 0

Max-Forwards: 69

From: "sipp";tag=10460SIPpTag001

Cseq: 1 ACK

Contact: sip:sipp-AT-127.0.0-DOT-1:5090

Subject: inviteuas Test

To: "sailfin";tag=g043761z-1

Call-Id: 1-10460-AT-127.0.0-DOT-1

Via: SIP/2.0/UDP 127.0.0-DOT-1:5090;branch=z9hG4bK-10460-1-5

|#]#|2009-09-27T23:21:04.073+0530|FINE|sun-glassfish-comms-server2.0|javax.enterprise.system.container.sip.smi|_ThreadID=18;_ThreadName=SipContainer-serversWorkerThread-5060-6;ClassName=org.jvnet.glassfish.comms.admin.reporter.SMIBaseReporter;MethodName=log;_RequestID=c88e7c7c-18a1-4632-9994-1e12d6a52d8c;|SMI -->IN Request BYE At: inviteuas/TestSipServlet -->

BYE sip:sailfin-AT-inviteuas-DOT-com;transport=UDP;fid=server_1 SIP/2.0

Content-Length: 0

Max-Forwards: 69

From: "sipp";tag=10460SIPpTag001

Cseq: 2 BYE

Contact: sip:sipp-AT-

Subject: inviteuas Test

To: "sailfin";tag=g043761z-1

Call-Id: 1-10460-AT-

Via: SIP/2.0/UDP;branch=z9hG4bK-10460-1-7


[#|2009-09-27T23:21:04.087+0530|FINE|sun-glassfish-comms-server2.0|javax.enterprise.system.container.sip.smi|_ThreadID=18;_ThreadName=SipContainer-serversWorkerThread-5060-6;ClassName=org.jvnet.glassfish.comms.admin.reporter.SMIBaseReporter;MethodName=log;_RequestID=c88e7c7c-18a1-4632-9994-1e12d6a52d8c;|SMI <--OUT Response 200 (BYE) At: inviteuas/TestSipServlet -->

SIP/2.0 200 OK

From: "sipp";tag=10460SIPpTag001

Cseq: 2 BYE

To: "sailfin";tag=g043761z-1

Server: Glassfish_SIP_2.0.0

Call-Id: 1-10460-AT-

Via: SIP/2.0/UDP;branch=z9hG4bK-10460-1-7


Tuesday Feb 10, 2009

SIP Extension Headers in SailFin

Interpretation of extension-headers as specified in the RFC 3261 is confusing and the extension-headers may be treated as multi valued or single value based on how implementation choose to implement it.

According to RFC 3261 25.1 Basic Rules:

extension-header = header-name HCOLON header-value
header-name = token
header-value = \*(TEXT-UTF8char / UTF8-CONT / LWS)
message-body = \*OCTET

According to the above grammar, extension-headers (user defined headers), which are also not defined by any known RFCs may be treated as single valued headers but most of the applications use the extension-headers as multi valued headers and that puts the implementors in doubt. If the implementation choose either way, some applications may not behave as they intended. One such example is, should "My-Header : Foo,Bar" be treated as as My-Header having Foo and Bar as values? or what if the user wanted it as as single value "Foo,Bar", where comma is a part of value not a value separator. I have looked for guidance from RFC authors on this issue, but with out success.

Mattias from Ericsson has explained in detail, in his own words

IMHO an implementation that is unaware of the exact (BNF) definition of an extension header cannot know whether a comma in its value is intended as just another byte in the value or as a value separator. Further, it cannot know whether any double-quote character in the value is intended as just another byte in the value or as a quoting character, which could, but does not necessarily, imply that any subsequent comma should be interpreted differently. The same goes for any other character (for example single quote, angle or square brackets, etc) that may or may not be used as a quoting character by the extension. In fact, since it's impossible to know _what_ characters an extension may define for quoting, it's completely impossible to even guess at how to interpret a comma.

In short, an unaware implementation cannot be expected to interpret the values of extension headers. The only safe way to define an API is to treat the rest of the (possibly folded) line as a single value.

This does not imply that multiple values are not possible. For example, an unaware proxy that forwards the header unaltered will of course not know whether there is one or more values, but if the ultimately receiving UA is aware of the extension, it will still correctly interpret the contents as one or more values. The important thing here is for the unaware proxy to forward the header _unaltered_!

I also believe that you are correct in your interpretation of the BNF. From a strict BNF perspective, it indeed allows multiple To, From and other well-known single-value-only headers. To maintain a level of simplicity in the BNF, many such semantic rules are instead defined in the text of the RFC. Thus, the argument that the BNF allows multiple
instances of "extension-header" is worthless. For the record, it would be virtually impossible to define a BNF that allows for an arbitrary number of (different) extension headers but limits the number of each header to one, at least without enumerating all possible extension header names (which, of course, would be an infinitely long list given
that there are no length restrictions on such names). Further, it would be impossible to define it such that some extension headers would be allowed in multiple instances but others would not (which, as we've seen in _actual_ extensions, is a perfectly legitimate requirement). The only reasonable way is to keep the BNF "flexible" in this sense, and, as you point out, define for each extension, as it is defined in its own RFC, whether it's allowed one or more times, and, in the latter case, whether comma separation is allowed.

In conclusion, an unaware implementation cannot possibly know whether to allow an extension header name only once or more than one time, even on separate lines. Again, the only safe bet is to be tolerant and assume that whoever sent the extension knows what they're doing and forward any and all such extension headers, again unaltered (and to make them available on the API, accessible as one header instance per line, with a single value per such instance). It has to be left to a node (another proxy or the ultimate UA) that _is_ aware of the extension to judge whether the occurrence of one or more header instances, on a single line with comma separation or on multiple lines, or indeed on a combination of both, makes the SIP message valid.

On a final note: The above outline allows perfectly well for an application built on top of the unaware API to add awareness of the extension. It will just have to parse each "single" value given from the API according to the specific rules of the extension, to see if that "single" value needs to be "split" into several values. Further, the application may use its extension awareness to judge whether additional values on separate lines are permissible. The application, with its additional extension awareness, can do this but the API implementor/provider could never do it correctly. The API implementation would have to choose either to always split at commas or never to do it, and either to always allow multiple separate lines are never to do it. Regardless of which path is taken, some (possibly not yet defined)
extensions would be handled the wrong way.


By taking the spirit from the above explanation, SailFin treats extension-headers as multi valued headers by default and provides configurable mechanism to specify the headers which should take comma as part of value.
org.glassfish.sip.commaisnotaseperator system property can be specified with header names as a comma separated list. For example -Dorg.glassfish.sip.commaisnotaseperator=Header1,Header2, then Header1 and Header2 are interpreted as single valued headers.

Thursday Nov 20, 2008

Parameterable Headers in SailFin

Headers which have "field-name: field-value \*(;parameter-name=parameter-value)" have a direct support for manipulating headers in JSR 289 and referred as Parameterable Headers. javax.servlet.sip.Parameterable interface defines the contract for Parameterable header, javax.servlet.sip.SipFactory.createParameterable(String) helps in creating a Parameterable and javax.servlet.sip.ServletMessage getters and setters helps in adding and retrieves headers in Parameterable form.

According to the JSR 289, a Parameterable header should be interpreted as "field-value \*(;parameter-name[=parameter-value])"
where the field-value may be in name-addr or addr-spec format as defined in RFC 3261 or may be any sequence of tokens till the first semicolon.

With the above interpretation, almost all the headers would be qualified as Parameterable headers, and there is away to create Parameterable but then there is a restriction while adding the created Parameterable to the message as the JSR 289 disallows any header, whose form is not the form in its BNF.

java.lang.IllegalArgumentException - if the specified header is not defined to hold Parameterable values or if the specified header field is a system header

With this the implementation is in a tricky situation and it has to know before hand, what are all the headers which have Parameterable header form, if not for the extension headers, this task is not overly complex. Since some of the extension headers defined by other RFCs might have Parameterable form, there should be a way of extending the list of headers, which takes Parameterable form.

SailFin's Parameterable implementation has been extended so that there is a configurable way of allowing any header to be added to SipServletMessage as a Parameterable. Two system properties which effect this behaviour are:
1) org.glassfish.sip.parameterablecheck : This property can be set to to false to allow any header name to be added to the message as a Parameterable as long as it follows Parameterable's BNF.

Example, the domain.xml:

2) org.glassfish.sip.parameterablelist : This property can be used to specify the explicit list of header names to be considered as Parameterable headers. Union of predefined Parameterable headers as specified in the 4.2.1 of the JSR 289 spec
and this list will be considered as the list of Parameterable headers.

Example, in the domain.xml:

We hope, predefined parameterable headers are good enough for most users and where it is not sufficient, above mechanism can be used.

Tuesday Mar 06, 2007

Code Example: List.toArray(T[] a)

Most of the time, I write small code snippets and wrap them in a small test case to test my assumptions before I put them in a real places. For long a time, I wanted to capture these code snippets some where with my observations. Suddenly I realized, I could blog them too. I hope to continue this practice, but I am not very positive though :-)

Coming to my code snippet, I need to convert a List into an array and I saw java.util.List's " T[] toArray(T[] a)" fitting my bill. This syntax didn't really looked natural to me and I wrote this test case.

import java.util.ArrayList;
public class ToArray {
public static void main(String args[]) {
ArrayList list = new ArrayList();
Integer[] ints = list.toArray(new Integer[]{});
for (Integer i : ints) {

Output of theabove code snippet is:
$ java ToArray

I was bit confused whether the parameter to the toArray should be the same array
Integer[] ints = {};
ints = list.toArray(ints);
or any array of the same type
Integer[] ints = list.toArray(new Integer[]{});

Both of the above two works and what matters is only is the only type.

Tuesday Aug 01, 2006

Search option @ blogs.sun.com

Searching at blogs.sun.com doesn't seems to be returning correct results. I couldn't understand whether search is just applied to the content, or content and author, or title etc. For example, recently there were some posts on GTLC and when I tried to search I get zero results.

Sunday May 21, 2006

Day out in San Francisco

We (Siva and myself)reached SFO two days before Java One. We had the whole sunday to explore SFO. I spoke to couple of my friends to ask for suggestions on what to do at SFO. Prasad gave us some useful suggestions. Finally we came up with a list of things to do. Some of the suggestions included (SFO momo, Sony Metreon, Fisherman warf, coit tower, golden gate park, rent a bike and and go for biking on golden gate bridge to Sausalito and take a ferry back. We finally zeroed on what we partially wanted to do.

We went to travel desk at the hotel (Handlery Union Square) and told our plan. Both of us don't drive and we can't afford taxi to roam all the way. Travel desk guy gave us a great one page map of SFO and suggested us to take street cars. That turned out to be a great suggestion.
It is just $1.50 for a trip and you could use it as a transfer slip for 2 and half hours. Effectively we could roam around quite bit and spend too little on the travel. Great deal and to add they are zero emission vehicles.

We started at market street and took a "F" line and went to Pier 39 (Fisherman's wharf). We roamed there a bit and took pictures all around. We went to bike rental shop near by and asked about the price. He said $8 per hour. Then I immediately translated into rupees and told to siva, if we rent it for three hours, with that money we could buy a new bike in India. Oh! God, when will I stop thinking in these lines? Well, if you want to do any thing including eating, you should just stop thinking in terms of rupees. I managed to do it most of the times, but I can't do it all the time. We dropped the idea of biking, primarily because we weren't confident enough to bike.

We thought of going to Coit tower by walking from there, but fortunately we enquired at the information booth and they said it will be very difficult. So, we walked to Ghiradelli square and bought some ghiradelli chocos. It seems, siva bought from the same place for the last two years. Again there is a information counter there and we got the street car numbers to reach coit tower. From Ghiradelli square, we reached Washington square, which is at the Columus, Union Street intersection by car no 30. We need to take car no 39 to reach, but missed it by a few secs and the next one comes after half an hour. We decided to climb to the tower and it tunred out to be bit more difficult than what I anticipated. I love hiking and trecking, so no complaints here.

Only way to reach the top of coit tower summit is by elevator (unless there is a fire I guess) and it looked like it took quite a bit of time to reach the top. Once you are on top, 360 degrees view of the SFO is great, unfortunately it is not photo friendly as it is completly covered by glass panels. We were wishing atleast there is a space to put camera there so that we could capture some nice photos. Never the less, view is fantastic. Coit tower is on top of telegraph hill and there are some beautiful houses on the hill. From there we took 39 to reach washington square and 30 to reach market street.

We had lunch at Burger King and then to golden gate park. We took 5 fulton and got down at 8th avenue and Fulton intersection and walked into golden gate park. It seems, golden gate park is closed for traffic on sunday and it is very peaceful. Every one seems to have a very relaxed time out there. Few people biking, few people having sun bath and getting tanned. Few people got their snaks and having picnic sort of thing. Over all it sounded amazing.

We went to "conservatory of flowers",which is with in the golden gate park. They are doing pretty good job of conservating different flowers and plants which can only grow in their own climates. "Butterfly garden", "Aquatic plants", "High tropical palnts" and two more sections, whose names I couldn't recollect now. Overall impressed with what we have seen there. Inside it was very humid and difficult to stay there for some time, even by our own standards. There is an entry ticket for $5.

Our next destination is "De Young Museum", "art section"entry is ot free, otherwise it is a free entry. I am not so much of an art fan, so we have taken an elevator (you need to stand in the line for 20 mins to get into elevator) and went into observatory tower in 9th floor. Like Coit tower, here also view is amazing but same story, fully covered with glass panels.

We skipped Japanese Tea garden and moved to stow lake. There is a boating facility, they are peddling type boats and meant for relaxation. Lot of people are on the lake boating. We sat there for some time watching people.

We went out of the park and took a 28 at Presido, Fulton intersection to the golden gate brige. It goes to the starting of the bridge. From there we walked on the golden gate bridge till the half way, enjoing the surroundings and thinking "aren't we walking on the most glamorous and photo graphed bridge that is known to human?" We turned back and then took the 28 back to fulton and 5 back to market street.

We have decided to finally end the day out. What a day!!!. Unlike the previous day and other days in the week, that day is sunny, no fog and no cold wind.

I am not sure, whether mark twain said "The coldest winter I ever spent was a summer in San Francisco'' or not, but I felt bit like this the day before, but not on this day.Turned out to be a great day for going out in SFO and pretty satisfied at the end of day!!!

Friday Feb 10, 2006

Is google search spoiling us?

In most cases google search is of immense help. Now days, when you need bit of help, I tend to rely on google search instead of asking a colleague in the next cube. I kind of wasted an hour today in trying to fix a problem by relying on google search.

One of my colleague's xserver on RHLis not starting at boot time and we kind of thought let us fix it. First thing we did was a google search.

First search result told us to try copying "/etc/X11/XF86Config.backup" to "/etc/X11/XF86Config" and try restaring xserver. This did not help us.

Then we tried couple more suggestions and they didn't help too. Then we had a look at the xserver log "XFree86.0.log" and found out that xserver in not started because it couldn't find "fixed" font which is necessary for xserver to start.

So, we have some information and went ahead for another google search. This time it told us to find if "fixed" font is infact installed on the system. We used "fslsfonts" command to see if the fixed font is installed or not? We realized that font server service is not running. We tried restarting etc. and nothing helped.

At this time fortunately we didn't go for another google search. We ran "df -k". Guess what, file system is 100% full. Finally some relief!!!




« April 2014