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