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 "TCPRelay.h"
00038 
00039 #include "ErrorHandlerMacros.h"
00040 #include "GenericCriticalSection.h"
00041 #include "OSManager.h"
00042 
00043 #ifdef _MEMORY_DEBUG 
00044     #define new    DEBUG_NEW  
00045     #define malloc DEBUG_MALLOC  
00046     static char THIS_FILE[] = __FILE__;  
00047 #endif
00048 
00049 KOMODIA_NAMESPACE_START
00050 
00051 
00052 
00053 #define CAcceptSocket_Class "CAcceptSocket"
00054 
00055 CTCPRelay::CAcceptSocket::CAcceptSocket(CTCPRelay* pFather) : CTCPSocketAsync(FALSE),
00056                                                               m_pFather(pFather)
00057 {
00058     try
00059     {
00060         
00061         SetName(CAcceptSocket_Class);
00062     }
00063     ERROR_HANDLER("CAcceptSocket")
00064 }
00065 
00066 CTCPRelay::CAcceptSocket::~CAcceptSocket()
00067 {
00068 }
00069 
00070 BOOL CTCPRelay::CAcceptSocket::OnSocketAccept(int iErrorCode)
00071 {
00072     try
00073     {
00074         
00075         if (iErrorCode)
00076         {
00077             
00078             ReportError("OnSocketAccept","Had an error code!",iErrorCode);
00079 
00080             
00081             return FALSE;
00082         }
00083 
00084         
00085         CClientSocket* pSocket;
00086         pSocket=new CClientSocket(m_pFather,
00087                                   NULL);
00088 
00089         
00090         std::auto_ptr<CClientSocket> pProtection(pSocket);
00091 
00092         
00093         if (!Accept(pSocket))
00094         {
00095             
00096             ReportErrorOS("OnSocketAccept","Failed to accept socket!");
00097 
00098             
00099             return FALSE;
00100         }
00101 
00102         
00103         CClientSocket* pOutgoingSocket;
00104         pOutgoingSocket=new CClientSocket(m_pFather,
00105                                           pSocket);
00106 
00107         
00108         std::auto_ptr<CClientSocket> pProtection2(pOutgoingSocket);
00109 
00110         
00111         if (!pOutgoingSocket->Create())
00112         {
00113             
00114             ReportErrorOS("OnSocketAccept","Failed to create socket!");
00115 
00116             
00117             return FALSE;
00118         }
00119 
00120         
00121         pSocket->SetSocket(pOutgoingSocket);
00122 
00123         
00124         pProtection.release();
00125         pProtection2.release();
00126 
00127         
00128         pSocket->Connect();
00129 
00130         
00131         return TRUE;
00132     }
00133     ERROR_HANDLER_RETURN("OnSocketAccept",FALSE)
00134 }
00135 
00136 
00137 
00138 
00139 
00140 #define CClientSocket_Class "CClientSocket"
00141 
00142 CTCPRelay::CClientSocket::CClientSocket(CTCPRelay* pFather,
00143                                         CClientSocket* pSocket) : CTCPSocketAsync(FALSE),
00144                                                                   m_pFather(pFather),
00145                                                                   m_pSocket(pSocket),
00146                                                                   m_bIncoming(pSocket==NULL),
00147                                                                   m_pCSection(NULL),
00148                                                                   m_aConnectionID(0)
00149 {
00150     try
00151     {
00152         
00153         SetName(CClientSocket_Class);
00154 
00155         
00156         if (m_bIncoming)
00157             m_pCSection=COSManager::CreateCriticalSection();
00158     }
00159     ERROR_HANDLER("CClientSocket")
00160 }
00161 
00162 CTCPRelay::CClientSocket::~CClientSocket()
00163 {
00164     try
00165     {
00166         delete m_pCSection;
00167     }
00168     ERROR_HANDLER("~CClientSocket")
00169 }
00170 
00171 void CTCPRelay::CClientSocket::Connect()
00172 {
00173     try
00174     {
00175         
00176         ((CTCPSocketAsync*)m_pSocket)->Connect(0,
00177                                                m_pFather->GetTarget(),
00178                                                m_pFather->GetTargetPort(),
00179                                                FALSE,
00180                                                TRUE);
00181     }
00182     ERROR_HANDLER("Connect")
00183 }
00184 
00185 int CTCPRelay::CClientSocket::Send(const char* pBuffer,
00186                                    unsigned long ulBufferLength)
00187 {
00188     try
00189     {
00190         
00191         if (m_bIncoming &&
00192             m_pFather->GetTimeout())
00193             
00194             if (!SetTimeout(m_pFather->GetTimeout()))
00195                 
00196                 ReportError("Send","Failed to set timeout!");
00197 
00198         
00199         return CTCPSocketAsync::Send(pBuffer,
00200                                      ulBufferLength);
00201     }
00202     ERROR_HANDLER_RETURN("Send",GetErrorCode())
00203 }
00204 
00205 BOOL CTCPRelay::CClientSocket::OnSocketConnect(int iErrorCode)
00206 {
00207     try
00208     {
00209         
00210         if (iErrorCode)
00211         {
00212             
00213             m_pSocket->DeleteSocketFromThread();
00214             m_pSocket=NULL;
00215 
00216             
00217             DeleteSocketFromThread();
00218 
00219             
00220             return FALSE;
00221         }
00222 
00223         
00224         
00225         m_aConnectionID=m_pFather->NewConnection(m_pSocket,
00226                                                  this);
00227 
00228         
00229         m_pSocket->SetConnectionID(m_aConnectionID);
00230 
00231         
00232         return TRUE;
00233     }
00234     ERROR_HANDLER_RETURN("OnSocketConnect",FALSE)
00235 }
00236 
00237 BOOL CTCPRelay::CClientSocket::OnSocketClose(int iErrorCode)
00238 {
00239     try
00240     {
00241         
00242         m_pFather->RemoveConnection(m_aConnectionID);
00243 
00244         
00245         m_pSocket->DeleteSocketFromThread();
00246         m_pSocket=NULL;
00247 
00248         
00249         DeleteSocketFromThread();
00250 
00251         
00252         return TRUE;
00253     }
00254     ERROR_HANDLER_RETURN("OnSocketClose",FALSE)
00255 }
00256 
00257 BOOL CTCPRelay::CClientSocket::OnSocketTimeout()
00258 {
00259     try
00260     {
00261         
00262         m_pSocket->Stop();
00263 
00264         
00265         m_pFather->RemoveConnection(m_aConnectionID);
00266 
00267         
00268         delete this;
00269 
00270         
00271         return FALSE;
00272     }
00273     ERROR_HANDLER_RETURN("OnSocketTimeout",FALSE)
00274 }
00275 
00276 BOOL CTCPRelay::CClientSocket::OnSocketReceive(int iErrorCode)
00277 {
00278     try
00279     {
00280         if (iErrorCode)
00281         {
00282             
00283             ReportError("OnSocketReceive","Received an error code!",iErrorCode);
00284 
00285             
00286             return FALSE;
00287         }
00288             
00289         
00290         if (m_bIncoming &&
00291             m_pFather->GetTimeout())
00292             
00293             if (!SetTimeout(m_pFather->GetTimeout()))
00294                 
00295                 ReportError("OnSocketReceive","Failed to set timeout!");
00296 
00297         
00298         if (m_pCSection)
00299         {
00300             
00301             CCriticalAutoRelease aRelease(m_pCSection);
00302 
00303             
00304             if (m_aConnectionID)
00305             {
00306                 
00307                 m_bEvent=FALSE;
00308 
00309                 
00310                 CGenericCriticalSection* pCS;
00311                 pCS=m_pCSection;
00312                 m_pCSection=NULL;
00313 
00314                 
00315                 aRelease.Exit();
00316 
00317                 
00318                 delete pCS;
00319             }
00320             else
00321             {
00322                 
00323                 m_bEvent=TRUE;
00324 
00325                 
00326                 return TRUE;
00327             }
00328         }
00329 
00330         char cBuffer[2000];
00331 
00332         
00333         int iResult;
00334         iResult=Receive(cBuffer,
00335                         sizeof(cBuffer)-1);
00336 
00337         
00338         if (iResult>=0)
00339         {
00340             
00341             cBuffer[iResult]=0;
00342 
00343             
00344             std::string sModifiedString;
00345             sModifiedString=m_pFather->ModifyReceiveString(m_bIncoming,
00346                                                            cBuffer,
00347                                                            iResult);
00348 
00349             
00350             if (!sModifiedString.empty())
00351             {
00352                 
00353                 strcpy(cBuffer,
00354                        sModifiedString.c_str());
00355 
00356                 
00357                 iResult=sModifiedString.size();
00358             }
00359         }
00360 
00361         
00362         CClientSocket* pSocket;
00363         pSocket=m_pSocket;
00364 
00365         
00366         if (iResult>0)
00367             if (pSocket &&
00368                 pSocket->Send(cBuffer,
00369                               iResult)<=0)
00370             {
00371                 
00372                 ReportErrorOS("OnSocketReceive","Failed to send data!");
00373 
00374                 
00375                 return FALSE;
00376             }
00377             else
00378                 ;
00379         else if (iResult==GetErrorCode())
00380         {
00381             
00382             ReportErrorOS("OnSocketReceive","Failed to receive data!");
00383 
00384             
00385             return FALSE;
00386         }
00387 
00388         
00389         return TRUE;
00390     }
00391     ERROR_HANDLER_RETURN("OnSocketReceive",FALSE)
00392 }
00393 
00394 void CTCPRelay::CClientSocket::SetSocket(CClientSocket* pSocket)
00395 {
00396     
00397     m_pSocket=pSocket;
00398 }   
00399 
00400 void CTCPRelay::CClientSocket::SetConnectionID(ConnectionID aConnectionID)
00401 {
00402     try
00403     {
00404         
00405         if (m_pCSection)
00406         {
00407             
00408             CCriticalAutoRelease aRelease(m_pCSection);
00409 
00410             
00411             m_aConnectionID=aConnectionID;
00412 
00413             
00414             if (m_bEvent)
00415                 
00416                 ForceReceiveEvent();
00417         }
00418         else
00419             
00420             m_aConnectionID=aConnectionID;
00421     }
00422     ERROR_HANDLER("SetConnectionID")
00423 }
00424 
00425 void CTCPRelay::CClientSocket::Stop()
00426 {
00427     try
00428     {
00429         
00430         if (m_bIncoming)
00431         {
00432             
00433             CClientSocket* pSocket;
00434             pSocket=m_pSocket;
00435             m_pSocket=NULL;
00436 
00437             
00438             pSocket->Stop();
00439         }
00440         else
00441             m_pSocket=NULL;
00442 
00443         
00444         DeleteSocketFromThread();
00445     }
00446     ERROR_HANDLER("Stop")
00447 }
00448 
00449 
00450 
00451 #define CTCPRelay_Class "CTCPRelay"
00452 
00453 CTCPRelay::CTCPRelay() : CRelay(),
00454                          m_pCSection(NULL),
00455                          m_pSocket(NULL),
00456                          m_aRunningID(0),
00457                          m_bCreated(FALSE)
00458 {
00459     try
00460     {
00461         
00462         SetName(CTCPRelay_Class);
00463 
00464         
00465         m_pCSection=COSManager::CreateCriticalSection();
00466     }
00467     ERROR_HANDLER("CTCPRelay")
00468 }
00469 
00470 CTCPRelay::~CTCPRelay()
00471 {
00472     try
00473     {
00474         
00475         if (m_bCreated)
00476             Stop();
00477 
00478         
00479         delete m_pCSection;
00480     }
00481     ERROR_HANDLER("~CTCPRelay")
00482 }
00483 
00484 CTCPRelay::ConnectionID CTCPRelay::NewConnection(CClientSocket* pIncomingConnection,
00485                                                  CClientSocket* pOutgoingConnection)
00486 {
00487     try
00488     {
00489         
00490         SocketData aData;
00491         aData.pIncomingConnection=pIncomingConnection;
00492         aData.pOutgoingConnection=pOutgoingConnection;
00493 
00494         
00495         CCriticalAutoRelease aRelease(m_pCSection);
00496 
00497         
00498         ConnectionID aID;
00499         aID=++m_aRunningID;
00500 
00501         
00502         m_aClientMap.insert(ClientMap::value_type(aID,aData));
00503 
00504         
00505         return aID;
00506     }
00507     ERROR_HANDLER_RETURN("NewConnection",0)
00508 }
00509 
00510 void CTCPRelay::RemoveConnection(ConnectionID aConnectionID)
00511 {
00512     try
00513     {
00514         
00515         CCriticalAutoRelease aRelease(m_pCSection);
00516 
00517         
00518         m_aClientMap.erase(aConnectionID);
00519 
00520         
00521     }
00522     ERROR_HANDLER("RemoveConnection")
00523 }
00524 
00525 IP CTCPRelay::GetTarget()const
00526 {
00527     return m_aTarget;
00528 }
00529 
00530 unsigned short CTCPRelay::GetTargetPort()const
00531 {
00532     return m_usTargetPort;
00533 }
00534 
00535 IP CTCPRelay::GetBindAddress()const
00536 {
00537     return m_aBindAddress;
00538 }
00539 
00540 BOOL CTCPRelay::Relay(IP aBindAddress,
00541                       unsigned short usBindPort,
00542                       IP aDestinationAddress,
00543                       unsigned short usDestinationPort)
00544 {
00545     try
00546     {
00547         
00548         if (m_bCreated)
00549         {
00550             
00551             ReportError("Relay","Already created!");
00552 
00553             
00554             return FALSE;
00555         }
00556 
00557         
00558         m_pSocket=new CAcceptSocket(this);
00559 
00560         
00561         std::auto_ptr<CAcceptSocket> pProtection(m_pSocket);
00562 
00563         
00564         if (!m_pSocket->Create())
00565         {
00566             
00567             ReportError("Relay","Failed to create socket!");
00568 
00569             
00570             return FALSE;
00571         }
00572 
00573         
00574         if (!m_pSocket->Bind(aBindAddress,
00575                              usBindPort))
00576         {
00577             
00578             ReportError("Relay","Failed to create socket!");
00579 
00580             
00581             return FALSE;
00582         }
00583 
00584         
00585         m_aTarget=aDestinationAddress;
00586         m_usTargetPort=usDestinationPort;
00587         m_aBindAddress=aBindAddress;
00588 
00589         
00590         if (!m_pSocket->Listen())
00591         {
00592             
00593             ReportError("Relay","Failed to listen!");
00594 
00595             
00596             return FALSE;
00597         }
00598 
00599         
00600         pProtection.release();
00601 
00602         
00603         m_bCreated=TRUE;
00604 
00605         
00606         return TRUE;
00607     }
00608     ERROR_HANDLER_RETURN("Relay",FALSE)
00609 }
00610 
00611 BOOL CTCPRelay::Relay(const std::string& rBindAddress,
00612                       unsigned short usBindPort,
00613                       const std::string& rDestinationAddress,
00614                       unsigned short usDestinationPort)
00615 {
00616     try
00617     {
00618         return Relay(CSpoofBase::StringToLong(rBindAddress),
00619                      usBindPort,
00620                      CSpoofBase::StringToLong(rDestinationAddress),
00621                      usDestinationPort);
00622     }
00623     ERROR_HANDLER_RETURN("Relay",FALSE)
00624 }
00625 
00626 BOOL CTCPRelay::IsRunning()const
00627 {
00628     return m_bCreated;
00629 }
00630 
00631 BOOL CTCPRelay::Stop()
00632 {
00633     try
00634     {
00635         
00636         if (!m_bCreated)
00637             return TRUE;
00638 
00639         
00640         m_pSocket->DeleteSocketFromThread();
00641         m_pSocket=NULL;
00642 
00643         {
00644             
00645             CCriticalAutoRelease aRelease(m_pCSection);
00646 
00647             
00648             ClientMap::iterator aIterator;
00649             aIterator=m_aClientMap.begin();
00650             while (aIterator!=m_aClientMap.end())
00651             {
00652                 
00653                 aIterator->second.pIncomingConnection->Stop();
00654 
00655                 
00656                 aIterator=m_aClientMap.erase(aIterator);
00657             }
00658         }
00659 
00660         
00661         m_bCreated=FALSE;
00662 
00663         
00664         return TRUE;
00665     }
00666     ERROR_HANDLER_RETURN("Stop",FALSE)
00667 }
00668 
00669 std::string CTCPRelay::ModifyReceiveString(BOOL bIncoming,
00670                                            const char* pBuffer,
00671                                            unsigned short usBufferSize)const
00672 {
00673     return "";
00674 }
00675 
00676 KOMODIA_NAMESPACE_END