[Common-cvs] netio iresolv.cpp,1.30,1.31
ckarusala at helixcommunity.org ckarusala at helixcommunity.orgUpdate of /cvsroot/common/netio In directory cvs:/tmp/cvs-serv28198 Modified Files: iresolv.cpp Log Message: Synopsis ======== This CR includes fix for the PR 150272: Nokia 6630 causes CAs On Content request from Windows server Quick link to the PR : https://bugs.dev.prognet.com/show_bug.cgi?id=150272 Branch : SERVER_CURRENT_RN Suggested Reviewer : Liam Murray Description ========= Server running on the external windows machine (fallguy.real.com) CAs when any content is requested through Nokia 6630 handset. The crash occurs while resolving the http server name sent in the x-wap-profile header of the DESCRIBE event. This is not specific to windows and it can occur on all the platforms if the DNS requests sent by the server machine are getting timed out. When the server tries to get a client profile from a remote machine via http, it creates a httpfsys file object which in turn creates a CIntResolver object to resolve the http server name sent in the x-wap-profile. The resolver object creates a CNodeQuery object for sending DNS queries to the DNS server and this CNodeQuery object registers a callback to trigger after a certain interval so that it can retry a different DNS server. This registered callback gets removed only when there is a response from the DNS server in CNodeQuery::HandleResponse(). Since there is no response from the DNS server in this particular scenario, this callback is never getting removed from the scheduler. The httpfsys object gets destroyed after 10 seconds of attempting to get the client profile from the remote http server. When it is doing so, it tries to destroy the resolver object created by it by calling 'close' on resolver object and decrementing its refcount. At this time, CIntResolver and CNodeQuery objects are supposed to get destroyed. But they are not, because the scheduler is holding a reference on the CNodeQuery object (through its callback) which in turn is holding the CIntResolver object since resolver object is the owner of the query object. As a result, when the callback gets triggered after httpfsys object closes resolver object, server CAs while trying to access the resolver's member variable m_pResponse (in CIntResolver::QueryDone) which had already been destroyed. The fix is to remove the call back registered by CNodeQuery from the scheduler when the httpfsys file object is trying to close the resolver so that the CNodeQuery and CIntResolver objects get destroyed as expected. Files Affected ============== common/netio/iresolv.cpp common/netio/pub/iresolv.h Testing Performed ================= Unit Tests: - Start the server on fallguy.real.com and request any content through Nokia 6630 handset. Ensure that the clip plays and the server doesn't CA. - Start the server on a machine with unreachable/unresponding DNS servers. Send a DESCRIBE event with x-wap-profile to the RTSP port through telnet client. Ensure that the server doesn't crash after the time out. Integration Tests: - None Leak Tests: - None Performance Tests: - None Platforms Tested: win32-i386-vc7 Build verified: win32-i386-vc7 QA Hints =============== - Regress PR 150272 on all the three platforms using the test cases mentioned in "Unit Tests" section above. Thanks, Chytanya Index: iresolv.cpp =================================================================== RCS file: /cvsroot/common/netio/iresolv.cpp,v retrieving revision 1.30 retrieving revision 1.31 diff -u -d -r1.30 -r1.31 --- iresolv.cpp 20 Sep 2005 23:50:00 -0000 1.30 +++ iresolv.cpp 8 Nov 2005 22:44:51 -0000 1.31 @@ -538,6 +538,16 @@ } } +void +CNodeQuery::RemoveCallback() +{ + if (m_CallbackHandle && m_pScheduler) + { + m_pScheduler->Remove(m_CallbackHandle); + m_CallbackHandle = 0; + } +} + STDMETHODIMP CNodeQuery::QueryInterface(REFIID riid, void** ppvObj) { @@ -582,6 +592,8 @@ // we should call m_pOwner->QueryDone(HXR_OK, m_szNode) here AddRef(); + m_CallbackHandle = 0; + // Query timed out -- next nameserver m_nCurServer++; if(m_nCurServer >= g_nNameservers) @@ -1055,6 +1067,7 @@ LONG32 lQueryID = 0; CNodeQuery* pQuery = NULL; m_mapHostQueries.GetNextAssoc(pos, lQueryID, (void*&)pQuery); + pQuery->RemoveCallback(); HX_RELEASE(pQuery); } m_mapHostQueries.RemoveAll();