Anshuman S. Rawat wrote:
> It fixes the the problem I described in 
> http://list.sipfoundry.org/archive/sipxtapi-dev/msg01649.html
> 
> Regards,
> Anshuman

I applied the fix to svn.

> Does this patch fix STUN ?

Stun bug can be fixed by attached patch.

Jaro
Index: 
sipXmediaAdapterLib/sipXmediaMediaProcessing/src/CpPhoneMediaInterface.cpp
===================================================================
--- sipXmediaAdapterLib/sipXmediaMediaProcessing/src/CpPhoneMediaInterface.cpp  
(revision 9889)
+++ sipXmediaAdapterLib/sipXmediaMediaProcessing/src/CpPhoneMediaInterface.cpp  
(working copy)
@@ -2652,37 +2652,71 @@
 
    if (!isMulticast)
    {
-       // Enable Stun if we have a stun server and either non-local contact 
type or 
-       // ICE is enabled.
-       if ((mStunServer.length() != 0) && ((contactType != CONTACT_LOCAL) || 
mEnableIce))
-       {
-          ((OsNatDatagramSocket*)rtpSocket)->enableStun(mStunServer, mStunPort,
-                                                        
mStunRefreshPeriodSecs, 0, false) ;
-       }
+      NAT_BINDING rtpBindingMode = NO_BINDING;
+      NAT_BINDING rtcpBindingMode = NO_BINDING;
 
-       // Enable Turn if we have a stun server and either non-local contact 
type or 
-       // ICE is enabled.
-       if ((mTurnServer.length() != 0) && ((contactType != CONTACT_LOCAL) || 
mEnableIce))
-       {
-          ((OsNatDatagramSocket*)rtpSocket)->enableTurn(mTurnServer, 
mTurnPort, 
-                   mTurnRefreshPeriodSecs, mTurnUsername, mTurnPassword, 
false) ;
-       }
+      // Enable Stun if we have a stun server and either non-local contact 
type or 
+      // ICE is enabled.
+      if ((mStunServer.length() != 0) && ((contactType != CONTACT_LOCAL) || 
mEnableIce))
+      {
+         ((OsNatDatagramSocket*)rtpSocket)->enableStun(mStunServer, mStunPort, 
mStunRefreshPeriodSecs, 0, false) ;
+         rtpBindingMode = STUN_BINDING;
+      }
 
-       // Enable Stun if we have a stun server and either non-local contact 
type or 
-       // ICE is enabled.
-       if ((mStunServer.length() != 0) && ((contactType != CONTACT_LOCAL) || 
mEnableIce))
-       {
-          ((OsNatDatagramSocket*)rtcpSocket)->enableStun(mStunServer, 
mStunPort,
-                                                         
mStunRefreshPeriodSecs, 0, false) ;
-       }
+      // Enable Turn if we have a stun server and either non-local contact 
type or 
+      // ICE is enabled.
+      if ((mTurnServer.length() != 0) && ((contactType != CONTACT_LOCAL) || 
mEnableIce))
+      {
+         ((OsNatDatagramSocket*)rtpSocket)->enableTurn(mTurnServer, mTurnPort, 
+                  mTurnRefreshPeriodSecs, mTurnUsername, mTurnPassword, false) 
;
 
-       // Enable Turn if we have a stun server and either non-local contact 
type or 
-       // ICE is enabled.
-       if ((mTurnServer.length() != 0) && ((contactType != CONTACT_LOCAL) || 
mEnableIce))
-       {
-          ((OsNatDatagramSocket*)rtcpSocket)->enableTurn(mTurnServer, 
mTurnPort, 
-                   mTurnRefreshPeriodSecs, mTurnUsername, mTurnPassword, 
false) ;
-       }
+         if (rtpBindingMode == STUN_BINDING)
+         {
+            rtpBindingMode = STUN_TURN_BINDING;
+         }
+         else
+         {
+            rtpBindingMode = TURN_BINDING;
+         }
+      }
+
+      // Enable Stun if we have a stun server and either non-local contact 
type or 
+      // ICE is enabled.
+      if ((mStunServer.length() != 0) && ((contactType != CONTACT_LOCAL) || 
mEnableIce))
+      {
+         ((OsNatDatagramSocket*)rtcpSocket)->enableStun(mStunServer, 
mStunPort, mStunRefreshPeriodSecs, 0, false) ;
+         rtcpBindingMode = STUN_BINDING;
+      }
+
+      // Enable Turn if we have a stun server and either non-local contact 
type or 
+      // ICE is enabled.
+      if ((mTurnServer.length() != 0) && ((contactType != CONTACT_LOCAL) || 
mEnableIce))
+      {
+         ((OsNatDatagramSocket*)rtcpSocket)->enableTurn(mTurnServer, 
mTurnPort, 
+                  mTurnRefreshPeriodSecs, mTurnUsername, mTurnPassword, false) 
;
+
+         if (rtcpBindingMode == STUN_BINDING)
+         {
+            rtcpBindingMode = STUN_TURN_BINDING;
+         }
+         else
+         {
+            rtcpBindingMode = TURN_BINDING;
+         }
+      }
+
+      // wait until all sockets have results
+      if (rtpBindingMode != NO_BINDING || rtcpBindingMode!= NO_BINDING)
+      {
+         bool bRepeat = true;
+         while(bRepeat)
+         {
+            bRepeat = false;
+            bRepeat |= 
((OsNatDatagramSocket*)rtpSocket)->waitForBinding(rtpBindingMode, false);
+            bRepeat |= 
((OsNatDatagramSocket*)rtcpSocket)->waitForBinding(rtcpBindingMode, false);
+            // repeat as long as one of sockets is waiting for result
+         }
+      }
    }
 
    return OS_SUCCESS;
