Index: net/third_party/udt/src/channel.cpp |
=================================================================== |
--- net/third_party/udt/src/channel.cpp (revision 78992) |
+++ net/third_party/udt/src/channel.cpp (working copy) |
@@ -1,346 +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/27/2011 |
-*****************************************************************************/ |
- |
-#ifndef WIN32 |
- #include <netdb.h> |
- #include <arpa/inet.h> |
- #include <unistd.h> |
- #include <fcntl.h> |
- #include <cstring> |
- #include <cstdio> |
- #include <cerrno> |
-#else |
- #include <winsock2.h> |
- #include <ws2tcpip.h> |
- #ifdef LEGACY_WIN32 |
- #include <wspiapi.h> |
- #endif |
-#endif |
-#include "channel.h" |
-#include "packet.h" |
- |
-#ifdef WIN32 |
- #define socklen_t int |
-#endif |
- |
-#ifndef WIN32 |
- #define NET_ERROR errno |
-#else |
- #define NET_ERROR WSAGetLastError() |
-#endif |
- |
- |
-CChannel::CChannel(): |
-m_iIPversion(AF_INET), |
-m_iSockAddrSize(sizeof(sockaddr_in)), |
-m_iSocket(), |
-m_iSndBufSize(65536), |
-m_iRcvBufSize(65536) |
-{ |
-} |
- |
-CChannel::CChannel(const int& version): |
-m_iIPversion(version), |
-m_iSocket(), |
-m_iSndBufSize(65536), |
-m_iRcvBufSize(65536) |
-{ |
- m_iSockAddrSize = (AF_INET == m_iIPversion) ? sizeof(sockaddr_in) : sizeof(sockaddr_in6); |
-} |
- |
-CChannel::~CChannel() |
-{ |
-} |
- |
-void CChannel::open(const sockaddr* addr) |
-{ |
- // construct an socket |
- m_iSocket = socket(m_iIPversion, SOCK_DGRAM, 0); |
- |
- #ifdef WIN32 |
- if (INVALID_SOCKET == m_iSocket) |
- #else |
- if (m_iSocket < 0) |
- #endif |
- throw CUDTException(1, 0, NET_ERROR); |
- |
- if (NULL != addr) |
- { |
- socklen_t namelen = m_iSockAddrSize; |
- |
- if (0 != bind(m_iSocket, addr, namelen)) |
- throw CUDTException(1, 3, NET_ERROR); |
- } |
- else |
- { |
- //sendto or WSASendTo will also automatically bind the socket |
- addrinfo hints; |
- addrinfo* res; |
- |
- memset(&hints, 0, sizeof(struct addrinfo)); |
- |
- hints.ai_flags = AI_PASSIVE; |
- hints.ai_family = m_iIPversion; |
- hints.ai_socktype = SOCK_DGRAM; |
- |
- if (0 != getaddrinfo(NULL, "0", &hints, &res)) |
- throw CUDTException(1, 3, NET_ERROR); |
- |
- if (0 != bind(m_iSocket, res->ai_addr, res->ai_addrlen)) |
- throw CUDTException(1, 3, NET_ERROR); |
- |
- freeaddrinfo(res); |
- } |
- |
- setUDPSockOpt(); |
-} |
- |
-void CChannel::open(UDPSOCKET udpsock) |
-{ |
- m_iSocket = udpsock; |
- setUDPSockOpt(); |
-} |
- |
-void CChannel::setUDPSockOpt() |
-{ |
- #if defined(BSD) || defined(OSX) |
- // BSD system will fail setsockopt if the requested buffer size exceeds system maximum value |
- int maxsize = 64000; |
- if (0 != setsockopt(m_iSocket, SOL_SOCKET, SO_RCVBUF, (char*)&m_iRcvBufSize, sizeof(int))) |
- setsockopt(m_iSocket, SOL_SOCKET, SO_RCVBUF, (char*)&maxsize, sizeof(int)); |
- if (0 != setsockopt(m_iSocket, SOL_SOCKET, SO_SNDBUF, (char*)&m_iSndBufSize, sizeof(int))) |
- setsockopt(m_iSocket, SOL_SOCKET, SO_SNDBUF, (char*)&maxsize, sizeof(int)); |
- #else |
- // for other systems, if requested is greated than maximum, the maximum value will be automactally used |
- if ((0 != setsockopt(m_iSocket, SOL_SOCKET, SO_RCVBUF, (char*)&m_iRcvBufSize, sizeof(int))) || |
- (0 != setsockopt(m_iSocket, SOL_SOCKET, SO_SNDBUF, (char*)&m_iSndBufSize, sizeof(int)))) |
- throw CUDTException(1, 3, NET_ERROR); |
- #endif |
- |
- timeval tv; |
- tv.tv_sec = 0; |
- #if defined (BSD) || defined (OSX) |
- // Known BSD bug as the day I wrote this code. |
- // A small time out value will cause the socket to block forever. |
- tv.tv_usec = 10000; |
- #else |
- tv.tv_usec = 100; |
- #endif |
- |
- #ifdef UNIX |
- // Set non-blocking I/O |
- // UNIX does not support SO_RCVTIMEO |
- int opts = fcntl(m_iSocket, F_GETFL); |
- if (-1 == fcntl(m_iSocket, F_SETFL, opts | O_NONBLOCK)) |
- throw CUDTException(1, 3, NET_ERROR); |
- #elif WIN32 |
- DWORD ot = 1; //milliseconds |
- if (0 != setsockopt(m_iSocket, SOL_SOCKET, SO_RCVTIMEO, (char *)&ot, sizeof(DWORD))) |
- throw CUDTException(1, 3, NET_ERROR); |
- #else |
- // Set receiving time-out value |
- if (0 != setsockopt(m_iSocket, SOL_SOCKET, SO_RCVTIMEO, (char *)&tv, sizeof(timeval))) |
- throw CUDTException(1, 3, NET_ERROR); |
- #endif |
-} |
- |
-void CChannel::close() const |
-{ |
- #ifndef WIN32 |
- ::close(m_iSocket); |
- #else |
- closesocket(m_iSocket); |
- #endif |
-} |
- |
-int CChannel::getSndBufSize() |
-{ |
- socklen_t size = sizeof(socklen_t); |
- |
- getsockopt(m_iSocket, SOL_SOCKET, SO_SNDBUF, (char *)&m_iSndBufSize, &size); |
- |
- return m_iSndBufSize; |
-} |
- |
-int CChannel::getRcvBufSize() |
-{ |
- socklen_t size = sizeof(socklen_t); |
- |
- getsockopt(m_iSocket, SOL_SOCKET, SO_RCVBUF, (char *)&m_iRcvBufSize, &size); |
- |
- return m_iRcvBufSize; |
-} |
- |
-void CChannel::setSndBufSize(const int& size) |
-{ |
- m_iSndBufSize = size; |
-} |
- |
-void CChannel::setRcvBufSize(const int& size) |
-{ |
- m_iRcvBufSize = size; |
-} |
- |
-void CChannel::getSockAddr(sockaddr* addr) const |
-{ |
- socklen_t namelen = m_iSockAddrSize; |
- |
- getsockname(m_iSocket, addr, &namelen); |
-} |
- |
-void CChannel::getPeerAddr(sockaddr* addr) const |
-{ |
- socklen_t namelen = m_iSockAddrSize; |
- |
- getpeername(m_iSocket, addr, &namelen); |
-} |
- |
-int CChannel::sendto(const sockaddr* addr, CPacket& packet) const |
-{ |
- // convert control information into network order |
- if (packet.getFlag()) |
- for (int i = 0, n = packet.getLength() / 4; i < n; ++ i) |
- *((uint32_t *)packet.m_pcData + i) = htonl(*((uint32_t *)packet.m_pcData + i)); |
- |
- // convert packet header into network order |
- //for (int j = 0; j < 4; ++ j) |
- // packet.m_nHeader[j] = htonl(packet.m_nHeader[j]); |
- uint32_t* p = packet.m_nHeader; |
- for (int j = 0; j < 4; ++ j) |
- { |
- *p = htonl(*p); |
- ++ p; |
- } |
- |
- #ifndef WIN32 |
- msghdr mh; |
- mh.msg_name = (sockaddr*)addr; |
- mh.msg_namelen = m_iSockAddrSize; |
- mh.msg_iov = (iovec*)packet.m_PacketVector; |
- mh.msg_iovlen = 2; |
- mh.msg_control = NULL; |
- mh.msg_controllen = 0; |
- mh.msg_flags = 0; |
- |
- int res = sendmsg(m_iSocket, &mh, 0); |
- #else |
- DWORD size = CPacket::m_iPktHdrSize + packet.getLength(); |
- int addrsize = m_iSockAddrSize; |
- int res = WSASendTo(m_iSocket, (LPWSABUF)packet.m_PacketVector, 2, &size, 0, addr, addrsize, NULL, NULL); |
- res = (0 == res) ? size : -1; |
- #endif |
- |
- // convert back into local host order |
- //for (int k = 0; k < 4; ++ k) |
- // packet.m_nHeader[k] = ntohl(packet.m_nHeader[k]); |
- p = packet.m_nHeader; |
- for (int k = 0; k < 4; ++ k) |
- { |
- *p = ntohl(*p); |
- ++ p; |
- } |
- |
- if (packet.getFlag()) |
- { |
- for (int l = 0, n = packet.getLength() / 4; l < n; ++ l) |
- *((uint32_t *)packet.m_pcData + l) = ntohl(*((uint32_t *)packet.m_pcData + l)); |
- } |
- |
- return res; |
-} |
- |
-int CChannel::recvfrom(sockaddr* addr, CPacket& packet) const |
-{ |
- #ifndef WIN32 |
- msghdr mh; |
- mh.msg_name = addr; |
- mh.msg_namelen = m_iSockAddrSize; |
- mh.msg_iov = packet.m_PacketVector; |
- mh.msg_iovlen = 2; |
- mh.msg_control = NULL; |
- mh.msg_controllen = 0; |
- mh.msg_flags = 0; |
- |
- #ifdef UNIX |
- fd_set set; |
- timeval tv; |
- FD_ZERO(&set); |
- FD_SET(m_iSocket, &set); |
- tv.tv_sec = 0; |
- tv.tv_usec = 10000; |
- select(m_iSocket+1, &set, NULL, &set, &tv); |
- #endif |
- |
- int res = recvmsg(m_iSocket, &mh, 0); |
- #else |
- DWORD size = CPacket::m_iPktHdrSize + packet.getLength(); |
- DWORD flag = 0; |
- int addrsize = m_iSockAddrSize; |
- |
- int res = WSARecvFrom(m_iSocket, (LPWSABUF)packet.m_PacketVector, 2, &size, &flag, addr, &addrsize, NULL, NULL); |
- res = (0 == res) ? size : -1; |
- #endif |
- |
- if (res <= 0) |
- { |
- packet.setLength(-1); |
- return -1; |
- } |
- |
- packet.setLength(res - CPacket::m_iPktHdrSize); |
- |
- // convert back into local host order |
- //for (int i = 0; i < 4; ++ i) |
- // packet.m_nHeader[i] = ntohl(packet.m_nHeader[i]); |
- uint32_t* p = packet.m_nHeader; |
- for (int i = 0; i < 4; ++ i) |
- { |
- *p = ntohl(*p); |
- ++ p; |
- } |
- |
- if (packet.getFlag()) |
- { |
- for (int j = 0, n = packet.getLength() / 4; j < n; ++ j) |
- *((uint32_t *)packet.m_pcData + j) = ntohl(*((uint32_t *)packet.m_pcData + j)); |
- } |
- |
- return packet.getLength(); |
-} |