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/