@@ -2692,4 +2726,3 @@
 
 /* ============================ FUNCTIONS ================================= */
 
-
Index: sipXportLib/include/os/OsNatDatagramSocket.h
===================================================================
--- sipXportLib/include/os/OsNatDatagramSocket.h        (revision 9889)
+++ sipXportLib/include/os/OsNatDatagramSocket.h        (working copy)
@@ -50,6 +50,14 @@
 } NAT_STATUS ;
 
 
+typedef enum
+{
+   NO_BINDING,
+   STUN_BINDING,
+   TURN_BINDING,
+   STUN_TURN_BINDING
+} NAT_BINDING;
+
 /**
  * STUN_STATE holds state information for a STUN discovery binding/attempt 
  */
@@ -221,6 +229,19 @@
      */
     virtual void disableTurn() ;
 
+    /**
+     * Waits for result of STUN/TURN binding on this socket. Must be
+     * called after STUN/TURN is enabled and reading is not done from
+     * socket.
+     *
+     * @param binding Binding type to wait for.
+     * @param bWaitUntilReady Whether we should block until bindings are
+     *        ready
+     * @return True if this function needs to be called again, because
+     *         some of bindings are not yet available. False if all requested
+     *         bindings are ready.
+     */
+    virtual bool waitForBinding(NAT_BINDING binding, bool bWaitUntilReady);
 
     /**
      * When a stun packet is received this socket can either call read again
Index: sipXportLib/src/os/OsNatDatagramSocket.cpp
===================================================================
--- sipXportLib/src/os/OsNatDatagramSocket.cpp  (revision 9889)
+++ sipXportLib/src/os/OsNatDatagramSocket.cpp  (working copy)
@@ -303,7 +303,7 @@
 
                 while (mStunState.status == NAT_STATUS_UNKNOWN)
                 {
-                    read(cBuf, sizeof(cBuf), 500) ;                
+                    read(cBuf, sizeof(cBuf), 100) ;                
                     if (mStunState.status == NAT_STATUS_UNKNOWN)
                     {
                         OsTask::yield() ;
@@ -354,7 +354,7 @@
 
                 while (mTurnState.status == NAT_STATUS_UNKNOWN)
                 {
-                    read(cBuf, sizeof(cBuf), 500) ;
+                    read(cBuf, sizeof(cBuf), 100) ;
                     if (mTurnState.status == NAT_STATUS_UNKNOWN)
                     {
                         OsTask::yield() ;
@@ -381,6 +381,49 @@
 }
 
 
+bool OsNatDatagramSocket::waitForBinding(NAT_BINDING binding, bool 
bWaitUntilReady)
+{
+   bool result = false;
+
+   if (binding != NO_BINDING)
+   {
+      char cBuf[2048];
+
+      do
+      {
+         if (!(((binding == STUN_BINDING || binding == STUN_TURN_BINDING) &&
+            mStunState.status == NAT_STATUS_UNKNOWN)
+            ||
+            ((binding == TURN_BINDING || binding == STUN_TURN_BINDING) &&
+            mTurnState.status == NAT_STATUS_UNKNOWN)))
+         {
+            // leave loop, since stun/turn result is known
+            break;
+         }
+
+         read(cBuf, sizeof(cBuf), 50);
+      } while (bWaitUntilReady);
+
+      if (!(((binding == STUN_BINDING || binding == STUN_TURN_BINDING) &&
+         mStunState.status == NAT_STATUS_UNKNOWN)
+         ||
+         ((binding == TURN_BINDING || binding == STUN_TURN_BINDING) &&
+         mTurnState.status == NAT_STATUS_UNKNOWN)))
+      {
+         // if stun or turn result is known and is requested
+         result = false; // no need to call this function again
+      }
+      else
+      {
+         // either stun or turn result is not yet available and is requested
+         result = true; // we need to call this function again
+      }
+   }
+   
+   return result;
+}
+
+
 void OsNatDatagramSocket::enableTransparentReads(bool bEnable)
 {
     mbTransparentReads = bEnable ;
@@ -662,6 +705,7 @@
     return bRC ;
 }
 
+
 /* //////////////////////////// PRIVATE /////////////////////////////////// */
 
 /* ============================ FUNCTIONS ================================= */
_______________________________________________
sipxtapi-dev mailing list
[email protected]
List Archive: http://list.sipfoundry.org/archive/sipxtapi-dev/

Reply via email to