Issues regarding NAT traversal

[Date Prev][Date Next][Thread Prev][Thread Next][Date Index][Thread Index]

 



Hi.
  i have found two issues:
First is in EndpointRec::SetSocket(CallSignalSocket *socket) there is
if (!socket->IsConnected()) {  return;  }
which in (i think) some kind of race condition with tcp handshake 
sequence causes first information packet sent in this connection to be 
dropped which in turn renders socket unusable and terminal unavaiable 
for incoming calls until it sends next informational packet which may 
happen several minutes later.
i would suggest changing return statement to some warning in log  like
PTRACE(1, "Q931\twarning: NAT socket not (yet?) connected " << 
socket->Name() << " for endpoint " << GetEndpointIdentifier().GetValue());
espacialy that socket is forced to connected state right after setSocket 
exits in CallSignalSocket::OnInformation()

Second issue is with ipphone KE1020 which i think is also known under 
other names.
they are sending in RRQ something like this:
[..]    nonStandardData = {   nonStandardIdentifier = object
data =  18 octets { ADDR=192.168.2.100      }    }
[..]	endpointVendor = {
vendor = { t35CountryCode = 38 t35Extension = 0 manufacturerCode = 
21845}  productId =  16 octets {  Koncept       }
versionId =  5 octets {  2.19.      }}

