<html xmlns:v="urn:schemas-microsoft-com:vml" xmlns:o="urn:schemas-microsoft-com:office:office" xmlns:w="urn:schemas-microsoft-com:office:word" xmlns:m="http://schemas.microsoft.com/office/2004/12/omml" xmlns="http://www.w3.org/TR/REC-html40"><head><meta http-equiv=Content-Type content="text/html; charset=utf-8"><meta name=Generator content="Microsoft Word 15 (filtered medium)"><!--[if !mso]><style>v\:* {behavior:url(#default#VML);}
o\:* {behavior:url(#default#VML);}
w\:* {behavior:url(#default#VML);}
.shape {behavior:url(#default#VML);}
</style><![endif]--><style><!--
/* Font Definitions */
@font-face
        {font-family:"Cambria Math";
        panose-1:2 4 5 3 5 4 6 3 2 4;}
@font-face
        {font-family:Calibri;
        panose-1:2 15 5 2 2 2 4 3 2 4;}
/* Style Definitions */
p.MsoNormal, li.MsoNormal, div.MsoNormal
        {margin:0in;
        margin-bottom:.0001pt;
        font-size:12.0pt;
        font-family:"Times New Roman",serif;}
a:link, span.MsoHyperlink
        {mso-style-priority:99;
        color:#0563C1;
        text-decoration:underline;}
a:visited, span.MsoHyperlinkFollowed
        {mso-style-priority:99;
        color:#954F72;
        text-decoration:underline;}
span.xfm23438827
        {mso-style-name:xfm_23438827;}
span.EmailStyle18
        {mso-style-type:personal-reply;
        font-family:"Calibri",sans-serif;
        color:#1F497D;}
.MsoChpDefault
        {mso-style-type:export-only;
        font-size:10.0pt;}
@page WordSection1
        {size:8.5in 11.0in;
        margin:1.0in 1.0in 1.0in 1.0in;}
div.WordSection1
        {page:WordSection1;}
--></style><!--[if gte mso 9]><xml>
<o:shapedefaults v:ext="edit" spidmax="1026" />
</xml><![endif]--><!--[if gte mso 9]><xml>
<o:shapelayout v:ext="edit">
<o:idmap v:ext="edit" data="1" />
</o:shapelayout></xml><![endif]--></head><body lang=EN-US link="#0563C1" vlink="#954F72"><div class=WordSection1><p class=MsoNormal><span style='font-size:11.0pt;font-family:"Calibri",sans-serif;color:#1F497D'>Iurii<o:p></o:p></span></p><p class=MsoNormal><span style='font-size:11.0pt;font-family:"Calibri",sans-serif;color:#1F497D'><o:p> </o:p></span></p><p class=MsoNormal><span style='font-size:11.0pt;font-family:"Calibri",sans-serif;color:#1F497D'>Fix checked into CVS.<o:p></o:p></span></p><p class=MsoNormal><span style='font-size:11.0pt;font-family:"Calibri",sans-serif;color:#1F497D'><o:p> </o:p></span></p><p class=MsoNormal><span style='font-size:11.0pt;font-family:"Calibri",sans-serif;color:#1F497D'>Simon<o:p></o:p></span></p><p class=MsoNormal><span style='font-size:11.0pt;font-family:"Calibri",sans-serif;color:#1F497D'><o:p> </o:p></span></p><div><div style='border:none;border-top:solid #E1E1E1 1.0pt;padding:3.0pt 0in 0in 0in'><p class=MsoNormal><b><span style='font-size:11.0pt;font-family:"Calibri",sans-serif'>From:</span></b><span style='font-size:11.0pt;font-family:"Calibri",sans-serif'> h323plus [mailto:h323plus-bounces@lists.packetizer.com] <b>On Behalf Of </b>Iurii Gordiienko<br><b>Sent:</b> Thursday, December 31, 2015 8:40 PM<br><b>To:</b> h323plus@lists.packetizer.com<br><b>Subject:</b> [h323plus] H323EndPoint::InternalMakeCall bug<o:p></o:p></span></p></div></div><p class=MsoNormal><o:p> </o:p></p><p class=MsoNormal><span class=xfm23438827>Hi,<o:p></o:p></span></p><div><p class=MsoNormal><o:p> </o:p></p></div><div><p class=MsoNormal>I have found an issue with H323EndPoint::InternalMakeCall function for case when it running from H323EndPoint::ForwardConnection function (may be for some others cases too).<o:p></o:p></p></div><div><p class=MsoNormal>Take a look:<o:p></o:p></p></div><div><p class=MsoNormal>1.We are trying to connect to some host which uses Gatekeeper.<o:p></o:p></p></div><div><p class=MsoNormal>2.From H323EndPoint::ForwardConnection call H323EndPoint::InternalMakeCall function with some internal token="ip$xxx.xxx.xxx.xxx/port"<o:p></o:p></p></div><div><p class=MsoNormal>3.In the body of H323EndPoint::InternalMakeCall we have the replacement current callToken-connection pair to new one with "ip$xxx.xxx.xxx.xxx/port-replaced-1" string, like<o:p></o:p></p></div><div><div><p class=MsoNormal>    <o:p></o:p></p></div><div><p class=MsoNormal>    connectionsActive.SetAt(adjustedToken, connectionsActive.RemoveAt(newToken));<o:p></o:p></p></div><div><p class=MsoNormal>    connectionsToBeCleaned += adjustedToken;<o:p></o:p></p></div></div><div><p class=MsoNormal><o:p> </o:p></p></div><div><p class=MsoNormal>4.But if for some reason our virtual CreateConnection function returns NULL...<o:p></o:p></p></div><div><p class=MsoNormal><o:p> </o:p></p></div><div><p class=MsoNormal>  connection = CreateConnection(lastReference, userData, transport, NULL);<o:p></o:p></p></div><div><div><p class=MsoNormal>  if (connection == NULL) {<o:p></o:p></p></div><div><p class=MsoNormal>    PTRACE(1, "H323\tCreateConnection returned NULL");<o:p></o:p></p></div><div><p class=MsoNormal>    connectionsMutex.Signal();<o:p></o:p></p></div><div><p class=MsoNormal><o:p> </o:p></p></div><div><p class=MsoNormal>    return NULL;<o:p></o:p></p></div><div><p class=MsoNormal>  }<o:p></o:p></p></div></div><div><p class=MsoNormal><o:p> </o:p></p></div><div><p class=MsoNormal> ... we cannot clear current Connection because it has not actual callToken "ip$xxx.xxx.xxx.xxx/port" but H323EndPoint::connectionsActive has "ip$xxx.xxx.xxx.xxx/port-replaced-1" and endpoint.ClearCall(callToken, reason) or something similar will be failed because not able to found the Connection by own callToken.<o:p></o:p></p></div><div><p class=MsoNormal><o:p> </o:p></p></div><div><p class=MsoNormal>5.Also we have redundant call connectionsMutex.Signal().<o:p></o:p></p></div><div><div><p class=MsoNormal><o:p> </o:p></p></div><div><p class=MsoNormal>if (connection == NULL) {<o:p></o:p></p></div><div><p class=MsoNormal>    PTRACE(1, "H323\tCreateConnection returned NULL");<o:p></o:p></p></div><div><p class=MsoNormal>    connectionsMutex.Signal();<o:p></o:p></p></div><div><p class=MsoNormal><o:p> </o:p></p></div><div><p class=MsoNormal>    return NULL;<o:p></o:p></p></div><div><p class=MsoNormal>  }<o:p></o:p></p></div></div><div><p class=MsoNormal><o:p> </o:p></p></div><div><p class=MsoNormal><o:p> </o:p></p></div><div><p class=MsoNormal>My proposition - just rename back callToken for H323EndPoint::connectionsActive and remove adjustedToken from H323EndPoint::connectionsToBeCleaned if we have NULL connection.<o:p></o:p></p></div><div><p class=MsoNormal>My H323EndPoint::InternalMakeCall function looks like this:<o:p></o:p></p></div><div><p class=MsoNormal><o:p> </o:p></p></div><div><div><p class=MsoNormal>H323Connection * H323EndPoint::InternalMakeCall(const PString & trasferFromToken,<o:p></o:p></p></div><div><p class=MsoNormal>                                                const PString & callIdentity,<o:p></o:p></p></div><div><p class=MsoNormal>                                                unsigned capabilityLevel,<o:p></o:p></p></div><div><p class=MsoNormal>                                                const PString & remoteParty,<o:p></o:p></p></div><div><p class=MsoNormal>                                                H323Transport * transport,<o:p></o:p></p></div><div><p class=MsoNormal>                                                PString & newToken,<o:p></o:p></p></div><div><p class=MsoNormal>                                                void * userData,<o:p></o:p></p></div><div><p class=MsoNormal>                                                PBoolean supplimentary<o:p></o:p></p></div><div><p class=MsoNormal>                                                )<o:p></o:p></p></div><div><p class=MsoNormal>{<o:p></o:p></p></div><div><p class=MsoNormal>  PTRACE(2, "H323\tMaking call to: " << remoteParty);<o:p></o:p></p></div><div><p class=MsoNormal><o:p> </o:p></p></div><div><p class=MsoNormal>  PString alias;<o:p></o:p></p></div><div><p class=MsoNormal>  H323TransportAddress address;<o:p></o:p></p></div><div><p class=MsoNormal>  if (!ParsePartyName(remoteParty, alias, address)) {<o:p></o:p></p></div><div><p class=MsoNormal>    PTRACE(2, "H323\tCould not parse \"" << remoteParty << '"');<o:p></o:p></p></div><div><p class=MsoNormal>    return NULL;<o:p></o:p></p></div><div><p class=MsoNormal>  }<o:p></o:p></p></div><div><p class=MsoNormal><o:p> </o:p></p></div><div><p class=MsoNormal>#ifdef H323_H46017<o:p></o:p></p></div><div><p class=MsoNormal>  // If H.460.17 use the existing H.460.17 Transport<o:p></o:p></p></div><div><p class=MsoNormal>  if (transport == NULL && RegisteredWithH46017())<o:p></o:p></p></div><div><p class=MsoNormal>      transport = GetH46017Transport();<o:p></o:p></p></div><div><p class=MsoNormal>#endif<o:p></o:p></p></div><div><p class=MsoNormal><o:p> </o:p></p></div><div><p class=MsoNormal>  if (transport == NULL) {<o:p></o:p></p></div><div><p class=MsoNormal>    // Restriction: the call must be made on the same transport as the one<o:p></o:p></p></div><div><p class=MsoNormal>    // that the gatekeeper is using.<o:p></o:p></p></div><div><p class=MsoNormal>    if (gatekeeper != NULL)<o:p></o:p></p></div><div><p class=MsoNormal>      transport = gatekeeper->GetTransport().GetRemoteAddress().CreateTransport(*this);<o:p></o:p></p></div><div><p class=MsoNormal><o:p> </o:p></p></div><div><p class=MsoNormal>    // assume address is an IP address/hostname<o:p></o:p></p></div><div><p class=MsoNormal>    else<o:p></o:p></p></div><div><p class=MsoNormal>      transport = address.CreateTransport(*this);<o:p></o:p></p></div><div><p class=MsoNormal><o:p> </o:p></p></div><div><p class=MsoNormal>    if (transport == NULL) {<o:p></o:p></p></div><div><p class=MsoNormal>      PTRACE(1, "H323\tInvalid transport in \"" << remoteParty << '"');<o:p></o:p></p></div><div><p class=MsoNormal>      return NULL;<o:p></o:p></p></div><div><p class=MsoNormal>    }<o:p></o:p></p></div><div><p class=MsoNormal>  }<o:p></o:p></p></div><div><p class=MsoNormal><o:p> </o:p></p></div><div><p class=MsoNormal>  H323Connection * connection;<o:p></o:p></p></div><div><p class=MsoNormal><o:p> </o:p></p></div><div><p class=MsoNormal>  connectionsMutex.Wait();<o:p></o:p></p></div><div><p class=MsoNormal><o:p> </o:p></p></div><div><p class=MsoNormal>  PString adjustedToken;<o:p></o:p></p></div><div><p class=MsoNormal>  unsigned lastReference;<o:p></o:p></p></div><div><p class=MsoNormal>  if (newToken.IsEmpty()) {<o:p></o:p></p></div><div><p class=MsoNormal>    do {<o:p></o:p></p></div><div><p class=MsoNormal>      lastReference = Q931::GenerateCallReference();<o:p></o:p></p></div><div><p class=MsoNormal>      newToken = BuildConnectionToken(*transport, lastReference, FALSE);<o:p></o:p></p></div><div><p class=MsoNormal>    } while (connectionsActive.Contains(newToken));<o:p></o:p></p></div><div><p class=MsoNormal>  }<o:p></o:p></p></div><div><p class=MsoNormal>  else {<o:p></o:p></p></div><div><p class=MsoNormal>    lastReference = newToken.Mid(newToken.Find('/')+1).AsUnsigned();<o:p></o:p></p></div><div><p class=MsoNormal><o:p> </o:p></p></div><div><p class=MsoNormal>    // Move old connection on token to new value and flag for removal<o:p></o:p></p></div><div><p class=MsoNormal>    unsigned tieBreaker = 0;<o:p></o:p></p></div><div><p class=MsoNormal>    do {<o:p></o:p></p></div><div><p class=MsoNormal>      adjustedToken = newToken + "-replaced";<o:p></o:p></p></div><div><p class=MsoNormal>      adjustedToken.sprintf("-%u", ++tieBreaker);<o:p></o:p></p></div><div><p class=MsoNormal>    } while (connectionsActive.Contains(adjustedToken));<o:p></o:p></p></div><div><p class=MsoNormal>    connectionsActive.SetAt(adjustedToken, connectionsActive.RemoveAt(newToken));<o:p></o:p></p></div><div><p class=MsoNormal>    connectionsToBeCleaned += adjustedToken;<o:p></o:p></p></div><div><p class=MsoNormal>    PTRACE(3, "H323\tOverwriting call " << newToken << ", renamed to " << adjustedToken);<o:p></o:p></p></div><div><p class=MsoNormal>  }<o:p></o:p></p></div><div><p class=MsoNormal>  connectionsMutex.Signal();<o:p></o:p></p></div><div><p class=MsoNormal><o:p> </o:p></p></div><div><p class=MsoNormal>  connection = CreateConnection(lastReference, userData, transport, NULL);<o:p></o:p></p></div><div><p class=MsoNormal>  if (connection == NULL) {<o:p></o:p></p></div><div><p class=MsoNormal>    PTRACE(1, "H323\tCreateConnection returned NULL");<o:p></o:p></p></div><div><p class=MsoNormal>    <o:p></o:p></p></div><div><p class=MsoNormal>    if (!adjustedToken.IsEmpty())<o:p></o:p></p></div><div><p class=MsoNormal>    {<o:p></o:p></p></div><div><p class=MsoNormal>        connectionsMutex.Wait();<o:p></o:p></p></div><div><p class=MsoNormal><o:p> </o:p></p></div><div><p class=MsoNormal>        connectionsActive.SetAt(newToken, connectionsActive.RemoveAt(adjustedToken));<o:p></o:p></p></div><div><p class=MsoNormal>        connectionsToBeCleaned -= adjustedToken;<o:p></o:p></p></div><div><p class=MsoNormal><o:p> </o:p></p></div><div><p class=MsoNormal>        PTRACE(3, "H323\tOverwriting call " << adjustedToken << ", renamed to " << newToken);<o:p></o:p></p></div><div><p class=MsoNormal><o:p> </o:p></p></div><div><p class=MsoNormal>        connectionsMutex.Signal();<o:p></o:p></p></div><div><p class=MsoNormal>    }<o:p></o:p></p></div><div><p class=MsoNormal><o:p> </o:p></p></div><div><p class=MsoNormal>    return NULL;<o:p></o:p></p></div><div><p class=MsoNormal>  }<o:p></o:p></p></div><div><p class=MsoNormal>  connection->SetRemotePartyName(remoteParty);<o:p></o:p></p></div><div><p class=MsoNormal><o:p> </o:p></p></div><div><p class=MsoNormal>  if (supplimentary) <o:p></o:p></p></div><div><p class=MsoNormal>      connection->SetNonCallConnection();     <o:p></o:p></p></div><div><p class=MsoNormal><o:p> </o:p></p></div><div><p class=MsoNormal>  connection->Lock();<o:p></o:p></p></div><div><p class=MsoNormal><o:p> </o:p></p></div><div><p class=MsoNormal>  connectionsMutex.Wait();<o:p></o:p></p></div><div><p class=MsoNormal>  connectionsActive.SetAt(newToken, connection);<o:p></o:p></p></div><div><p class=MsoNormal><o:p> </o:p></p></div><div><p class=MsoNormal>  connectionsMutex.Signal();<o:p></o:p></p></div><div><p class=MsoNormal><o:p> </o:p></p></div><div><p class=MsoNormal>  connection->AttachSignalChannel(newToken, transport, FALSE);<o:p></o:p></p></div><div><p class=MsoNormal><o:p> </o:p></p></div><div><p class=MsoNormal>#ifdef H323_H450<o:p></o:p></p></div><div><p class=MsoNormal>  if (capabilityLevel == UINT_MAX)<o:p></o:p></p></div><div><p class=MsoNormal>    connection->HandleTransferCall(trasferFromToken, callIdentity);<o:p></o:p></p></div><div><p class=MsoNormal>  else {<o:p></o:p></p></div><div><p class=MsoNormal>    connection->HandleIntrudeCall(trasferFromToken, callIdentity);<o:p></o:p></p></div><div><p class=MsoNormal>    connection->IntrudeCall(capabilityLevel);<o:p></o:p></p></div><div><p class=MsoNormal>  }<o:p></o:p></p></div><div><p class=MsoNormal>#endif<o:p></o:p></p></div><div><p class=MsoNormal><o:p> </o:p></p></div><div><p class=MsoNormal>  PTRACE(3, "H323\tCreated new connection: " << newToken);<o:p></o:p></p></div><div><p class=MsoNormal><o:p> </o:p></p></div><div><p class=MsoNormal>#ifdef H323_H46017<o:p></o:p></p></div><div><p class=MsoNormal>  if (RegisteredWithH46017()) {<o:p></o:p></p></div><div><p class=MsoNormal>    H323Connection::CallEndReason reason = connection->SendSignalSetup(alias, address);<o:p></o:p></p></div><div><p class=MsoNormal>    if (reason != H323Connection::NumCallEndReasons)<o:p></o:p></p></div><div><p class=MsoNormal>      connection->ClearCall(reason);<o:p></o:p></p></div><div><p class=MsoNormal>  } else<o:p></o:p></p></div><div><p class=MsoNormal>#endif<o:p></o:p></p></div><div><p class=MsoNormal>      new H225CallThread(*this, *connection, *transport, alias, address);<o:p></o:p></p></div><div><p class=MsoNormal><o:p> </o:p></p></div><div><p class=MsoNormal>  return connection;<o:p></o:p></p></div><div><p class=MsoNormal>}<o:p></o:p></p></div></div><div><p class=MsoNormal><o:p> </o:p></p></div><div><p class=MsoNormal><o:p> </o:p></p></div><div><p class=MsoNormal><o:p> </o:p></p></div><div><p class=MsoNormal><o:p> </o:p></p></div><div><p class=MsoNormal>Thanks<o:p></o:p></p></div><div><p class=MsoNormal>--<o:p></o:p></p></div><div><p class=MsoNormal>Iurii Gordiienko<o:p></o:p></p></div><p class=MsoNormal><img width=1 height=1 id="_x0000_i1025" src="https://mail.ukr.net/api/public/message_read?a=nKmgvdFnKHmsk7uvZLEpXiblD9YyE83lU1NJebnGIxeofEcS2srd_e9yhYiMfmjk2T54SqWV9K_Bl-5oL7JgA0S8p5TmQW9gUdNY_EoDH8w="><o:p></o:p></p></div></body></html>