RE: [reSIProcate] Repost: DNS assert in TransactionState::handle() while unplugging the network cable
- From: "Derek MacDonald" <derek@xxxxxxxx>
- Date: Mon, 6 Dec 2004 10:29:55 -0800
I have changed DnsResult in my async-xten branch to fix a race condition;
I'll try to merge that back in today or tonight.
--Derek
> -----Original Message-----
> From: resiprocate-devel-bounces@xxxxxxxxxxxxxxxxxxx [mailto:resiprocate-
> devel-bounces@xxxxxxxxxxxxxxxxxxx] On Behalf Of Scott Godin
> Sent: Monday, December 06, 2004 6:24 AM
> To: 'kaiduan xie'; Scott Godin; resiprocate-devel@xxxxxxxxxxxxxxxxxxx
> Subject: 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
> _______________________________________________
> resiprocate-devel mailing list
> resiprocate-devel@xxxxxxxxxxxxxxxxxxx
> https://list.sipfoundry.org/mailman/listinfo/resiprocate-devel