Working as Proxy

From Wesip

From Wesip

Another signalling role that an application can take is that of the proxy. The SIP Servlet API abstracts the proxy operation by means of the Proxy object. The proxy object is obtained from the SipServletRequest via the getProxy() method. Any other message involved in the proxy operation carried out by this proxy object wil return the same Proxy instance.

The Proxy objects offers several setters to configure its behaviour. The configurable settings are the following

  • recurse : Tells the proxy to automatically retry when a 3xx response is received.True by default.
  • recordRoute : Whether the application is supposed to stay in the signalling path of the dialog. By default is false. If not modified the application won't receive subsequent requests (BYEs,ACKs...)
  • parallel : When proxying to multiple destinations this flag indicates whether the proxy should fork or retry sequentially. Default is true.
  • stateful : Indicates wethere the proxying should be carried out statelessly or statefully. Has no impact on the application so it may be considered a hint by the container.
  • supervised : If set to true (which is the default) responses coming from the downstream are delivered to the servlet. Otherwise they are forwarded upstream(if applies) by the container without application involvement.
  • sequentialSearchTimeout : How long will the proxy wait for one of its branches to send a final response before cancelling it. The default value is container dependent but can be modified with the sequential-search-timeout parameter of the deployment descriptor.

Proxy operation

Servlets can proxy a request obtaining a Proxy object, configuring its behaviour and then invoking its proxyTo method

....
public void doInvite(SipServletRequest req) { 

   if (req.isInitial()) {
     
     Proxy p = req.getProxy(); 
     p.setRecordRoute(true);
     p.setSupervised(false);
  
     //Obtain the target Request URI applying business logic over
     //the incoming request
     URI proxyTarget = myBusinessLogicMethod(req); 
     //If required you can push any number of URIs that force
     //the proxied request to visit a certain set of proxies
     //according to RFC 3261, section 16.6 
     req.pushRoute(NEXT_HOPE_PROXY);
     p.proxyTo(proxyTarget); 
   }
} 
....

That's all. If your application is not interested in managing the responses you can set the proxy to not supervised mode and let the container do the magic. It will forward the best response upstream when needed without extra code. Also note that since we have "record routed" subsequent requests inside the dialog will be delivered to the servlet. That means that a BYE request would hit the doBYE method but since we haven't extended it the default servlet behaviour applies which simply takes care of forwarding the request downstream as appropiate.

The servlet can cancel a pending proxy operation by simply calling to the cancel() method of the Proxy object. When doing so the container will send CANCELs to all the pending branches and then resume operation as per RFC. Please note that there is no way to cancel a particular branch and that CANCEL responses are not passed to the application even if proxy is working in supervised mode.

If the container receives a CANCEL then it automatically responds with a 200 to the CANCEL request and checks wether the original response has been already proxied or not.

  • If not it responds to it with a 487 final response and passes the CANCEL to the application. From this point onwards any attempt from the servlet to proxy the original request ends with an IllegalStateException.
  • If the original request had been already proxied the container will automatically cancel all active branches, pass the CANCEL request to the application and let processing follow as usual.

<< Working as B2BUA | Working as Proxy II >>