Revision: 8642
Author: vladimir.ralev
Date: Tue Nov 24 07:06:32 2009
Log: Recover some lost calls in proxy scenarios

http://code.google.com/p/mobicents/source/detail?r=8642

Modified:
/trunk/servers/sip-servlets/sip-servlets-impl/src/main/java/org/mobicents/servlet/sip/core/dispatchers/ResponseDispatcher.java /trunk/servers/sip-servlets/sip-servlets-impl/src/main/java/org/mobicents/servlet/sip/message/SipServletResponseImpl.java /trunk/servers/sip-servlets/sip-servlets-impl/src/main/java/org/mobicents/servlet/sip/proxy/ProxyBranchImpl.java /trunk/servers/sip-servlets/sip-servlets-impl/src/main/java/org/mobicents/servlet/sip/proxy/ProxyImpl.java /trunk/servers/sip-servlets/sip-servlets-impl/src/main/java/org/mobicents/servlet/sip/proxy/ProxyUtils.java

=======================================
--- /trunk/servers/sip-servlets/sip-servlets-impl/src/main/java/org/mobicents/servlet/sip/core/dispatchers/ResponseDispatcher.java Mon Nov 23 23:43:10 2009 +++ /trunk/servers/sip-servlets/sip-servlets-impl/src/main/java/org/mobicents/servlet/sip/core/dispatchers/ResponseDispatcher.java Tue Nov 24 07:06:32 2009
@@ -221,8 +221,6 @@
                                                        }

                                                        if(session.getProxy() 
!= null) {
- // TODO: FIXME: On retrans - we get null transaction from JSIP thus we lose the info about the
-                                                               // proxy 
branch. Figure out a way to do the mapping.

// the final Application data is null meaning that the CTX was null, so it's a retransmission
                                                                if(proxyBranch 
== null) {
@@ -233,6 +231,15 @@
SIPTransaction tx = ((SipStackImpl)sipProvider.getSipStack()).findTransaction((SIPMessage) response, false);
                                                                        if(tx 
!= null) {
TransactionApplicationData tad = (TransactionApplicationData) tx.getApplicationData();
+                                                                               
if(tad == null) {
+                                                                               
        if(logger.isDebugEnabled()) {
+ logger.debug("Attempting to recover lost transaction app data for " + branch);
+                                                                               
        }
+ tad = (TransactionApplicationData) session.getProxy().getTransactionMap().get(branch);
+                                                                               
        if(logger.isDebugEnabled()) {
+ if(tad != null) logger.debug("Sucessfully recovered app data for " + branch + " " + tad);
+                                                                               
        }
+                                                                               
}
                                                                                
if(tad != null) {
                                                                                
        proxyBranch = tad.getProxyBranch();
logger.debug("A proxy response retransmission was able to recover the transaction application data");
=======================================
--- /trunk/servers/sip-servlets/sip-servlets-impl/src/main/java/org/mobicents/servlet/sip/message/SipServletResponseImpl.java Fri Nov 20 04:24:28 2009 +++ /trunk/servers/sip-servlets/sip-servlets-impl/src/main/java/org/mobicents/servlet/sip/message/SipServletResponseImpl.java Tue Nov 24 07:06:32 2009
@@ -50,6 +50,7 @@
 import javax.sip.header.RequireHeader;
 import javax.sip.header.RouteHeader;
 import javax.sip.header.SupportedHeader;
+import javax.sip.header.ViaHeader;
 import javax.sip.header.WWWAuthenticateHeader;
 import javax.sip.message.Request;
 import javax.sip.message.Response;
@@ -468,6 +469,19 @@
                        if(logger.isDebugEnabled()) {
                                logger.debug("sending response "+ this.message);
                        }
+                       if(originalRequest == null && session.getProxy() != 
null) {
+ String txid = ((ViaHeader) message.getHeader(ViaHeader.NAME)).getBranch(); + TransactionApplicationData tad = (TransactionApplicationData) session.getProxy().getTransactionMap().get(txid);
+                               if(logger.isDebugEnabled()) {
+ logger.debug("OTrying to recover lost transaction for proxy: " + txid);
+                               }
+                               if(tad != null) {
+                                       if(logger.isDebugEnabled()) {
+ logger.debug("Recovering lost transaction from the proxy transaction map is succesful: " + txid);
+                                       }
+                                       originalRequest = 
(SipServletRequestImpl) tad.getSipServletMessage();
+                               }
+                       }
//if a response is sent for an initial request, it means that the application //acted as an endpoint so a dialog must be created but only for dialog creating method
                        if(!Request.CANCEL.equals(originalRequest.getMethod())
=======================================
--- /trunk/servers/sip-servlets/sip-servlets-impl/src/main/java/org/mobicents/servlet/sip/proxy/ProxyBranchImpl.java Fri Nov 20 04:24:28 2009 +++ /trunk/servers/sip-servlets/sip-servlets-impl/src/main/java/org/mobicents/servlet/sip/proxy/ProxyBranchImpl.java Tue Nov 24 07:06:32 2009
@@ -142,6 +142,7 @@
         */
public void cancel(String[] protocol, int[] reasonCode, String[] reasonText) { if(proxy.getAckReceived()) throw new IllegalStateException("There has been an ACK received on this branch. Can not cancel.");
+
                try {
                        cancelTimer();
                        if(this.isStarted() && !canceled && !timedOut &&
@@ -186,6 +187,17 @@
                }
                catch(Exception e) {
                        throw new IllegalStateException("Failed canceling proxy 
branch", e);
+               } finally {
+                       onBranchTerminated();
+               }
+
+       }
+
+ // This will be called when we are sure this branch will not succeed and we moved on to other branches.
+       public void onBranchTerminated() {
+               if(outgoingRequest != null) {
+ String txid = ((ViaHeader) outgoingRequest.getMessage().getHeader(ViaHeader.NAME)).getBranch();
+                       proxy.getTransactionMap().remove(txid);
                }
        }

@@ -364,6 +376,10 @@
                }
                
clonedRequest.getTransactionApplicationData().setProxyBranch(this);
                clonedRequest.send();
+ String txid = ((ViaHeader) clonedRequest.getMessage().getHeader(ViaHeader.NAME)).getBranch();
+               if(clonedRequest.getTransactionApplicationData() != null) {
+ proxy.transactionMap.put(txid, clonedRequest.getTransactionApplicationData());
+               }
        }

        /**
=======================================
--- /trunk/servers/sip-servlets/sip-servlets-impl/src/main/java/org/mobicents/servlet/sip/proxy/ProxyImpl.java Tue Nov 24 01:44:57 2009 +++ /trunk/servers/sip-servlets/sip-servlets-impl/src/main/java/org/mobicents/servlet/sip/proxy/ProxyImpl.java Tue Nov 24 07:06:32 2009
@@ -25,6 +25,7 @@
 import java.net.InetAddress;
 import java.net.InetSocketAddress;
 import java.util.ArrayList;
+import java.util.HashMap;
 import java.util.LinkedHashMap;
 import java.util.List;
 import java.util.ListIterator;
@@ -82,6 +83,8 @@
        // clustering : will be recreated when loaded from the cache
        private transient ProxyUtils proxyUtils;

+ transient HashMap<String, Object> transactionMap = new HashMap<String, Object>();
+
        private transient Map<URI, ProxyBranch> proxyBranches;
        private boolean started;
        private boolean ackReceived = false;
@@ -110,6 +113,10 @@
this.outboundInterface = ((MobicentsSipSession)request.getSession()).getOutboundInterface();
                this.callerFromHeader = request.getFrom().toString();
                this.previousNode = extractPreviousNodeFromRequest(request);
+ String txid = ((ViaHeader) request.getMessage().getHeader(ViaHeader.NAME)).getBranch();
+               if(originalRequest.getTransactionApplicationData() != null) {
+ this.transactionMap.put(txid, originalRequest.getTransactionApplicationData());
+               }
        }

        /*
@@ -553,6 +560,7 @@
                                        if(logger.isDebugEnabled())
                                                logger.debug("Trying new branch in 
proxy" );
                                        startNextUntriedBranch();
+                                       branch.onBranchTerminated();
                                }
                        }
                }
@@ -572,6 +580,7 @@
                        {
                                branch.cancel();
                                startNextUntriedBranch();
+                               branch.onBranchTerminated();
                        }
                }
        }
@@ -633,13 +642,18 @@

                if(logger.isDebugEnabled())
                                        logger.debug("Proxy branch has NOT timed 
out");
-
-
+
                //Otherwise proceed with proxying the response
                SipServletResponseImpl proxiedResponse =
                        getProxyUtils().createProxiedResponse(response, 
proxyBranch);

-               if(proxiedResponse.getRequest() != null) {
+
+               if(proxiedResponse.getMessage() == null) {
+                       return;// drop out of order message
+               }
+
+
+               if(originalRequest != null && proxiedResponse.getRequest() != 
null) {
                        if(logger.isDebugEnabled())
logger.debug("Response was dropped because getProxyUtils().createProxiedResponse(response, proxyBranch) returned null");
                        // non retransmission case
@@ -773,6 +787,10 @@
        public void setCallerFromHeader(String initiatorFromHeader) {
                this.callerFromHeader = initiatorFromHeader;
        }
+
+       public HashMap<String, Object> getTransactionMap() {
+               return transactionMap;
+       }

        public void readExternal(ObjectInput in) throws IOException,
                        ClassNotFoundException {
=======================================
--- /trunk/servers/sip-servlets/sip-servlets-impl/src/main/java/org/mobicents/servlet/sip/proxy/ProxyUtils.java Fri Nov 20 04:24:28 2009 +++ /trunk/servers/sip-servlets/sip-servlets-impl/src/main/java/org/mobicents/servlet/sip/proxy/ProxyUtils.java Tue Nov 24 07:06:32 2009
@@ -253,7 +253,8 @@
                }

                SipServletResponseImpl newServletResponseImpl = null;
-               if(sipServetResponse.getTransaction() != null) {
+
+ if(sipServetResponse.getTransaction() != null && originalRequest != null) {
                        // non retransmission case
                        newServletResponseImpl = new 
SipServletResponseImpl(clonedResponse,
                                        sipFactoryImpl,

Reply via email to