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 "UDPRelay.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 CListenSocket_Class "CListenSocket"
00054 
00055 CUDPRelay::CListenSocket::CListenSocket(CUDPRelay* pFather) : CUDPSocketAsync(FALSE),
00056                                                               m_pFather(pFather)
00057 {
00058     try
00059     {
00060         
00061         SetName(CListenSocket_Class);
00062     }
00063     ERROR_HANDLER("CListenSocket")
00064 }
00065 
00066 CUDPRelay::CListenSocket::~CListenSocket()
00067 {
00068 }
00069 
00070 BOOL CUDPRelay::CListenSocket::OnSocketReceive(int iErrorCode)
00071 {
00072     try
00073     {
00074         if (iErrorCode)
00075         {
00076             
00077             ReportError("OnSocketReceive","Received an error code!",iErrorCode);
00078 
00079             
00080             return FALSE;
00081         }
00082 
00083         char cBuffer[65536];
00084 
00085         
00086         IP aIP;
00087         unsigned short usPort;
00088 
00089         
00090         int iResult;
00091         iResult=Receive(cBuffer,
00092                         sizeof(cBuffer),
00093                         aIP,
00094                         usPort);
00095 
00096         
00097         if (iResult>0)
00098             
00099             m_pFather->SendData(cBuffer,
00100                                 iResult,
00101                                 aIP,
00102                                 usPort);
00103         else
00104             
00105             ReportErrorOS("OnSocketReceive","Failed to receive data!");
00106 
00107         
00108         return TRUE;
00109     }
00110     ERROR_HANDLER_RETURN("OnSocketReceive",FALSE)
00111 }
00112 
00113 
00114 
00115 
00116 
00117 #define CClientSocket_Class "CClientSocket"
00118 
00119 CUDPRelay::CClientSocket::CClientSocket(CUDPRelay* pFather,
00120                                         IP aSourceAddress,
00121                                         unsigned short usSourcePort) : CUDPSocketAsync(FALSE),
00122                                                                        m_pFather(pFather),
00123                                                                        m_aSourceAddress(aSourceAddress),
00124                                                                        m_usSourcePort(usSourcePort),
00125                                                                        m_usLocalPort(0)
00126 {
00127     try
00128     {
00129         
00130         SetName(CClientSocket_Class);
00131 
00132         
00133         m_usLocalPort=m_pFather->AllocateLocalPort();
00134     }
00135     ERROR_HANDLER("CClientSocket")
00136 }
00137 
00138 CUDPRelay::CClientSocket::~CClientSocket()
00139 {
00140 }
00141 
00142 BOOL CUDPRelay::CClientSocket::OnSocketReceive(int iErrorCode)
00143 {
00144     try
00145     {
00146         if (iErrorCode)
00147         {
00148             
00149             ReportError("OnSocketReceive","Received an error code!",iErrorCode);
00150 
00151             
00152             return FALSE;
00153         }
00154 
00155         
00156         if (m_pFather->GetTimeout())
00157             
00158             if (!SetTimeout(m_pFather->GetTimeout()))
00159                 
00160                 ReportError("OnSocketReceive","Failed to set timeout!");
00161 
00162         char cBuffer[65536];
00163 
00164         
00165         IP aIP;
00166         unsigned short usPort;
00167 
00168         
00169         int iResult;
00170         iResult=Receive(cBuffer,
00171                         sizeof(cBuffer),
00172                         aIP,
00173                         usPort);
00174 
00175         
00176         if (iResult>0)
00177         {
00178             
00179             CListenSocket* pSocket;
00180             pSocket=m_pFather->m_pSocket;
00181 
00182             
00183             if (pSocket &&
00184                 pSocket->Send(m_aSourceAddress,
00185                               m_usSourcePort,
00186                               cBuffer,
00187                               iResult)<=0)
00188                 
00189                 ReportError("OnSocketReceive","Failed to send data!");
00190             else
00191                 return TRUE;
00192         }
00193         else
00194             
00195             ReportErrorOS("OnSocketReceive","Failed to receive data!");
00196 
00197         
00198         return FALSE;
00199     }
00200     ERROR_HANDLER_RETURN("OnSocketReceive",FALSE)
00201 }
00202 
00203 int CUDPRelay::CClientSocket::SendData(const char* pBuffer,
00204                                        unsigned long ulBufferSize)
00205 {
00206     try
00207     {
00208         
00209         if (m_pFather->GetTimeout())
00210             
00211             if (!SetTimeout(m_pFather->GetTimeout()))
00212                 
00213                 ReportError("SendData","Failed to set timeout!");
00214 
00215         
00216         return Send(m_usLocalPort,
00217                     m_pFather->GetTarget(),
00218                     m_pFather->GetTargetPort(),
00219                     pBuffer,
00220                     ulBufferSize);
00221     }
00222     ERROR_HANDLER_RETURN("SendData",GetErrorCode())
00223 }
00224 
00225 BOOL CUDPRelay::CClientSocket::OnSocketTimeout()
00226 {
00227     try
00228     {
00229         
00230         m_pFather->RemoveSocket(m_aSourceAddress,
00231                                 m_usSourcePort);
00232 
00233         
00234         delete this;
00235 
00236         
00237         return FALSE;
00238     }
00239     ERROR_HANDLER_RETURN("OnSocketTimeout",FALSE)
00240 }
00241 
00242 
00243 
00244 #define CUDPRelay_Class "CUDPRelay"
00245 
00246 CUDPRelay::CUDPRelay() : CRelay(),
00247                          m_pSocket(NULL),
00248                          m_bCreated(FALSE),
00249                          m_aTarget(0),
00250                          m_usTargetPort(0),
00251                          m_pCSection(NULL),
00252                          m_pCSectionPorts(NULL),
00253                          m_usBindPort(0)
00254 {
00255     try
00256     {
00257         
00258         SetName(CUDPRelay_Class);
00259 
00260         
00261         m_pCSection=COSManager::CreateCriticalSection();
00262         m_pCSectionPorts=COSManager::CreateCriticalSection();
00263     }
00264     ERROR_HANDLER("CUDPRelay")
00265 }
00266 
00267 CUDPRelay::~CUDPRelay()
00268 {
00269     try
00270     {
00271         delete m_pCSection;
00272         delete m_pCSectionPorts;
00273     }
00274     ERROR_HANDLER("~CUDPRelay")
00275 }
00276 
00277 BOOL CUDPRelay::Relay(IP aBindAddress,
00278                       unsigned short usBindPort,
00279                       IP aDestinationAddress,
00280                       unsigned short usDestinationPort)
00281 {
00282     try
00283     {
00284         
00285         if (m_bCreated)
00286         {
00287             
00288             ReportError("Relay","Already created!");
00289 
00290             
00291             return FALSE;
00292         }
00293 
00294         
00295         m_pSocket=new CListenSocket(this);
00296 
00297         
00298         std::auto_ptr<CListenSocket> pProtection(m_pSocket);
00299 
00300         
00301         if (!m_pSocket->Create())
00302         {
00303             
00304             ReportError("Relay","Failed to create socket!");
00305 
00306             
00307             return FALSE;
00308         }
00309 
00310         
00311         if (!m_pSocket->Bind(aBindAddress,
00312                              usBindPort))
00313         {
00314             
00315             ReportError("Relay","Failed to create socket!");
00316 
00317             
00318             return FALSE;
00319         }
00320 
00321         
00322         m_aTarget=aDestinationAddress;
00323         m_usTargetPort=usDestinationPort;
00324         m_usBindPort=usBindPort;
00325 
00326         
00327         m_usLocalPort=1024;
00328 
00329         
00330         if (!m_pSocket->Listen())
00331         {
00332             
00333             ReportError("Relay","Failed to listen!");
00334 
00335             
00336             return FALSE;
00337         }
00338 
00339         
00340         pProtection.release();
00341 
00342         
00343         m_bCreated=TRUE;
00344 
00345         
00346         return TRUE;
00347     }
00348     ERROR_HANDLER_RETURN("Relay",FALSE)
00349 }
00350 
00351 BOOL CUDPRelay::Relay(const std::string& rBindAddress,
00352                       unsigned short usBindPort,
00353                       const std::string& rDestinationAddress,
00354                       unsigned short usDestinationPort)
00355 {
00356     try
00357     {
00358         return Relay(CSpoofBase::StringToLong(rBindAddress),
00359                      usBindPort,
00360                      CSpoofBase::StringToLong(rDestinationAddress),
00361                      usDestinationPort);
00362     }
00363     ERROR_HANDLER_RETURN("Relay",FALSE)
00364 }
00365 
00366 IP CUDPRelay::GetTarget()const
00367 {
00368     return m_aTarget;
00369 }
00370 
00371 unsigned short CUDPRelay::GetTargetPort()const
00372 {
00373     return m_usTargetPort;
00374 }
00375 
00376 unsigned short CUDPRelay::GetBindPort()const
00377 {
00378     return m_usBindPort;
00379 }
00380 
00381 void CUDPRelay::SendData(const char* pBuffer,
00382                          unsigned long ulBufferSize,
00383                          IP aDestinationIP,
00384                          unsigned short usDestinationPort)
00385 {
00386     try
00387     {
00388         
00389         ConnectionData aData;
00390         aData.aSourceIP=aDestinationIP;
00391         aData.usSourcePort=usDestinationPort;
00392 
00393         
00394         CClientSocket* pSocket;
00395         pSocket=NULL;
00396 
00397         {
00398             
00399             CCriticalAutoRelease aRelease(m_pCSection);
00400             
00401             
00402             SocketMap::iterator aIterator;
00403             aIterator=m_aSocketMap.find(aData);
00404             if (aIterator!=m_aSocketMap.end())
00405                 
00406                 pSocket=aIterator->second;
00407         }
00408 
00409         
00410         if (pSocket)
00411             
00412             if (pSocket->SendData(pBuffer,
00413                                   ulBufferSize)<=0)
00414                 
00415                 ReportErrorOS("SendData","Failed to send data!");
00416             else
00417                 ;
00418         else
00419         {
00420             
00421             if (!(pSocket=CreateSocket(aDestinationIP,
00422                                        usDestinationPort)))
00423                 
00424                 ReportError("CreateSocket","Failed to create socket!");
00425             else
00426                 
00427                 SendData(pBuffer,
00428                          ulBufferSize,
00429                          aDestinationIP,
00430                          usDestinationPort);
00431         }
00432     }
00433     ERROR_HANDLER("SendData")
00434 }
00435 
00436 unsigned short CUDPRelay::AllocateLocalPort()const
00437 {
00438     try
00439     {
00440         
00441         CCriticalAutoRelease aRelease(m_pCSectionPorts);
00442 
00443         
00444         return ++m_usLocalPort;
00445     }
00446     ERROR_HANDLER_RETURN("AllocateLocalPort",m_usLocalPort)
00447 }
00448 
00449 void CUDPRelay::RemoveSocket(IP aSourceAddress,
00450                              unsigned short usSourcePort)
00451 {
00452     try
00453     {
00454         
00455         ConnectionData aData;
00456         aData.aSourceIP=aSourceAddress;
00457         aData.usSourcePort=usSourcePort;
00458 
00459         
00460         CCriticalAutoRelease aRelease(m_pCSection);
00461 
00462         
00463         m_aSocketMap.erase(aData);
00464     }
00465     ERROR_HANDLER("RemoveSocket")
00466 }
00467 
00468 CUDPRelay::CClientSocket* CUDPRelay::CreateSocket(IP aSourceAddress,
00469                                                   unsigned short usSourcePort)
00470 {
00471     try
00472     {
00473         
00474         CClientSocket* pSocket;
00475         pSocket=new CClientSocket(this,
00476                                   aSourceAddress,
00477                                   usSourcePort);
00478 
00479         
00480         std::auto_ptr<CClientSocket> pProtection(pSocket);
00481 
00482         
00483         if (!pSocket->Create())
00484         {
00485             
00486             ReportError("CreateSocket","Failed to create socket!");
00487 
00488             
00489             return NULL;
00490         }
00491         
00492         
00493         if (!pSocket->Listen())
00494         {
00495             
00496             ReportError("CreateSocket","Failed to create socket!");
00497 
00498             
00499             return NULL;
00500         }
00501 
00502         
00503         ConnectionData aData;
00504         aData.aSourceIP=aSourceAddress;
00505         aData.usSourcePort=usSourcePort;
00506 
00507         {
00508             
00509             CCriticalAutoRelease aRelease(m_pCSection);
00510 
00511             
00512             m_aSocketMap.insert(SocketMap::value_type(aData,pSocket));
00513         }
00514 
00515         
00516         pProtection.release();
00517 
00518         
00519         return pSocket;
00520     }
00521     ERROR_HANDLER_RETURN("CreateSocket",NULL)
00522 }
00523 
00524 BOOL CUDPRelay::Stop()
00525 {
00526     try
00527     {
00528         
00529         if (!m_bCreated)
00530             return TRUE;
00531 
00532         
00533         m_pSocket->DeleteSocketFromThread();
00534         m_pSocket=NULL;
00535 
00536         {
00537             
00538             CCriticalAutoRelease aRelease(m_pCSection);
00539 
00540             
00541             SocketMap::iterator aIterator;
00542             aIterator=m_aSocketMap.begin();
00543             while (aIterator!=m_aSocketMap.end())
00544             {
00545                 
00546                 aIterator->second->DeleteSocketFromThread();
00547 
00548                 
00549                 aIterator=m_aSocketMap.erase(aIterator);
00550             }
00551         }
00552 
00553         
00554         m_bCreated=FALSE;
00555 
00556         
00557         return TRUE;
00558     }
00559     ERROR_HANDLER_RETURN("Stop",FALSE)
00560 }
00561 
00562 KOMODIA_NAMESPACE_END