< Previous by Date Date Index Next by Date >
< Previous in Thread Thread Index Next in Thread >

RE: [reSIProcate] Repost: DNS assert in TransactionState::handle( ) while unplugging the network cable


I see.  However, I'm not convinced that the change you recommended is the
best solution.  In the trap scenario you mentioned, handle() gets calls
synchronously because of the socket failure.  But... what if processHost is
called asynchronously with some error status code and there are valid DNS
results to return from the other queries - in this case setting to Finished
may not be the best approach.

The proper solution will likely involve either making sure handle() is never
called synchronously (from DnsResult::lookup()) or making sure mDnsResult is
set in Transaction state before lookup() is called.

Can someone who is more familiar with this DnsResult code - please look into
what the appropriate fix would be?

Thanks,

Scott

-----Original Message-----
From: kaiduan xie [mailto:kaiduanx@xxxxxxxx] 
Sent: Friday, December 03, 2004 3:24 PM
To: Scott Godin; resiprocate-devel@xxxxxxxxxxxxxxxxxxx
Subject: RE: [reSIProcate] Repost: DNS assert in TransactionState::handle( )
while unplugging the network cable

Scott,

The case is after unplugging the network cable, the
call stack looks like as follow,

mDnsResult =
mController.mTransportSelector.dnsResolve(sip, this);
 -> TransportSelector::dnsResolve()
    ...
    -> ares_gethostbyname()
       ...
       ->ares__send_query(), and in this function
         open_udp_socket() failed immediately due to
no network connection !!!!
         ....
          -> ares::end_query()
             ->DnsResult::aresHostCallback()
                ->DnsResult::processHost(), the status
of ares query is 4 (ARES_ENOTFOUND).
without the change, it will go to
TransactionState::handle(), since the mDnsResult() was
not yet assigned, the assert(mDnsResult) failed. In
simple words,

mDnsResult =
mController.mTransportSelector.dnsResolve(sip, this);
   ---> TransactionState::handle(),
TransactionState::handle() function was called BEFORE
mDnsResult was assigned!!!

Hope this time it is clear.

kaiduan

     
 
 --- Scott Godin <slgodin@xxxxxxxxxxxx> wrote: 
> Kaidun,
> 
> If status != ARES_SUCCESS, then should mSrvCount ==
> 0 and mResults should be
> empty.  If that is the case then the state is set to
> Finished and it just
> returns.  Did you see a case where status !=
> ARES_SUCCESS and mSrvCount !=
> 0?
> 
> I commited a change for the init_by_defaults issue.
> 
> Thanks,
> 
> Scott
> 
> -----Original Message-----
> From: kaiduan xie [mailto:kaiduanx@xxxxxxxx] 
> Sent: Thursday, November 25, 2004 11:51 PM
> To: resiprocate-devel@xxxxxxxxxxxxxxxxxxx
> Subject: [reSIProcate] Repost: DNS assert in
> TransactionState::handle()
> while unplugging the network cable
> 
> hi, all,
> 
> If the network connection is unplugged while
> running,
> DNS assert failed at TransactionState.cxx #1282
> 
> TransactionState::handle(DnsResult* result)
> {
>    // got a DNS response, so send the current
> message
>    StackLog (<< *this << " got DNS result: " <<
> *result);
> 
>    if (mTarget.getType() == UNKNOWN_TRANSPORT) 
>    {
>     assert(mDnsResult);// failed here, xkd 
>     ......
>    }
> 
> Cullen also posted the same problem on 27 Aug,
> please
> refer
>
http://list.sipfoundry.org/archive/resiprocate-devel/msg01316.html
> 
> After digging into the ares library and Dns related
> class, I though I have found the reason, :).
> 
> In DnsResult::processHost()
> 
> void
> DnsResult::processHost(int status, struct hostent*
> result)
> {
>    StackLog (<< "DnsResult::processHost() " <<
> status);
>    
>    // This function assumes that the A query that
> caused this callback
>    // is the _only_ outstanding DNS query that might
> result in a
>    // callback into this function
>    if ( mType == Destroyed )
>    {
>       destroy();
>       return;
>    }
> 
>    if (status == ARES_SUCCESS)
>    {
>     .....
>    }
>    else
>    {
>       char* errmem=0;
>       StackLog (<< "Failed async A query: " <<
> ares_strerror(status, &errmem));
>       ares_free_errmem(errmem);
>       mType = Finished;//xkd-2004-11-25-begin
>       // Just set the status as Finished, donot
> delete
> or destroy it
>      // It will be deleted in TransactionState's
> destructor after receiving 408 (timeout)      
>       return; //xkd-2004-11-25-end
>    }
> 
> Also I found a mis-consideration in ares_init().
> In init_by_defaults()
> 
> {
> ....
>         num = 0;
>         pIPAddr = &FixedInfo->DnsServerList;     
>         while ( pIPAddr &&
> strlen(pIPAddr->IpAddress.String) > 0)
>         {
>           num++;
>           pIPAddr = pIPAddr ->Next;
>         }
>         channel->servers = malloc( (num) *
> sizeof(struct server_state));
> ...
> }
> 
> It is better to check the value of num, if num is
> zero, i.e., no network connection, no DNS server, in
> this case it should return error.
> 
> kaiduan
> 
> 
> 
>
______________________________________________________________________
> 
> Post your free ad now! http://personals.yahoo.ca
> _______________________________________________
> resiprocate-devel mailing list
> resiprocate-devel@xxxxxxxxxxxxxxxxxxx
>
https://list.sipfoundry.org/mailman/listinfo/resiprocate-devel
>  

______________________________________________________________________ 
Post your free ad now! http://personals.yahoo.ca