Index: net/third_party/udt/src/api.cpp |
=================================================================== |
--- net/third_party/udt/src/api.cpp (revision 78992) |
+++ net/third_party/udt/src/api.cpp (working copy) |
@@ -1,2262 +0,0 @@ |
-/***************************************************************************** |
-Copyright (c) 2001 - 2011, The Board of Trustees of the University of Illinois. |
-All rights reserved. |
- |
-Redistribution and use in source and binary forms, with or without |
-modification, are permitted provided that the following conditions are |
-met: |
- |
-* Redistributions of source code must retain the above |
- copyright notice, this list of conditions and the |
- following disclaimer. |
- |
-* Redistributions in binary form must reproduce the |
- above copyright notice, this list of conditions |
- and the following disclaimer in the documentation |
- and/or other materials provided with the distribution. |
- |
-* Neither the name of the University of Illinois |
- nor the names of its contributors may be used to |
- endorse or promote products derived from this |
- software without specific prior written permission. |
- |
-THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS |
-IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, |
-THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR |
-PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR |
-CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, |
-EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, |
-PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR |
-PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF |
-LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING |
-NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS |
-SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. |
-*****************************************************************************/ |
- |
-/***************************************************************************** |
-written by |
- Yunhong Gu, last updated 01/31/2011 |
-*****************************************************************************/ |
- |
-#ifdef WIN32 |
- #include <winsock2.h> |
- #include <ws2tcpip.h> |
- #ifdef LEGACY_WIN32 |
- #include <wspiapi.h> |
- #endif |
-#else |
- #include <unistd.h> |
-#endif |
-#include <cstring> |
-#include "api.h" |
-#include "core.h" |
- |
-using namespace std; |
- |
-CUDTSocket::CUDTSocket(): |
-m_Status(INIT), |
-m_TimeStamp(0), |
-m_iIPversion(0), |
-m_pSelfAddr(NULL), |
-m_pPeerAddr(NULL), |
-m_SocketID(0), |
-m_ListenSocket(0), |
-m_PeerID(0), |
-m_iISN(0), |
-m_pUDT(NULL), |
-m_pQueuedSockets(NULL), |
-m_pAcceptSockets(NULL), |
-m_AcceptCond(), |
-m_AcceptLock(), |
-m_uiBackLog(0), |
-m_iMuxID(-1) |
-{ |
- #ifndef WIN32 |
- pthread_mutex_init(&m_AcceptLock, NULL); |
- pthread_cond_init(&m_AcceptCond, NULL); |
- #else |
- m_AcceptLock = CreateMutex(NULL, false, NULL); |
- m_AcceptCond = CreateEvent(NULL, false, false, NULL); |
- #endif |
-} |
- |
-CUDTSocket::~CUDTSocket() |
-{ |
- if (AF_INET == m_iIPversion) |
- { |
- delete (sockaddr_in*)m_pSelfAddr; |
- delete (sockaddr_in*)m_pPeerAddr; |
- } |
- else |
- { |
- delete (sockaddr_in6*)m_pSelfAddr; |
- delete (sockaddr_in6*)m_pPeerAddr; |
- } |
- |
- delete m_pUDT; |
- m_pUDT = NULL; |
- |
- delete m_pQueuedSockets; |
- delete m_pAcceptSockets; |
- |
- #ifndef WIN32 |
- pthread_mutex_destroy(&m_AcceptLock); |
- pthread_cond_destroy(&m_AcceptCond); |
- #else |
- CloseHandle(m_AcceptLock); |
- CloseHandle(m_AcceptCond); |
- #endif |
-} |
- |
-//////////////////////////////////////////////////////////////////////////////// |
- |
-CUDTUnited::CUDTUnited(): |
-m_Sockets(), |
-m_ControlLock(), |
-m_IDLock(), |
-m_SocketID(0), |
-m_TLSError(), |
-m_mMultiplexer(), |
-m_MultiplexerLock(), |
-m_pCache(NULL), |
-m_bClosing(false), |
-m_GCStopLock(), |
-m_GCStopCond(), |
-m_InitLock(), |
-m_iInstanceCount(0), |
-m_bGCStatus(false), |
-m_GCThread(), |
-m_ClosedSockets() |
-{ |
- // Socket ID MUST start from a random value |
- srand((unsigned int)CTimer::getTime()); |
- m_SocketID = 1 + (int)((1 << 30) * (double(rand()) / RAND_MAX)); |
- |
- #ifndef WIN32 |
- pthread_mutex_init(&m_ControlLock, NULL); |
- pthread_mutex_init(&m_IDLock, NULL); |
- pthread_mutex_init(&m_InitLock, NULL); |
- #else |
- m_ControlLock = CreateMutex(NULL, false, NULL); |
- m_IDLock = CreateMutex(NULL, false, NULL); |
- m_InitLock = CreateMutex(NULL, false, NULL); |
- #endif |
- |
- #ifndef WIN32 |
- pthread_key_create(&m_TLSError, TLSDestroy); |
- #else |
- m_TLSError = TlsAlloc(); |
- m_TLSLock = CreateMutex(NULL, false, NULL); |
- #endif |
- |
- m_pCache = new CCache; |
-} |
- |
-CUDTUnited::~CUDTUnited() |
-{ |
- #ifndef WIN32 |
- pthread_mutex_destroy(&m_ControlLock); |
- pthread_mutex_destroy(&m_IDLock); |
- pthread_mutex_destroy(&m_InitLock); |
- #else |
- CloseHandle(m_ControlLock); |
- CloseHandle(m_IDLock); |
- CloseHandle(m_InitLock); |
- #endif |
- |
- #ifndef WIN32 |
- pthread_key_delete(m_TLSError); |
- #else |
- TlsFree(m_TLSError); |
- CloseHandle(m_TLSLock); |
- #endif |
- |
- delete m_pCache; |
-} |
- |
-int CUDTUnited::startup() |
-{ |
- CGuard gcinit(m_InitLock); |
- |
- if (m_iInstanceCount++ > 0) |
- return 0; |
- |
- // Global initialization code |
- #ifdef WIN32 |
- WORD wVersionRequested; |
- WSADATA wsaData; |
- wVersionRequested = MAKEWORD(2, 2); |
- |
- if (0 != WSAStartup(wVersionRequested, &wsaData)) |
- throw CUDTException(1, 0, WSAGetLastError()); |
- #endif |
- |
- //init CTimer::EventLock |
- |
- if (m_bGCStatus) |
- return true; |
- |
- m_bClosing = false; |
- #ifndef WIN32 |
- pthread_mutex_init(&m_GCStopLock, NULL); |
- pthread_cond_init(&m_GCStopCond, NULL); |
- pthread_create(&m_GCThread, NULL, garbageCollect, this); |
- #else |
- m_GCStopLock = CreateMutex(NULL, false, NULL); |
- m_GCStopCond = CreateEvent(NULL, false, false, NULL); |
- DWORD ThreadID; |
- m_GCThread = CreateThread(NULL, 0, garbageCollect, this, 0, &ThreadID); |
- #endif |
- |
- m_bGCStatus = true; |
- |
- return 0; |
-} |
- |
-int CUDTUnited::cleanup() |
-{ |
- CGuard gcinit(m_InitLock); |
- |
- if (--m_iInstanceCount > 0) |
- return 0; |
- |
- //destroy CTimer::EventLock |
- |
- if (!m_bGCStatus) |
- return 0; |
- |
- m_bClosing = true; |
- #ifndef WIN32 |
- pthread_cond_signal(&m_GCStopCond); |
- pthread_join(m_GCThread, NULL); |
- pthread_mutex_destroy(&m_GCStopLock); |
- pthread_cond_destroy(&m_GCStopCond); |
- #else |
- SetEvent(m_GCStopCond); |
- WaitForSingleObject(m_GCThread, INFINITE); |
- CloseHandle(m_GCThread); |
- CloseHandle(m_GCStopLock); |
- CloseHandle(m_GCStopCond); |
- #endif |
- |
- m_bGCStatus = false; |
- |
- // Global destruction code |
- #ifdef WIN32 |
- WSACleanup(); |
- #endif |
- |
- return 0; |
-} |
- |
-UDTSOCKET CUDTUnited::newSocket(const int& af, const int& type) |
-{ |
- if ((type != SOCK_STREAM) && (type != SOCK_DGRAM)) |
- throw CUDTException(5, 3, 0); |
- |
- CUDTSocket* ns = NULL; |
- |
- try |
- { |
- ns = new CUDTSocket; |
- ns->m_pUDT = new CUDT; |
- if (AF_INET == af) |
- { |
- ns->m_pSelfAddr = (sockaddr*)(new sockaddr_in); |
- ((sockaddr_in*)(ns->m_pSelfAddr))->sin_port = 0; |
- } |
- else |
- { |
- ns->m_pSelfAddr = (sockaddr*)(new sockaddr_in6); |
- ((sockaddr_in6*)(ns->m_pSelfAddr))->sin6_port = 0; |
- } |
- } |
- catch (...) |
- { |
- delete ns; |
- throw CUDTException(3, 2, 0); |
- } |
- |
- CGuard::enterCS(m_IDLock); |
- ns->m_SocketID = -- m_SocketID; |
- CGuard::leaveCS(m_IDLock); |
- |
- ns->m_Status = INIT; |
- ns->m_ListenSocket = 0; |
- ns->m_pUDT->m_SocketID = ns->m_SocketID; |
- ns->m_pUDT->m_iSockType = (SOCK_STREAM == type) ? UDT_STREAM : UDT_DGRAM; |
- ns->m_pUDT->m_iIPversion = ns->m_iIPversion = af; |
- ns->m_pUDT->m_pCache = m_pCache; |
- |
- // protect the m_Sockets structure. |
- CGuard::enterCS(m_ControlLock); |
- try |
- { |
- m_Sockets[ns->m_SocketID] = ns; |
- } |
- catch (...) |
- { |
- //failure and rollback |
- delete ns; |
- ns = NULL; |
- } |
- CGuard::leaveCS(m_ControlLock); |
- |
- if (NULL == ns) |
- throw CUDTException(3, 2, 0); |
- |
- return ns->m_SocketID; |
-} |
- |
-int CUDTUnited::newConnection(const UDTSOCKET listen, const sockaddr* peer, CHandShake* hs) |
-{ |
- CUDTSocket* ns = NULL; |
- CUDTSocket* ls = locate(listen); |
- |
- if (NULL == ls) |
- return -1; |
- |
- // if this connection has already been processed |
- if (NULL != (ns = locate(peer, hs->m_iID, hs->m_iISN))) |
- { |
- if (ns->m_pUDT->m_bBroken) |
- { |
- // last connection from the "peer" address has been broken |
- ns->m_Status = CLOSED; |
- ns->m_TimeStamp = CTimer::getTime(); |
- |
- CGuard::enterCS(ls->m_AcceptLock); |
- ls->m_pQueuedSockets->erase(ns->m_SocketID); |
- ls->m_pAcceptSockets->erase(ns->m_SocketID); |
- CGuard::leaveCS(ls->m_AcceptLock); |
- } |
- else |
- { |
- // connection already exist, this is a repeated connection request |
- // respond with existing HS information |
- |
- hs->m_iISN = ns->m_pUDT->m_iISN; |
- hs->m_iMSS = ns->m_pUDT->m_iMSS; |
- hs->m_iFlightFlagSize = ns->m_pUDT->m_iFlightFlagSize; |
- hs->m_iReqType = -1; |
- hs->m_iID = ns->m_SocketID; |
- |
- return 0; |
- |
- //except for this situation a new connection should be started |
- } |
- } |
- |
- // exceeding backlog, refuse the connection request |
- if (ls->m_pQueuedSockets->size() >= ls->m_uiBackLog) |
- return -1; |
- |
- try |
- { |
- ns = new CUDTSocket; |
- ns->m_pUDT = new CUDT(*(ls->m_pUDT)); |
- if (AF_INET == ls->m_iIPversion) |
- { |
- ns->m_pSelfAddr = (sockaddr*)(new sockaddr_in); |
- ((sockaddr_in*)(ns->m_pSelfAddr))->sin_port = 0; |
- ns->m_pPeerAddr = (sockaddr*)(new sockaddr_in); |
- memcpy(ns->m_pPeerAddr, peer, sizeof(sockaddr_in)); |
- } |
- else |
- { |
- ns->m_pSelfAddr = (sockaddr*)(new sockaddr_in6); |
- ((sockaddr_in6*)(ns->m_pSelfAddr))->sin6_port = 0; |
- ns->m_pPeerAddr = (sockaddr*)(new sockaddr_in6); |
- memcpy(ns->m_pPeerAddr, peer, sizeof(sockaddr_in6)); |
- } |
- } |
- catch (...) |
- { |
- delete ns; |
- return -1; |
- } |
- |
- CGuard::enterCS(m_IDLock); |
- ns->m_SocketID = -- m_SocketID; |
- CGuard::leaveCS(m_IDLock); |
- |
- ns->m_ListenSocket = listen; |
- ns->m_iIPversion = ls->m_iIPversion; |
- ns->m_pUDT->m_SocketID = ns->m_SocketID; |
- ns->m_PeerID = hs->m_iID; |
- ns->m_iISN = hs->m_iISN; |
- |
- int error = 0; |
- |
- try |
- { |
- // bind to the same addr of listening socket |
- ns->m_pUDT->open(); |
- updateMux(ns, ls); |
- ns->m_pUDT->connect(peer, hs); |
- } |
- catch (...) |
- { |
- error = 1; |
- goto ERR_ROLLBACK; |
- } |
- |
- ns->m_Status = CONNECTED; |
- |
- // copy address information of local node |
- ns->m_pUDT->m_pSndQueue->m_pChannel->getSockAddr(ns->m_pSelfAddr); |
- CIPAddress::pton(ns->m_pSelfAddr, ns->m_pUDT->m_piSelfIP, ns->m_iIPversion); |
- |
- // protect the m_Sockets structure. |
- CGuard::enterCS(m_ControlLock); |
- try |
- { |
- m_Sockets[ns->m_SocketID] = ns; |
- m_PeerRec[(ns->m_PeerID << 30) + ns->m_iISN].insert(ns->m_SocketID); |
- } |
- catch (...) |
- { |
- error = 2; |
- } |
- CGuard::leaveCS(m_ControlLock); |
- |
- CGuard::enterCS(ls->m_AcceptLock); |
- try |
- { |
- ls->m_pQueuedSockets->insert(ns->m_SocketID); |
- } |
- catch (...) |
- { |
- error = 3; |
- } |
- CGuard::leaveCS(ls->m_AcceptLock); |
- |
- CTimer::triggerEvent(); |
- |
- ERR_ROLLBACK: |
- if (error > 0) |
- { |
- ns->m_pUDT->close(); |
- ns->m_Status = CLOSED; |
- ns->m_TimeStamp = CTimer::getTime(); |
- |
- return -1; |
- } |
- |
- // wake up a waiting accept() call |
- #ifndef WIN32 |
- pthread_mutex_lock(&(ls->m_AcceptLock)); |
- pthread_cond_signal(&(ls->m_AcceptCond)); |
- pthread_mutex_unlock(&(ls->m_AcceptLock)); |
- #else |
- SetEvent(ls->m_AcceptCond); |
- #endif |
- |
- return 1; |
-} |
- |
-CUDT* CUDTUnited::lookup(const UDTSOCKET u) |
-{ |
- // protects the m_Sockets structure |
- CGuard cg(m_ControlLock); |
- |
- map<UDTSOCKET, CUDTSocket*>::iterator i = m_Sockets.find(u); |
- |
- if ((i == m_Sockets.end()) || (i->second->m_Status == CLOSED)) |
- throw CUDTException(5, 4, 0); |
- |
- return i->second->m_pUDT; |
-} |
- |
-UDTSTATUS CUDTUnited::getStatus(const UDTSOCKET u) |
-{ |
- // protects the m_Sockets structure |
- CGuard cg(m_ControlLock); |
- |
- map<UDTSOCKET, CUDTSocket*>::iterator i = m_Sockets.find(u); |
- |
- if (i == m_Sockets.end()) |
- { |
- if (m_ClosedSockets.find(u) != m_ClosedSockets.end()) |
- return CLOSED; |
- |
- return NONEXIST; |
- } |
- |
- if (i->second->m_pUDT->m_bBroken) |
- return BROKEN; |
- |
- return i->second->m_Status; |
-} |
- |
-int CUDTUnited::bind(const UDTSOCKET u, const sockaddr* name, const int& namelen) |
-{ |
- CUDTSocket* s = locate(u); |
- |
- if (NULL == s) |
- throw CUDTException(5, 4, 0); |
- |
- // cannot bind a socket more than once |
- if (INIT != s->m_Status) |
- throw CUDTException(5, 0, 0); |
- |
- // check the size of SOCKADDR structure |
- if (AF_INET == s->m_iIPversion) |
- { |
- if (namelen != sizeof(sockaddr_in)) |
- throw CUDTException(5, 3, 0); |
- } |
- else |
- { |
- if (namelen != sizeof(sockaddr_in6)) |
- throw CUDTException(5, 3, 0); |
- } |
- |
- s->m_pUDT->open(); |
- updateMux(s, name); |
- s->m_Status = OPENED; |
- |
- // copy address information of local node |
- s->m_pUDT->m_pSndQueue->m_pChannel->getSockAddr(s->m_pSelfAddr); |
- |
- return 0; |
-} |
- |
-int CUDTUnited::bind(UDTSOCKET u, UDPSOCKET udpsock) |
-{ |
- CUDTSocket* s = locate(u); |
- |
- if (NULL == s) |
- throw CUDTException(5, 4, 0); |
- |
- // cannot bind a socket more than once |
- if (INIT != s->m_Status) |
- throw CUDTException(5, 0, 0); |
- |
- sockaddr_in name4; |
- sockaddr_in6 name6; |
- sockaddr* name; |
- socklen_t namelen; |
- |
- if (AF_INET == s->m_iIPversion) |
- { |
- namelen = sizeof(sockaddr_in); |
- name = (sockaddr*)&name4; |
- } |
- else |
- { |
- namelen = sizeof(sockaddr_in6); |
- name = (sockaddr*)&name6; |
- } |
- |
- if (-1 == ::getsockname(udpsock, name, &namelen)) |
- throw CUDTException(5, 3); |
- |
- s->m_pUDT->open(); |
- updateMux(s, name, &udpsock); |
- s->m_Status = OPENED; |
- |
- // copy address information of local node |
- s->m_pUDT->m_pSndQueue->m_pChannel->getSockAddr(s->m_pSelfAddr); |
- |
- return 0; |
-} |
- |
-int CUDTUnited::listen(const UDTSOCKET u, const int& backlog) |
-{ |
- CUDTSocket* s = locate(u); |
- |
- if (NULL == s) |
- throw CUDTException(5, 4, 0); |
- |
- // do nothing if the socket is already listening |
- if (LISTENING == s->m_Status) |
- return 0; |
- |
- // a socket can listen only if is in OPENED status |
- if (OPENED != s->m_Status) |
- throw CUDTException(5, 5, 0); |
- |
- // listen is not supported in rendezvous connection setup |
- if (s->m_pUDT->m_bRendezvous) |
- throw CUDTException(5, 7, 0); |
- |
- if (backlog <= 0) |
- throw CUDTException(5, 3, 0); |
- |
- s->m_uiBackLog = backlog; |
- |
- try |
- { |
- s->m_pQueuedSockets = new set<UDTSOCKET>; |
- s->m_pAcceptSockets = new set<UDTSOCKET>; |
- } |
- catch (...) |
- { |
- delete s->m_pQueuedSockets; |
- throw CUDTException(3, 2, 0); |
- } |
- |
- s->m_pUDT->listen(); |
- |
- s->m_Status = LISTENING; |
- |
- return 0; |
-} |
- |
-UDTSOCKET CUDTUnited::accept(const UDTSOCKET listen, sockaddr* addr, int* addrlen) |
-{ |
- if ((NULL != addr) && (NULL == addrlen)) |
- throw CUDTException(5, 3, 0); |
- |
- CUDTSocket* ls = locate(listen); |
- |
- if (ls == NULL) |
- throw CUDTException(5, 4, 0); |
- |
- // the "listen" socket must be in LISTENING status |
- if (LISTENING != ls->m_Status) |
- throw CUDTException(5, 6, 0); |
- |
- // no "accept" in rendezvous connection setup |
- if (ls->m_pUDT->m_bRendezvous) |
- throw CUDTException(5, 7, 0); |
- |
- UDTSOCKET u = CUDT::INVALID_SOCK; |
- bool accepted = false; |
- |
- // !!only one conection can be set up each time!! |
- #ifndef WIN32 |
- while (!accepted) |
- { |
- pthread_mutex_lock(&(ls->m_AcceptLock)); |
- |
- if (ls->m_pQueuedSockets->size() > 0) |
- { |
- u = *(ls->m_pQueuedSockets->begin()); |
- ls->m_pAcceptSockets->insert(ls->m_pAcceptSockets->end(), u); |
- ls->m_pQueuedSockets->erase(ls->m_pQueuedSockets->begin()); |
- accepted = true; |
- } |
- else if (!ls->m_pUDT->m_bSynRecving) |
- accepted = true; |
- else if (LISTENING == ls->m_Status) |
- pthread_cond_wait(&(ls->m_AcceptCond), &(ls->m_AcceptLock)); |
- |
- if ((LISTENING != ls->m_Status) || ls->m_pUDT->m_bBroken) |
- accepted = true; |
- |
- if (ls->m_pQueuedSockets->empty()) |
- m_EPoll.disable_read(listen, ls->m_pUDT->m_sPollID); |
- |
- pthread_mutex_unlock(&(ls->m_AcceptLock)); |
- } |
- #else |
- while (!accepted) |
- { |
- WaitForSingleObject(ls->m_AcceptLock, INFINITE); |
- |
- if (ls->m_pQueuedSockets->size() > 0) |
- { |
- u = *(ls->m_pQueuedSockets->begin()); |
- ls->m_pAcceptSockets->insert(ls->m_pAcceptSockets->end(), u); |
- ls->m_pQueuedSockets->erase(ls->m_pQueuedSockets->begin()); |
- |
- accepted = true; |
- } |
- else if (!ls->m_pUDT->m_bSynRecving) |
- accepted = true; |
- |
- ReleaseMutex(ls->m_AcceptLock); |
- |
- if (!accepted & (LISTENING == ls->m_Status)) |
- WaitForSingleObject(ls->m_AcceptCond, INFINITE); |
- |
- if ((LISTENING != ls->m_Status) || ls->m_pUDT->m_bBroken) |
- { |
- SetEvent(ls->m_AcceptCond); |
- accepted = true; |
- } |
- |
- if (ls->m_pQueuedSockets->empty()) |
- m_EPoll.disable_read(listen, ls->m_pUDT->m_sPollID); |
- } |
- #endif |
- |
- if (u == CUDT::INVALID_SOCK) |
- { |
- // non-blocking receiving, no connection available |
- if (!ls->m_pUDT->m_bSynRecving) |
- throw CUDTException(6, 2, 0); |
- |
- // listening socket is closed |
- throw CUDTException(5, 6, 0); |
- } |
- |
- if ((addr != NULL) && (addrlen != NULL)) |
- { |
- if (AF_INET == locate(u)->m_iIPversion) |
- *addrlen = sizeof(sockaddr_in); |
- else |
- *addrlen = sizeof(sockaddr_in6); |
- |
- // copy address information of peer node |
- memcpy(addr, locate(u)->m_pPeerAddr, *addrlen); |
- } |
- |
- return u; |
-} |
- |
-int CUDTUnited::connect(const UDTSOCKET u, const sockaddr* name, const int& namelen) |
-{ |
- CUDTSocket* s = locate(u); |
- |
- if (NULL == s) |
- throw CUDTException(5, 4, 0); |
- |
- // check the size of SOCKADDR structure |
- if (AF_INET == s->m_iIPversion) |
- { |
- if (namelen != sizeof(sockaddr_in)) |
- throw CUDTException(5, 3, 0); |
- } |
- else |
- { |
- if (namelen != sizeof(sockaddr_in6)) |
- throw CUDTException(5, 3, 0); |
- } |
- |
- // a socket can "connect" only if it is in INIT or OPENED status |
- if (INIT == s->m_Status) |
- { |
- if (!s->m_pUDT->m_bRendezvous) |
- { |
- s->m_pUDT->open(); |
- updateMux(s); |
- s->m_Status = OPENED; |
- } |
- else |
- throw CUDTException(5, 8, 0); |
- } |
- else if (OPENED != s->m_Status) |
- throw CUDTException(5, 2, 0); |
- |
- s->m_pUDT->connect(name); |
- s->m_Status = CONNECTED; |
- |
- // copy address information of local node |
- // the local port must be correctly assigned BEFORE CUDT::connect(), |
- // otherwise if connect() fails, the multiplexer cannot be located by garbage collection and will cause leak |
- s->m_pUDT->m_pSndQueue->m_pChannel->getSockAddr(s->m_pSelfAddr); |
- CIPAddress::pton(s->m_pSelfAddr, s->m_pUDT->m_piSelfIP, s->m_iIPversion); |
- |
- // record peer address |
- if (AF_INET == s->m_iIPversion) |
- { |
- s->m_pPeerAddr = (sockaddr*)(new sockaddr_in); |
- memcpy(s->m_pPeerAddr, name, sizeof(sockaddr_in)); |
- } |
- else |
- { |
- s->m_pPeerAddr = (sockaddr*)(new sockaddr_in6); |
- memcpy(s->m_pPeerAddr, name, sizeof(sockaddr_in6)); |
- } |
- |
- return 0; |
-} |
- |
-int CUDTUnited::close(const UDTSOCKET u) |
-{ |
- CUDTSocket* s = locate(u); |
- |
- if (NULL == s) |
- throw CUDTException(5, 4, 0); |
- |
- if (s->m_Status == LISTENING) |
- { |
- if (s->m_pUDT->m_bBroken) |
- return 0; |
- |
- s->m_TimeStamp = CTimer::getTime(); |
- s->m_pUDT->m_bBroken = true; |
- |
- // broadcast all "accept" waiting |
- #ifndef WIN32 |
- pthread_mutex_lock(&(s->m_AcceptLock)); |
- pthread_cond_broadcast(&(s->m_AcceptCond)); |
- pthread_mutex_unlock(&(s->m_AcceptLock)); |
- #else |
- SetEvent(s->m_AcceptCond); |
- #endif |
- |
- return 0; |
- } |
- |
- s->m_pUDT->close(); |
- |
- // synchronize with garbage collection. |
- CGuard cg(m_ControlLock); |
- |
- // since "s" is located before m_ControlLock, locate it again in case it became invalid |
- map<UDTSOCKET, CUDTSocket*>::iterator i = m_Sockets.find(u); |
- if ((i == m_Sockets.end()) || (i->second->m_Status == CLOSED)) |
- return 0; |
- s = i->second; |
- |
- s->m_Status = CLOSED; |
- |
- // a socket will not be immediated removed when it is closed |
- // in order to prevent other methods from accessing invalid address |
- // a timer is started and the socket will be removed after approximately 1 second |
- s->m_TimeStamp = CTimer::getTime(); |
- |
- m_Sockets.erase(s->m_SocketID); |
- m_ClosedSockets.insert(pair<UDTSOCKET, CUDTSocket*>(s->m_SocketID, s)); |
- |
- CTimer::triggerEvent(); |
- |
- return 0; |
-} |
- |
-int CUDTUnited::getpeername(const UDTSOCKET u, sockaddr* name, int* namelen) |
-{ |
- if (CONNECTED != getStatus(u)) |
- throw CUDTException(2, 2, 0); |
- |
- CUDTSocket* s = locate(u); |
- |
- if (NULL == s) |
- throw CUDTException(5, 4, 0); |
- |
- if (!s->m_pUDT->m_bConnected || s->m_pUDT->m_bBroken) |
- throw CUDTException(2, 2, 0); |
- |
- if (AF_INET == s->m_iIPversion) |
- *namelen = sizeof(sockaddr_in); |
- else |
- *namelen = sizeof(sockaddr_in6); |
- |
- // copy address information of peer node |
- memcpy(name, s->m_pPeerAddr, *namelen); |
- |
- return 0; |
-} |
- |
-int CUDTUnited::getsockname(const UDTSOCKET u, sockaddr* name, int* namelen) |
-{ |
- CUDTSocket* s = locate(u); |
- |
- if (NULL == s) |
- throw CUDTException(5, 4, 0); |
- |
- if (s->m_pUDT->m_bBroken) |
- throw CUDTException(5, 4, 0); |
- |
- if (INIT == s->m_Status) |
- throw CUDTException(2, 2, 0); |
- |
- if (AF_INET == s->m_iIPversion) |
- *namelen = sizeof(sockaddr_in); |
- else |
- *namelen = sizeof(sockaddr_in6); |
- |
- // copy address information of local node |
- memcpy(name, s->m_pSelfAddr, *namelen); |
- |
- return 0; |
-} |
- |
-int CUDTUnited::select(ud_set* readfds, ud_set* writefds, ud_set* exceptfds, const timeval* timeout) |
-{ |
- uint64_t entertime = CTimer::getTime(); |
- |
- uint64_t to; |
- if (NULL == timeout) |
- to = 0xFFFFFFFFFFFFFFFFULL; |
- else |
- to = timeout->tv_sec * 1000000 + timeout->tv_usec; |
- |
- // initialize results |
- int count = 0; |
- set<UDTSOCKET> rs, ws, es; |
- |
- // retrieve related UDT sockets |
- vector<CUDTSocket*> ru, wu, eu; |
- CUDTSocket* s; |
- if (NULL != readfds) |
- for (set<UDTSOCKET>::iterator i1 = readfds->begin(); i1 != readfds->end(); ++ i1) |
- { |
- if (BROKEN == getStatus(*i1)) |
- { |
- rs.insert(*i1); |
- ++ count; |
- } |
- else if (NULL == (s = locate(*i1))) |
- throw CUDTException(5, 4, 0); |
- else |
- ru.insert(ru.end(), s); |
- } |
- if (NULL != writefds) |
- for (set<UDTSOCKET>::iterator i2 = writefds->begin(); i2 != writefds->end(); ++ i2) |
- { |
- if (BROKEN == getStatus(*i2)) |
- { |
- ws.insert(*i2); |
- ++ count; |
- } |
- else if (NULL == (s = locate(*i2))) |
- throw CUDTException(5, 4, 0); |
- else |
- wu.insert(wu.end(), s); |
- } |
- if (NULL != exceptfds) |
- for (set<UDTSOCKET>::iterator i3 = exceptfds->begin(); i3 != exceptfds->end(); ++ i3) |
- { |
- if (BROKEN == getStatus(*i3)) |
- { |
- es.insert(*i3); |
- ++ count; |
- } |
- else if (NULL == (s = locate(*i3))) |
- throw CUDTException(5, 4, 0); |
- else |
- eu.insert(eu.end(), s); |
- } |
- |
- do |
- { |
- // query read sockets |
- for (vector<CUDTSocket*>::iterator j1 = ru.begin(); j1 != ru.end(); ++ j1) |
- { |
- s = *j1; |
- |
- if ((s->m_pUDT->m_bConnected && (s->m_pUDT->m_pRcvBuffer->getRcvDataSize() > 0) && ((s->m_pUDT->m_iSockType == UDT_STREAM) || (s->m_pUDT->m_pRcvBuffer->getRcvMsgNum() > 0))) |
- || (!s->m_pUDT->m_bListening && (s->m_pUDT->m_bBroken || !s->m_pUDT->m_bConnected)) |
- || (s->m_pUDT->m_bListening && (s->m_pQueuedSockets->size() > 0)) |
- || (s->m_Status == CLOSED)) |
- { |
- rs.insert(s->m_SocketID); |
- ++ count; |
- } |
- } |
- |
- // query write sockets |
- for (vector<CUDTSocket*>::iterator j2 = wu.begin(); j2 != wu.end(); ++ j2) |
- { |
- s = *j2; |
- |
- if ((s->m_pUDT->m_bConnected && (s->m_pUDT->m_pSndBuffer->getCurrBufSize() < s->m_pUDT->m_iSndBufSize)) |
- || s->m_pUDT->m_bBroken || !s->m_pUDT->m_bConnected || (s->m_Status == CLOSED)) |
- { |
- ws.insert(s->m_SocketID); |
- ++ count; |
- } |
- } |
- |
- // query exceptions on sockets |
- for (vector<CUDTSocket*>::iterator j3 = eu.begin(); j3 != eu.end(); ++ j3) |
- { |
- // check connection request status, not supported now |
- } |
- |
- if (0 < count) |
- break; |
- |
- CTimer::waitForEvent(); |
- } while (to > CTimer::getTime() - entertime); |
- |
- if (NULL != readfds) |
- *readfds = rs; |
- |
- if (NULL != writefds) |
- *writefds = ws; |
- |
- if (NULL != exceptfds) |
- *exceptfds = es; |
- |
- return count; |
-} |
- |
-int CUDTUnited::selectEx(const vector<UDTSOCKET>& fds, vector<UDTSOCKET>* readfds, vector<UDTSOCKET>* writefds, vector<UDTSOCKET>* exceptfds, int64_t msTimeOut) |
-{ |
- uint64_t entertime = CTimer::getTime(); |
- |
- uint64_t to; |
- if (msTimeOut >= 0) |
- to = msTimeOut * 1000; |
- else |
- to = 0xFFFFFFFFFFFFFFFFULL; |
- |
- // initialize results |
- int count = 0; |
- if (NULL != readfds) |
- readfds->clear(); |
- if (NULL != writefds) |
- writefds->clear(); |
- if (NULL != exceptfds) |
- exceptfds->clear(); |
- |
- do |
- { |
- for (vector<UDTSOCKET>::const_iterator i = fds.begin(); i != fds.end(); ++ i) |
- { |
- CUDTSocket* s = locate(*i); |
- |
- if ((NULL == s) || s->m_pUDT->m_bBroken || (s->m_Status == CLOSED)) |
- { |
- if (NULL != exceptfds) |
- { |
- exceptfds->push_back(*i); |
- ++ count; |
- } |
- continue; |
- } |
- |
- if (NULL != readfds) |
- { |
- if ((s->m_pUDT->m_bConnected && (s->m_pUDT->m_pRcvBuffer->getRcvDataSize() > 0) && ((s->m_pUDT->m_iSockType == UDT_STREAM) || (s->m_pUDT->m_pRcvBuffer->getRcvMsgNum() > 0))) |
- || (s->m_pUDT->m_bListening && (s->m_pQueuedSockets->size() > 0))) |
- { |
- readfds->push_back(s->m_SocketID); |
- ++ count; |
- } |
- } |
- |
- if (NULL != writefds) |
- { |
- if (s->m_pUDT->m_bConnected && (s->m_pUDT->m_pSndBuffer->getCurrBufSize() < s->m_pUDT->m_iSndBufSize)) |
- { |
- writefds->push_back(s->m_SocketID); |
- ++ count; |
- } |
- } |
- } |
- |
- if (count > 0) |
- break; |
- |
- CTimer::waitForEvent(); |
- } while (to > CTimer::getTime() - entertime); |
- |
- return count; |
-} |
- |
-int CUDTUnited::epoll_create() |
-{ |
- return m_EPoll.create(); |
-} |
- |
-int CUDTUnited::epoll_add_usock(const int eid, const UDTSOCKET u, const int* events) |
-{ |
- CUDTSocket* s = locate(u); |
- if (NULL != s) |
- { |
- s->m_pUDT->addEPoll(eid); |
- } |
- else |
- { |
- throw CUDTException(5, 4); |
- } |
- |
- return m_EPoll.add_usock(eid, u, events); |
-} |
- |
-int CUDTUnited::epoll_add_ssock(const int eid, const SYSSOCKET s, const int* events) |
-{ |
- return m_EPoll.add_ssock(eid, s, events); |
-} |
- |
-int CUDTUnited::epoll_remove_usock(const int eid, const UDTSOCKET u, const int* events) |
-{ |
- CUDTSocket* s = locate(u); |
- if (NULL != s) |
- { |
- s->m_pUDT->removeEPoll(eid); |
- } |
- else |
- { |
- throw CUDTException(5, 4); |
- } |
- |
- return m_EPoll.remove_usock(eid, u, events); |
-} |
- |
-int CUDTUnited::epoll_remove_ssock(const int eid, const SYSSOCKET s, const int* events) |
-{ |
- return m_EPoll.remove_ssock(eid, s, events); |
-} |
- |
-int CUDTUnited::epoll_wait(const int eid, set<UDTSOCKET>* readfds, set<UDTSOCKET>* writefds, int64_t msTimeOut, set<SYSSOCKET>* lrfds, set<SYSSOCKET>* lwfds) |
-{ |
- return m_EPoll.wait(eid, readfds, writefds, msTimeOut, lrfds, lwfds); |
-} |
- |
-int CUDTUnited::epoll_release(const int eid) |
-{ |
- return m_EPoll.release(eid); |
-} |
- |
-CUDTSocket* CUDTUnited::locate(const UDTSOCKET u) |
-{ |
- CGuard cg(m_ControlLock); |
- |
- map<UDTSOCKET, CUDTSocket*>::iterator i = m_Sockets.find(u); |
- |
- if ((i == m_Sockets.end()) || (i->second->m_Status == CLOSED)) |
- return NULL; |
- |
- return i->second; |
-} |
- |
-CUDTSocket* CUDTUnited::locate(const sockaddr* peer, const UDTSOCKET& id, const int32_t& isn) |
-{ |
- CGuard cg(m_ControlLock); |
- |
- map<int64_t, set<UDTSOCKET> >::iterator i = m_PeerRec.find((id << 30) + isn); |
- if (i == m_PeerRec.end()) |
- return NULL; |
- |
- for (set<UDTSOCKET>::iterator j = i->second.begin(); j != i->second.end(); ++ j) |
- { |
- map<UDTSOCKET, CUDTSocket*>::iterator k = m_Sockets.find(*j); |
- // this socket might have been closed and moved m_ClosedSockets |
- if (k == m_Sockets.end()) |
- continue; |
- |
- if (CIPAddress::ipcmp(peer, k->second->m_pPeerAddr, k->second->m_iIPversion)) |
- return k->second; |
- } |
- |
- return NULL; |
-} |
- |
-void CUDTUnited::checkBrokenSockets() |
-{ |
- CGuard cg(m_ControlLock); |
- |
- // set of sockets To Be Closed and To Be Removed |
- vector<UDTSOCKET> tbc; |
- vector<UDTSOCKET> tbr; |
- |
- for (map<UDTSOCKET, CUDTSocket*>::iterator i = m_Sockets.begin(); i != m_Sockets.end(); ++ i) |
- { |
- // check broken connection |
- if (i->second->m_pUDT->m_bBroken) |
- { |
- if (i->second->m_Status == LISTENING) |
- { |
- // for a listening socket, it should wait an extra 3 seconds in case a client is connecting |
- if (CTimer::getTime() - i->second->m_TimeStamp < 3000000) |
- continue; |
- } |
- else if ((i->second->m_pUDT->m_pRcvBuffer->getRcvDataSize() > 0) && (i->second->m_pUDT->m_iBrokenCounter -- > 0)) |
- { |
- // if there is still data in the receiver buffer, wait longer |
- continue; |
- } |
- |
- //close broken connections and start removal timer |
- i->second->m_Status = CLOSED; |
- i->second->m_TimeStamp = CTimer::getTime(); |
- tbc.push_back(i->first); |
- m_ClosedSockets[i->first] = i->second; |
- |
- // remove from listener's queue |
- map<UDTSOCKET, CUDTSocket*>::iterator ls = m_Sockets.find(i->second->m_ListenSocket); |
- if (ls == m_Sockets.end()) |
- { |
- ls = m_ClosedSockets.find(i->second->m_ListenSocket); |
- if (ls == m_ClosedSockets.end()) |
- continue; |
- } |
- |
- CGuard::enterCS(ls->second->m_AcceptLock); |
- ls->second->m_pQueuedSockets->erase(i->second->m_SocketID); |
- ls->second->m_pAcceptSockets->erase(i->second->m_SocketID); |
- CGuard::leaveCS(ls->second->m_AcceptLock); |
- } |
- } |
- |
- for (map<UDTSOCKET, CUDTSocket*>::iterator j = m_ClosedSockets.begin(); j != m_ClosedSockets.end(); ++ j) |
- { |
- // timeout 1 second to destroy a socket AND it has been removed from RcvUList AND no linger data to send |
- if ((CTimer::getTime() - j->second->m_TimeStamp > 1000000) && |
- ((NULL == j->second->m_pUDT->m_pRNode) || !j->second->m_pUDT->m_pRNode->m_bOnList) && |
- ((NULL == j->second->m_pUDT->m_pSndBuffer) || (0 == j->second->m_pUDT->m_pSndBuffer->getCurrBufSize()) || (j->second->m_pUDT->m_ullLingerExpiration <= CTimer::getTime()))) |
- { |
- tbr.push_back(j->first); |
- } |
- } |
- |
- // move closed sockets to the ClosedSockets structure |
- for (vector<UDTSOCKET>::iterator k = tbc.begin(); k != tbc.end(); ++ k) |
- m_Sockets.erase(*k); |
- |
- // remove those timeout sockets |
- for (vector<UDTSOCKET>::iterator l = tbr.begin(); l != tbr.end(); ++ l) |
- removeSocket(*l); |
-} |
- |
-void CUDTUnited::removeSocket(const UDTSOCKET u) |
-{ |
- map<UDTSOCKET, CUDTSocket*>::iterator i = m_ClosedSockets.find(u); |
- |
- // invalid socket ID |
- if (i == m_ClosedSockets.end()) |
- return; |
- |
- // decrease multiplexer reference count, and remove it if necessary |
- const int mid = i->second->m_iMuxID; |
- |
- if (NULL != i->second->m_pQueuedSockets) |
- { |
- CGuard::enterCS(i->second->m_AcceptLock); |
- |
- // if it is a listener, close all un-accepted sockets in its queue and remove them later |
- for (set<UDTSOCKET>::iterator q = i->second->m_pQueuedSockets->begin(); q != i->second->m_pQueuedSockets->end(); ++ q) |
- { |
- m_Sockets[*q]->m_pUDT->m_bBroken = true; |
- m_Sockets[*q]->m_pUDT->close(); |
- m_Sockets[*q]->m_TimeStamp = CTimer::getTime(); |
- m_Sockets[*q]->m_Status = CLOSED; |
- m_ClosedSockets[*q] = m_Sockets[*q]; |
- m_Sockets.erase(*q); |
- } |
- |
- CGuard::leaveCS(i->second->m_AcceptLock); |
- } |
- |
- // remove from peer rec |
- map<int64_t, set<UDTSOCKET> >::iterator j = m_PeerRec.find((i->second->m_PeerID << 30) + i->second->m_iISN); |
- if (j != m_PeerRec.end()) |
- { |
- j->second.erase(u); |
- if (j->second.empty()) |
- m_PeerRec.erase(j); |
- } |
- |
- // delete this one |
- i->second->m_pUDT->close(); |
- delete i->second; |
- m_ClosedSockets.erase(i); |
- |
- map<int, CMultiplexer>::iterator m; |
- m = m_mMultiplexer.find(mid); |
- if (m == m_mMultiplexer.end()) |
- { |
- //something is wrong!!! |
- return; |
- } |
- |
- m->second.m_iRefCount --; |
- if (0 == m->second.m_iRefCount) |
- { |
- m->second.m_pChannel->close(); |
- delete m->second.m_pSndQueue; |
- delete m->second.m_pRcvQueue; |
- delete m->second.m_pTimer; |
- delete m->second.m_pChannel; |
- m_mMultiplexer.erase(m); |
- } |
-} |
- |
-void CUDTUnited::setError(CUDTException* e) |
-{ |
- #ifndef WIN32 |
- delete (CUDTException*)pthread_getspecific(m_TLSError); |
- pthread_setspecific(m_TLSError, e); |
- #else |
- CGuard tg(m_TLSLock); |
- delete (CUDTException*)TlsGetValue(m_TLSError); |
- TlsSetValue(m_TLSError, e); |
- m_mTLSRecord[GetCurrentThreadId()] = e; |
- #endif |
-} |
- |
-CUDTException* CUDTUnited::getError() |
-{ |
- #ifndef WIN32 |
- if(NULL == pthread_getspecific(m_TLSError)) |
- pthread_setspecific(m_TLSError, new CUDTException); |
- return (CUDTException*)pthread_getspecific(m_TLSError); |
- #else |
- CGuard tg(m_TLSLock); |
- if(NULL == TlsGetValue(m_TLSError)) |
- { |
- CUDTException* e = new CUDTException; |
- TlsSetValue(m_TLSError, e); |
- m_mTLSRecord[GetCurrentThreadId()] = e; |
- } |
- return (CUDTException*)TlsGetValue(m_TLSError); |
- #endif |
-} |
- |
-#ifdef WIN32 |
-void CUDTUnited::checkTLSValue() |
-{ |
- CGuard tg(m_TLSLock); |
- |
- vector<DWORD> tbr; |
- for (map<DWORD, CUDTException*>::iterator i = m_mTLSRecord.begin(); i != m_mTLSRecord.end(); ++ i) |
- { |
- HANDLE h = OpenThread(THREAD_QUERY_INFORMATION, FALSE, i->first); |
- if (NULL == h) |
- { |
- tbr.insert(tbr.end(), i->first); |
- break; |
- } |
- if (WAIT_OBJECT_0 == WaitForSingleObject(h, 0)) |
- { |
- delete i->second; |
- tbr.insert(tbr.end(), i->first); |
- } |
- CloseHandle(h); |
- } |
- for (vector<DWORD>::iterator j = tbr.begin(); j != tbr.end(); ++ j) |
- m_mTLSRecord.erase(*j); |
-} |
-#endif |
- |
-void CUDTUnited::updateMux(CUDTSocket* s, const sockaddr* addr, const UDPSOCKET* udpsock) |
-{ |
- CGuard cg(m_ControlLock); |
- |
- if ((s->m_pUDT->m_bReuseAddr) && (NULL != addr)) |
- { |
- int port = (AF_INET == s->m_pUDT->m_iIPversion) ? ntohs(((sockaddr_in*)addr)->sin_port) : ntohs(((sockaddr_in6*)addr)->sin6_port); |
- |
- // find a reusable address |
- for (map<int, CMultiplexer>::iterator i = m_mMultiplexer.begin(); i != m_mMultiplexer.end(); ++ i) |
- { |
- if ((i->second.m_iIPversion == s->m_pUDT->m_iIPversion) && (i->second.m_iMSS == s->m_pUDT->m_iMSS) && i->second.m_bReusable) |
- { |
- if (i->second.m_iPort == port) |
- { |
- // reuse the existing multiplexer |
- ++ i->second.m_iRefCount; |
- s->m_pUDT->m_pSndQueue = i->second.m_pSndQueue; |
- s->m_pUDT->m_pRcvQueue = i->second.m_pRcvQueue; |
- s->m_iMuxID = i->second.m_iID; |
- return; |
- } |
- } |
- } |
- } |
- |
- // a new multiplexer is needed |
- CMultiplexer m; |
- m.m_iMSS = s->m_pUDT->m_iMSS; |
- m.m_iIPversion = s->m_pUDT->m_iIPversion; |
- m.m_iRefCount = 1; |
- m.m_bReusable = s->m_pUDT->m_bReuseAddr; |
- m.m_iID = s->m_SocketID; |
- |
- m.m_pChannel = new CChannel(s->m_pUDT->m_iIPversion); |
- m.m_pChannel->setSndBufSize(s->m_pUDT->m_iUDPSndBufSize); |
- m.m_pChannel->setRcvBufSize(s->m_pUDT->m_iUDPRcvBufSize); |
- |
- try |
- { |
- if (NULL != udpsock) |
- m.m_pChannel->open(*udpsock); |
- else |
- m.m_pChannel->open(addr); |
- } |
- catch (CUDTException& e) |
- { |
- m.m_pChannel->close(); |
- delete m.m_pChannel; |
- throw e; |
- } |
- |
- sockaddr* sa = (AF_INET == s->m_pUDT->m_iIPversion) ? (sockaddr*) new sockaddr_in : (sockaddr*) new sockaddr_in6; |
- m.m_pChannel->getSockAddr(sa); |
- m.m_iPort = (AF_INET == s->m_pUDT->m_iIPversion) ? ntohs(((sockaddr_in*)sa)->sin_port) : ntohs(((sockaddr_in6*)sa)->sin6_port); |
- if (AF_INET == s->m_pUDT->m_iIPversion) delete (sockaddr_in*)sa; else delete (sockaddr_in6*)sa; |
- |
- m.m_pTimer = new CTimer; |
- |
- m.m_pSndQueue = new CSndQueue; |
- m.m_pSndQueue->init(m.m_pChannel, m.m_pTimer); |
- m.m_pRcvQueue = new CRcvQueue; |
- m.m_pRcvQueue->init(32, s->m_pUDT->m_iPayloadSize, m.m_iIPversion, 1024, m.m_pChannel, m.m_pTimer); |
- |
- m_mMultiplexer[m.m_iID] = m; |
- |
- s->m_pUDT->m_pSndQueue = m.m_pSndQueue; |
- s->m_pUDT->m_pRcvQueue = m.m_pRcvQueue; |
- s->m_iMuxID = m.m_iID; |
-} |
- |
-void CUDTUnited::updateMux(CUDTSocket* s, const CUDTSocket* ls) |
-{ |
- CGuard cg(m_ControlLock); |
- |
- int port = (AF_INET == ls->m_iIPversion) ? ntohs(((sockaddr_in*)ls->m_pSelfAddr)->sin_port) : ntohs(((sockaddr_in6*)ls->m_pSelfAddr)->sin6_port); |
- |
- // find the listener's address |
- for (map<int, CMultiplexer>::iterator i = m_mMultiplexer.begin(); i != m_mMultiplexer.end(); ++ i) |
- { |
- if (i->second.m_iPort == port) |
- { |
- // reuse the existing multiplexer |
- ++ i->second.m_iRefCount; |
- s->m_pUDT->m_pSndQueue = i->second.m_pSndQueue; |
- s->m_pUDT->m_pRcvQueue = i->second.m_pRcvQueue; |
- s->m_iMuxID = i->second.m_iID; |
- return; |
- } |
- } |
-} |
- |
-#ifndef WIN32 |
- void* CUDTUnited::garbageCollect(void* p) |
-#else |
- DWORD WINAPI CUDTUnited::garbageCollect(LPVOID p) |
-#endif |
-{ |
- CUDTUnited* self = (CUDTUnited*)p; |
- |
- CGuard gcguard(self->m_GCStopLock); |
- |
- while (!self->m_bClosing) |
- { |
- self->checkBrokenSockets(); |
- |
- #ifdef WIN32 |
- self->checkTLSValue(); |
- #endif |
- |
- #ifndef WIN32 |
- timeval now; |
- timespec timeout; |
- gettimeofday(&now, 0); |
- timeout.tv_sec = now.tv_sec + 1; |
- timeout.tv_nsec = now.tv_usec * 1000; |
- |
- pthread_cond_timedwait(&self->m_GCStopCond, &self->m_GCStopLock, &timeout); |
- #else |
- WaitForSingleObject(self->m_GCStopCond, 1000); |
- #endif |
- } |
- |
- // remove all sockets and multiplexers |
- CGuard::enterCS(self->m_ControlLock); |
- for (map<UDTSOCKET, CUDTSocket*>::iterator i = self->m_Sockets.begin(); i != self->m_Sockets.end(); ++ i) |
- { |
- i->second->m_pUDT->m_bBroken = true; |
- i->second->m_pUDT->close(); |
- i->second->m_Status = CLOSED; |
- i->second->m_TimeStamp = CTimer::getTime(); |
- self->m_ClosedSockets[i->first] = i->second; |
- |
- // remove from listener's queue |
- map<UDTSOCKET, CUDTSocket*>::iterator ls = self->m_Sockets.find(i->second->m_ListenSocket); |
- if (ls == self->m_Sockets.end()) |
- { |
- ls = self->m_ClosedSockets.find(i->second->m_ListenSocket); |
- if (ls == self->m_ClosedSockets.end()) |
- continue; |
- } |
- |
- CGuard::enterCS(ls->second->m_AcceptLock); |
- ls->second->m_pQueuedSockets->erase(i->second->m_SocketID); |
- ls->second->m_pAcceptSockets->erase(i->second->m_SocketID); |
- CGuard::leaveCS(ls->second->m_AcceptLock); |
- } |
- self->m_Sockets.clear(); |
- |
- for (map<UDTSOCKET, CUDTSocket*>::iterator j = self->m_ClosedSockets.begin(); j != self->m_ClosedSockets.end(); ++ j) |
- { |
- j->second->m_TimeStamp = 0; |
- } |
- CGuard::leaveCS(self->m_ControlLock); |
- |
- while (true) |
- { |
- self->checkBrokenSockets(); |
- |
- CGuard::enterCS(self->m_ControlLock); |
- bool empty = self->m_ClosedSockets.empty(); |
- CGuard::leaveCS(self->m_ControlLock); |
- |
- if (empty) |
- break; |
- |
- CTimer::sleep(); |
- } |
- |
- #ifndef WIN32 |
- return NULL; |
- #else |
- return 0; |
- #endif |
-} |
- |
-//////////////////////////////////////////////////////////////////////////////// |
- |
-int CUDT::startup() |
-{ |
- return s_UDTUnited.startup(); |
-} |
- |
-int CUDT::cleanup() |
-{ |
- return s_UDTUnited.cleanup(); |
-} |
- |
-UDTSOCKET CUDT::socket(int af, int type, int) |
-{ |
- if (!s_UDTUnited.m_bGCStatus) |
- s_UDTUnited.startup(); |
- |
- try |
- { |
- return s_UDTUnited.newSocket(af, type); |
- } |
- catch (CUDTException& e) |
- { |
- s_UDTUnited.setError(new CUDTException(e)); |
- return INVALID_SOCK; |
- } |
- catch (bad_alloc&) |
- { |
- s_UDTUnited.setError(new CUDTException(3, 2, 0)); |
- return INVALID_SOCK; |
- } |
- catch (...) |
- { |
- s_UDTUnited.setError(new CUDTException(-1, 0, 0)); |
- return INVALID_SOCK; |
- } |
-} |
- |
-int CUDT::bind(UDTSOCKET u, const sockaddr* name, int namelen) |
-{ |
- try |
- { |
- return s_UDTUnited.bind(u, name, namelen); |
- } |
- catch (CUDTException& e) |
- { |
- s_UDTUnited.setError(new CUDTException(e)); |
- return ERROR; |
- } |
- catch (bad_alloc&) |
- { |
- s_UDTUnited.setError(new CUDTException(3, 2, 0)); |
- return ERROR; |
- } |
- catch (...) |
- { |
- s_UDTUnited.setError(new CUDTException(-1, 0, 0)); |
- return ERROR; |
- } |
-} |
- |
-int CUDT::bind(UDTSOCKET u, UDPSOCKET udpsock) |
-{ |
- try |
- { |
- return s_UDTUnited.bind(u, udpsock); |
- } |
- catch (CUDTException& e) |
- { |
- s_UDTUnited.setError(new CUDTException(e)); |
- return ERROR; |
- } |
- catch (bad_alloc&) |
- { |
- s_UDTUnited.setError(new CUDTException(3, 2, 0)); |
- return ERROR; |
- } |
- catch (...) |
- { |
- s_UDTUnited.setError(new CUDTException(-1, 0, 0)); |
- return ERROR; |
- } |
-} |
- |
-int CUDT::listen(UDTSOCKET u, int backlog) |
-{ |
- try |
- { |
- return s_UDTUnited.listen(u, backlog); |
- } |
- catch (CUDTException& e) |
- { |
- s_UDTUnited.setError(new CUDTException(e)); |
- return ERROR; |
- } |
- catch (bad_alloc&) |
- { |
- s_UDTUnited.setError(new CUDTException(3, 2, 0)); |
- return ERROR; |
- } |
- catch (...) |
- { |
- s_UDTUnited.setError(new CUDTException(-1, 0, 0)); |
- return ERROR; |
- } |
-} |
- |
-UDTSOCKET CUDT::accept(UDTSOCKET u, sockaddr* addr, int* addrlen) |
-{ |
- try |
- { |
- return s_UDTUnited.accept(u, addr, addrlen); |
- } |
- catch (CUDTException& e) |
- { |
- s_UDTUnited.setError(new CUDTException(e)); |
- return INVALID_SOCK; |
- } |
- catch (...) |
- { |
- s_UDTUnited.setError(new CUDTException(-1, 0, 0)); |
- return INVALID_SOCK; |
- } |
-} |
- |
-int CUDT::connect(UDTSOCKET u, const sockaddr* name, int namelen) |
-{ |
- try |
- { |
- return s_UDTUnited.connect(u, name, namelen); |
- } |
- catch (CUDTException e) |
- { |
- s_UDTUnited.setError(new CUDTException(e)); |
- return ERROR; |
- } |
- catch (bad_alloc&) |
- { |
- s_UDTUnited.setError(new CUDTException(3, 2, 0)); |
- return ERROR; |
- } |
- catch (...) |
- { |
- s_UDTUnited.setError(new CUDTException(-1, 0, 0)); |
- return ERROR; |
- } |
-} |
- |
-int CUDT::close(UDTSOCKET u) |
-{ |
- try |
- { |
- return s_UDTUnited.close(u); |
- } |
- catch (CUDTException e) |
- { |
- s_UDTUnited.setError(new CUDTException(e)); |
- return ERROR; |
- } |
- catch (...) |
- { |
- s_UDTUnited.setError(new CUDTException(-1, 0, 0)); |
- return ERROR; |
- } |
-} |
- |
-int CUDT::getpeername(UDTSOCKET u, sockaddr* name, int* namelen) |
-{ |
- try |
- { |
- return s_UDTUnited.getpeername(u, name, namelen); |
- } |
- catch (CUDTException e) |
- { |
- s_UDTUnited.setError(new CUDTException(e)); |
- return ERROR; |
- } |
- catch (...) |
- { |
- s_UDTUnited.setError(new CUDTException(-1, 0, 0)); |
- return ERROR; |
- } |
-} |
- |
-int CUDT::getsockname(UDTSOCKET u, sockaddr* name, int* namelen) |
-{ |
- try |
- { |
- return s_UDTUnited.getsockname(u, name, namelen);; |
- } |
- catch (CUDTException e) |
- { |
- s_UDTUnited.setError(new CUDTException(e)); |
- return ERROR; |
- } |
- catch (...) |
- { |
- s_UDTUnited.setError(new CUDTException(-1, 0, 0)); |
- return ERROR; |
- } |
-} |
- |
-int CUDT::getsockopt(UDTSOCKET u, int, UDTOpt optname, void* optval, int* optlen) |
-{ |
- try |
- { |
- CUDT* udt = s_UDTUnited.lookup(u); |
- udt->getOpt(optname, optval, *optlen); |
- return 0; |
- } |
- catch (CUDTException e) |
- { |
- s_UDTUnited.setError(new CUDTException(e)); |
- return ERROR; |
- } |
- catch (...) |
- { |
- s_UDTUnited.setError(new CUDTException(-1, 0, 0)); |
- return ERROR; |
- } |
-} |
- |
-int CUDT::setsockopt(UDTSOCKET u, int, UDTOpt optname, const void* optval, int optlen) |
-{ |
- try |
- { |
- CUDT* udt = s_UDTUnited.lookup(u); |
- udt->setOpt(optname, optval, optlen); |
- return 0; |
- } |
- catch (CUDTException e) |
- { |
- s_UDTUnited.setError(new CUDTException(e)); |
- return ERROR; |
- } |
- catch (...) |
- { |
- s_UDTUnited.setError(new CUDTException(-1, 0, 0)); |
- return ERROR; |
- } |
-} |
- |
-int CUDT::send(UDTSOCKET u, const char* buf, int len, int) |
-{ |
- try |
- { |
- CUDT* udt = s_UDTUnited.lookup(u); |
- return udt->send((char*)buf, len); |
- } |
- catch (CUDTException e) |
- { |
- s_UDTUnited.setError(new CUDTException(e)); |
- return ERROR; |
- } |
- catch (bad_alloc&) |
- { |
- s_UDTUnited.setError(new CUDTException(3, 2, 0)); |
- return ERROR; |
- } |
- catch (...) |
- { |
- s_UDTUnited.setError(new CUDTException(-1, 0, 0)); |
- return ERROR; |
- } |
-} |
- |
-int CUDT::recv(UDTSOCKET u, char* buf, int len, int) |
-{ |
- try |
- { |
- CUDT* udt = s_UDTUnited.lookup(u); |
- return udt->recv(buf, len); |
- } |
- catch (CUDTException e) |
- { |
- s_UDTUnited.setError(new CUDTException(e)); |
- return ERROR; |
- } |
- catch (...) |
- { |
- s_UDTUnited.setError(new CUDTException(-1, 0, 0)); |
- return ERROR; |
- } |
-} |
- |
-int CUDT::sendmsg(UDTSOCKET u, const char* buf, int len, int ttl, bool inorder) |
-{ |
- try |
- { |
- CUDT* udt = s_UDTUnited.lookup(u); |
- return udt->sendmsg((char*)buf, len, ttl, inorder); |
- } |
- catch (CUDTException e) |
- { |
- s_UDTUnited.setError(new CUDTException(e)); |
- return ERROR; |
- } |
- catch (bad_alloc&) |
- { |
- s_UDTUnited.setError(new CUDTException(3, 2, 0)); |
- return ERROR; |
- } |
- catch (...) |
- { |
- s_UDTUnited.setError(new CUDTException(-1, 0, 0)); |
- return ERROR; |
- } |
-} |
- |
-int CUDT::recvmsg(UDTSOCKET u, char* buf, int len) |
-{ |
- try |
- { |
- CUDT* udt = s_UDTUnited.lookup(u); |
- return udt->recvmsg(buf, len); |
- } |
- catch (CUDTException e) |
- { |
- s_UDTUnited.setError(new CUDTException(e)); |
- return ERROR; |
- } |
- catch (...) |
- { |
- s_UDTUnited.setError(new CUDTException(-1, 0, 0)); |
- return ERROR; |
- } |
-} |
- |
-int64_t CUDT::sendfile(UDTSOCKET u, fstream& ifs, int64_t& offset, const int64_t& size, const int& block) |
-{ |
- try |
- { |
- CUDT* udt = s_UDTUnited.lookup(u); |
- return udt->sendfile(ifs, offset, size, block); |
- } |
- catch (CUDTException e) |
- { |
- s_UDTUnited.setError(new CUDTException(e)); |
- return ERROR; |
- } |
- catch (bad_alloc&) |
- { |
- s_UDTUnited.setError(new CUDTException(3, 2, 0)); |
- return ERROR; |
- } |
- catch (...) |
- { |
- s_UDTUnited.setError(new CUDTException(-1, 0, 0)); |
- return ERROR; |
- } |
-} |
- |
-int64_t CUDT::recvfile(UDTSOCKET u, fstream& ofs, int64_t& offset, const int64_t& size, const int& block) |
-{ |
- try |
- { |
- CUDT* udt = s_UDTUnited.lookup(u); |
- return udt->recvfile(ofs, offset, size, block); |
- } |
- catch (CUDTException e) |
- { |
- s_UDTUnited.setError(new CUDTException(e)); |
- return ERROR; |
- } |
- catch (...) |
- { |
- s_UDTUnited.setError(new CUDTException(-1, 0, 0)); |
- return ERROR; |
- } |
-} |
- |
-int CUDT::select(int, ud_set* readfds, ud_set* writefds, ud_set* exceptfds, const timeval* timeout) |
-{ |
- if ((NULL == readfds) && (NULL == writefds) && (NULL == exceptfds)) |
- { |
- s_UDTUnited.setError(new CUDTException(5, 3, 0)); |
- return ERROR; |
- } |
- |
- try |
- { |
- return s_UDTUnited.select(readfds, writefds, exceptfds, timeout); |
- } |
- catch (CUDTException e) |
- { |
- s_UDTUnited.setError(new CUDTException(e)); |
- return ERROR; |
- } |
- catch (bad_alloc&) |
- { |
- s_UDTUnited.setError(new CUDTException(3, 2, 0)); |
- return ERROR; |
- } |
- catch (...) |
- { |
- s_UDTUnited.setError(new CUDTException(-1, 0, 0)); |
- return ERROR; |
- } |
-} |
- |
-int CUDT::selectEx(const vector<UDTSOCKET>& fds, vector<UDTSOCKET>* readfds, vector<UDTSOCKET>* writefds, vector<UDTSOCKET>* exceptfds, int64_t msTimeOut) |
-{ |
- if ((NULL == readfds) && (NULL == writefds) && (NULL == exceptfds)) |
- { |
- s_UDTUnited.setError(new CUDTException(5, 3, 0)); |
- return ERROR; |
- } |
- |
- try |
- { |
- return s_UDTUnited.selectEx(fds, readfds, writefds, exceptfds, msTimeOut); |
- } |
- catch (CUDTException e) |
- { |
- s_UDTUnited.setError(new CUDTException(e)); |
- return ERROR; |
- } |
- catch (bad_alloc&) |
- { |
- s_UDTUnited.setError(new CUDTException(3, 2, 0)); |
- return ERROR; |
- } |
- catch (...) |
- { |
- s_UDTUnited.setError(new CUDTException(-1, 0, 0)); |
- return ERROR; |
- } |
-} |
- |
-int CUDT::epoll_create() |
-{ |
- try |
- { |
- return s_UDTUnited.epoll_create(); |
- } |
- catch (CUDTException e) |
- { |
- s_UDTUnited.setError(new CUDTException(e)); |
- return ERROR; |
- } |
- catch (...) |
- { |
- s_UDTUnited.setError(new CUDTException(-1, 0, 0)); |
- return ERROR; |
- } |
-} |
- |
-int CUDT::epoll_add_usock(const int eid, const UDTSOCKET u, const int* events) |
-{ |
- try |
- { |
- return s_UDTUnited.epoll_add_usock(eid, u, events); |
- } |
- catch (CUDTException e) |
- { |
- s_UDTUnited.setError(new CUDTException(e)); |
- return ERROR; |
- } |
- catch (...) |
- { |
- s_UDTUnited.setError(new CUDTException(-1, 0, 0)); |
- return ERROR; |
- } |
-} |
- |
-int CUDT::epoll_add_ssock(const int eid, const SYSSOCKET s, const int* events) |
-{ |
- try |
- { |
- return s_UDTUnited.epoll_add_ssock(eid, s, events); |
- } |
- catch (CUDTException e) |
- { |
- s_UDTUnited.setError(new CUDTException(e)); |
- return ERROR; |
- } |
- catch (...) |
- { |
- s_UDTUnited.setError(new CUDTException(-1, 0, 0)); |
- return ERROR; |
- } |
-} |
- |
-int CUDT::epoll_remove_usock(const int eid, const UDTSOCKET u, const int* events) |
-{ |
- try |
- { |
- return s_UDTUnited.epoll_remove_usock(eid, u, events); |
- } |
- catch (CUDTException e) |
- { |
- s_UDTUnited.setError(new CUDTException(e)); |
- return ERROR; |
- } |
- catch (...) |
- { |
- s_UDTUnited.setError(new CUDTException(-1, 0, 0)); |
- return ERROR; |
- } |
-} |
- |
-int CUDT::epoll_remove_ssock(const int eid, const SYSSOCKET s, const int* events) |
-{ |
- try |
- { |
- return s_UDTUnited.epoll_remove_ssock(eid, s, events); |
- } |
- catch (CUDTException e) |
- { |
- s_UDTUnited.setError(new CUDTException(e)); |
- return ERROR; |
- } |
- catch (...) |
- { |
- s_UDTUnited.setError(new CUDTException(-1, 0, 0)); |
- return ERROR; |
- } |
-} |
- |
-int CUDT::epoll_wait(const int eid, set<UDTSOCKET>* readfds, set<UDTSOCKET>* writefds, int64_t msTimeOut, set<SYSSOCKET>* lrfds, set<SYSSOCKET>* lwfds) |
-{ |
- try |
- { |
- return s_UDTUnited.epoll_wait(eid, readfds, writefds, msTimeOut, lrfds, lwfds); |
- } |
- catch (CUDTException e) |
- { |
- s_UDTUnited.setError(new CUDTException(e)); |
- return ERROR; |
- } |
- catch (...) |
- { |
- s_UDTUnited.setError(new CUDTException(-1, 0, 0)); |
- return ERROR; |
- } |
-} |
- |
-int CUDT::epoll_release(const int eid) |
-{ |
- try |
- { |
- return s_UDTUnited.epoll_release(eid); |
- } |
- catch (CUDTException e) |
- { |
- s_UDTUnited.setError(new CUDTException(e)); |
- return ERROR; |
- } |
- catch (...) |
- { |
- s_UDTUnited.setError(new CUDTException(-1, 0, 0)); |
- return ERROR; |
- } |
-} |
- |
-CUDTException& CUDT::getlasterror() |
-{ |
- return *s_UDTUnited.getError(); |
-} |
- |
-int CUDT::perfmon(UDTSOCKET u, CPerfMon* perf, bool clear) |
-{ |
- try |
- { |
- CUDT* udt = s_UDTUnited.lookup(u); |
- udt->sample(perf, clear); |
- return 0; |
- } |
- catch (CUDTException e) |
- { |
- s_UDTUnited.setError(new CUDTException(e)); |
- return ERROR; |
- } |
- catch (...) |
- { |
- s_UDTUnited.setError(new CUDTException(-1, 0, 0)); |
- return ERROR; |
- } |
-} |
- |
-CUDT* CUDT::getUDTHandle(UDTSOCKET u) |
-{ |
- try |
- { |
- return s_UDTUnited.lookup(u); |
- } |
- catch (...) |
- { |
- return NULL; |
- } |
-} |
- |
-UDTSTATUS CUDT::getsockstate(UDTSOCKET u) |
-{ |
- try |
- { |
- return s_UDTUnited.getStatus(u); |
- } |
- catch (...) |
- { |
- s_UDTUnited.setError(new CUDTException(-1, 0, 0)); |
- return NONEXIST; |
- } |
-} |
- |
- |
-//////////////////////////////////////////////////////////////////////////////// |
- |
-namespace UDT |
-{ |
- |
-int startup() |
-{ |
- return CUDT::startup(); |
-} |
- |
-int cleanup() |
-{ |
- return CUDT::cleanup(); |
-} |
- |
-UDTSOCKET socket(int af, int type, int protocol) |
-{ |
- return CUDT::socket(af, type, protocol); |
-} |
- |
-int bind(UDTSOCKET u, const struct sockaddr* name, int namelen) |
-{ |
- return CUDT::bind(u, name, namelen); |
-} |
- |
-int bind(UDTSOCKET u, UDPSOCKET udpsock) |
-{ |
- return CUDT::bind(u, udpsock); |
-} |
- |
-int listen(UDTSOCKET u, int backlog) |
-{ |
- return CUDT::listen(u, backlog); |
-} |
- |
-UDTSOCKET accept(UDTSOCKET u, struct sockaddr* addr, int* addrlen) |
-{ |
- return CUDT::accept(u, addr, addrlen); |
-} |
- |
-int connect(UDTSOCKET u, const struct sockaddr* name, int namelen) |
-{ |
- return CUDT::connect(u, name, namelen); |
-} |
- |
-int close(UDTSOCKET u) |
-{ |
- return CUDT::close(u); |
-} |
- |
-int getpeername(UDTSOCKET u, struct sockaddr* name, int* namelen) |
-{ |
- return CUDT::getpeername(u, name, namelen); |
-} |
- |
-int getsockname(UDTSOCKET u, struct sockaddr* name, int* namelen) |
-{ |
- return CUDT::getsockname(u, name, namelen); |
-} |
- |
-int getsockopt(UDTSOCKET u, int level, SOCKOPT optname, void* optval, int* optlen) |
-{ |
- return CUDT::getsockopt(u, level, optname, optval, optlen); |
-} |
- |
-int setsockopt(UDTSOCKET u, int level, SOCKOPT optname, const void* optval, int optlen) |
-{ |
- return CUDT::setsockopt(u, level, optname, optval, optlen); |
-} |
- |
-int send(UDTSOCKET u, const char* buf, int len, int flags) |
-{ |
- return CUDT::send(u, buf, len, flags); |
-} |
- |
-int recv(UDTSOCKET u, char* buf, int len, int flags) |
-{ |
- return CUDT::recv(u, buf, len, flags); |
-} |
- |
-int sendmsg(UDTSOCKET u, const char* buf, int len, int ttl, bool inorder) |
-{ |
- return CUDT::sendmsg(u, buf, len, ttl, inorder); |
-} |
- |
-int recvmsg(UDTSOCKET u, char* buf, int len) |
-{ |
- return CUDT::recvmsg(u, buf, len); |
-} |
- |
-int64_t sendfile(UDTSOCKET u, fstream& ifs, int64_t& offset, int64_t size, int block) |
-{ |
- return CUDT::sendfile(u, ifs, offset, size, block); |
-} |
- |
-int64_t recvfile(UDTSOCKET u, fstream& ofs, int64_t& offset, int64_t size, int block) |
-{ |
- return CUDT::recvfile(u, ofs, offset, size, block); |
-} |
- |
-int select(int nfds, UDSET* readfds, UDSET* writefds, UDSET* exceptfds, const struct timeval* timeout) |
-{ |
- return CUDT::select(nfds, readfds, writefds, exceptfds, timeout); |
-} |
- |
-int selectEx(const vector<UDTSOCKET>& fds, vector<UDTSOCKET>* readfds, vector<UDTSOCKET>* writefds, vector<UDTSOCKET>* exceptfds, int64_t msTimeOut) |
-{ |
- return CUDT::selectEx(fds, readfds, writefds, exceptfds, msTimeOut); |
-} |
- |
-int epoll_create() |
-{ |
- return CUDT::epoll_create(); |
-} |
- |
-int epoll_add_usock(const int eid, const UDTSOCKET u, const int* events) |
-{ |
- return CUDT::epoll_add_usock(eid, u, events); |
-} |
- |
-int epoll_add_ssock(const int eid, const SYSSOCKET s, const int* events) |
-{ |
- return CUDT::epoll_add_ssock(eid, s, events); |
-} |
- |
-int epoll_remove_usock(const int eid, const UDTSOCKET u, const int* events) |
-{ |
- return CUDT::epoll_remove_usock(eid, u, events); |
-} |
- |
-int epoll_remove_ssock(const int eid, const SYSSOCKET s, const int* events) |
-{ |
- return CUDT::epoll_remove_usock(eid, s, events); |
-} |
- |
-int epoll_wait(const int eid, set<int>* readfds, set<int>* writefds, int64_t msTimeOut, set<SYSSOCKET>* lrfds, set<SYSSOCKET>* lwfds) |
-{ |
- return CUDT::epoll_wait(eid, readfds, writefds, msTimeOut, lrfds, lwfds); |
-} |
- |
-int epoll_release(const int eid) |
-{ |
- return CUDT::epoll_release(eid); |
-} |
- |
-ERRORINFO& getlasterror() |
-{ |
- return CUDT::getlasterror(); |
-} |
- |
-int perfmon(UDTSOCKET u, TRACEINFO* perf, bool clear) |
-{ |
- return CUDT::perfmon(u, perf, clear); |
-} |
- |
-UDTSTATUS getsockstate(UDTSOCKET u) |
-{ |
- return CUDT::getsockstate(u); |
-} |
- |
-} |