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:[email protected]
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/