| OLD | NEW |
| (Empty) |
| 1 /***************************************************************************** | |
| 2 Copyright (c) 2001 - 2011, The Board of Trustees of the University of Illinois. | |
| 3 All rights reserved. | |
| 4 | |
| 5 Redistribution and use in source and binary forms, with or without | |
| 6 modification, are permitted provided that the following conditions are | |
| 7 met: | |
| 8 | |
| 9 * Redistributions of source code must retain the above | |
| 10 copyright notice, this list of conditions and the | |
| 11 following disclaimer. | |
| 12 | |
| 13 * Redistributions in binary form must reproduce the | |
| 14 above copyright notice, this list of conditions | |
| 15 and the following disclaimer in the documentation | |
| 16 and/or other materials provided with the distribution. | |
| 17 | |
| 18 * Neither the name of the University of Illinois | |
| 19 nor the names of its contributors may be used to | |
| 20 endorse or promote products derived from this | |
| 21 software without specific prior written permission. | |
| 22 | |
| 23 THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS | |
| 24 IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, | |
| 25 THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR | |
| 26 PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR | |
| 27 CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, | |
| 28 EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, | |
| 29 PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR | |
| 30 PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF | |
| 31 LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING | |
| 32 NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS | |
| 33 SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. | |
| 34 *****************************************************************************/ | |
| 35 | |
| 36 /***************************************************************************** | |
| 37 written by | |
| 38 Yunhong Gu, last updated 01/31/2011 | |
| 39 *****************************************************************************/ | |
| 40 | |
| 41 #ifdef WIN32 | |
| 42 #include <winsock2.h> | |
| 43 #include <ws2tcpip.h> | |
| 44 #ifdef LEGACY_WIN32 | |
| 45 #include <wspiapi.h> | |
| 46 #endif | |
| 47 #else | |
| 48 #include <unistd.h> | |
| 49 #endif | |
| 50 #include <cstring> | |
| 51 #include "api.h" | |
| 52 #include "core.h" | |
| 53 | |
| 54 using namespace std; | |
| 55 | |
| 56 CUDTSocket::CUDTSocket(): | |
| 57 m_Status(INIT), | |
| 58 m_TimeStamp(0), | |
| 59 m_iIPversion(0), | |
| 60 m_pSelfAddr(NULL), | |
| 61 m_pPeerAddr(NULL), | |
| 62 m_SocketID(0), | |
| 63 m_ListenSocket(0), | |
| 64 m_PeerID(0), | |
| 65 m_iISN(0), | |
| 66 m_pUDT(NULL), | |
| 67 m_pQueuedSockets(NULL), | |
| 68 m_pAcceptSockets(NULL), | |
| 69 m_AcceptCond(), | |
| 70 m_AcceptLock(), | |
| 71 m_uiBackLog(0), | |
| 72 m_iMuxID(-1) | |
| 73 { | |
| 74 #ifndef WIN32 | |
| 75 pthread_mutex_init(&m_AcceptLock, NULL); | |
| 76 pthread_cond_init(&m_AcceptCond, NULL); | |
| 77 #else | |
| 78 m_AcceptLock = CreateMutex(NULL, false, NULL); | |
| 79 m_AcceptCond = CreateEvent(NULL, false, false, NULL); | |
| 80 #endif | |
| 81 } | |
| 82 | |
| 83 CUDTSocket::~CUDTSocket() | |
| 84 { | |
| 85 if (AF_INET == m_iIPversion) | |
| 86 { | |
| 87 delete (sockaddr_in*)m_pSelfAddr; | |
| 88 delete (sockaddr_in*)m_pPeerAddr; | |
| 89 } | |
| 90 else | |
| 91 { | |
| 92 delete (sockaddr_in6*)m_pSelfAddr; | |
| 93 delete (sockaddr_in6*)m_pPeerAddr; | |
| 94 } | |
| 95 | |
| 96 delete m_pUDT; | |
| 97 m_pUDT = NULL; | |
| 98 | |
| 99 delete m_pQueuedSockets; | |
| 100 delete m_pAcceptSockets; | |
| 101 | |
| 102 #ifndef WIN32 | |
| 103 pthread_mutex_destroy(&m_AcceptLock); | |
| 104 pthread_cond_destroy(&m_AcceptCond); | |
| 105 #else | |
| 106 CloseHandle(m_AcceptLock); | |
| 107 CloseHandle(m_AcceptCond); | |
| 108 #endif | |
| 109 } | |
| 110 | |
| 111 //////////////////////////////////////////////////////////////////////////////// | |
| 112 | |
| 113 CUDTUnited::CUDTUnited(): | |
| 114 m_Sockets(), | |
| 115 m_ControlLock(), | |
| 116 m_IDLock(), | |
| 117 m_SocketID(0), | |
| 118 m_TLSError(), | |
| 119 m_mMultiplexer(), | |
| 120 m_MultiplexerLock(), | |
| 121 m_pCache(NULL), | |
| 122 m_bClosing(false), | |
| 123 m_GCStopLock(), | |
| 124 m_GCStopCond(), | |
| 125 m_InitLock(), | |
| 126 m_iInstanceCount(0), | |
| 127 m_bGCStatus(false), | |
| 128 m_GCThread(), | |
| 129 m_ClosedSockets() | |
| 130 { | |
| 131 // Socket ID MUST start from a random value | |
| 132 srand((unsigned int)CTimer::getTime()); | |
| 133 m_SocketID = 1 + (int)((1 << 30) * (double(rand()) / RAND_MAX)); | |
| 134 | |
| 135 #ifndef WIN32 | |
| 136 pthread_mutex_init(&m_ControlLock, NULL); | |
| 137 pthread_mutex_init(&m_IDLock, NULL); | |
| 138 pthread_mutex_init(&m_InitLock, NULL); | |
| 139 #else | |
| 140 m_ControlLock = CreateMutex(NULL, false, NULL); | |
| 141 m_IDLock = CreateMutex(NULL, false, NULL); | |
| 142 m_InitLock = CreateMutex(NULL, false, NULL); | |
| 143 #endif | |
| 144 | |
| 145 #ifndef WIN32 | |
| 146 pthread_key_create(&m_TLSError, TLSDestroy); | |
| 147 #else | |
| 148 m_TLSError = TlsAlloc(); | |
| 149 m_TLSLock = CreateMutex(NULL, false, NULL); | |
| 150 #endif | |
| 151 | |
| 152 m_pCache = new CCache; | |
| 153 } | |
| 154 | |
| 155 CUDTUnited::~CUDTUnited() | |
| 156 { | |
| 157 #ifndef WIN32 | |
| 158 pthread_mutex_destroy(&m_ControlLock); | |
| 159 pthread_mutex_destroy(&m_IDLock); | |
| 160 pthread_mutex_destroy(&m_InitLock); | |
| 161 #else | |
| 162 CloseHandle(m_ControlLock); | |
| 163 CloseHandle(m_IDLock); | |
| 164 CloseHandle(m_InitLock); | |
| 165 #endif | |
| 166 | |
| 167 #ifndef WIN32 | |
| 168 pthread_key_delete(m_TLSError); | |
| 169 #else | |
| 170 TlsFree(m_TLSError); | |
| 171 CloseHandle(m_TLSLock); | |
| 172 #endif | |
| 173 | |
| 174 delete m_pCache; | |
| 175 } | |
| 176 | |
| 177 int CUDTUnited::startup() | |
| 178 { | |
| 179 CGuard gcinit(m_InitLock); | |
| 180 | |
| 181 if (m_iInstanceCount++ > 0) | |
| 182 return 0; | |
| 183 | |
| 184 // Global initialization code | |
| 185 #ifdef WIN32 | |
| 186 WORD wVersionRequested; | |
| 187 WSADATA wsaData; | |
| 188 wVersionRequested = MAKEWORD(2, 2); | |
| 189 | |
| 190 if (0 != WSAStartup(wVersionRequested, &wsaData)) | |
| 191 throw CUDTException(1, 0, WSAGetLastError()); | |
| 192 #endif | |
| 193 | |
| 194 //init CTimer::EventLock | |
| 195 | |
| 196 if (m_bGCStatus) | |
| 197 return true; | |
| 198 | |
| 199 m_bClosing = false; | |
| 200 #ifndef WIN32 | |
| 201 pthread_mutex_init(&m_GCStopLock, NULL); | |
| 202 pthread_cond_init(&m_GCStopCond, NULL); | |
| 203 pthread_create(&m_GCThread, NULL, garbageCollect, this); | |
| 204 #else | |
| 205 m_GCStopLock = CreateMutex(NULL, false, NULL); | |
| 206 m_GCStopCond = CreateEvent(NULL, false, false, NULL); | |
| 207 DWORD ThreadID; | |
| 208 m_GCThread = CreateThread(NULL, 0, garbageCollect, this, 0, &ThreadID); | |
| 209 #endif | |
| 210 | |
| 211 m_bGCStatus = true; | |
| 212 | |
| 213 return 0; | |
| 214 } | |
| 215 | |
| 216 int CUDTUnited::cleanup() | |
| 217 { | |
| 218 CGuard gcinit(m_InitLock); | |
| 219 | |
| 220 if (--m_iInstanceCount > 0) | |
| 221 return 0; | |
| 222 | |
| 223 //destroy CTimer::EventLock | |
| 224 | |
| 225 if (!m_bGCStatus) | |
| 226 return 0; | |
| 227 | |
| 228 m_bClosing = true; | |
| 229 #ifndef WIN32 | |
| 230 pthread_cond_signal(&m_GCStopCond); | |
| 231 pthread_join(m_GCThread, NULL); | |
| 232 pthread_mutex_destroy(&m_GCStopLock); | |
| 233 pthread_cond_destroy(&m_GCStopCond); | |
| 234 #else | |
| 235 SetEvent(m_GCStopCond); | |
| 236 WaitForSingleObject(m_GCThread, INFINITE); | |
| 237 CloseHandle(m_GCThread); | |
| 238 CloseHandle(m_GCStopLock); | |
| 239 CloseHandle(m_GCStopCond); | |
| 240 #endif | |
| 241 | |
| 242 m_bGCStatus = false; | |
| 243 | |
| 244 // Global destruction code | |
| 245 #ifdef WIN32 | |
| 246 WSACleanup(); | |
| 247 #endif | |
| 248 | |
| 249 return 0; | |
| 250 } | |
| 251 | |
| 252 UDTSOCKET CUDTUnited::newSocket(const int& af, const int& type) | |
| 253 { | |
| 254 if ((type != SOCK_STREAM) && (type != SOCK_DGRAM)) | |
| 255 throw CUDTException(5, 3, 0); | |
| 256 | |
| 257 CUDTSocket* ns = NULL; | |
| 258 | |
| 259 try | |
| 260 { | |
| 261 ns = new CUDTSocket; | |
| 262 ns->m_pUDT = new CUDT; | |
| 263 if (AF_INET == af) | |
| 264 { | |
| 265 ns->m_pSelfAddr = (sockaddr*)(new sockaddr_in); | |
| 266 ((sockaddr_in*)(ns->m_pSelfAddr))->sin_port = 0; | |
| 267 } | |
| 268 else | |
| 269 { | |
| 270 ns->m_pSelfAddr = (sockaddr*)(new sockaddr_in6); | |
| 271 ((sockaddr_in6*)(ns->m_pSelfAddr))->sin6_port = 0; | |
| 272 } | |
| 273 } | |
| 274 catch (...) | |
| 275 { | |
| 276 delete ns; | |
| 277 throw CUDTException(3, 2, 0); | |
| 278 } | |
| 279 | |
| 280 CGuard::enterCS(m_IDLock); | |
| 281 ns->m_SocketID = -- m_SocketID; | |
| 282 CGuard::leaveCS(m_IDLock); | |
| 283 | |
| 284 ns->m_Status = INIT; | |
| 285 ns->m_ListenSocket = 0; | |
| 286 ns->m_pUDT->m_SocketID = ns->m_SocketID; | |
| 287 ns->m_pUDT->m_iSockType = (SOCK_STREAM == type) ? UDT_STREAM : UDT_DGRAM; | |
| 288 ns->m_pUDT->m_iIPversion = ns->m_iIPversion = af; | |
| 289 ns->m_pUDT->m_pCache = m_pCache; | |
| 290 | |
| 291 // protect the m_Sockets structure. | |
| 292 CGuard::enterCS(m_ControlLock); | |
| 293 try | |
| 294 { | |
| 295 m_Sockets[ns->m_SocketID] = ns; | |
| 296 } | |
| 297 catch (...) | |
| 298 { | |
| 299 //failure and rollback | |
| 300 delete ns; | |
| 301 ns = NULL; | |
| 302 } | |
| 303 CGuard::leaveCS(m_ControlLock); | |
| 304 | |
| 305 if (NULL == ns) | |
| 306 throw CUDTException(3, 2, 0); | |
| 307 | |
| 308 return ns->m_SocketID; | |
| 309 } | |
| 310 | |
| 311 int CUDTUnited::newConnection(const UDTSOCKET listen, const sockaddr* peer, CHan
dShake* hs) | |
| 312 { | |
| 313 CUDTSocket* ns = NULL; | |
| 314 CUDTSocket* ls = locate(listen); | |
| 315 | |
| 316 if (NULL == ls) | |
| 317 return -1; | |
| 318 | |
| 319 // if this connection has already been processed | |
| 320 if (NULL != (ns = locate(peer, hs->m_iID, hs->m_iISN))) | |
| 321 { | |
| 322 if (ns->m_pUDT->m_bBroken) | |
| 323 { | |
| 324 // last connection from the "peer" address has been broken | |
| 325 ns->m_Status = CLOSED; | |
| 326 ns->m_TimeStamp = CTimer::getTime(); | |
| 327 | |
| 328 CGuard::enterCS(ls->m_AcceptLock); | |
| 329 ls->m_pQueuedSockets->erase(ns->m_SocketID); | |
| 330 ls->m_pAcceptSockets->erase(ns->m_SocketID); | |
| 331 CGuard::leaveCS(ls->m_AcceptLock); | |
| 332 } | |
| 333 else | |
| 334 { | |
| 335 // connection already exist, this is a repeated connection request | |
| 336 // respond with existing HS information | |
| 337 | |
| 338 hs->m_iISN = ns->m_pUDT->m_iISN; | |
| 339 hs->m_iMSS = ns->m_pUDT->m_iMSS; | |
| 340 hs->m_iFlightFlagSize = ns->m_pUDT->m_iFlightFlagSize; | |
| 341 hs->m_iReqType = -1; | |
| 342 hs->m_iID = ns->m_SocketID; | |
| 343 | |
| 344 return 0; | |
| 345 | |
| 346 //except for this situation a new connection should be started | |
| 347 } | |
| 348 } | |
| 349 | |
| 350 // exceeding backlog, refuse the connection request | |
| 351 if (ls->m_pQueuedSockets->size() >= ls->m_uiBackLog) | |
| 352 return -1; | |
| 353 | |
| 354 try | |
| 355 { | |
| 356 ns = new CUDTSocket; | |
| 357 ns->m_pUDT = new CUDT(*(ls->m_pUDT)); | |
| 358 if (AF_INET == ls->m_iIPversion) | |
| 359 { | |
| 360 ns->m_pSelfAddr = (sockaddr*)(new sockaddr_in); | |
| 361 ((sockaddr_in*)(ns->m_pSelfAddr))->sin_port = 0; | |
| 362 ns->m_pPeerAddr = (sockaddr*)(new sockaddr_in); | |
| 363 memcpy(ns->m_pPeerAddr, peer, sizeof(sockaddr_in)); | |
| 364 } | |
| 365 else | |
| 366 { | |
| 367 ns->m_pSelfAddr = (sockaddr*)(new sockaddr_in6); | |
| 368 ((sockaddr_in6*)(ns->m_pSelfAddr))->sin6_port = 0; | |
| 369 ns->m_pPeerAddr = (sockaddr*)(new sockaddr_in6); | |
| 370 memcpy(ns->m_pPeerAddr, peer, sizeof(sockaddr_in6)); | |
| 371 } | |
| 372 } | |
| 373 catch (...) | |
| 374 { | |
| 375 delete ns; | |
| 376 return -1; | |
| 377 } | |
| 378 | |
| 379 CGuard::enterCS(m_IDLock); | |
| 380 ns->m_SocketID = -- m_SocketID; | |
| 381 CGuard::leaveCS(m_IDLock); | |
| 382 | |
| 383 ns->m_ListenSocket = listen; | |
| 384 ns->m_iIPversion = ls->m_iIPversion; | |
| 385 ns->m_pUDT->m_SocketID = ns->m_SocketID; | |
| 386 ns->m_PeerID = hs->m_iID; | |
| 387 ns->m_iISN = hs->m_iISN; | |
| 388 | |
| 389 int error = 0; | |
| 390 | |
| 391 try | |
| 392 { | |
| 393 // bind to the same addr of listening socket | |
| 394 ns->m_pUDT->open(); | |
| 395 updateMux(ns, ls); | |
| 396 ns->m_pUDT->connect(peer, hs); | |
| 397 } | |
| 398 catch (...) | |
| 399 { | |
| 400 error = 1; | |
| 401 goto ERR_ROLLBACK; | |
| 402 } | |
| 403 | |
| 404 ns->m_Status = CONNECTED; | |
| 405 | |
| 406 // copy address information of local node | |
| 407 ns->m_pUDT->m_pSndQueue->m_pChannel->getSockAddr(ns->m_pSelfAddr); | |
| 408 CIPAddress::pton(ns->m_pSelfAddr, ns->m_pUDT->m_piSelfIP, ns->m_iIPversion); | |
| 409 | |
| 410 // protect the m_Sockets structure. | |
| 411 CGuard::enterCS(m_ControlLock); | |
| 412 try | |
| 413 { | |
| 414 m_Sockets[ns->m_SocketID] = ns; | |
| 415 m_PeerRec[(ns->m_PeerID << 30) + ns->m_iISN].insert(ns->m_SocketID); | |
| 416 } | |
| 417 catch (...) | |
| 418 { | |
| 419 error = 2; | |
| 420 } | |
| 421 CGuard::leaveCS(m_ControlLock); | |
| 422 | |
| 423 CGuard::enterCS(ls->m_AcceptLock); | |
| 424 try | |
| 425 { | |
| 426 ls->m_pQueuedSockets->insert(ns->m_SocketID); | |
| 427 } | |
| 428 catch (...) | |
| 429 { | |
| 430 error = 3; | |
| 431 } | |
| 432 CGuard::leaveCS(ls->m_AcceptLock); | |
| 433 | |
| 434 CTimer::triggerEvent(); | |
| 435 | |
| 436 ERR_ROLLBACK: | |
| 437 if (error > 0) | |
| 438 { | |
| 439 ns->m_pUDT->close(); | |
| 440 ns->m_Status = CLOSED; | |
| 441 ns->m_TimeStamp = CTimer::getTime(); | |
| 442 | |
| 443 return -1; | |
| 444 } | |
| 445 | |
| 446 // wake up a waiting accept() call | |
| 447 #ifndef WIN32 | |
| 448 pthread_mutex_lock(&(ls->m_AcceptLock)); | |
| 449 pthread_cond_signal(&(ls->m_AcceptCond)); | |
| 450 pthread_mutex_unlock(&(ls->m_AcceptLock)); | |
| 451 #else | |
| 452 SetEvent(ls->m_AcceptCond); | |
| 453 #endif | |
| 454 | |
| 455 return 1; | |
| 456 } | |
| 457 | |
| 458 CUDT* CUDTUnited::lookup(const UDTSOCKET u) | |
| 459 { | |
| 460 // protects the m_Sockets structure | |
| 461 CGuard cg(m_ControlLock); | |
| 462 | |
| 463 map<UDTSOCKET, CUDTSocket*>::iterator i = m_Sockets.find(u); | |
| 464 | |
| 465 if ((i == m_Sockets.end()) || (i->second->m_Status == CLOSED)) | |
| 466 throw CUDTException(5, 4, 0); | |
| 467 | |
| 468 return i->second->m_pUDT; | |
| 469 } | |
| 470 | |
| 471 UDTSTATUS CUDTUnited::getStatus(const UDTSOCKET u) | |
| 472 { | |
| 473 // protects the m_Sockets structure | |
| 474 CGuard cg(m_ControlLock); | |
| 475 | |
| 476 map<UDTSOCKET, CUDTSocket*>::iterator i = m_Sockets.find(u); | |
| 477 | |
| 478 if (i == m_Sockets.end()) | |
| 479 { | |
| 480 if (m_ClosedSockets.find(u) != m_ClosedSockets.end()) | |
| 481 return CLOSED; | |
| 482 | |
| 483 return NONEXIST; | |
| 484 } | |
| 485 | |
| 486 if (i->second->m_pUDT->m_bBroken) | |
| 487 return BROKEN; | |
| 488 | |
| 489 return i->second->m_Status; | |
| 490 } | |
| 491 | |
| 492 int CUDTUnited::bind(const UDTSOCKET u, const sockaddr* name, const int& namelen
) | |
| 493 { | |
| 494 CUDTSocket* s = locate(u); | |
| 495 | |
| 496 if (NULL == s) | |
| 497 throw CUDTException(5, 4, 0); | |
| 498 | |
| 499 // cannot bind a socket more than once | |
| 500 if (INIT != s->m_Status) | |
| 501 throw CUDTException(5, 0, 0); | |
| 502 | |
| 503 // check the size of SOCKADDR structure | |
| 504 if (AF_INET == s->m_iIPversion) | |
| 505 { | |
| 506 if (namelen != sizeof(sockaddr_in)) | |
| 507 throw CUDTException(5, 3, 0); | |
| 508 } | |
| 509 else | |
| 510 { | |
| 511 if (namelen != sizeof(sockaddr_in6)) | |
| 512 throw CUDTException(5, 3, 0); | |
| 513 } | |
| 514 | |
| 515 s->m_pUDT->open(); | |
| 516 updateMux(s, name); | |
| 517 s->m_Status = OPENED; | |
| 518 | |
| 519 // copy address information of local node | |
| 520 s->m_pUDT->m_pSndQueue->m_pChannel->getSockAddr(s->m_pSelfAddr); | |
| 521 | |
| 522 return 0; | |
| 523 } | |
| 524 | |
| 525 int CUDTUnited::bind(UDTSOCKET u, UDPSOCKET udpsock) | |
| 526 { | |
| 527 CUDTSocket* s = locate(u); | |
| 528 | |
| 529 if (NULL == s) | |
| 530 throw CUDTException(5, 4, 0); | |
| 531 | |
| 532 // cannot bind a socket more than once | |
| 533 if (INIT != s->m_Status) | |
| 534 throw CUDTException(5, 0, 0); | |
| 535 | |
| 536 sockaddr_in name4; | |
| 537 sockaddr_in6 name6; | |
| 538 sockaddr* name; | |
| 539 socklen_t namelen; | |
| 540 | |
| 541 if (AF_INET == s->m_iIPversion) | |
| 542 { | |
| 543 namelen = sizeof(sockaddr_in); | |
| 544 name = (sockaddr*)&name4; | |
| 545 } | |
| 546 else | |
| 547 { | |
| 548 namelen = sizeof(sockaddr_in6); | |
| 549 name = (sockaddr*)&name6; | |
| 550 } | |
| 551 | |
| 552 if (-1 == ::getsockname(udpsock, name, &namelen)) | |
| 553 throw CUDTException(5, 3); | |
| 554 | |
| 555 s->m_pUDT->open(); | |
| 556 updateMux(s, name, &udpsock); | |
| 557 s->m_Status = OPENED; | |
| 558 | |
| 559 // copy address information of local node | |
| 560 s->m_pUDT->m_pSndQueue->m_pChannel->getSockAddr(s->m_pSelfAddr); | |
| 561 | |
| 562 return 0; | |
| 563 } | |
| 564 | |
| 565 int CUDTUnited::listen(const UDTSOCKET u, const int& backlog) | |
| 566 { | |
| 567 CUDTSocket* s = locate(u); | |
| 568 | |
| 569 if (NULL == s) | |
| 570 throw CUDTException(5, 4, 0); | |
| 571 | |
| 572 // do nothing if the socket is already listening | |
| 573 if (LISTENING == s->m_Status) | |
| 574 return 0; | |
| 575 | |
| 576 // a socket can listen only if is in OPENED status | |
| 577 if (OPENED != s->m_Status) | |
| 578 throw CUDTException(5, 5, 0); | |
| 579 | |
| 580 // listen is not supported in rendezvous connection setup | |
| 581 if (s->m_pUDT->m_bRendezvous) | |
| 582 throw CUDTException(5, 7, 0); | |
| 583 | |
| 584 if (backlog <= 0) | |
| 585 throw CUDTException(5, 3, 0); | |
| 586 | |
| 587 s->m_uiBackLog = backlog; | |
| 588 | |
| 589 try | |
| 590 { | |
| 591 s->m_pQueuedSockets = new set<UDTSOCKET>; | |
| 592 s->m_pAcceptSockets = new set<UDTSOCKET>; | |
| 593 } | |
| 594 catch (...) | |
| 595 { | |
| 596 delete s->m_pQueuedSockets; | |
| 597 throw CUDTException(3, 2, 0); | |
| 598 } | |
| 599 | |
| 600 s->m_pUDT->listen(); | |
| 601 | |
| 602 s->m_Status = LISTENING; | |
| 603 | |
| 604 return 0; | |
| 605 } | |
| 606 | |
| 607 UDTSOCKET CUDTUnited::accept(const UDTSOCKET listen, sockaddr* addr, int* addrle
n) | |
| 608 { | |
| 609 if ((NULL != addr) && (NULL == addrlen)) | |
| 610 throw CUDTException(5, 3, 0); | |
| 611 | |
| 612 CUDTSocket* ls = locate(listen); | |
| 613 | |
| 614 if (ls == NULL) | |
| 615 throw CUDTException(5, 4, 0); | |
| 616 | |
| 617 // the "listen" socket must be in LISTENING status | |
| 618 if (LISTENING != ls->m_Status) | |
| 619 throw CUDTException(5, 6, 0); | |
| 620 | |
| 621 // no "accept" in rendezvous connection setup | |
| 622 if (ls->m_pUDT->m_bRendezvous) | |
| 623 throw CUDTException(5, 7, 0); | |
| 624 | |
| 625 UDTSOCKET u = CUDT::INVALID_SOCK; | |
| 626 bool accepted = false; | |
| 627 | |
| 628 // !!only one conection can be set up each time!! | |
| 629 #ifndef WIN32 | |
| 630 while (!accepted) | |
| 631 { | |
| 632 pthread_mutex_lock(&(ls->m_AcceptLock)); | |
| 633 | |
| 634 if (ls->m_pQueuedSockets->size() > 0) | |
| 635 { | |
| 636 u = *(ls->m_pQueuedSockets->begin()); | |
| 637 ls->m_pAcceptSockets->insert(ls->m_pAcceptSockets->end(), u); | |
| 638 ls->m_pQueuedSockets->erase(ls->m_pQueuedSockets->begin()); | |
| 639 accepted = true; | |
| 640 } | |
| 641 else if (!ls->m_pUDT->m_bSynRecving) | |
| 642 accepted = true; | |
| 643 else if (LISTENING == ls->m_Status) | |
| 644 pthread_cond_wait(&(ls->m_AcceptCond), &(ls->m_AcceptLock)); | |
| 645 | |
| 646 if ((LISTENING != ls->m_Status) || ls->m_pUDT->m_bBroken) | |
| 647 accepted = true; | |
| 648 | |
| 649 if (ls->m_pQueuedSockets->empty()) | |
| 650 m_EPoll.disable_read(listen, ls->m_pUDT->m_sPollID); | |
| 651 | |
| 652 pthread_mutex_unlock(&(ls->m_AcceptLock)); | |
| 653 } | |
| 654 #else | |
| 655 while (!accepted) | |
| 656 { | |
| 657 WaitForSingleObject(ls->m_AcceptLock, INFINITE); | |
| 658 | |
| 659 if (ls->m_pQueuedSockets->size() > 0) | |
| 660 { | |
| 661 u = *(ls->m_pQueuedSockets->begin()); | |
| 662 ls->m_pAcceptSockets->insert(ls->m_pAcceptSockets->end(), u); | |
| 663 ls->m_pQueuedSockets->erase(ls->m_pQueuedSockets->begin()); | |
| 664 | |
| 665 accepted = true; | |
| 666 } | |
| 667 else if (!ls->m_pUDT->m_bSynRecving) | |
| 668 accepted = true; | |
| 669 | |
| 670 ReleaseMutex(ls->m_AcceptLock); | |
| 671 | |
| 672 if (!accepted & (LISTENING == ls->m_Status)) | |
| 673 WaitForSingleObject(ls->m_AcceptCond, INFINITE); | |
| 674 | |
| 675 if ((LISTENING != ls->m_Status) || ls->m_pUDT->m_bBroken) | |
| 676 { | |
| 677 SetEvent(ls->m_AcceptCond); | |
| 678 accepted = true; | |
| 679 } | |
| 680 | |
| 681 if (ls->m_pQueuedSockets->empty()) | |
| 682 m_EPoll.disable_read(listen, ls->m_pUDT->m_sPollID); | |
| 683 } | |
| 684 #endif | |
| 685 | |
| 686 if (u == CUDT::INVALID_SOCK) | |
| 687 { | |
| 688 // non-blocking receiving, no connection available | |
| 689 if (!ls->m_pUDT->m_bSynRecving) | |
| 690 throw CUDTException(6, 2, 0); | |
| 691 | |
| 692 // listening socket is closed | |
| 693 throw CUDTException(5, 6, 0); | |
| 694 } | |
| 695 | |
| 696 if ((addr != NULL) && (addrlen != NULL)) | |
| 697 { | |
| 698 if (AF_INET == locate(u)->m_iIPversion) | |
| 699 *addrlen = sizeof(sockaddr_in); | |
| 700 else | |
| 701 *addrlen = sizeof(sockaddr_in6); | |
| 702 | |
| 703 // copy address information of peer node | |
| 704 memcpy(addr, locate(u)->m_pPeerAddr, *addrlen); | |
| 705 } | |
| 706 | |
| 707 return u; | |
| 708 } | |
| 709 | |
| 710 int CUDTUnited::connect(const UDTSOCKET u, const sockaddr* name, const int& name
len) | |
| 711 { | |
| 712 CUDTSocket* s = locate(u); | |
| 713 | |
| 714 if (NULL == s) | |
| 715 throw CUDTException(5, 4, 0); | |
| 716 | |
| 717 // check the size of SOCKADDR structure | |
| 718 if (AF_INET == s->m_iIPversion) | |
| 719 { | |
| 720 if (namelen != sizeof(sockaddr_in)) | |
| 721 throw CUDTException(5, 3, 0); | |
| 722 } | |
| 723 else | |
| 724 { | |
| 725 if (namelen != sizeof(sockaddr_in6)) | |
| 726 throw CUDTException(5, 3, 0); | |
| 727 } | |
| 728 | |
| 729 // a socket can "connect" only if it is in INIT or OPENED status | |
| 730 if (INIT == s->m_Status) | |
| 731 { | |
| 732 if (!s->m_pUDT->m_bRendezvous) | |
| 733 { | |
| 734 s->m_pUDT->open(); | |
| 735 updateMux(s); | |
| 736 s->m_Status = OPENED; | |
| 737 } | |
| 738 else | |
| 739 throw CUDTException(5, 8, 0); | |
| 740 } | |
| 741 else if (OPENED != s->m_Status) | |
| 742 throw CUDTException(5, 2, 0); | |
| 743 | |
| 744 s->m_pUDT->connect(name); | |
| 745 s->m_Status = CONNECTED; | |
| 746 | |
| 747 // copy address information of local node | |
| 748 // the local port must be correctly assigned BEFORE CUDT::connect(), | |
| 749 // otherwise if connect() fails, the multiplexer cannot be located by garbage
collection and will cause leak | |
| 750 s->m_pUDT->m_pSndQueue->m_pChannel->getSockAddr(s->m_pSelfAddr); | |
| 751 CIPAddress::pton(s->m_pSelfAddr, s->m_pUDT->m_piSelfIP, s->m_iIPversion); | |
| 752 | |
| 753 // record peer address | |
| 754 if (AF_INET == s->m_iIPversion) | |
| 755 { | |
| 756 s->m_pPeerAddr = (sockaddr*)(new sockaddr_in); | |
| 757 memcpy(s->m_pPeerAddr, name, sizeof(sockaddr_in)); | |
| 758 } | |
| 759 else | |
| 760 { | |
| 761 s->m_pPeerAddr = (sockaddr*)(new sockaddr_in6); | |
| 762 memcpy(s->m_pPeerAddr, name, sizeof(sockaddr_in6)); | |
| 763 } | |
| 764 | |
| 765 return 0; | |
| 766 } | |
| 767 | |
| 768 int CUDTUnited::close(const UDTSOCKET u) | |
| 769 { | |
| 770 CUDTSocket* s = locate(u); | |
| 771 | |
| 772 if (NULL == s) | |
| 773 throw CUDTException(5, 4, 0); | |
| 774 | |
| 775 if (s->m_Status == LISTENING) | |
| 776 { | |
| 777 if (s->m_pUDT->m_bBroken) | |
| 778 return 0; | |
| 779 | |
| 780 s->m_TimeStamp = CTimer::getTime(); | |
| 781 s->m_pUDT->m_bBroken = true; | |
| 782 | |
| 783 // broadcast all "accept" waiting | |
| 784 #ifndef WIN32 | |
| 785 pthread_mutex_lock(&(s->m_AcceptLock)); | |
| 786 pthread_cond_broadcast(&(s->m_AcceptCond)); | |
| 787 pthread_mutex_unlock(&(s->m_AcceptLock)); | |
| 788 #else | |
| 789 SetEvent(s->m_AcceptCond); | |
| 790 #endif | |
| 791 | |
| 792 return 0; | |
| 793 } | |
| 794 | |
| 795 s->m_pUDT->close(); | |
| 796 | |
| 797 // synchronize with garbage collection. | |
| 798 CGuard cg(m_ControlLock); | |
| 799 | |
| 800 // since "s" is located before m_ControlLock, locate it again in case it beca
me invalid | |
| 801 map<UDTSOCKET, CUDTSocket*>::iterator i = m_Sockets.find(u); | |
| 802 if ((i == m_Sockets.end()) || (i->second->m_Status == CLOSED)) | |
| 803 return 0; | |
| 804 s = i->second; | |
| 805 | |
| 806 s->m_Status = CLOSED; | |
| 807 | |
| 808 // a socket will not be immediated removed when it is closed | |
| 809 // in order to prevent other methods from accessing invalid address | |
| 810 // a timer is started and the socket will be removed after approximately 1 se
cond | |
| 811 s->m_TimeStamp = CTimer::getTime(); | |
| 812 | |
| 813 m_Sockets.erase(s->m_SocketID); | |
| 814 m_ClosedSockets.insert(pair<UDTSOCKET, CUDTSocket*>(s->m_SocketID, s)); | |
| 815 | |
| 816 CTimer::triggerEvent(); | |
| 817 | |
| 818 return 0; | |
| 819 } | |
| 820 | |
| 821 int CUDTUnited::getpeername(const UDTSOCKET u, sockaddr* name, int* namelen) | |
| 822 { | |
| 823 if (CONNECTED != getStatus(u)) | |
| 824 throw CUDTException(2, 2, 0); | |
| 825 | |
| 826 CUDTSocket* s = locate(u); | |
| 827 | |
| 828 if (NULL == s) | |
| 829 throw CUDTException(5, 4, 0); | |
| 830 | |
| 831 if (!s->m_pUDT->m_bConnected || s->m_pUDT->m_bBroken) | |
| 832 throw CUDTException(2, 2, 0); | |
| 833 | |
| 834 if (AF_INET == s->m_iIPversion) | |
| 835 *namelen = sizeof(sockaddr_in); | |
| 836 else | |
| 837 *namelen = sizeof(sockaddr_in6); | |
| 838 | |
| 839 // copy address information of peer node | |
| 840 memcpy(name, s->m_pPeerAddr, *namelen); | |
| 841 | |
| 842 return 0; | |
| 843 } | |
| 844 | |
| 845 int CUDTUnited::getsockname(const UDTSOCKET u, sockaddr* name, int* namelen) | |
| 846 { | |
| 847 CUDTSocket* s = locate(u); | |
| 848 | |
| 849 if (NULL == s) | |
| 850 throw CUDTException(5, 4, 0); | |
| 851 | |
| 852 if (s->m_pUDT->m_bBroken) | |
| 853 throw CUDTException(5, 4, 0); | |
| 854 | |
| 855 if (INIT == s->m_Status) | |
| 856 throw CUDTException(2, 2, 0); | |
| 857 | |
| 858 if (AF_INET == s->m_iIPversion) | |
| 859 *namelen = sizeof(sockaddr_in); | |
| 860 else | |
| 861 *namelen = sizeof(sockaddr_in6); | |
| 862 | |
| 863 // copy address information of local node | |
| 864 memcpy(name, s->m_pSelfAddr, *namelen); | |
| 865 | |
| 866 return 0; | |
| 867 } | |
| 868 | |
| 869 int CUDTUnited::select(ud_set* readfds, ud_set* writefds, ud_set* exceptfds, con
st timeval* timeout) | |
| 870 { | |
| 871 uint64_t entertime = CTimer::getTime(); | |
| 872 | |
| 873 uint64_t to; | |
| 874 if (NULL == timeout) | |
| 875 to = 0xFFFFFFFFFFFFFFFFULL; | |
| 876 else | |
| 877 to = timeout->tv_sec * 1000000 + timeout->tv_usec; | |
| 878 | |
| 879 // initialize results | |
| 880 int count = 0; | |
| 881 set<UDTSOCKET> rs, ws, es; | |
| 882 | |
| 883 // retrieve related UDT sockets | |
| 884 vector<CUDTSocket*> ru, wu, eu; | |
| 885 CUDTSocket* s; | |
| 886 if (NULL != readfds) | |
| 887 for (set<UDTSOCKET>::iterator i1 = readfds->begin(); i1 != readfds->end();
++ i1) | |
| 888 { | |
| 889 if (BROKEN == getStatus(*i1)) | |
| 890 { | |
| 891 rs.insert(*i1); | |
| 892 ++ count; | |
| 893 } | |
| 894 else if (NULL == (s = locate(*i1))) | |
| 895 throw CUDTException(5, 4, 0); | |
| 896 else | |
| 897 ru.insert(ru.end(), s); | |
| 898 } | |
| 899 if (NULL != writefds) | |
| 900 for (set<UDTSOCKET>::iterator i2 = writefds->begin(); i2 != writefds->end(
); ++ i2) | |
| 901 { | |
| 902 if (BROKEN == getStatus(*i2)) | |
| 903 { | |
| 904 ws.insert(*i2); | |
| 905 ++ count; | |
| 906 } | |
| 907 else if (NULL == (s = locate(*i2))) | |
| 908 throw CUDTException(5, 4, 0); | |
| 909 else | |
| 910 wu.insert(wu.end(), s); | |
| 911 } | |
| 912 if (NULL != exceptfds) | |
| 913 for (set<UDTSOCKET>::iterator i3 = exceptfds->begin(); i3 != exceptfds->en
d(); ++ i3) | |
| 914 { | |
| 915 if (BROKEN == getStatus(*i3)) | |
| 916 { | |
| 917 es.insert(*i3); | |
| 918 ++ count; | |
| 919 } | |
| 920 else if (NULL == (s = locate(*i3))) | |
| 921 throw CUDTException(5, 4, 0); | |
| 922 else | |
| 923 eu.insert(eu.end(), s); | |
| 924 } | |
| 925 | |
| 926 do | |
| 927 { | |
| 928 // query read sockets | |
| 929 for (vector<CUDTSocket*>::iterator j1 = ru.begin(); j1 != ru.end(); ++ j1) | |
| 930 { | |
| 931 s = *j1; | |
| 932 | |
| 933 if ((s->m_pUDT->m_bConnected && (s->m_pUDT->m_pRcvBuffer->getRcvDataSiz
e() > 0) && ((s->m_pUDT->m_iSockType == UDT_STREAM) || (s->m_pUDT->m_pRcvBuffer-
>getRcvMsgNum() > 0))) | |
| 934 || (!s->m_pUDT->m_bListening && (s->m_pUDT->m_bBroken || !s->m_pUDT-
>m_bConnected)) | |
| 935 || (s->m_pUDT->m_bListening && (s->m_pQueuedSockets->size() > 0)) | |
| 936 || (s->m_Status == CLOSED)) | |
| 937 { | |
| 938 rs.insert(s->m_SocketID); | |
| 939 ++ count; | |
| 940 } | |
| 941 } | |
| 942 | |
| 943 // query write sockets | |
| 944 for (vector<CUDTSocket*>::iterator j2 = wu.begin(); j2 != wu.end(); ++ j2) | |
| 945 { | |
| 946 s = *j2; | |
| 947 | |
| 948 if ((s->m_pUDT->m_bConnected && (s->m_pUDT->m_pSndBuffer->getCurrBufSiz
e() < s->m_pUDT->m_iSndBufSize)) | |
| 949 || s->m_pUDT->m_bBroken || !s->m_pUDT->m_bConnected || (s->m_Status
== CLOSED)) | |
| 950 { | |
| 951 ws.insert(s->m_SocketID); | |
| 952 ++ count; | |
| 953 } | |
| 954 } | |
| 955 | |
| 956 // query exceptions on sockets | |
| 957 for (vector<CUDTSocket*>::iterator j3 = eu.begin(); j3 != eu.end(); ++ j3) | |
| 958 { | |
| 959 // check connection request status, not supported now | |
| 960 } | |
| 961 | |
| 962 if (0 < count) | |
| 963 break; | |
| 964 | |
| 965 CTimer::waitForEvent(); | |
| 966 } while (to > CTimer::getTime() - entertime); | |
| 967 | |
| 968 if (NULL != readfds) | |
| 969 *readfds = rs; | |
| 970 | |
| 971 if (NULL != writefds) | |
| 972 *writefds = ws; | |
| 973 | |
| 974 if (NULL != exceptfds) | |
| 975 *exceptfds = es; | |
| 976 | |
| 977 return count; | |
| 978 } | |
| 979 | |
| 980 int CUDTUnited::selectEx(const vector<UDTSOCKET>& fds, vector<UDTSOCKET>* readfd
s, vector<UDTSOCKET>* writefds, vector<UDTSOCKET>* exceptfds, int64_t msTimeOut) | |
| 981 { | |
| 982 uint64_t entertime = CTimer::getTime(); | |
| 983 | |
| 984 uint64_t to; | |
| 985 if (msTimeOut >= 0) | |
| 986 to = msTimeOut * 1000; | |
| 987 else | |
| 988 to = 0xFFFFFFFFFFFFFFFFULL; | |
| 989 | |
| 990 // initialize results | |
| 991 int count = 0; | |
| 992 if (NULL != readfds) | |
| 993 readfds->clear(); | |
| 994 if (NULL != writefds) | |
| 995 writefds->clear(); | |
| 996 if (NULL != exceptfds) | |
| 997 exceptfds->clear(); | |
| 998 | |
| 999 do | |
| 1000 { | |
| 1001 for (vector<UDTSOCKET>::const_iterator i = fds.begin(); i != fds.end(); ++
i) | |
| 1002 { | |
| 1003 CUDTSocket* s = locate(*i); | |
| 1004 | |
| 1005 if ((NULL == s) || s->m_pUDT->m_bBroken || (s->m_Status == CLOSED)) | |
| 1006 { | |
| 1007 if (NULL != exceptfds) | |
| 1008 { | |
| 1009 exceptfds->push_back(*i); | |
| 1010 ++ count; | |
| 1011 } | |
| 1012 continue; | |
| 1013 } | |
| 1014 | |
| 1015 if (NULL != readfds) | |
| 1016 { | |
| 1017 if ((s->m_pUDT->m_bConnected && (s->m_pUDT->m_pRcvBuffer->getRcvData
Size() > 0) && ((s->m_pUDT->m_iSockType == UDT_STREAM) || (s->m_pUDT->m_pRcvBuff
er->getRcvMsgNum() > 0))) | |
| 1018 || (s->m_pUDT->m_bListening && (s->m_pQueuedSockets->size() > 0))
) | |
| 1019 { | |
| 1020 readfds->push_back(s->m_SocketID); | |
| 1021 ++ count; | |
| 1022 } | |
| 1023 } | |
| 1024 | |
| 1025 if (NULL != writefds) | |
| 1026 { | |
| 1027 if (s->m_pUDT->m_bConnected && (s->m_pUDT->m_pSndBuffer->getCurrBufS
ize() < s->m_pUDT->m_iSndBufSize)) | |
| 1028 { | |
| 1029 writefds->push_back(s->m_SocketID); | |
| 1030 ++ count; | |
| 1031 } | |
| 1032 } | |
| 1033 } | |
| 1034 | |
| 1035 if (count > 0) | |
| 1036 break; | |
| 1037 | |
| 1038 CTimer::waitForEvent(); | |
| 1039 } while (to > CTimer::getTime() - entertime); | |
| 1040 | |
| 1041 return count; | |
| 1042 } | |
| 1043 | |
| 1044 int CUDTUnited::epoll_create() | |
| 1045 { | |
| 1046 return m_EPoll.create(); | |
| 1047 } | |
| 1048 | |
| 1049 int CUDTUnited::epoll_add_usock(const int eid, const UDTSOCKET u, const int* eve
nts) | |
| 1050 { | |
| 1051 CUDTSocket* s = locate(u); | |
| 1052 if (NULL != s) | |
| 1053 { | |
| 1054 s->m_pUDT->addEPoll(eid); | |
| 1055 } | |
| 1056 else | |
| 1057 { | |
| 1058 throw CUDTException(5, 4); | |
| 1059 } | |
| 1060 | |
| 1061 return m_EPoll.add_usock(eid, u, events); | |
| 1062 } | |
| 1063 | |
| 1064 int CUDTUnited::epoll_add_ssock(const int eid, const SYSSOCKET s, const int* eve
nts) | |
| 1065 { | |
| 1066 return m_EPoll.add_ssock(eid, s, events); | |
| 1067 } | |
| 1068 | |
| 1069 int CUDTUnited::epoll_remove_usock(const int eid, const UDTSOCKET u, const int*
events) | |
| 1070 { | |
| 1071 CUDTSocket* s = locate(u); | |
| 1072 if (NULL != s) | |
| 1073 { | |
| 1074 s->m_pUDT->removeEPoll(eid); | |
| 1075 } | |
| 1076 else | |
| 1077 { | |
| 1078 throw CUDTException(5, 4); | |
| 1079 } | |
| 1080 | |
| 1081 return m_EPoll.remove_usock(eid, u, events); | |
| 1082 } | |
| 1083 | |
| 1084 int CUDTUnited::epoll_remove_ssock(const int eid, const SYSSOCKET s, const int*
events) | |
| 1085 { | |
| 1086 return m_EPoll.remove_ssock(eid, s, events); | |
| 1087 } | |
| 1088 | |
| 1089 int CUDTUnited::epoll_wait(const int eid, set<UDTSOCKET>* readfds, set<UDTSOCKET
>* writefds, int64_t msTimeOut, set<SYSSOCKET>* lrfds, set<SYSSOCKET>* lwfds) | |
| 1090 { | |
| 1091 return m_EPoll.wait(eid, readfds, writefds, msTimeOut, lrfds, lwfds); | |
| 1092 } | |
| 1093 | |
| 1094 int CUDTUnited::epoll_release(const int eid) | |
| 1095 { | |
| 1096 return m_EPoll.release(eid); | |
| 1097 } | |
| 1098 | |
| 1099 CUDTSocket* CUDTUnited::locate(const UDTSOCKET u) | |
| 1100 { | |
| 1101 CGuard cg(m_ControlLock); | |
| 1102 | |
| 1103 map<UDTSOCKET, CUDTSocket*>::iterator i = m_Sockets.find(u); | |
| 1104 | |
| 1105 if ((i == m_Sockets.end()) || (i->second->m_Status == CLOSED)) | |
| 1106 return NULL; | |
| 1107 | |
| 1108 return i->second; | |
| 1109 } | |
| 1110 | |
| 1111 CUDTSocket* CUDTUnited::locate(const sockaddr* peer, const UDTSOCKET& id, const
int32_t& isn) | |
| 1112 { | |
| 1113 CGuard cg(m_ControlLock); | |
| 1114 | |
| 1115 map<int64_t, set<UDTSOCKET> >::iterator i = m_PeerRec.find((id << 30) + isn); | |
| 1116 if (i == m_PeerRec.end()) | |
| 1117 return NULL; | |
| 1118 | |
| 1119 for (set<UDTSOCKET>::iterator j = i->second.begin(); j != i->second.end(); ++
j) | |
| 1120 { | |
| 1121 map<UDTSOCKET, CUDTSocket*>::iterator k = m_Sockets.find(*j); | |
| 1122 // this socket might have been closed and moved m_ClosedSockets | |
| 1123 if (k == m_Sockets.end()) | |
| 1124 continue; | |
| 1125 | |
| 1126 if (CIPAddress::ipcmp(peer, k->second->m_pPeerAddr, k->second->m_iIPversio
n)) | |
| 1127 return k->second; | |
| 1128 } | |
| 1129 | |
| 1130 return NULL; | |
| 1131 } | |
| 1132 | |
| 1133 void CUDTUnited::checkBrokenSockets() | |
| 1134 { | |
| 1135 CGuard cg(m_ControlLock); | |
| 1136 | |
| 1137 // set of sockets To Be Closed and To Be Removed | |
| 1138 vector<UDTSOCKET> tbc; | |
| 1139 vector<UDTSOCKET> tbr; | |
| 1140 | |
| 1141 for (map<UDTSOCKET, CUDTSocket*>::iterator i = m_Sockets.begin(); i != m_Sock
ets.end(); ++ i) | |
| 1142 { | |
| 1143 // check broken connection | |
| 1144 if (i->second->m_pUDT->m_bBroken) | |
| 1145 { | |
| 1146 if (i->second->m_Status == LISTENING) | |
| 1147 { | |
| 1148 // for a listening socket, it should wait an extra 3 seconds in case
a client is connecting | |
| 1149 if (CTimer::getTime() - i->second->m_TimeStamp < 3000000) | |
| 1150 continue; | |
| 1151 } | |
| 1152 else if ((i->second->m_pUDT->m_pRcvBuffer->getRcvDataSize() > 0) && (i-
>second->m_pUDT->m_iBrokenCounter -- > 0)) | |
| 1153 { | |
| 1154 // if there is still data in the receiver buffer, wait longer | |
| 1155 continue; | |
| 1156 } | |
| 1157 | |
| 1158 //close broken connections and start removal timer | |
| 1159 i->second->m_Status = CLOSED; | |
| 1160 i->second->m_TimeStamp = CTimer::getTime(); | |
| 1161 tbc.push_back(i->first); | |
| 1162 m_ClosedSockets[i->first] = i->second; | |
| 1163 | |
| 1164 // remove from listener's queue | |
| 1165 map<UDTSOCKET, CUDTSocket*>::iterator ls = m_Sockets.find(i->second->m_
ListenSocket); | |
| 1166 if (ls == m_Sockets.end()) | |
| 1167 { | |
| 1168 ls = m_ClosedSockets.find(i->second->m_ListenSocket); | |
| 1169 if (ls == m_ClosedSockets.end()) | |
| 1170 continue; | |
| 1171 } | |
| 1172 | |
| 1173 CGuard::enterCS(ls->second->m_AcceptLock); | |
| 1174 ls->second->m_pQueuedSockets->erase(i->second->m_SocketID); | |
| 1175 ls->second->m_pAcceptSockets->erase(i->second->m_SocketID); | |
| 1176 CGuard::leaveCS(ls->second->m_AcceptLock); | |
| 1177 } | |
| 1178 } | |
| 1179 | |
| 1180 for (map<UDTSOCKET, CUDTSocket*>::iterator j = m_ClosedSockets.begin(); j !=
m_ClosedSockets.end(); ++ j) | |
| 1181 { | |
| 1182 // timeout 1 second to destroy a socket AND it has been removed from RcvUL
ist AND no linger data to send | |
| 1183 if ((CTimer::getTime() - j->second->m_TimeStamp > 1000000) && | |
| 1184 ((NULL == j->second->m_pUDT->m_pRNode) || !j->second->m_pUDT->m_pRNode
->m_bOnList) && | |
| 1185 ((NULL == j->second->m_pUDT->m_pSndBuffer) || (0 == j->second->m_pUDT-
>m_pSndBuffer->getCurrBufSize()) || (j->second->m_pUDT->m_ullLingerExpiration <=
CTimer::getTime()))) | |
| 1186 { | |
| 1187 tbr.push_back(j->first); | |
| 1188 } | |
| 1189 } | |
| 1190 | |
| 1191 // move closed sockets to the ClosedSockets structure | |
| 1192 for (vector<UDTSOCKET>::iterator k = tbc.begin(); k != tbc.end(); ++ k) | |
| 1193 m_Sockets.erase(*k); | |
| 1194 | |
| 1195 // remove those timeout sockets | |
| 1196 for (vector<UDTSOCKET>::iterator l = tbr.begin(); l != tbr.end(); ++ l) | |
| 1197 removeSocket(*l); | |
| 1198 } | |
| 1199 | |
| 1200 void CUDTUnited::removeSocket(const UDTSOCKET u) | |
| 1201 { | |
| 1202 map<UDTSOCKET, CUDTSocket*>::iterator i = m_ClosedSockets.find(u); | |
| 1203 | |
| 1204 // invalid socket ID | |
| 1205 if (i == m_ClosedSockets.end()) | |
| 1206 return; | |
| 1207 | |
| 1208 // decrease multiplexer reference count, and remove it if necessary | |
| 1209 const int mid = i->second->m_iMuxID; | |
| 1210 | |
| 1211 if (NULL != i->second->m_pQueuedSockets) | |
| 1212 { | |
| 1213 CGuard::enterCS(i->second->m_AcceptLock); | |
| 1214 | |
| 1215 // if it is a listener, close all un-accepted sockets in its queue and rem
ove them later | |
| 1216 for (set<UDTSOCKET>::iterator q = i->second->m_pQueuedSockets->begin(); q
!= i->second->m_pQueuedSockets->end(); ++ q) | |
| 1217 { | |
| 1218 m_Sockets[*q]->m_pUDT->m_bBroken = true; | |
| 1219 m_Sockets[*q]->m_pUDT->close(); | |
| 1220 m_Sockets[*q]->m_TimeStamp = CTimer::getTime(); | |
| 1221 m_Sockets[*q]->m_Status = CLOSED; | |
| 1222 m_ClosedSockets[*q] = m_Sockets[*q]; | |
| 1223 m_Sockets.erase(*q); | |
| 1224 } | |
| 1225 | |
| 1226 CGuard::leaveCS(i->second->m_AcceptLock); | |
| 1227 } | |
| 1228 | |
| 1229 // remove from peer rec | |
| 1230 map<int64_t, set<UDTSOCKET> >::iterator j = m_PeerRec.find((i->second->m_Peer
ID << 30) + i->second->m_iISN); | |
| 1231 if (j != m_PeerRec.end()) | |
| 1232 { | |
| 1233 j->second.erase(u); | |
| 1234 if (j->second.empty()) | |
| 1235 m_PeerRec.erase(j); | |
| 1236 } | |
| 1237 | |
| 1238 // delete this one | |
| 1239 i->second->m_pUDT->close(); | |
| 1240 delete i->second; | |
| 1241 m_ClosedSockets.erase(i); | |
| 1242 | |
| 1243 map<int, CMultiplexer>::iterator m; | |
| 1244 m = m_mMultiplexer.find(mid); | |
| 1245 if (m == m_mMultiplexer.end()) | |
| 1246 { | |
| 1247 //something is wrong!!! | |
| 1248 return; | |
| 1249 } | |
| 1250 | |
| 1251 m->second.m_iRefCount --; | |
| 1252 if (0 == m->second.m_iRefCount) | |
| 1253 { | |
| 1254 m->second.m_pChannel->close(); | |
| 1255 delete m->second.m_pSndQueue; | |
| 1256 delete m->second.m_pRcvQueue; | |
| 1257 delete m->second.m_pTimer; | |
| 1258 delete m->second.m_pChannel; | |
| 1259 m_mMultiplexer.erase(m); | |
| 1260 } | |
| 1261 } | |
| 1262 | |
| 1263 void CUDTUnited::setError(CUDTException* e) | |
| 1264 { | |
| 1265 #ifndef WIN32 | |
| 1266 delete (CUDTException*)pthread_getspecific(m_TLSError); | |
| 1267 pthread_setspecific(m_TLSError, e); | |
| 1268 #else | |
| 1269 CGuard tg(m_TLSLock); | |
| 1270 delete (CUDTException*)TlsGetValue(m_TLSError); | |
| 1271 TlsSetValue(m_TLSError, e); | |
| 1272 m_mTLSRecord[GetCurrentThreadId()] = e; | |
| 1273 #endif | |
| 1274 } | |
| 1275 | |
| 1276 CUDTException* CUDTUnited::getError() | |
| 1277 { | |
| 1278 #ifndef WIN32 | |
| 1279 if(NULL == pthread_getspecific(m_TLSError)) | |
| 1280 pthread_setspecific(m_TLSError, new CUDTException); | |
| 1281 return (CUDTException*)pthread_getspecific(m_TLSError); | |
| 1282 #else | |
| 1283 CGuard tg(m_TLSLock); | |
| 1284 if(NULL == TlsGetValue(m_TLSError)) | |
| 1285 { | |
| 1286 CUDTException* e = new CUDTException; | |
| 1287 TlsSetValue(m_TLSError, e); | |
| 1288 m_mTLSRecord[GetCurrentThreadId()] = e; | |
| 1289 } | |
| 1290 return (CUDTException*)TlsGetValue(m_TLSError); | |
| 1291 #endif | |
| 1292 } | |
| 1293 | |
| 1294 #ifdef WIN32 | |
| 1295 void CUDTUnited::checkTLSValue() | |
| 1296 { | |
| 1297 CGuard tg(m_TLSLock); | |
| 1298 | |
| 1299 vector<DWORD> tbr; | |
| 1300 for (map<DWORD, CUDTException*>::iterator i = m_mTLSRecord.begin(); i != m_mT
LSRecord.end(); ++ i) | |
| 1301 { | |
| 1302 HANDLE h = OpenThread(THREAD_QUERY_INFORMATION, FALSE, i->first); | |
| 1303 if (NULL == h) | |
| 1304 { | |
| 1305 tbr.insert(tbr.end(), i->first); | |
| 1306 break; | |
| 1307 } | |
| 1308 if (WAIT_OBJECT_0 == WaitForSingleObject(h, 0)) | |
| 1309 { | |
| 1310 delete i->second; | |
| 1311 tbr.insert(tbr.end(), i->first); | |
| 1312 } | |
| 1313 CloseHandle(h); | |
| 1314 } | |
| 1315 for (vector<DWORD>::iterator j = tbr.begin(); j != tbr.end(); ++ j) | |
| 1316 m_mTLSRecord.erase(*j); | |
| 1317 } | |
| 1318 #endif | |
| 1319 | |
| 1320 void CUDTUnited::updateMux(CUDTSocket* s, const sockaddr* addr, const UDPSOCKET*
udpsock) | |
| 1321 { | |
| 1322 CGuard cg(m_ControlLock); | |
| 1323 | |
| 1324 if ((s->m_pUDT->m_bReuseAddr) && (NULL != addr)) | |
| 1325 { | |
| 1326 int port = (AF_INET == s->m_pUDT->m_iIPversion) ? ntohs(((sockaddr_in*)add
r)->sin_port) : ntohs(((sockaddr_in6*)addr)->sin6_port); | |
| 1327 | |
| 1328 // find a reusable address | |
| 1329 for (map<int, CMultiplexer>::iterator i = m_mMultiplexer.begin(); i != m_m
Multiplexer.end(); ++ i) | |
| 1330 { | |
| 1331 if ((i->second.m_iIPversion == s->m_pUDT->m_iIPversion) && (i->second.m
_iMSS == s->m_pUDT->m_iMSS) && i->second.m_bReusable) | |
| 1332 { | |
| 1333 if (i->second.m_iPort == port) | |
| 1334 { | |
| 1335 // reuse the existing multiplexer | |
| 1336 ++ i->second.m_iRefCount; | |
| 1337 s->m_pUDT->m_pSndQueue = i->second.m_pSndQueue; | |
| 1338 s->m_pUDT->m_pRcvQueue = i->second.m_pRcvQueue; | |
| 1339 s->m_iMuxID = i->second.m_iID; | |
| 1340 return; | |
| 1341 } | |
| 1342 } | |
| 1343 } | |
| 1344 } | |
| 1345 | |
| 1346 // a new multiplexer is needed | |
| 1347 CMultiplexer m; | |
| 1348 m.m_iMSS = s->m_pUDT->m_iMSS; | |
| 1349 m.m_iIPversion = s->m_pUDT->m_iIPversion; | |
| 1350 m.m_iRefCount = 1; | |
| 1351 m.m_bReusable = s->m_pUDT->m_bReuseAddr; | |
| 1352 m.m_iID = s->m_SocketID; | |
| 1353 | |
| 1354 m.m_pChannel = new CChannel(s->m_pUDT->m_iIPversion); | |
| 1355 m.m_pChannel->setSndBufSize(s->m_pUDT->m_iUDPSndBufSize); | |
| 1356 m.m_pChannel->setRcvBufSize(s->m_pUDT->m_iUDPRcvBufSize); | |
| 1357 | |
| 1358 try | |
| 1359 { | |
| 1360 if (NULL != udpsock) | |
| 1361 m.m_pChannel->open(*udpsock); | |
| 1362 else | |
| 1363 m.m_pChannel->open(addr); | |
| 1364 } | |
| 1365 catch (CUDTException& e) | |
| 1366 { | |
| 1367 m.m_pChannel->close(); | |
| 1368 delete m.m_pChannel; | |
| 1369 throw e; | |
| 1370 } | |
| 1371 | |
| 1372 sockaddr* sa = (AF_INET == s->m_pUDT->m_iIPversion) ? (sockaddr*) new sockadd
r_in : (sockaddr*) new sockaddr_in6; | |
| 1373 m.m_pChannel->getSockAddr(sa); | |
| 1374 m.m_iPort = (AF_INET == s->m_pUDT->m_iIPversion) ? ntohs(((sockaddr_in*)sa)->
sin_port) : ntohs(((sockaddr_in6*)sa)->sin6_port); | |
| 1375 if (AF_INET == s->m_pUDT->m_iIPversion) delete (sockaddr_in*)sa; else delete
(sockaddr_in6*)sa; | |
| 1376 | |
| 1377 m.m_pTimer = new CTimer; | |
| 1378 | |
| 1379 m.m_pSndQueue = new CSndQueue; | |
| 1380 m.m_pSndQueue->init(m.m_pChannel, m.m_pTimer); | |
| 1381 m.m_pRcvQueue = new CRcvQueue; | |
| 1382 m.m_pRcvQueue->init(32, s->m_pUDT->m_iPayloadSize, m.m_iIPversion, 1024, m.m_
pChannel, m.m_pTimer); | |
| 1383 | |
| 1384 m_mMultiplexer[m.m_iID] = m; | |
| 1385 | |
| 1386 s->m_pUDT->m_pSndQueue = m.m_pSndQueue; | |
| 1387 s->m_pUDT->m_pRcvQueue = m.m_pRcvQueue; | |
| 1388 s->m_iMuxID = m.m_iID; | |
| 1389 } | |
| 1390 | |
| 1391 void CUDTUnited::updateMux(CUDTSocket* s, const CUDTSocket* ls) | |
| 1392 { | |
| 1393 CGuard cg(m_ControlLock); | |
| 1394 | |
| 1395 int port = (AF_INET == ls->m_iIPversion) ? ntohs(((sockaddr_in*)ls->m_pSelfAd
dr)->sin_port) : ntohs(((sockaddr_in6*)ls->m_pSelfAddr)->sin6_port); | |
| 1396 | |
| 1397 // find the listener's address | |
| 1398 for (map<int, CMultiplexer>::iterator i = m_mMultiplexer.begin(); i != m_mMul
tiplexer.end(); ++ i) | |
| 1399 { | |
| 1400 if (i->second.m_iPort == port) | |
| 1401 { | |
| 1402 // reuse the existing multiplexer | |
| 1403 ++ i->second.m_iRefCount; | |
| 1404 s->m_pUDT->m_pSndQueue = i->second.m_pSndQueue; | |
| 1405 s->m_pUDT->m_pRcvQueue = i->second.m_pRcvQueue; | |
| 1406 s->m_iMuxID = i->second.m_iID; | |
| 1407 return; | |
| 1408 } | |
| 1409 } | |
| 1410 } | |
| 1411 | |
| 1412 #ifndef WIN32 | |
| 1413 void* CUDTUnited::garbageCollect(void* p) | |
| 1414 #else | |
| 1415 DWORD WINAPI CUDTUnited::garbageCollect(LPVOID p) | |
| 1416 #endif | |
| 1417 { | |
| 1418 CUDTUnited* self = (CUDTUnited*)p; | |
| 1419 | |
| 1420 CGuard gcguard(self->m_GCStopLock); | |
| 1421 | |
| 1422 while (!self->m_bClosing) | |
| 1423 { | |
| 1424 self->checkBrokenSockets(); | |
| 1425 | |
| 1426 #ifdef WIN32 | |
| 1427 self->checkTLSValue(); | |
| 1428 #endif | |
| 1429 | |
| 1430 #ifndef WIN32 | |
| 1431 timeval now; | |
| 1432 timespec timeout; | |
| 1433 gettimeofday(&now, 0); | |
| 1434 timeout.tv_sec = now.tv_sec + 1; | |
| 1435 timeout.tv_nsec = now.tv_usec * 1000; | |
| 1436 | |
| 1437 pthread_cond_timedwait(&self->m_GCStopCond, &self->m_GCStopLock, &timeo
ut); | |
| 1438 #else | |
| 1439 WaitForSingleObject(self->m_GCStopCond, 1000); | |
| 1440 #endif | |
| 1441 } | |
| 1442 | |
| 1443 // remove all sockets and multiplexers | |
| 1444 CGuard::enterCS(self->m_ControlLock); | |
| 1445 for (map<UDTSOCKET, CUDTSocket*>::iterator i = self->m_Sockets.begin(); i !=
self->m_Sockets.end(); ++ i) | |
| 1446 { | |
| 1447 i->second->m_pUDT->m_bBroken = true; | |
| 1448 i->second->m_pUDT->close(); | |
| 1449 i->second->m_Status = CLOSED; | |
| 1450 i->second->m_TimeStamp = CTimer::getTime(); | |
| 1451 self->m_ClosedSockets[i->first] = i->second; | |
| 1452 | |
| 1453 // remove from listener's queue | |
| 1454 map<UDTSOCKET, CUDTSocket*>::iterator ls = self->m_Sockets.find(i->second-
>m_ListenSocket); | |
| 1455 if (ls == self->m_Sockets.end()) | |
| 1456 { | |
| 1457 ls = self->m_ClosedSockets.find(i->second->m_ListenSocket); | |
| 1458 if (ls == self->m_ClosedSockets.end()) | |
| 1459 continue; | |
| 1460 } | |
| 1461 | |
| 1462 CGuard::enterCS(ls->second->m_AcceptLock); | |
| 1463 ls->second->m_pQueuedSockets->erase(i->second->m_SocketID); | |
| 1464 ls->second->m_pAcceptSockets->erase(i->second->m_SocketID); | |
| 1465 CGuard::leaveCS(ls->second->m_AcceptLock); | |
| 1466 } | |
| 1467 self->m_Sockets.clear(); | |
| 1468 | |
| 1469 for (map<UDTSOCKET, CUDTSocket*>::iterator j = self->m_ClosedSockets.begin();
j != self->m_ClosedSockets.end(); ++ j) | |
| 1470 { | |
| 1471 j->second->m_TimeStamp = 0; | |
| 1472 } | |
| 1473 CGuard::leaveCS(self->m_ControlLock); | |
| 1474 | |
| 1475 while (true) | |
| 1476 { | |
| 1477 self->checkBrokenSockets(); | |
| 1478 | |
| 1479 CGuard::enterCS(self->m_ControlLock); | |
| 1480 bool empty = self->m_ClosedSockets.empty(); | |
| 1481 CGuard::leaveCS(self->m_ControlLock); | |
| 1482 | |
| 1483 if (empty) | |
| 1484 break; | |
| 1485 | |
| 1486 CTimer::sleep(); | |
| 1487 } | |
| 1488 | |
| 1489 #ifndef WIN32 | |
| 1490 return NULL; | |
| 1491 #else | |
| 1492 return 0; | |
| 1493 #endif | |
| 1494 } | |
| 1495 | |
| 1496 //////////////////////////////////////////////////////////////////////////////// | |
| 1497 | |
| 1498 int CUDT::startup() | |
| 1499 { | |
| 1500 return s_UDTUnited.startup(); | |
| 1501 } | |
| 1502 | |
| 1503 int CUDT::cleanup() | |
| 1504 { | |
| 1505 return s_UDTUnited.cleanup(); | |
| 1506 } | |
| 1507 | |
| 1508 UDTSOCKET CUDT::socket(int af, int type, int) | |
| 1509 { | |
| 1510 if (!s_UDTUnited.m_bGCStatus) | |
| 1511 s_UDTUnited.startup(); | |
| 1512 | |
| 1513 try | |
| 1514 { | |
| 1515 return s_UDTUnited.newSocket(af, type); | |
| 1516 } | |
| 1517 catch (CUDTException& e) | |
| 1518 { | |
| 1519 s_UDTUnited.setError(new CUDTException(e)); | |
| 1520 return INVALID_SOCK; | |
| 1521 } | |
| 1522 catch (bad_alloc&) | |
| 1523 { | |
| 1524 s_UDTUnited.setError(new CUDTException(3, 2, 0)); | |
| 1525 return INVALID_SOCK; | |
| 1526 } | |
| 1527 catch (...) | |
| 1528 { | |
| 1529 s_UDTUnited.setError(new CUDTException(-1, 0, 0)); | |
| 1530 return INVALID_SOCK; | |
| 1531 } | |
| 1532 } | |
| 1533 | |
| 1534 int CUDT::bind(UDTSOCKET u, const sockaddr* name, int namelen) | |
| 1535 { | |
| 1536 try | |
| 1537 { | |
| 1538 return s_UDTUnited.bind(u, name, namelen); | |
| 1539 } | |
| 1540 catch (CUDTException& e) | |
| 1541 { | |
| 1542 s_UDTUnited.setError(new CUDTException(e)); | |
| 1543 return ERROR; | |
| 1544 } | |
| 1545 catch (bad_alloc&) | |
| 1546 { | |
| 1547 s_UDTUnited.setError(new CUDTException(3, 2, 0)); | |
| 1548 return ERROR; | |
| 1549 } | |
| 1550 catch (...) | |
| 1551 { | |
| 1552 s_UDTUnited.setError(new CUDTException(-1, 0, 0)); | |
| 1553 return ERROR; | |
| 1554 } | |
| 1555 } | |
| 1556 | |
| 1557 int CUDT::bind(UDTSOCKET u, UDPSOCKET udpsock) | |
| 1558 { | |
| 1559 try | |
| 1560 { | |
| 1561 return s_UDTUnited.bind(u, udpsock); | |
| 1562 } | |
| 1563 catch (CUDTException& e) | |
| 1564 { | |
| 1565 s_UDTUnited.setError(new CUDTException(e)); | |
| 1566 return ERROR; | |
| 1567 } | |
| 1568 catch (bad_alloc&) | |
| 1569 { | |
| 1570 s_UDTUnited.setError(new CUDTException(3, 2, 0)); | |
| 1571 return ERROR; | |
| 1572 } | |
| 1573 catch (...) | |
| 1574 { | |
| 1575 s_UDTUnited.setError(new CUDTException(-1, 0, 0)); | |
| 1576 return ERROR; | |
| 1577 } | |
| 1578 } | |
| 1579 | |
| 1580 int CUDT::listen(UDTSOCKET u, int backlog) | |
| 1581 { | |
| 1582 try | |
| 1583 { | |
| 1584 return s_UDTUnited.listen(u, backlog); | |
| 1585 } | |
| 1586 catch (CUDTException& e) | |
| 1587 { | |
| 1588 s_UDTUnited.setError(new CUDTException(e)); | |
| 1589 return ERROR; | |
| 1590 } | |
| 1591 catch (bad_alloc&) | |
| 1592 { | |
| 1593 s_UDTUnited.setError(new CUDTException(3, 2, 0)); | |
| 1594 return ERROR; | |
| 1595 } | |
| 1596 catch (...) | |
| 1597 { | |
| 1598 s_UDTUnited.setError(new CUDTException(-1, 0, 0)); | |
| 1599 return ERROR; | |
| 1600 } | |
| 1601 } | |
| 1602 | |
| 1603 UDTSOCKET CUDT::accept(UDTSOCKET u, sockaddr* addr, int* addrlen) | |
| 1604 { | |
| 1605 try | |
| 1606 { | |
| 1607 return s_UDTUnited.accept(u, addr, addrlen); | |
| 1608 } | |
| 1609 catch (CUDTException& e) | |
| 1610 { | |
| 1611 s_UDTUnited.setError(new CUDTException(e)); | |
| 1612 return INVALID_SOCK; | |
| 1613 } | |
| 1614 catch (...) | |
| 1615 { | |
| 1616 s_UDTUnited.setError(new CUDTException(-1, 0, 0)); | |
| 1617 return INVALID_SOCK; | |
| 1618 } | |
| 1619 } | |
| 1620 | |
| 1621 int CUDT::connect(UDTSOCKET u, const sockaddr* name, int namelen) | |
| 1622 { | |
| 1623 try | |
| 1624 { | |
| 1625 return s_UDTUnited.connect(u, name, namelen); | |
| 1626 } | |
| 1627 catch (CUDTException e) | |
| 1628 { | |
| 1629 s_UDTUnited.setError(new CUDTException(e)); | |
| 1630 return ERROR; | |
| 1631 } | |
| 1632 catch (bad_alloc&) | |
| 1633 { | |
| 1634 s_UDTUnited.setError(new CUDTException(3, 2, 0)); | |
| 1635 return ERROR; | |
| 1636 } | |
| 1637 catch (...) | |
| 1638 { | |
| 1639 s_UDTUnited.setError(new CUDTException(-1, 0, 0)); | |
| 1640 return ERROR; | |
| 1641 } | |
| 1642 } | |
| 1643 | |
| 1644 int CUDT::close(UDTSOCKET u) | |
| 1645 { | |
| 1646 try | |
| 1647 { | |
| 1648 return s_UDTUnited.close(u); | |
| 1649 } | |
| 1650 catch (CUDTException e) | |
| 1651 { | |
| 1652 s_UDTUnited.setError(new CUDTException(e)); | |
| 1653 return ERROR; | |
| 1654 } | |
| 1655 catch (...) | |
| 1656 { | |
| 1657 s_UDTUnited.setError(new CUDTException(-1, 0, 0)); | |
| 1658 return ERROR; | |
| 1659 } | |
| 1660 } | |
| 1661 | |
| 1662 int CUDT::getpeername(UDTSOCKET u, sockaddr* name, int* namelen) | |
| 1663 { | |
| 1664 try | |
| 1665 { | |
| 1666 return s_UDTUnited.getpeername(u, name, namelen); | |
| 1667 } | |
| 1668 catch (CUDTException e) | |
| 1669 { | |
| 1670 s_UDTUnited.setError(new CUDTException(e)); | |
| 1671 return ERROR; | |
| 1672 } | |
| 1673 catch (...) | |
| 1674 { | |
| 1675 s_UDTUnited.setError(new CUDTException(-1, 0, 0)); | |
| 1676 return ERROR; | |
| 1677 } | |
| 1678 } | |
| 1679 | |
| 1680 int CUDT::getsockname(UDTSOCKET u, sockaddr* name, int* namelen) | |
| 1681 { | |
| 1682 try | |
| 1683 { | |
| 1684 return s_UDTUnited.getsockname(u, name, namelen);; | |
| 1685 } | |
| 1686 catch (CUDTException e) | |
| 1687 { | |
| 1688 s_UDTUnited.setError(new CUDTException(e)); | |
| 1689 return ERROR; | |
| 1690 } | |
| 1691 catch (...) | |
| 1692 { | |
| 1693 s_UDTUnited.setError(new CUDTException(-1, 0, 0)); | |
| 1694 return ERROR; | |
| 1695 } | |
| 1696 } | |
| 1697 | |
| 1698 int CUDT::getsockopt(UDTSOCKET u, int, UDTOpt optname, void* optval, int* optlen
) | |
| 1699 { | |
| 1700 try | |
| 1701 { | |
| 1702 CUDT* udt = s_UDTUnited.lookup(u); | |
| 1703 udt->getOpt(optname, optval, *optlen); | |
| 1704 return 0; | |
| 1705 } | |
| 1706 catch (CUDTException e) | |
| 1707 { | |
| 1708 s_UDTUnited.setError(new CUDTException(e)); | |
| 1709 return ERROR; | |
| 1710 } | |
| 1711 catch (...) | |
| 1712 { | |
| 1713 s_UDTUnited.setError(new CUDTException(-1, 0, 0)); | |
| 1714 return ERROR; | |
| 1715 } | |
| 1716 } | |
| 1717 | |
| 1718 int CUDT::setsockopt(UDTSOCKET u, int, UDTOpt optname, const void* optval, int o
ptlen) | |
| 1719 { | |
| 1720 try | |
| 1721 { | |
| 1722 CUDT* udt = s_UDTUnited.lookup(u); | |
| 1723 udt->setOpt(optname, optval, optlen); | |
| 1724 return 0; | |
| 1725 } | |
| 1726 catch (CUDTException e) | |
| 1727 { | |
| 1728 s_UDTUnited.setError(new CUDTException(e)); | |
| 1729 return ERROR; | |
| 1730 } | |
| 1731 catch (...) | |
| 1732 { | |
| 1733 s_UDTUnited.setError(new CUDTException(-1, 0, 0)); | |
| 1734 return ERROR; | |
| 1735 } | |
| 1736 } | |
| 1737 | |
| 1738 int CUDT::send(UDTSOCKET u, const char* buf, int len, int) | |
| 1739 { | |
| 1740 try | |
| 1741 { | |
| 1742 CUDT* udt = s_UDTUnited.lookup(u); | |
| 1743 return udt->send((char*)buf, len); | |
| 1744 } | |
| 1745 catch (CUDTException e) | |
| 1746 { | |
| 1747 s_UDTUnited.setError(new CUDTException(e)); | |
| 1748 return ERROR; | |
| 1749 } | |
| 1750 catch (bad_alloc&) | |
| 1751 { | |
| 1752 s_UDTUnited.setError(new CUDTException(3, 2, 0)); | |
| 1753 return ERROR; | |
| 1754 } | |
| 1755 catch (...) | |
| 1756 { | |
| 1757 s_UDTUnited.setError(new CUDTException(-1, 0, 0)); | |
| 1758 return ERROR; | |
| 1759 } | |
| 1760 } | |
| 1761 | |
| 1762 int CUDT::recv(UDTSOCKET u, char* buf, int len, int) | |
| 1763 { | |
| 1764 try | |
| 1765 { | |
| 1766 CUDT* udt = s_UDTUnited.lookup(u); | |
| 1767 return udt->recv(buf, len); | |
| 1768 } | |
| 1769 catch (CUDTException e) | |
| 1770 { | |
| 1771 s_UDTUnited.setError(new CUDTException(e)); | |
| 1772 return ERROR; | |
| 1773 } | |
| 1774 catch (...) | |
| 1775 { | |
| 1776 s_UDTUnited.setError(new CUDTException(-1, 0, 0)); | |
| 1777 return ERROR; | |
| 1778 } | |
| 1779 } | |
| 1780 | |
| 1781 int CUDT::sendmsg(UDTSOCKET u, const char* buf, int len, int ttl, bool inorder) | |
| 1782 { | |
| 1783 try | |
| 1784 { | |
| 1785 CUDT* udt = s_UDTUnited.lookup(u); | |
| 1786 return udt->sendmsg((char*)buf, len, ttl, inorder); | |
| 1787 } | |
| 1788 catch (CUDTException e) | |
| 1789 { | |
| 1790 s_UDTUnited.setError(new CUDTException(e)); | |
| 1791 return ERROR; | |
| 1792 } | |
| 1793 catch (bad_alloc&) | |
| 1794 { | |
| 1795 s_UDTUnited.setError(new CUDTException(3, 2, 0)); | |
| 1796 return ERROR; | |
| 1797 } | |
| 1798 catch (...) | |
| 1799 { | |
| 1800 s_UDTUnited.setError(new CUDTException(-1, 0, 0)); | |
| 1801 return ERROR; | |
| 1802 } | |
| 1803 } | |
| 1804 | |
| 1805 int CUDT::recvmsg(UDTSOCKET u, char* buf, int len) | |
| 1806 { | |
| 1807 try | |
| 1808 { | |
| 1809 CUDT* udt = s_UDTUnited.lookup(u); | |
| 1810 return udt->recvmsg(buf, len); | |
| 1811 } | |
| 1812 catch (CUDTException e) | |
| 1813 { | |
| 1814 s_UDTUnited.setError(new CUDTException(e)); | |
| 1815 return ERROR; | |
| 1816 } | |
| 1817 catch (...) | |
| 1818 { | |
| 1819 s_UDTUnited.setError(new CUDTException(-1, 0, 0)); | |
| 1820 return ERROR; | |
| 1821 } | |
| 1822 } | |
| 1823 | |
| 1824 int64_t CUDT::sendfile(UDTSOCKET u, fstream& ifs, int64_t& offset, const int64_t
& size, const int& block) | |
| 1825 { | |
| 1826 try | |
| 1827 { | |
| 1828 CUDT* udt = s_UDTUnited.lookup(u); | |
| 1829 return udt->sendfile(ifs, offset, size, block); | |
| 1830 } | |
| 1831 catch (CUDTException e) | |
| 1832 { | |
| 1833 s_UDTUnited.setError(new CUDTException(e)); | |
| 1834 return ERROR; | |
| 1835 } | |
| 1836 catch (bad_alloc&) | |
| 1837 { | |
| 1838 s_UDTUnited.setError(new CUDTException(3, 2, 0)); | |
| 1839 return ERROR; | |
| 1840 } | |
| 1841 catch (...) | |
| 1842 { | |
| 1843 s_UDTUnited.setError(new CUDTException(-1, 0, 0)); | |
| 1844 return ERROR; | |
| 1845 } | |
| 1846 } | |
| 1847 | |
| 1848 int64_t CUDT::recvfile(UDTSOCKET u, fstream& ofs, int64_t& offset, const int64_t
& size, const int& block) | |
| 1849 { | |
| 1850 try | |
| 1851 { | |
| 1852 CUDT* udt = s_UDTUnited.lookup(u); | |
| 1853 return udt->recvfile(ofs, offset, size, block); | |
| 1854 } | |
| 1855 catch (CUDTException e) | |
| 1856 { | |
| 1857 s_UDTUnited.setError(new CUDTException(e)); | |
| 1858 return ERROR; | |
| 1859 } | |
| 1860 catch (...) | |
| 1861 { | |
| 1862 s_UDTUnited.setError(new CUDTException(-1, 0, 0)); | |
| 1863 return ERROR; | |
| 1864 } | |
| 1865 } | |
| 1866 | |
| 1867 int CUDT::select(int, ud_set* readfds, ud_set* writefds, ud_set* exceptfds, cons
t timeval* timeout) | |
| 1868 { | |
| 1869 if ((NULL == readfds) && (NULL == writefds) && (NULL == exceptfds)) | |
| 1870 { | |
| 1871 s_UDTUnited.setError(new CUDTException(5, 3, 0)); | |
| 1872 return ERROR; | |
| 1873 } | |
| 1874 | |
| 1875 try | |
| 1876 { | |
| 1877 return s_UDTUnited.select(readfds, writefds, exceptfds, timeout); | |
| 1878 } | |
| 1879 catch (CUDTException e) | |
| 1880 { | |
| 1881 s_UDTUnited.setError(new CUDTException(e)); | |
| 1882 return ERROR; | |
| 1883 } | |
| 1884 catch (bad_alloc&) | |
| 1885 { | |
| 1886 s_UDTUnited.setError(new CUDTException(3, 2, 0)); | |
| 1887 return ERROR; | |
| 1888 } | |
| 1889 catch (...) | |
| 1890 { | |
| 1891 s_UDTUnited.setError(new CUDTException(-1, 0, 0)); | |
| 1892 return ERROR; | |
| 1893 } | |
| 1894 } | |
| 1895 | |
| 1896 int CUDT::selectEx(const vector<UDTSOCKET>& fds, vector<UDTSOCKET>* readfds, vec
tor<UDTSOCKET>* writefds, vector<UDTSOCKET>* exceptfds, int64_t msTimeOut) | |
| 1897 { | |
| 1898 if ((NULL == readfds) && (NULL == writefds) && (NULL == exceptfds)) | |
| 1899 { | |
| 1900 s_UDTUnited.setError(new CUDTException(5, 3, 0)); | |
| 1901 return ERROR; | |
| 1902 } | |
| 1903 | |
| 1904 try | |
| 1905 { | |
| 1906 return s_UDTUnited.selectEx(fds, readfds, writefds, exceptfds, msTimeOut); | |
| 1907 } | |
| 1908 catch (CUDTException e) | |
| 1909 { | |
| 1910 s_UDTUnited.setError(new CUDTException(e)); | |
| 1911 return ERROR; | |
| 1912 } | |
| 1913 catch (bad_alloc&) | |
| 1914 { | |
| 1915 s_UDTUnited.setError(new CUDTException(3, 2, 0)); | |
| 1916 return ERROR; | |
| 1917 } | |
| 1918 catch (...) | |
| 1919 { | |
| 1920 s_UDTUnited.setError(new CUDTException(-1, 0, 0)); | |
| 1921 return ERROR; | |
| 1922 } | |
| 1923 } | |
| 1924 | |
| 1925 int CUDT::epoll_create() | |
| 1926 { | |
| 1927 try | |
| 1928 { | |
| 1929 return s_UDTUnited.epoll_create(); | |
| 1930 } | |
| 1931 catch (CUDTException e) | |
| 1932 { | |
| 1933 s_UDTUnited.setError(new CUDTException(e)); | |
| 1934 return ERROR; | |
| 1935 } | |
| 1936 catch (...) | |
| 1937 { | |
| 1938 s_UDTUnited.setError(new CUDTException(-1, 0, 0)); | |
| 1939 return ERROR; | |
| 1940 } | |
| 1941 } | |
| 1942 | |
| 1943 int CUDT::epoll_add_usock(const int eid, const UDTSOCKET u, const int* events) | |
| 1944 { | |
| 1945 try | |
| 1946 { | |
| 1947 return s_UDTUnited.epoll_add_usock(eid, u, events); | |
| 1948 } | |
| 1949 catch (CUDTException e) | |
| 1950 { | |
| 1951 s_UDTUnited.setError(new CUDTException(e)); | |
| 1952 return ERROR; | |
| 1953 } | |
| 1954 catch (...) | |
| 1955 { | |
| 1956 s_UDTUnited.setError(new CUDTException(-1, 0, 0)); | |
| 1957 return ERROR; | |
| 1958 } | |
| 1959 } | |
| 1960 | |
| 1961 int CUDT::epoll_add_ssock(const int eid, const SYSSOCKET s, const int* events) | |
| 1962 { | |
| 1963 try | |
| 1964 { | |
| 1965 return s_UDTUnited.epoll_add_ssock(eid, s, events); | |
| 1966 } | |
| 1967 catch (CUDTException e) | |
| 1968 { | |
| 1969 s_UDTUnited.setError(new CUDTException(e)); | |
| 1970 return ERROR; | |
| 1971 } | |
| 1972 catch (...) | |
| 1973 { | |
| 1974 s_UDTUnited.setError(new CUDTException(-1, 0, 0)); | |
| 1975 return ERROR; | |
| 1976 } | |
| 1977 } | |
| 1978 | |
| 1979 int CUDT::epoll_remove_usock(const int eid, const UDTSOCKET u, const int* events
) | |
| 1980 { | |
| 1981 try | |
| 1982 { | |
| 1983 return s_UDTUnited.epoll_remove_usock(eid, u, events); | |
| 1984 } | |
| 1985 catch (CUDTException e) | |
| 1986 { | |
| 1987 s_UDTUnited.setError(new CUDTException(e)); | |
| 1988 return ERROR; | |
| 1989 } | |
| 1990 catch (...) | |
| 1991 { | |
| 1992 s_UDTUnited.setError(new CUDTException(-1, 0, 0)); | |
| 1993 return ERROR; | |
| 1994 } | |
| 1995 } | |
| 1996 | |
| 1997 int CUDT::epoll_remove_ssock(const int eid, const SYSSOCKET s, const int* events
) | |
| 1998 { | |
| 1999 try | |
| 2000 { | |
| 2001 return s_UDTUnited.epoll_remove_ssock(eid, s, events); | |
| 2002 } | |
| 2003 catch (CUDTException e) | |
| 2004 { | |
| 2005 s_UDTUnited.setError(new CUDTException(e)); | |
| 2006 return ERROR; | |
| 2007 } | |
| 2008 catch (...) | |
| 2009 { | |
| 2010 s_UDTUnited.setError(new CUDTException(-1, 0, 0)); | |
| 2011 return ERROR; | |
| 2012 } | |
| 2013 } | |
| 2014 | |
| 2015 int CUDT::epoll_wait(const int eid, set<UDTSOCKET>* readfds, set<UDTSOCKET>* wri
tefds, int64_t msTimeOut, set<SYSSOCKET>* lrfds, set<SYSSOCKET>* lwfds) | |
| 2016 { | |
| 2017 try | |
| 2018 { | |
| 2019 return s_UDTUnited.epoll_wait(eid, readfds, writefds, msTimeOut, lrfds, lw
fds); | |
| 2020 } | |
| 2021 catch (CUDTException e) | |
| 2022 { | |
| 2023 s_UDTUnited.setError(new CUDTException(e)); | |
| 2024 return ERROR; | |
| 2025 } | |
| 2026 catch (...) | |
| 2027 { | |
| 2028 s_UDTUnited.setError(new CUDTException(-1, 0, 0)); | |
| 2029 return ERROR; | |
| 2030 } | |
| 2031 } | |
| 2032 | |
| 2033 int CUDT::epoll_release(const int eid) | |
| 2034 { | |
| 2035 try | |
| 2036 { | |
| 2037 return s_UDTUnited.epoll_release(eid); | |
| 2038 } | |
| 2039 catch (CUDTException e) | |
| 2040 { | |
| 2041 s_UDTUnited.setError(new CUDTException(e)); | |
| 2042 return ERROR; | |
| 2043 } | |
| 2044 catch (...) | |
| 2045 { | |
| 2046 s_UDTUnited.setError(new CUDTException(-1, 0, 0)); | |
| 2047 return ERROR; | |
| 2048 } | |
| 2049 } | |
| 2050 | |
| 2051 CUDTException& CUDT::getlasterror() | |
| 2052 { | |
| 2053 return *s_UDTUnited.getError(); | |
| 2054 } | |
| 2055 | |
| 2056 int CUDT::perfmon(UDTSOCKET u, CPerfMon* perf, bool clear) | |
| 2057 { | |
| 2058 try | |
| 2059 { | |
| 2060 CUDT* udt = s_UDTUnited.lookup(u); | |
| 2061 udt->sample(perf, clear); | |
| 2062 return 0; | |
| 2063 } | |
| 2064 catch (CUDTException e) | |
| 2065 { | |
| 2066 s_UDTUnited.setError(new CUDTException(e)); | |
| 2067 return ERROR; | |
| 2068 } | |
| 2069 catch (...) | |
| 2070 { | |
| 2071 s_UDTUnited.setError(new CUDTException(-1, 0, 0)); | |
| 2072 return ERROR; | |
| 2073 } | |
| 2074 } | |
| 2075 | |
| 2076 CUDT* CUDT::getUDTHandle(UDTSOCKET u) | |
| 2077 { | |
| 2078 try | |
| 2079 { | |
| 2080 return s_UDTUnited.lookup(u); | |
| 2081 } | |
| 2082 catch (...) | |
| 2083 { | |
| 2084 return NULL; | |
| 2085 } | |
| 2086 } | |
| 2087 | |
| 2088 UDTSTATUS CUDT::getsockstate(UDTSOCKET u) | |
| 2089 { | |
| 2090 try | |
| 2091 { | |
| 2092 return s_UDTUnited.getStatus(u); | |
| 2093 } | |
| 2094 catch (...) | |
| 2095 { | |
| 2096 s_UDTUnited.setError(new CUDTException(-1, 0, 0)); | |
| 2097 return NONEXIST; | |
| 2098 } | |
| 2099 } | |
| 2100 | |
| 2101 | |
| 2102 //////////////////////////////////////////////////////////////////////////////// | |
| 2103 | |
| 2104 namespace UDT | |
| 2105 { | |
| 2106 | |
| 2107 int startup() | |
| 2108 { | |
| 2109 return CUDT::startup(); | |
| 2110 } | |
| 2111 | |
| 2112 int cleanup() | |
| 2113 { | |
| 2114 return CUDT::cleanup(); | |
| 2115 } | |
| 2116 | |
| 2117 UDTSOCKET socket(int af, int type, int protocol) | |
| 2118 { | |
| 2119 return CUDT::socket(af, type, protocol); | |
| 2120 } | |
| 2121 | |
| 2122 int bind(UDTSOCKET u, const struct sockaddr* name, int namelen) | |
| 2123 { | |
| 2124 return CUDT::bind(u, name, namelen); | |
| 2125 } | |
| 2126 | |
| 2127 int bind(UDTSOCKET u, UDPSOCKET udpsock) | |
| 2128 { | |
| 2129 return CUDT::bind(u, udpsock); | |
| 2130 } | |
| 2131 | |
| 2132 int listen(UDTSOCKET u, int backlog) | |
| 2133 { | |
| 2134 return CUDT::listen(u, backlog); | |
| 2135 } | |
| 2136 | |
| 2137 UDTSOCKET accept(UDTSOCKET u, struct sockaddr* addr, int* addrlen) | |
| 2138 { | |
| 2139 return CUDT::accept(u, addr, addrlen); | |
| 2140 } | |
| 2141 | |
| 2142 int connect(UDTSOCKET u, const struct sockaddr* name, int namelen) | |
| 2143 { | |
| 2144 return CUDT::connect(u, name, namelen); | |
| 2145 } | |
| 2146 | |
| 2147 int close(UDTSOCKET u) | |
| 2148 { | |
| 2149 return CUDT::close(u); | |
| 2150 } | |
| 2151 | |
| 2152 int getpeername(UDTSOCKET u, struct sockaddr* name, int* namelen) | |
| 2153 { | |
| 2154 return CUDT::getpeername(u, name, namelen); | |
| 2155 } | |
| 2156 | |
| 2157 int getsockname(UDTSOCKET u, struct sockaddr* name, int* namelen) | |
| 2158 { | |
| 2159 return CUDT::getsockname(u, name, namelen); | |
| 2160 } | |
| 2161 | |
| 2162 int getsockopt(UDTSOCKET u, int level, SOCKOPT optname, void* optval, int* optle
n) | |
| 2163 { | |
| 2164 return CUDT::getsockopt(u, level, optname, optval, optlen); | |
| 2165 } | |
| 2166 | |
| 2167 int setsockopt(UDTSOCKET u, int level, SOCKOPT optname, const void* optval, int
optlen) | |
| 2168 { | |
| 2169 return CUDT::setsockopt(u, level, optname, optval, optlen); | |
| 2170 } | |
| 2171 | |
| 2172 int send(UDTSOCKET u, const char* buf, int len, int flags) | |
| 2173 { | |
| 2174 return CUDT::send(u, buf, len, flags); | |
| 2175 } | |
| 2176 | |
| 2177 int recv(UDTSOCKET u, char* buf, int len, int flags) | |
| 2178 { | |
| 2179 return CUDT::recv(u, buf, len, flags); | |
| 2180 } | |
| 2181 | |
| 2182 int sendmsg(UDTSOCKET u, const char* buf, int len, int ttl, bool inorder) | |
| 2183 { | |
| 2184 return CUDT::sendmsg(u, buf, len, ttl, inorder); | |
| 2185 } | |
| 2186 | |
| 2187 int recvmsg(UDTSOCKET u, char* buf, int len) | |
| 2188 { | |
| 2189 return CUDT::recvmsg(u, buf, len); | |
| 2190 } | |
| 2191 | |
| 2192 int64_t sendfile(UDTSOCKET u, fstream& ifs, int64_t& offset, int64_t size, int b
lock) | |
| 2193 { | |
| 2194 return CUDT::sendfile(u, ifs, offset, size, block); | |
| 2195 } | |
| 2196 | |
| 2197 int64_t recvfile(UDTSOCKET u, fstream& ofs, int64_t& offset, int64_t size, int b
lock) | |
| 2198 { | |
| 2199 return CUDT::recvfile(u, ofs, offset, size, block); | |
| 2200 } | |
| 2201 | |
| 2202 int select(int nfds, UDSET* readfds, UDSET* writefds, UDSET* exceptfds, const st
ruct timeval* timeout) | |
| 2203 { | |
| 2204 return CUDT::select(nfds, readfds, writefds, exceptfds, timeout); | |
| 2205 } | |
| 2206 | |
| 2207 int selectEx(const vector<UDTSOCKET>& fds, vector<UDTSOCKET>* readfds, vector<UD
TSOCKET>* writefds, vector<UDTSOCKET>* exceptfds, int64_t msTimeOut) | |
| 2208 { | |
| 2209 return CUDT::selectEx(fds, readfds, writefds, exceptfds, msTimeOut); | |
| 2210 } | |
| 2211 | |
| 2212 int epoll_create() | |
| 2213 { | |
| 2214 return CUDT::epoll_create(); | |
| 2215 } | |
| 2216 | |
| 2217 int epoll_add_usock(const int eid, const UDTSOCKET u, const int* events) | |
| 2218 { | |
| 2219 return CUDT::epoll_add_usock(eid, u, events); | |
| 2220 } | |
| 2221 | |
| 2222 int epoll_add_ssock(const int eid, const SYSSOCKET s, const int* events) | |
| 2223 { | |
| 2224 return CUDT::epoll_add_ssock(eid, s, events); | |
| 2225 } | |
| 2226 | |
| 2227 int epoll_remove_usock(const int eid, const UDTSOCKET u, const int* events) | |
| 2228 { | |
| 2229 return CUDT::epoll_remove_usock(eid, u, events); | |
| 2230 } | |
| 2231 | |
| 2232 int epoll_remove_ssock(const int eid, const SYSSOCKET s, const int* events) | |
| 2233 { | |
| 2234 return CUDT::epoll_remove_usock(eid, s, events); | |
| 2235 } | |
| 2236 | |
| 2237 int epoll_wait(const int eid, set<int>* readfds, set<int>* writefds, int64_t msT
imeOut, set<SYSSOCKET>* lrfds, set<SYSSOCKET>* lwfds) | |
| 2238 { | |
| 2239 return CUDT::epoll_wait(eid, readfds, writefds, msTimeOut, lrfds, lwfds); | |
| 2240 } | |
| 2241 | |
| 2242 int epoll_release(const int eid) | |
| 2243 { | |
| 2244 return CUDT::epoll_release(eid); | |
| 2245 } | |
| 2246 | |
| 2247 ERRORINFO& getlasterror() | |
| 2248 { | |
| 2249 return CUDT::getlasterror(); | |
| 2250 } | |
| 2251 | |
| 2252 int perfmon(UDTSOCKET u, TRACEINFO* perf, bool clear) | |
| 2253 { | |
| 2254 return CUDT::perfmon(u, perf, clear); | |
| 2255 } | |
| 2256 | |
| 2257 UDTSTATUS getsockstate(UDTSOCKET u) | |
| 2258 { | |
| 2259 return CUDT::getsockstate(u); | |
| 2260 } | |
| 2261 | |
| 2262 } | |
| OLD | NEW |