00001
00002
00003
00004
00005
00006
00007
00008
00009
00010
00011
00012
00013
00014
00015
00016
00017
00018
00019
00020
00021
00022
00023
00024
00025
00026
00027
00028
00029
00030
00031
00032
00033
00034
00035
00036 #include "stdafx.h"
00037 #include "RealTimeTraceRouteSocket.h"
00038
00039 #include "ErrorHandlerMacros.h"
00040 #include "ThreadPool.h"
00041 #include "GenericCriticalSection.h"
00042 #include "OSManager.h"
00043
00044 #include <atlbase.h>
00045
00046 #ifdef _MEMORY_DEBUG
00047 #define new DEBUG_NEW
00048 #define malloc DEBUG_MALLOC
00049 static char THIS_FILE[] = __FILE__;
00050 #endif
00051
00052 KOMODIA_NAMESPACE_START
00053
00054
00055
00056 #define CRealTimeDNSManager_Class "CRealTimeDNSManager"
00057
00058 CRealTimeTraceRouteSocket::CRealTimeDNSManager::CRealTimeDNSManager(CRealTimeTraceRouteSocket* pFather,
00059 const std::string strDNSServer,
00060 BOOL bTCP) : CDNSManager(strDNSServer,
00061 bTCP,
00062 TRUE,
00063 TRUE),
00064 m_pFather(pFather)
00065 {
00066 try
00067 {
00068
00069 SetName(CRealTimeDNSManager_Class);
00070 }
00071 ERROR_HANDLER("CRealTimeDNSManager")
00072 }
00073
00074 CRealTimeTraceRouteSocket::CRealTimeDNSManager::~CRealTimeDNSManager()
00075 {
00076 }
00077
00078 void CRealTimeTraceRouteSocket::CRealTimeDNSManager::OnDNSError(int iErrorCode,
00079 LPVOID lpLocalIDData)
00080 {
00081 try
00082 {
00083
00084 m_pFather->AdjustResolvers(-1);
00085
00086
00087 m_pFather->DNSDone();
00088 }
00089 ERROR_HANDLER("OnDNSError")
00090 }
00091
00092 void CRealTimeTraceRouteSocket::CRealTimeDNSManager::OnDNSTimeout(const KomodiaDNS::CDNSQuery& rQuery,
00093 LPVOID lpLocalIDData)
00094 {
00095 try
00096 {
00097
00098 m_pFather->AdjustResolvers(-1);
00099
00100
00101 m_pFather->DNSDone();
00102 }
00103 ERROR_HANDLER("OnDNSTimeout")
00104 }
00105
00106 void CRealTimeTraceRouteSocket::CRealTimeDNSManager::OnDNSReceive(KomodiaDNS::CDNSAnswers* pAnswers,
00107 LPVOID lpLocalIDData)
00108 {
00109 try
00110 {
00111
00112 std::auto_ptr<KomodiaDNS::CDNSAnswers> pProtection(pAnswers);
00113
00114
00115 if (m_pFather->m_bTraceDone)
00116 return;
00117
00118
00119 if (lpLocalIDData)
00120 {
00121
00122 TraceRouteData* pData;
00123 pData=(TraceRouteData*)lpLocalIDData;
00124
00125
00126 pData->pDNS=NULL;
00127
00128
00129 if (pAnswers->IsResolved())
00130
00131 if (!pAnswers->GetAnswer().empty())
00132 {
00133
00134 pData->sReverseDNS=pAnswers->GetAnswer();
00135
00136
00137 pData->bResolved=TRUE;
00138
00139
00140 if (pData->aReplyingAddress)
00141 {
00142
00143 m_pFather->TraceDataForModify(pData,
00144 TRUE);
00145
00146
00147 m_pFather->TraceData(pData,
00148 TRUE);
00149 }
00150 }
00151 else
00152 ReportError("CRealTimeDNSManager","Received empty answer!");
00153 }
00154
00155
00156 m_pFather->AdjustResolvers(-1);
00157
00158
00159 m_pFather->DNSDone();
00160 }
00161 ERROR_HANDLER("OnDNSReceive")
00162 }
00163
00164
00165
00166 #define CRealTimeTraceRouteSocket_Class "CRealTimeTraceRouteSocket"
00167
00168 unsigned short CRealTimeTraceRouteSocket::m_sPortStart=0;
00169
00170 CRealTimeTraceRouteSocket::CRealTimeTraceRouteSocket(std::string sDNSServer,
00171 BOOL bDNSTcp,
00172 BOOL bMultithreaded) : CPingSocket(),
00173 m_bTraceDone(TRUE),
00174 m_pManager(NULL),
00175 m_pCSection(NULL),
00176 m_bInitialized(FALSE),
00177 m_bResolveIPs(TRUE),
00178 m_pCSectionResolve(NULL),
00179 m_pCSectionGeneral(NULL),
00180 m_bFinishing(FALSE),
00181 m_bPartialDone(FALSE)
00182 {
00183 try
00184 {
00185
00186 SetName(CRealTimeTraceRouteSocket_Class);
00187
00188
00189 SetUseSameID(TRUE);
00190
00191
00192 m_pManager=new CRealTimeDNSManager(this,
00193 sDNSServer,
00194 bDNSTcp);
00195
00196
00197 m_pCSection=COSManager::CreateCriticalSection();
00198 m_pCSectionResolve=COSManager::CreateCriticalSection();
00199 m_pCSectionGeneral=COSManager::CreateCriticalSection();
00200
00201
00202 if (!(m_bInitialized=m_pManager->Initialize()))
00203
00204 ReportError("CRealTimeTraceRouteSocket","Failed to initialize DNS!");
00205 else
00206 {
00207
00208 m_pManager->SetDNSTimeout(15000);
00209
00210
00211 m_pManager->SetConnectionTimeout(7500);
00212
00213
00214 if (bMultithreaded)
00215 m_pManager->ParseMultithreaded(10);
00216 }
00217 }
00218 ERROR_HANDLER("CRealTimeTraceRouteSocket")
00219 }
00220
00221 CRealTimeTraceRouteSocket::~CRealTimeTraceRouteSocket()
00222 {
00223 try
00224 {
00225
00226 delete m_pCSection;
00227 delete m_pCSectionResolve;
00228 delete m_pCSectionGeneral;
00229
00230
00231 delete m_pManager;
00232 }
00233 ERROR_HANDLER("~CRealTimeTraceRouteSocket")
00234 }
00235
00236 BOOL CRealTimeTraceRouteSocket::IsTraceDone()const
00237 {
00238 return m_bTraceDone;
00239 }
00240
00241 BOOL CRealTimeTraceRouteSocket::TraceRoute(const std::string& rDestinationAddress,
00242 DWORD dwTimeout)
00243 {
00244 try
00245 {
00246 return TraceRoute(StringToLong(rDestinationAddress),
00247 dwTimeout);
00248 }
00249 ERROR_HANDLER_RETURN("TraceRoute",FALSE)
00250 }
00251
00252 BOOL CRealTimeTraceRouteSocket::TraceRoute(IP aDestinationAddress,
00253 DWORD dwTimeout)
00254 {
00255 try
00256 {
00257 if (!m_bTraceDone ||
00258 !m_bInitialized ||
00259 m_bFinishing ||
00260 m_bPartialDone)
00261 return FALSE;
00262
00263
00264 m_bTraceDone=FALSE;
00265 m_bPartialDone=FALSE;
00266 m_bFinishing=FALSE;
00267
00268
00269 m_aTracedAddress=aDestinationAddress;
00270
00271
00272 for (int iCounter=0;iCounter<=mhMaxHops;++iCounter)
00273 {
00274
00275 m_aData[iCounter].aReplyingAddress=0;
00276 m_aData[iCounter].ucTTL=0;
00277 m_aData[iCounter].dwElapsedTime=0;
00278 m_aData[iCounter].pDNS=m_pManager;
00279 m_aData[iCounter].bResolved=FALSE;
00280 m_aData[iCounter].bTarget=FALSE;
00281 m_aData[iCounter].bFinal=FALSE;
00282 m_aData[iCounter].lpUserData=NULL;
00283
00284
00285 std::auto_ptr<CGenericCriticalSection> pProtection(COSManager::CreateCriticalSection());
00286
00287
00288 m_aData[iCounter].pCSection=pProtection;
00289 }
00290
00291 m_ucMaxHOP=0;
00292 m_ucMinHOP=mhMaxHops;
00293
00294
00295
00296 m_aData[mhMaxHops].bTarget=TRUE;
00297
00298
00299 m_ulResolvers=0;
00300
00301
00302 m_usPortStart=GetPortStart();
00303
00304
00305 for (int iPings=0;iPings<3;++iPings)
00306 for (int iCounter=1;
00307 iCounter<=mhMaxHops;
00308 ++iCounter)
00309 {
00310
00311 SetTTL(iCounter);
00312
00313
00314 SetID(iCounter);
00315
00316
00317 SetSequence(m_usPortStart);
00318
00319
00320 if (!Ping(aDestinationAddress,
00321 0))
00322 {
00323
00324 m_bTraceDone=TRUE;
00325
00326
00327 TraceDone(TRUE);
00328
00329
00330 return FALSE;
00331 }
00332 }
00333
00334
00335 SetTimeout(dwTimeout);
00336
00337
00338 if (m_bResolveIPs)
00339 {
00340
00341 AdjustResolvers(1);
00342
00343
00344 ResolveThreadData* pThreadData;
00345 pThreadData=new ResolveThreadData;
00346
00347
00348 pThreadData->pClass=this;
00349 pThreadData->pData=&m_aData[mhMaxHops];
00350
00351
00352
00353 m_pManager->GetThreadManager()->SubmitJob(ResolveData,(LPVOID)pThreadData);
00354 }
00355
00356
00357 return TRUE;
00358 }
00359 ERROR_HANDLER_RETURN("TraceRoute",FALSE)
00360 }
00361
00362 void CRealTimeTraceRouteSocket::PingDoneData(IP aReplyingAddress,
00363 unsigned char ucTTL,
00364 DWORD dwTimeElapsed,
00365 int iDataSize,
00366 unsigned short usID,
00367 BOOL bTTLExpired)
00368 {
00369 try
00370 {
00371
00372 if (m_bTraceDone ||
00373 m_bPartialDone)
00374 return;
00375
00376 if (usID>mhMaxHops)
00377 return;
00378
00379
00380 if (m_aData[usID].aReplyingAddress)
00381 return;
00382
00383 if (!bTTLExpired)
00384 {
00385
00386 if (!m_aData[mhMaxHops].aReplyingAddress)
00387 {
00388 {
00389
00390 CCriticalAutoRelease aRelease(m_aData[mhMaxHops].pCSection.get(),TRUE);
00391
00392
00393 m_aData[mhMaxHops].aReplyingAddress=aReplyingAddress;
00394 m_aData[mhMaxHops].dwElapsedTime=dwTimeElapsed;
00395 m_aData[mhMaxHops].ucTTL=usID;
00396 }
00397
00398
00399 if (m_bResolveIPs)
00400 {
00401
00402 AdjustResolvers(1);
00403
00404
00405 ResolveThreadData* pThreadData;
00406 pThreadData=new ResolveThreadData;
00407
00408
00409 pThreadData->pClass=this;
00410 pThreadData->pData=&m_aData[mhMaxHops];
00411
00412
00413 m_pManager->GetThreadManager()->SubmitJob(ResolveData,(LPVOID)pThreadData);
00414 }
00415
00416
00417 TraceDataForModify(&m_aData[mhMaxHops],
00418 FALSE);
00419
00420
00421 TraceData(&m_aData[mhMaxHops],
00422 FALSE);
00423 }
00424 }
00425 else
00426 {
00427 {
00428
00429 CCriticalAutoRelease aRelease(m_pCSection,TRUE);
00430
00431
00432 if (usID<m_ucMinHOP)
00433 m_ucMinHOP=usID;
00434
00435
00436 if (usID>m_ucMaxHOP)
00437 m_ucMaxHOP=usID;
00438 }
00439
00440 {
00441
00442 CCriticalAutoRelease aRelease(m_aData[usID].pCSection.get(),TRUE);
00443
00444
00445 m_aData[usID].aReplyingAddress=aReplyingAddress;
00446 m_aData[usID].dwElapsedTime=dwTimeElapsed;
00447 m_aData[usID].ucTTL=usID;
00448 m_aData[usID].pDNS=m_pManager;
00449 }
00450
00451
00452 if (m_bResolveIPs)
00453 {
00454
00455 AdjustResolvers(1);
00456
00457
00458 ResolveThreadData* pThreadData;
00459 pThreadData=new ResolveThreadData;
00460
00461
00462 pThreadData->pClass=this;
00463 pThreadData->pData=&m_aData[usID];
00464
00465
00466 m_pManager->GetThreadManager()->SubmitJob(ResolveData,(LPVOID)pThreadData);
00467 }
00468
00469
00470 TraceDataForModify(&m_aData[usID],
00471 FALSE);
00472
00473
00474 TraceData(&m_aData[usID],
00475 FALSE);
00476 }
00477 }
00478 ERROR_HANDLER("PingDoneData")
00479 }
00480
00481 BOOL CRealTimeTraceRouteSocket::IsIDOK(unsigned short usID,
00482 unsigned short usSequence)const
00483 {
00484 return m_usPortStart==usSequence &&
00485 usID<=mhMaxHops;
00486 }
00487
00488 void CRealTimeTraceRouteSocket::ResolveData(LPVOID lpData)
00489 {
00490 try
00491 {
00492
00493 std::auto_ptr<ResolveThreadData> pData((ResolveThreadData*)lpData);
00494
00495
00496 unsigned short usID;
00497
00498
00499 BOOL bAdjust;
00500
00501
00502 TraceRouteData aData;
00503
00504 {
00505
00506 CCriticalAutoRelease aRelease(pData->pData->pCSection.get(),TRUE);
00507
00508
00509 aData=*pData->pData;
00510 }
00511
00512
00513 if (aData.ucTTL>=mhMaxHops)
00514 {
00515
00516 pData->pClass->AdjustResolvers(-1);
00517
00518
00519 pData->pClass->DNSDone();
00520
00521
00522 return;
00523 }
00524 else if (!aData.ucTTL)
00525 usID=rand()%60000+mhMaxHops;
00526 else
00527 usID=aData.ucTTL;
00528
00529
00530 bAdjust=TRUE;
00531
00532
00533
00534 if (aData.pDNS)
00535 if (aData.pDNS->GetDNSEntry(aData.aReplyingAddress,
00536 usID,
00537 (LPVOID)pData->pData))
00538 bAdjust=FALSE;
00539 else
00540 ReportStaticError(CRealTimeTraceRouteSocket_Class,"ResolveData","Missing DNS information!");
00541
00542
00543 if (bAdjust)
00544 {
00545
00546 pData->pClass->AdjustResolvers(-1);
00547
00548
00549 pData->pClass->DNSDone();
00550 }
00551 }
00552 ERROR_HANDLER_STATIC(CRealTimeTraceRouteSocket_Class,"ResolveData")
00553 }
00554
00555 void CRealTimeTraceRouteSocket::TraceData(const TraceRouteData* pData,
00556 BOOL bResolved)
00557 {
00558 }
00559
00560 BOOL CRealTimeTraceRouteSocket::IsInitialized()const
00561 {
00562 return m_bInitialized;
00563 }
00564
00565 BOOL CRealTimeTraceRouteSocket::OnSocketTimeout()
00566 {
00567 try
00568 {
00569
00570 KillTimer();
00571
00572
00573 if (m_bTraceDone)
00574 return FALSE;
00575
00576
00577 if (GetResolvers())
00578 {
00579
00580 m_bPartialDone=TRUE;
00581
00582
00583 return FALSE;
00584 }
00585
00586
00587 m_bPartialDone=TRUE;
00588
00589
00590 InvokeTraceDone();
00591
00592
00593 return FALSE;
00594 }
00595 ERROR_HANDLER_RETURN("OnSocketTimeout",FALSE)
00596 }
00597
00598 void CRealTimeTraceRouteSocket::TraceDone(BOOL bError)
00599 {
00600 }
00601
00602 unsigned char CRealTimeTraceRouteSocket::GetMaxHops()const
00603 {
00604 return m_ucMaxHOP;
00605 }
00606
00607 const CRealTimeTraceRouteSocket::TraceRouteData* CRealTimeTraceRouteSocket::GetData()const
00608 {
00609 return (const TraceRouteData*)&m_aData;
00610 }
00611
00612 CRealTimeTraceRouteSocket::CRealTimeDNSManager* CRealTimeTraceRouteSocket::GetDNSManager()const
00613 {
00614 return m_pManager;
00615 }
00616
00617 void CRealTimeTraceRouteSocket::TraceDataForModify(TraceRouteData* pData,
00618 BOOL bResolved)
00619 {
00620 }
00621
00622 void CRealTimeTraceRouteSocket::SetResolveStatus(BOOL bResolve)
00623 {
00624 try
00625 {
00626 m_bResolveIPs=bResolve;
00627 }
00628 ERROR_HANDLER("SetResolveStatus")
00629 }
00630
00631 void CRealTimeTraceRouteSocket::AdjustResolvers(long lAmount)
00632 {
00633 try
00634 {
00635 if (m_bTraceDone)
00636 return;
00637
00638
00639 CCriticalAutoRelease aRelease(m_pCSectionResolve,TRUE);
00640
00641
00642 m_ulResolvers+=lAmount;
00643 }
00644 ERROR_HANDLER("AdjustResolvers")
00645 }
00646
00647 unsigned long CRealTimeTraceRouteSocket::GetResolvers()const
00648 {
00649 try
00650 {
00651
00652 CCriticalAutoRelease aRelease(m_pCSectionResolve,TRUE);
00653
00654
00655 return m_ulResolvers;
00656 }
00657 ERROR_HANDLER_RETURN("GetResolvers",0)
00658 }
00659
00660 void CRealTimeTraceRouteSocket::InvokeTraceDone()
00661 {
00662 try
00663 {
00664 {
00665
00666 CCriticalAutoRelease aRelease(m_pCSectionGeneral,TRUE);
00667
00668
00669 if (m_bFinishing ||
00670 m_bTraceDone)
00671 return;
00672 else
00673 m_bFinishing=TRUE;
00674 }
00675
00676
00677 BOOL bTrace;
00678
00679 {
00680
00681 CCriticalAutoRelease aRelease(m_aData[mhMaxHops].pCSection.get(),TRUE);
00682
00683 if (!m_aData[mhMaxHops].aReplyingAddress)
00684 {
00685
00686
00687 m_bFinishing=FALSE;
00688
00689
00690 aRelease.Exit();
00691
00692
00693 FakeLastRequest();
00694
00695
00696 return;
00697 }
00698
00699
00700 if (m_ucMaxHOP!=mhMaxHops)
00701 ++m_ucMaxHOP;
00702
00703
00704 if (m_ucMaxHOP>mhMaxHops)
00705 {
00706
00707 ReportError("InvokeTraceDone","Too big max hops!");
00708
00709
00710 m_ucMaxHOP=mhMaxHops;
00711 }
00712
00713
00714 m_aData[mhMaxHops].ucTTL=m_ucMaxHOP;
00715 m_aData[mhMaxHops].bFinal=TRUE;
00716
00717
00718 if (!m_aData[mhMaxHops].aReplyingAddress)
00719 m_aData[mhMaxHops].aReplyingAddress=m_aTracedAddress;
00720
00721
00722 bTrace=!m_aData[mhMaxHops].sReverseDNS.empty();
00723
00724 CCriticalAutoRelease aRelease2(m_aData[m_ucMaxHOP].pCSection.get(),TRUE);
00725
00726
00727
00728 m_aData[m_ucMaxHOP]=m_aData[mhMaxHops];
00729 }
00730
00731
00732 TraceDataForModify(&m_aData[m_ucMaxHOP],bTrace);
00733 TraceData(&m_aData[m_ucMaxHOP],bTrace);
00734
00735
00736 m_bTraceDone=TRUE;
00737
00738
00739 m_bFinishing=FALSE;
00740
00741
00742 TraceDone(FALSE);
00743 }
00744 ERROR_HANDLER("InvokeTraceDone")
00745 }
00746
00747 void CRealTimeTraceRouteSocket::DNSDone()
00748 {
00749 try
00750 {
00751
00752 if (m_bPartialDone &&
00753 !m_bTraceDone &&
00754 !GetResolvers())
00755
00756 InvokeTraceDone();
00757 }
00758 ERROR_HANDLER("DNSDone")
00759 }
00760
00761 unsigned short CRealTimeTraceRouteSocket::GetPortStart()
00762 {
00763 try
00764 {
00765
00766 CCriticalAutoRelease aRelease(CSpoofBase::GetGlobalCriticalSection(),TRUE);
00767
00768
00769 unsigned short usPort;
00770 usPort=m_sPortStart;
00771
00772
00773 ++m_sPortStart;
00774
00775
00776 if (m_sPortStart>=65000)
00777 m_sPortStart=0;
00778
00779
00780 return usPort;
00781 }
00782 ERROR_HANDLER_STATIC_RETURN(CRealTimeTraceRouteSocket_Class,"GetPortStart",0)
00783 }
00784
00785 void CRealTimeTraceRouteSocket::FakeLastRequest()
00786 {
00787 try
00788 {
00789
00790 if (!m_aData[mhMaxHops].aReplyingAddress)
00791 {
00792 {
00793
00794 CCriticalAutoRelease aRelease(m_aData[mhMaxHops].pCSection.get(),TRUE);
00795
00796
00797 m_aData[mhMaxHops].aReplyingAddress=m_aTracedAddress;
00798 m_aData[mhMaxHops].dwElapsedTime=0;
00799 m_aData[mhMaxHops].ucTTL=m_ucMaxHOP;
00800 m_aData[mhMaxHops].pDNS=m_pManager;
00801 }
00802
00803
00804 if (m_bResolveIPs)
00805 {
00806
00807 AdjustResolvers(1);
00808
00809
00810 ResolveThreadData* pThreadData;
00811 pThreadData=new ResolveThreadData;
00812
00813
00814 pThreadData->pClass=this;
00815 pThreadData->pData=&m_aData[mhMaxHops];
00816
00817
00818 m_pManager->GetThreadManager()->SubmitJob(ResolveData,(LPVOID)pThreadData);
00819 }
00820
00821
00822 TraceDataForModify(&m_aData[mhMaxHops],
00823 FALSE);
00824
00825
00826 TraceData(&m_aData[mhMaxHops],
00827 FALSE);
00828 }
00829 }
00830 ERROR_HANDLER("FakeLastRequest")
00831 }
00832
00833 KOMODIA_NAMESPACE_END