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/