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_pFather->GetTarget(),
00217                     m_pFather->GetTargetPort(),
00218                     pBuffer,
00219                     ulBufferSize);
00220     }
00221     ERROR_HANDLER_RETURN("SendData",GetErrorCode())
00222 }
00223 
00224 BOOL CUDPRelay::CClientSocket::OnSocketTimeout()
00225 {
00226     try
00227     {
00228         
00229         m_pFather->RemoveSocket(m_aSourceAddress,
00230                                 m_usSourcePort);
00231 
00232         
00233         delete this;
00234 
00235         
00236         return FALSE;
00237     }
00238     ERROR_HANDLER_RETURN("OnSocketTimeout",FALSE)
00239 }
00240 
00241 
00242 
00243 #define CUDPRelay_Class "CUDPRelay"
00244 
00245 CUDPRelay::CUDPRelay() : CRelay(),
00246                          m_pSocket(NULL),
00247                          m_bCreated(FALSE),
00248                          m_aTarget(0),
00249                          m_usTargetPort(0),
00250                          m_pCSection(NULL),
00251                          m_pCSectionPorts(NULL),
00252                          m_usBindPort(0)
00253 {
00254     try
00255     {
00256         
00257         SetName(CUDPRelay_Class);
00258 
00259         
00260         m_pCSection=COSManager::CreateCriticalSection();
00261         m_pCSectionPorts=COSManager::CreateCriticalSection();
00262     }
00263     ERROR_HANDLER("CUDPRelay")
00264 }
00265 
00266 CUDPRelay::~CUDPRelay()
00267 {
00268     try
00269     {
00270         delete m_pCSection;
00271         delete m_pCSectionPorts;
00272     }
00273     ERROR_HANDLER("~CUDPRelay")
00274 }
00275 
00276 BOOL CUDPRelay::Relay(IP aBindAddress,
00277                       unsigned short usBindPort,
00278                       IP aDestinationAddress,
00279                       unsigned short usDestinationPort)
00280 {
00281     try
00282     {
00283         
00284         if (m_bCreated)
00285         {
00286             
00287             ReportError("Relay","Already created!");
00288 
00289             
00290             return FALSE;
00291         }
00292 
00293         
00294         m_pSocket=new CListenSocket(this);
00295 
00296         
00297         std::auto_ptr<CListenSocket> pProtection(m_pSocket);
00298 
00299         
00300         if (!m_pSocket->Create())
00301         {
00302             
00303             ReportError("Relay","Failed to create socket!");
00304 
00305             
00306             return FALSE;
00307         }
00308 
00309         
00310         if (!m_pSocket->Bind(aBindAddress,
00311                              usBindPort))
00312         {
00313             
00314             ReportError("Relay","Failed to create socket!");
00315 
00316             
00317             return FALSE;
00318         }
00319 
00320         
00321         m_aTarget=aDestinationAddress;
00322         m_usTargetPort=usDestinationPort;
00323         m_usBindPort=usBindPort;
00324 
00325         
00326         m_usLocalPort=1024;
00327 
00328         
00329         if (!m_pSocket->Listen())
00330         {
00331             
00332             ReportError("Relay","Failed to listen!");
00333 
00334             
00335             return FALSE;
00336         }
00337 
00338         
00339         pProtection.release();
00340 
00341         
00342         m_bCreated=TRUE;
00343 
00344         
00345         return TRUE;
00346     }
00347     ERROR_HANDLER_RETURN("Relay",FALSE)
00348 }
00349 
00350 BOOL CUDPRelay::Relay(const std::string& rBindAddress,
00351                       unsigned short usBindPort,
00352                       const std::string& rDestinationAddress,
00353                       unsigned short usDestinationPort)
00354 {
00355     try
00356     {
00357         return Relay(CSocketBase::StringToLong(rBindAddress),
00358                      usBindPort,
00359                      CSocketBase::StringToLong(rDestinationAddress),
00360                      usDestinationPort);
00361     }
00362     ERROR_HANDLER_RETURN("Relay",FALSE)
00363 }
00364 
00365 IP CUDPRelay::GetTarget()const
00366 {
00367     return m_aTarget;
00368 }
00369 
00370 unsigned short CUDPRelay::GetTargetPort()const
00371 {
00372     return m_usTargetPort;
00373 }
00374 
00375 unsigned short CUDPRelay::GetBindPort()const
00376 {
00377     return m_usBindPort;
00378 }
00379 
00380 void CUDPRelay::SendData(const char* pBuffer,
00381                          unsigned long ulBufferSize,
00382                          IP aDestinationIP,
00383                          unsigned short usDestinationPort)
00384 {
00385     try
00386     {
00387         
00388         ConnectionData aData;
00389         aData.aSourceIP=aDestinationIP;
00390         aData.usSourcePort=usDestinationPort;
00391 
00392         
00393         CClientSocket* pSocket;
00394         pSocket=NULL;
00395 
00396         {
00397             
00398             CCriticalAutoRelease aRelease(m_pCSection);
00399             
00400             
00401             SocketMap::iterator aIterator;
00402             aIterator=m_aSocketMap.find(aData);
00403             if (aIterator!=m_aSocketMap.end())
00404                 
00405                 pSocket=aIterator->second;
00406         }
00407 
00408         
00409         if (pSocket)
00410             
00411             if (pSocket->SendData(pBuffer,
00412                                   ulBufferSize)<=0)
00413                 
00414                 ReportErrorOS("SendData","Failed to send data!");
00415             else
00416                 ;
00417         else
00418         {
00419             
00420             if (!(pSocket=CreateSocket(aDestinationIP,
00421                                        usDestinationPort)))
00422                 
00423                 ReportError("CreateSocket","Failed to create socket!");
00424             else
00425                 
00426                 SendData(pBuffer,
00427                          ulBufferSize,
00428                          aDestinationIP,
00429                          usDestinationPort);
00430         }
00431     }
00432     ERROR_HANDLER("SendData")
00433 }
00434 
00435 unsigned short CUDPRelay::AllocateLocalPort()const
00436 {
00437     try
00438     {
00439         
00440         CCriticalAutoRelease aRelease(m_pCSectionPorts);
00441 
00442         
00443         return ++m_usLocalPort;
00444     }
00445     ERROR_HANDLER_RETURN("AllocateLocalPort",m_usLocalPort)
00446 }
00447 
00448 void CUDPRelay::RemoveSocket(IP aSourceAddress,
00449                              unsigned short usSourcePort)
00450 {
00451     try
00452     {
00453         
00454         ConnectionData aData;
00455         aData.aSourceIP=aSourceAddress;
00456         aData.usSourcePort=usSourcePort;
00457 
00458         
00459         CCriticalAutoRelease aRelease(m_pCSection);
00460 
00461         
00462         m_aSocketMap.erase(aData);
00463     }
00464     ERROR_HANDLER("RemoveSocket")
00465 }
00466 
00467 CUDPRelay::CClientSocket* CUDPRelay::CreateSocket(IP aSourceAddress,
00468                                                   unsigned short usSourcePort)
00469 {
00470     try
00471     {
00472         
00473         CClientSocket* pSocket;
00474         pSocket=new CClientSocket(this,
00475                                   aSourceAddress,
00476                                   usSourcePort);
00477 
00478         
00479         std::auto_ptr<CClientSocket> pProtection(pSocket);
00480 
00481         
00482         if (!pSocket->Create())
00483         {
00484             
00485             ReportError("CreateSocket","Failed to create socket!");
00486 
00487             
00488             return NULL;
00489         }
00490         
00491         
00492         if (!pSocket->Listen())
00493         {
00494             
00495             ReportError("CreateSocket","Failed to create socket!");
00496 
00497             
00498             return NULL;
00499         }
00500 
00501         
00502         ConnectionData aData;
00503         aData.aSourceIP=aSourceAddress;
00504         aData.usSourcePort=usSourcePort;
00505 
00506         {
00507             
00508             CCriticalAutoRelease aRelease(m_pCSection);
00509 
00510             
00511             m_aSocketMap.insert(SocketMap::value_type(aData,pSocket));
00512         }
00513 
00514         
00515         pProtection.release();
00516 
00517         
00518         return pSocket;
00519     }
00520     ERROR_HANDLER_RETURN("CreateSocket",NULL)
00521 }
00522 
00523 BOOL CUDPRelay::Stop()
00524 {
00525     try
00526     {
00527         
00528         if (!m_bCreated)
00529             return TRUE;
00530 
00531         
00532         m_pSocket->DeleteSocketFromThread();
00533         m_pSocket=NULL;
00534 
00535         {
00536             
00537             CCriticalAutoRelease aRelease(m_pCSection);
00538 
00539             
00540             SocketMap::iterator aIterator;
00541             aIterator=m_aSocketMap.begin();
00542             while (aIterator!=m_aSocketMap.end())
00543             {
00544                 
00545                 aIterator->second->DeleteSocketFromThread();
00546 
00547                 
00548                 aIterator=m_aSocketMap.erase(aIterator);
00549             }
00550         }
00551 
00552         
00553         m_bCreated=FALSE;
00554 
00555         
00556         return TRUE;
00557     }
00558     ERROR_HANDLER_RETURN("Stop",FALSE)
00559 }
00560 
00561 KOMODIA_NAMESPACE_END