Resolve fix:
- CancelResolv(): Standard function to cancel name resolve requests - Allow Resolv request to complete if not cancelled - Clear memory if resolve request cancelled - getaddrinfo_a(): still leaks if thread not closed Other: - Code clean up
This commit is contained in:
@@ -65,7 +65,7 @@ CSelectableCore::CSelectableCore( const char * pName, const char * pType ) : CSe
|
||||
// Configure resolve signal handler
|
||||
ResolveAct.sa_sigaction = &ResolveHandler;
|
||||
sigemptyset( &ResolveAct.sa_mask );
|
||||
ResolveAct.sa_flags = SA_SIGINFO;
|
||||
ResolveAct.sa_flags = SA_SIGINFO;
|
||||
|
||||
sigaction( SIGRTMIN, &ResolveAct, NULL );
|
||||
}
|
||||
@@ -74,24 +74,17 @@ CSelectableCore::CSelectableCore( const char * pName, const char * pType ) : CSe
|
||||
CSelectableCore::~CSelectableCore()
|
||||
{
|
||||
THandle * NextHandle = NULL;
|
||||
bool Result;
|
||||
|
||||
// Destroy File Handles
|
||||
while (FirstHandle) {
|
||||
// Close active resolve request
|
||||
if (FirstHandle->ResolveReq) {
|
||||
if ((Result = gai_cancel( FirstHandle->ResolveReq->Request )) != 0) {
|
||||
if (Log) Log->Message( LogLevel, dlMedium, "%s/%s: Handle '%s' - Error canceling Host Name resolve [%s:%s] (%s)",
|
||||
ProcessName, Name, FirstHandle->Name, FirstHandle->HostName, FirstHandle->PortName, gai_strerror(Result) );
|
||||
DestroyResolveReq( FirstHandle, true );
|
||||
HandleState( FirstHandle, csFailed );
|
||||
}
|
||||
}
|
||||
// Cancel pending resolve request
|
||||
CancelResolve( FirstHandle );
|
||||
|
||||
// Close handle if open
|
||||
if ((FirstHandle->State == csOpen) || (FirstHandle->State == csWaitingtoOpen))
|
||||
Close( FirstHandle, false );
|
||||
|
||||
// Destroy handle
|
||||
NextHandle = FirstHandle->Next;
|
||||
DestroyHandle( FirstHandle );
|
||||
FirstHandle = NextHandle;
|
||||
@@ -286,20 +279,12 @@ bool CSelectableCore::Init( CDataMember * FunctionConfig )
|
||||
|
||||
bool CSelectableCore::DestroyHandle( THandle * Handle )
|
||||
{
|
||||
int Result;
|
||||
|
||||
// Validate Handle
|
||||
if (!Handle)
|
||||
return false;
|
||||
|
||||
// Destroy Resolve request
|
||||
if (Handle->ResolveReq) {
|
||||
if ((Result = gai_cancel( Handle->ResolveReq->Request )) != 0) {
|
||||
if (Log) Log->Message( LogLevel, dlMedium, "%s/%s: Handle '%s' - Error canceling Host Name resolve [%s:%s] (%s)",
|
||||
ProcessName, Name, Handle->Name, Handle->HostName, Handle->PortName, gai_strerror(Result) );
|
||||
}
|
||||
DestroyResolveReq( Handle, true );
|
||||
}
|
||||
// Cancel pending resolve request
|
||||
CancelResolve( Handle );
|
||||
|
||||
// Clear parameters
|
||||
if (Handle->Name)
|
||||
@@ -1002,8 +987,8 @@ bool CSelectableCore::ResolveAddress( THandle * Handle )
|
||||
ResolveReq = new TResolveReq;
|
||||
Handle->ResolveReq = ResolveReq;
|
||||
|
||||
ResolveReq->Handle = Handle;
|
||||
ResolveReq->Request = (gaicb*)calloc( 1, sizeof(gaicb) );
|
||||
ResolveReq->Handle = Handle;
|
||||
ResolveReq->Request = (gaicb*)calloc( 1, sizeof(gaicb) );
|
||||
|
||||
// DNS request / reply structure
|
||||
ResolveReq->Request->ar_name = Handle->HostName;
|
||||
@@ -1035,30 +1020,6 @@ bool CSelectableCore::ResolveAddress( THandle * Handle )
|
||||
}
|
||||
//---------------------------------------------------------------------------
|
||||
|
||||
bool CSelectableCore::DestroyResolveReq( THandle * Handle, bool DestroyResult )
|
||||
{
|
||||
// Validate
|
||||
if (!Handle || !Handle->ResolveReq)
|
||||
return false;
|
||||
|
||||
// Destroy
|
||||
if (DestroyResult) {
|
||||
if (Handle->ResolveReq->Request->ar_result)
|
||||
freeaddrinfo( Handle->ResolveReq->Request->ar_result );
|
||||
}
|
||||
if (Handle->ResolveReq->Request->ar_request)
|
||||
free( (void*)Handle->ResolveReq->Request->ar_request );
|
||||
if (Handle->ResolveReq->Request)
|
||||
free( Handle->ResolveReq->Request );
|
||||
if (Handle->ResolveReq)
|
||||
delete Handle->ResolveReq;
|
||||
|
||||
// Reset request
|
||||
Handle->ResolveReq = NULL;
|
||||
return true;
|
||||
}
|
||||
//---------------------------------------------------------------------------
|
||||
|
||||
bool CSelectableCore::HandleResolve( THandle * Handle )
|
||||
{
|
||||
bool Result;
|
||||
@@ -1107,6 +1068,59 @@ bool CSelectableCore::HandleResolve( THandle * Handle )
|
||||
}
|
||||
//---------------------------------------------------------------------------
|
||||
|
||||
bool CSelectableCore::CancelResolve( THandle * Handle )
|
||||
{
|
||||
int Result;
|
||||
int WaitCnt = 0;
|
||||
|
||||
// Check if request pending
|
||||
if (!Handle->ResolveReq)
|
||||
return true;
|
||||
|
||||
// Cancel request
|
||||
Result = gai_cancel( FirstHandle->ResolveReq->Request );
|
||||
if (Log) Log->Message( LogLevel, dlMedium, "%s/%s: Handle '%s' - Cancelling Host Name resolve [%s:%s] (%s)",
|
||||
ProcessName, Name, FirstHandle->Name, FirstHandle->HostName, FirstHandle->PortName, gai_strerror(Result) );
|
||||
|
||||
if (Result == EAI_CANCELED) {
|
||||
// Clear request
|
||||
DestroyResolveReq( Handle, true );
|
||||
}
|
||||
else if (Result == EAI_NOTCANCELED) {
|
||||
// Allow request to return
|
||||
while (FirstHandle->ResolveReq && (WaitCnt < 1000)) {
|
||||
WaitCnt++;
|
||||
usleep(1000);
|
||||
}
|
||||
}
|
||||
return true;
|
||||
}
|
||||
//---------------------------------------------------------------------------
|
||||
|
||||
bool CSelectableCore::DestroyResolveReq( THandle * Handle, bool DestroyResult )
|
||||
{
|
||||
// Validate
|
||||
if (!Handle || !Handle->ResolveReq)
|
||||
return false;
|
||||
|
||||
// Destroy resolv request
|
||||
if (Handle->ResolveReq->Request) {
|
||||
if (DestroyResult && Handle->ResolveReq->Request->ar_result)
|
||||
freeaddrinfo( Handle->ResolveReq->Request->ar_result );
|
||||
if (Handle->ResolveReq->Request->ar_request)
|
||||
free( (void*)Handle->ResolveReq->Request->ar_request );
|
||||
if (Handle->ResolveReq->Request)
|
||||
free( Handle->ResolveReq->Request );
|
||||
}
|
||||
|
||||
// Reset request
|
||||
if (Handle->ResolveReq)
|
||||
delete Handle->ResolveReq;
|
||||
Handle->ResolveReq = NULL;
|
||||
return true;
|
||||
}
|
||||
//---------------------------------------------------------------------------
|
||||
|
||||
THandle * CSelectableCore::OpenUDPserverSocket( THandle * Handle )
|
||||
{
|
||||
// Validate Handle
|
||||
|
||||
Reference in New Issue
Block a user