They were running perfectly with older gnugk versions (up to 2.2.5 
afair) (however i'm not quite sure how when i look into code ;-), but 
they seems to not like those new code which have been recently added to 
RasSrv.cxx:
rcf.m_nonStandardData.m_nonStandardIdentifier.SetTag(H225_NonStandardIdentifier::e_h221NonStandard);
H225_H221NonStandard &t35 = rcf.m_nonStandardData.m_nonStandardIdentifier;
t35.m_t35CountryCode = Toolkit::t35cPoland;
t35.m_manufacturerCode = Toolkit::t35mGnuGk;
t35.m_t35Extension = Toolkit::t35eNATTraversal;

and there are several changes i'm adding a patch, sory for excesive 
PTRACE inside but i have found it usefull. (patch is against todays 
RasSrv.cxx

Grzegorz Stanislawski


Index: RasSrv.cxx
===================================================================
RCS file: /cvsroot/openh323gk/openh323gk/RasSrv.cxx,v
retrieving revision 1.227
diff -u -r1.227 RasSrv.cxx
--- RasSrv.cxx  14 Oct 2008 10:38:36 -0000      1.227
+++ RasSrv.cxx  6 Nov 2008 20:12:57 -0000
@@ -1658,6 +1658,8 @@
                         // forward lightweights, too
                         if (bShellForwardRequest)
                                 RasSrv->ForwardRasMsg(m_msg->m_recvRAS);
+                       //hack race condition - deleted ep since found 
this porinter 50 lines above
+                       if(!ep) return 
BuildRRJ(H225_RegistrationRejectReason::e_fullRegistrationRequired);
                         // endpoint was already registered
                         ep->Update(m_msg->m_recvRAS);
                         return bShellSendReply ? BuildRCF(ep) : false;
@@ -1667,7 +1669,7 @@
         if (request.m_rasAddress.GetSize() == 0)
                 return 
BuildRRJ(H225_RegistrationRejectReason::e_invalidRASAddress);

-       bool nated = false, validaddress = false, internal = false;
+       bool nated = false, validaddress = false, internal = false, 
buggyCitron = false;
         if (request.m_callSignalAddress.GetSize() >= 1) {
                 PIPSocket::Address ipaddr;
                 for (int s = 0; s < 
request.m_callSignalAddress.GetSize(); ++s) {
@@ -1800,18 +1802,29 @@
                 return 
BuildRRJ(H225_RegistrationRejectReason::e_resourceUnavailable);
         }

-       if (!nated && 
request.HasOptionalField(H225_RegistrationRequest::e_nonStandardData)) {
+       if 
(request.HasOptionalField(H225_RegistrationRequest::e_nonStandardData)) {
+               if(!nated) {
+                       PTRACE(3, "RAS\tRRQ with citron from not (yet) 
NATED endpoint "<<AsDotString(SignalAddr));
+               }else {
+                       PTRACE(3, "RAS\tRRQ with citron from NATED 
endpoint "<<AsDotString(SignalAddr));
+               }
                 int iec = Toolkit::iecUnknown;
                 if 
(request.m_nonStandardData.m_nonStandardIdentifier.GetTag() == 
H225_NonStandardIdentifier::e_h221NonStandard) {
                         iec = 
Toolkit::Instance()->GetInternalExtensionCode(request.m_nonStandardData.m_nonStandardIdentifier);
+                       PTRACE(3, "RAS\tcitron check 1 
"<<AsDotString(SignalAddr));
                 } else if 
(request.m_nonStandardData.m_nonStandardIdentifier.GetTag() == 
H225_NonStandardIdentifier::e_object) {
+                       PTRACE(3, "RAS\tcitron check 2 
"<<AsDotString(SignalAddr));
                         PASN_ObjectId &oid = 
request.m_nonStandardData.m_nonStandardIdentifier;
                         if (oid.GetDataLength() == 0)
                                 iec = Toolkit::iecNATTraversal;
+               } else {
+                       PTRACE(3, "RAS\tcitron check 3 
"<<AsDotString(SignalAddr));
                 }
                 if (iec == Toolkit::iecNATTraversal) {
+                       PTRACE(3, "RAS\tcitron check 4 
(Toolkit::iecNATTraversal)"<<AsDotString(SignalAddr));
                         PString ipdata = 
request.m_nonStandardData.m_data.AsString();
                         if (strncmp(ipdata, "IP=", 3) == 0) {
+                               PTRACE(3, "RAS\tcitronNAT endpoint: good 
"<<AsDotString(SignalAddr));
                                 PStringArray 
ips(ipdata.Mid(3).Tokenise(",:;", false));
                                 PINDEX k;
                                 for (k = 0; k < ips.GetSize(); ++k)
@@ -1820,6 +1833,19 @@
                                 nated = (k >= ips.GetSize());
 
request.RemoveOptionalField(H225_RegistrationRequest::e_nonStandardData);
                         }
+                       if (strncmp(ipdata, "ADDR=", 5) == 0) {
+                               PTRACE(3, "RAS\tcitronNAT endpoint: 
buggy "<<AsDotString(SignalAddr));
+                               buggyCitron=true;
+                               PStringArray 
ips(ipdata.Mid(5).Tokenise(",:;", false));
+                               PINDEX k;
+                               for (k = 0; k < ips.GetSize(); ++k)
+                                       if (PIPSocket::Address(ips[k]) 
== rx_addr)
+                                               break;
+                               nated = (k >= ips.GetSize());
+ 
request.RemoveOptionalField(H225_RegistrationRequest::e_nonStandardData);
+                       }
+               } else {
+                   PTRACE(3, "RAS\tcitron check 5 
"<<AsDotString(SignalAddr));
                 }
         }
         request.m_callSignalAddress.SetSize(1);
@@ -1859,18 +1885,27 @@
                 BuildRCF(ep);
                 H225_RegistrationConfirm & rcf = m_msg->m_replyRAS;
                 if (supportcallingNAT && !internal) {
+                       PTRACE(3, "RAS\tabout to send RCF 
(supportcallingNAT && !internal)"<<AsDotString(SignalAddr));
                         // tell the endpoint its translated address
 
rcf.IncludeOptionalField(H225_RegistrationConfirm::e_nonStandardData);
+                 if(buggyCitron) {
+                       PTRACE(3, "RAS\tbuggy"<<AsDotString(SignalAddr));
+                 } else {
+                       PTRACE(3, "RAS\tnot 
buggy"<<AsDotString(SignalAddr));
 
rcf.m_nonStandardData.m_nonStandardIdentifier.SetTag(H225_NonStandardIdentifier::e_h221NonStandard);
                         H225_H221NonStandard &t35 = 
rcf.m_nonStandardData.m_nonStandardIdentifier;
                         t35.m_t35CountryCode = Toolkit::t35cPoland;
                         t35.m_manufacturerCode = Toolkit::t35mGnuGk;
                         t35.m_t35Extension = Toolkit::t35eNATTraversal;
+                 }
                   // if the client is NAT or you are forcing ALL 
registration to use a keepAlive TCP socket
-                 if ((nated) || 
Toolkit::AsBool(Kit->Config()->GetString(RoutedSec, "ForceNATKeepAlive", 
"0")))
+                 if ((nated) || 
Toolkit::AsBool(Kit->Config()->GetString(RoutedSec, "ForceNATKeepAlive", 
"0"))) {
+                       PTRACE(3, "RAS\tabout to send RCF 
(supportcallingNAT && !internal)(nated or 
ForceNATKeepAlive)"<<AsDotString(SignalAddr));
                         rcf.m_nonStandardData.m_data = "NAT=" + 
rx_addr.AsString();
-                 else  // Be careful as some public IP's may block TCP 
but not UDP resulting in an incorrect NAT test result.
+                 } else  { // Be careful as some public IP's may block 
TCP but not UDP resulting in an incorrect NAT test result.
+                       PTRACE(3, "RAS\tabout to send RCF 
(supportcallingNAT && !internal)(not nated or 
ForceNATKeepAlive)"<<AsDotString(SignalAddr));
                     rcf.m_nonStandardData.m_data = "NoNAT";
+                 }
                 }

  #ifdef hasH460


-------------------------------------------------------------------------
This SF.Net email is sponsored by the Moblin Your Move Developer's challenge
Build the coolest Linux based applications with Moblin SDK & win great prizes
Grand prize is a trip for two to an Open Source event anywhere in the world
http://moblin-contest.org/redirect.php?banner_id=100&url=/
_______________________________________________________

Posting: mailto:Openh323gk-users@xxxxxxxxxxxxxxxxxxxxx
Archive: http://sourceforge.net/mailarchive/forum.php?forum_name=openh323gk-users
Unsubscribe: http://lists.sourceforge.net/lists/listinfo/openh323gk-users
Homepage: http://www.gnugk.org/

[Index of Archives]     [SIP]     [Open H.323]     [Gnu Gatekeeper]     [Asterisk PBX]     [ISDN Cause Codes]     [Yosemite News]

  Powered by Linux