#148 thread synchronization problem in RAS protocol

open
nobody
OpenH323 (35)
5
2007-11-04
2007-11-04
Anonymous
No

openh323 thread synchronization problem in RAS protocol which crashed app
Change Desc.: Fixed thread synchronization problem in H323Transactor, requestsMutex now extended over Poll() and MakeRequest() function:

BOOL H323Transactor::MakeRequest(Request & request)
{
PTRACE(3, "Trans\tMaking request: " << request.requestPDU.GetChoice().GetTagName());

OnSendingPDU(request.requestPDU.GetPDU());

requestsMutex.Wait();
requests.SetAt(request.sequenceNumber, &request);
requestsMutex.Signal();

BOOL ok = request.Poll(*this);

// requestsMutex.Wait(); // FIX
requests.SetAt(request.sequenceNumber, NULL);
requestsMutex.Signal();

return ok;
}

BOOL H323Transactor::Request::Poll(H323Transactor & rasChannel)
{
H323EndPoint & endpoint = rasChannel.GetEndPoint();

responseResult = AwaitingResponse;

for (unsigned retry = 1; retry <= endpoint.GetRasRequestRetries(); retry++) {
// To avoid race condition with RIP must set timeout before sending the packet
whenResponseExpected = PTimer::Tick() + endpoint.GetRasRequestTimeout();

if (!rasChannel.WriteTo(requestPDU, requestAddresses, FALSE))
{
rasChannel.requestsMutex.Wait(); // FIX
break;
}

PTRACE(3, "Trans\tWaiting on response to seqnum=" << requestPDU.GetSequenceNumber()
<< " for " << setprecision(1) << endpoint.GetRasRequestTimeout() << " seconds");

do {
// Wait for a response
responseHandled.Wait(whenResponseExpected - PTimer::Tick());

rasChannel.requestsMutex.Wait(); // FIX

PWaitAndSignal mutex(responseMutex); // Wait till lastRequest goes out of scope

switch (responseResult) {
case AwaitingResponse : // Was a timeout
responseResult = NoResponseReceived;
break;

case ConfirmReceived :
return TRUE;

case RejectReceived :
return FALSE;

case BadCryptoTokens :
PTRACE(2, "Trans\tResponse to seqnum=" << requestPDU.GetSequenceNumber()
<< " had invalid crypto tokens.");
return FALSE;

default : // RequestInProgress
responseResult = AwaitingResponse; // Keep waiting
rasChannel.requestsMutex.Signal(); // FIX
break; // FIX
}

PTRACE_IF(3, responseResult == AwaitingResponse,
"Trans\tWaiting again on response to seqnum=" << requestPDU.GetSequenceNumber() <<
" for " << setprecision(1) << (whenResponseExpected - PTimer::Tick()) << " seconds");
} while (responseResult == AwaitingResponse);

PTRACE(1, "Trans\tTimeout on request seqnum=" << requestPDU.GetSequenceNumber()
<< ", try #" << retry << " of " << endpoint.GetRasRequestRetries());
}

PTRACE(1, "Trans\tPoll request ended with return value false");

return FALSE;
}

Discussion

  • arimont
    arimont
    2007-11-04

    Logged In: YES
    user_id=1929069
    Originator: NO

    bug/fix added by arimont