 |
How to build a Registrar Service
Description of the Service
The user agent sends a message to the SLEE. SLEE registers the location of the user agent and sends OK response to the user. The service also keeps track of a registration timer. If the user does not send a new Register request before the timer expires the Registrar Service will remove the registration entry from the location database.
Service Implementation
First Implementation
The Service “SIP Registrar Service Sbb”,”NIST”,”1.0” has a root Sbb “Registrar Sbb”, “NIST”, “1.0”. The deployment descriptor of the service is the following:
<service-xml>
<service>
<service-name>SIP Registrar Service</service-name>
<service-vendor>NIST</service-vendor>
<service-version>1.0</service-version>
<root-sbb>
<sbb-name>Sip Registrar Sbb</sbb-name>
<sbb-vendor>NIST</sbb-vendor>
<sbb-version>1.0</sbb-version>
</root-sbb>
<default-priority>0</default-priority>
</service>
</service-xml>
Service Events
The Registrar Sbb Deployment Descriptor specify two events:
- JAIN SIP REGISTER request method let’s take a look at the event properties inside the dd:
- The direction for this event is received, the Sbb has to define a handler to consume the event
- This event is an initial event
- The initial-event-select-variable for this event is ActivityContext?.
- A new service will be instantiated whenever an event coming from the resource adaptor is fired on a new ActivityContext?.
- The ActivityContext? has a 1-to-1 mapping with an Activity inside the SIP Resource Adaptor.
- The JAIN SIP resource adaptor type defines an activity, which has an associated SIP Transaction.
- A SIP Transaction is an abstraction in the SIP protocol that manages a request response paradigm. A SIP Transaction can be intuitively mapped to a phone conversation. A SIP transaction occurs between a client and a server and comprises all messages from the first request sent from the client to the server up to a final non-1xx response.
- There will be a service instantiation for each REGISTER request. So if the service has 100 users that are trying to REGISTER and each user sends 4 REGISTER requests, the service will be instantiated 400 times (this could lead to a flooding attack, see security notes).
- JAIN SLEE TimerEvent?
- The direction for this event is receive, the Sbb has to define a handler to consume the event
- The event is not an initial event.
<sbb-jar>
<sbb id="sip-registrar-sbb">
<description>JAIN SIP Registrar SBB</description>
<sbb-name>Sip Registrar Sbb</sbb-name>
<sbb-vendor>NIST</sbb-vendor>
<sbb-version>1.0</sbb-version>
<sbb-classes>
<sbb-abstract-class>
<sbb-abstract-class-name>
gov.nist.slee.test.services.sip.registrar.RegistrarSbb
</sbb-abstract-class-name>
</sbb-abstract-class>
<sbb-activity-context-interface>
<sbb-activity-context-interface-name>
gov.nist.slee.test.services.sip.registrar.RegistrarActivityContextInterface
</sbb-activity-context-interface-name>
</sbb-activity-context-interface>
</sbb-classes>
<event event-direction="Receive" initial-event="True">
<event-name>RegisterEvent</event-name>
<event-type-ref>
<event-type-name>javax.sip.message.Request.REGISTER</event-type-name>
<event-type-vendor>javax.sip</event-type-vendor>
<event-type-version>1.1</event-type-version>
</event-type-ref>
<initial-event-select variable="ActivityContext" />
</event>
<event event-direction="Receive" initial-event="False">
<event-name>TimerEvent</event-name>
<event-type-ref>
<event-type-name>javax.slee.facilities.TimerEvent</event-type-name>
<event-type-vendor>javax.slee</event-type-vendor>
<event-type-version>1.0</event-type-version>
</event-type-ref>
</event>
<resource-adaptor-type-binding>
. . . . .
</resource-adaptor-type-binding>
</sbb>
</sbb-jar>
Service Logic
The onRegisterEvent method inside the registrar Sbb:
- Creates an entry for the user agent sip url inside the location servicedb. The entry contains the following informations: the contact point of the user agent (ip address and udp port) , the expiration time for this entry, CallID? and the sequence number of the sip request.
- Creates a NullActivity
- Creates a timer by setting the expire time
- Attach the timer and itself to the ActivityContext? corresponding to the newly created NullActivity
- The Sbb Sets the sequence number of the registration request inside the ActivityContext? by using the RegisterActivityContextInterface?.
Timer
When the Timer fires the onTimerEvent method is triggered.
- The Sbb checks the value inside the ActivityContext? by using the RegisterActivityContextInterface? and compares this value with the value inside the location entry. If the value inside the location service is greater than the value inside the ActivityContext? this registration has been updated by a new registration request, in this case the Service does not delete the registration entry. If the value is equal to the value inside the activity context the registration has expired and the Service remove the location entry for the given sip url.
public interface RegistrarActivityContextInterface extends ActivityContextInterface{
/** sipAddress - User's public, well-known SIP address */
public String getSipAddress();
public void setSipAddress(String sipAddress);
/** sipContactAddress - Physical network address registered for above sipAddress */
public String getSipContactAddress();
public void setSipContactAddress(String sipContactAddress);
/** callId - SIP callId that was used in the REGISTER request */
public String getCallId();
public void setCallId(String callId);
/** cSeq - SIP sequence number that was used in the REGISTER request */
public long getCSeq();
public void setCSeq(long cSeq);
}
Comments
The problem with this approach is that every time a new sip request is sent to the slee the Service will create a new instance of the root SBB, this will lead to the creation of a new null activity and a new timer. If we have 100 user of the system and each user sends 4 registrations request the Service will create 400 Service instance and for every service instance will create 400 root Sbbs, 400 NullActivities, 400 Timers. Each root sbb is removed only after the timer associated with the registration will fire.
All the 400 timer will fire when the timer expire because when a new request comes in the previous timers are not cancelled.
Regarding the location database a entry write is done for every REGISTER request during the onRegisterEvent call and a entry read will be done inside the onTimerEvent method, if the registration expires we will also have a entry deletion from the location db.
This will lead to 400 entry write, 400 entry read and x entry deletion.
Goals for improvement
We want to reduce the number of service instance and resources created inside the SLEE
We want to cancel the timer just when they are no longer meaningful (i.e. when a new request comes in for a given uri the previous timer associated with the request should be canncelled).
We want to prevent that a user will flood the SLEE by keep sending REGISTER request.
Second Implementation
Strategy
The Service will be instantiated only once for each sip url, this can be done by using the Address attribute for initial-event-select-variable. The Register service will create a nullactivity when the rootSbb is created (i.e in the postCreate method).
The root sbb will have a persistent field in which the sbb can store the timerID of the last timer that has been set by the rootSbb. When a register comes in the previous timer is cancelled and a new timer is set on the null Activity Context. If the service has 100 user agents and they send 4 register request each we will have 100 service instance, 100 nullactivity and 100 timer in turn.
Talkback
[Author: Francesco Moggia]
-- Main.ivelin - 19 Mar 2005
|