+// ***************************************************************************
+// TcpSocketEngine_win_p.cpp (c) 2011 Derek Barnett
+// Marth Lab, Department of Biology, Boston College
+// ---------------------------------------------------------------------------
+// Last modified: 10 November 2011 (DB)
+// ---------------------------------------------------------------------------
+// Provides low-level implementation of TCP I/O for all Windows systems
+// ***************************************************************************
+
#include "api/internal/io/TcpSocketEngine_p.h"
#include "api/internal/io/NetWin_p.h"
using namespace BamTools;
namespace BamTools {
namespace Internal {
-static inline
-void getPortAndAddress(const sockaddr* s, uint16_t& port, HostAddress& address) {
-
- // IPv6
- if (s->sa_family == AF_INET6) {
- sockaddr_in6* ip6 = (sockaddr_in6*)s;
- port = ntohs(ip6->sin6_port);
- IPv6Address tmp;
- memcpy(&tmp, &ip6->sin6_addr.in6_addr, sizeof(tmp));
- address.SetAddress(tmp);
- return;
- }
-
- // IPv4
- if ( s->sa_family == AF_INET ) {
- sockaddr_in* ip4 = (sockaddr_in*)s;
- port = ntohl(ip4->sin_port);
- address.SetAddress( ntohl(ip4->sin_addr) );
- return;
- }
-
- // should be unreachable
- BT_ASSERT_X(false, "TcpSocketEngine::getPortAndAddress() : unknown network protocol ");
- return false;
-}
+//static inline
+//void getPortAndAddress(const sockaddr* s, uint16_t& port, HostAddress& address) {
+
+// // IPv6
+// if (s->sa_family == AF_INET6) {
+// sockaddr_in6* ip6 = (sockaddr_in6*)s;
+// port = ntohs(ip6->sin6_port);
+// IPv6Address tmp;
+// memcpy(&tmp, &ip6->sin6_addr.in6_addr, sizeof(tmp));
+// address.SetAddress(tmp);
+// return;
+// }
+
+// // IPv4
+// if ( s->sa_family == AF_INET ) {
+// sockaddr_in* ip4 = (sockaddr_in*)s;
+// port = ntohl(ip4->sin_port);
+// address.SetAddress( ntohl(ip4->sin_addr) );
+// return;
+// }
+
+// // should be unreachable
+// BT_ASSERT_X(false, "TcpSocketEngine::getPortAndAddress() : unknown network protocol ");
+// return false;
+//}
} // namespace Internal
} // namespace BamTools
// --------------------------------
void TcpSocketEngine::nativeClose(void) {
- close(m_socketDescriptor);
+
+// close(m_socketDescriptor);
}
bool TcpSocketEngine::nativeConnect(const HostAddress& address, const uint16_t port) {
// setup connection parameters from address/port
- sockaddr_in sockAddrIPv4;
- sockaddr_in6 sockAddrIPv6;
- sockaddr* sockAddrPtr = 0;
- BT_SOCKLEN_T sockAddrSize = 0;
-
- // IPv6
- if ( address.GetProtocol() == HostAddress::IPv6Protocol ) {
-
- memset(&sockAddrIPv6, 0, sizeof(sockAddrIPv6));
- sockAddrIPv6.sin6_family = AF_INET6;
- sockAddrIPv6.sin6_port = htons(port);
-
- IPv6Address ip6 = address.GetIPv6Address();
- memcpy(&sockAddrIPv6.sin6_addr.s6_addr, &ip6, sizeof(ip6));
-
- sockAddrSize = sizeof(sockAddrIPv6);
- sockAddrPtr = (sockaddr*)&sockAddrIPv6;
- }
-
- // IPv4
- else if ( address.GetProtocol() == HostAddress::IPv4Protocol ) {
-
- memset(&sockAddrIPv4, 0, sizeof(sockAddrIPv4));
- sockAddrIPv4.sin_family = AF_INET;
- sockAddrIPv4.sin_port = htons(port);
- sockAddrIPv4.sin_addr.s_addr = htonl(address.GetIPv4Address());
-
- sockAddrSize = sizeof(sockAddrIPv4);
- sockAddrPtr = (sockaddr*)&sockAddrIPv4;
- }
-
- // unknown (should be unreachable)
- else BT_ASSERT_X(false, "TcpSocketEngine::nativeConnect() : unknown network protocol");
-
- // attempt conenction
- int connectResult = connect(socketDescriptor, sockAddrPtr, sockAddrSize);
-
- // if hit error
- if ( connectResult == -1 ) {
-
- // see what error was encountered
- switch ( errno ) {
-
- case EISCONN:
- m_socketState = TcpSocket::ConnectedState;
- break;
- case ECONNREFUSED:
- case EINVAL:
- m_socketError = TcpSocket::ConnectionRefusedError;
- m_socketState = TcpSocket::UnconnectedState;
- m_errorString = "connection refused";
- break;
- case ETIMEDOUT:
- m_socketError = TcpSocket::NetworkError;
- m_errorString = "connection timed out";
- break;
- case EHOSTUNREACH:
- m_socketError = TcpSocket::NetworkError;
- m_socketState = TcpSocket::UnconnectedState;
- m_errorString = "host unreachable";
- break;
- case ENETUNREACH:
- m_socketError = TcpSocket::NetworkError;
- m_socketState = TcpSocket::UnconnectedState;
- m_errorString = "network unreachable";
- break;
- case EADDRINUSE:
- m_socketError = TcpSocket::NetworkError;
- m_errorString = "address already in use";
- break;
- case EACCES:
- case EPERM:
- m_socketError = TcpSocket::SocketAccessError;
- m_socketState = TcpSocket::UnconnectedState;
- m_errorString = "permission denied";
- case EAFNOSUPPORT:
- case EBADF:
- case EFAULT:
- case ENOTSOCK:
- m_socketState = TcpSocket::UnconnectedState;
- default:
- break;
- }
-
- if ( m_socketState != TcpSocket::ConnectedState )
- return false;
- }
-
- // otherwise, we should be good
- // update state & return success
- m_socketState = TcpSocket::ConnectedState;
- return true;
+// sockaddr_in sockAddrIPv4;
+// sockaddr_in6 sockAddrIPv6;
+// sockaddr* sockAddrPtr = 0;
+// BT_SOCKLEN_T sockAddrSize = 0;
+
+// // IPv6
+// if ( address.GetProtocol() == HostAddress::IPv6Protocol ) {
+
+// memset(&sockAddrIPv6, 0, sizeof(sockAddrIPv6));
+// sockAddrIPv6.sin6_family = AF_INET6;
+// sockAddrIPv6.sin6_port = htons(port);
+
+// IPv6Address ip6 = address.GetIPv6Address();
+// memcpy(&sockAddrIPv6.sin6_addr.s6_addr, &ip6, sizeof(ip6));
+
+// sockAddrSize = sizeof(sockAddrIPv6);
+// sockAddrPtr = (sockaddr*)&sockAddrIPv6;
+// }
+
+// // IPv4
+// else if ( address.GetProtocol() == HostAddress::IPv4Protocol ) {
+
+// memset(&sockAddrIPv4, 0, sizeof(sockAddrIPv4));
+// sockAddrIPv4.sin_family = AF_INET;
+// sockAddrIPv4.sin_port = htons(port);
+// sockAddrIPv4.sin_addr.s_addr = htonl(address.GetIPv4Address());
+
+// sockAddrSize = sizeof(sockAddrIPv4);
+// sockAddrPtr = (sockaddr*)&sockAddrIPv4;
+// }
+
+// // unknown (should be unreachable)
+// else BT_ASSERT_X(false, "TcpSocketEngine::nativeConnect() : unknown network protocol");
+
+// // attempt conenction
+// int connectResult = connect(socketDescriptor, sockAddrPtr, sockAddrSize);
+
+// // if hit error
+// if ( connectResult == -1 ) {
+
+// // see what error was encountered
+// switch ( errno ) {
+
+// case EISCONN:
+// m_socketState = TcpSocket::ConnectedState;
+// break;
+// case ECONNREFUSED:
+// case EINVAL:
+// m_socketError = TcpSocket::ConnectionRefusedError;
+// m_socketState = TcpSocket::UnconnectedState;
+// m_errorString = "connection refused";
+// break;
+// case ETIMEDOUT:
+// m_socketError = TcpSocket::NetworkError;
+// m_errorString = "connection timed out";
+// break;
+// case EHOSTUNREACH:
+// m_socketError = TcpSocket::NetworkError;
+// m_socketState = TcpSocket::UnconnectedState;
+// m_errorString = "host unreachable";
+// break;
+// case ENETUNREACH:
+// m_socketError = TcpSocket::NetworkError;
+// m_socketState = TcpSocket::UnconnectedState;
+// m_errorString = "network unreachable";
+// break;
+// case EADDRINUSE:
+// m_socketError = TcpSocket::NetworkError;
+// m_errorString = "address already in use";
+// break;
+// case EACCES:
+// case EPERM:
+// m_socketError = TcpSocket::SocketAccessError;
+// m_socketState = TcpSocket::UnconnectedState;
+// m_errorString = "permission denied";
+// case EAFNOSUPPORT:
+// case EBADF:
+// case EFAULT:
+// case ENOTSOCK:
+// m_socketState = TcpSocket::UnconnectedState;
+// default:
+// break;
+// }
+
+// if ( m_socketState != TcpSocket::ConnectedState )
+// return false;
+// }
+
+// // otherwise, we should be good
+// // update state & return success
+// m_socketState = TcpSocket::ConnectedState;
+// return true;
}
bool TcpSocketEngine::nativeCreateSocket(HostAddress::NetworkProtocol protocol) {
- // get protocol value for requested protocol type
- const int protocolNum = ( (protocol == HostAddress::IPv6Protocol) ? AF_INET6 : AF_INET );
-
- // attempt to create socket
- int socketFd = socket(protocolNum, SOCK_STREAM, IPPROTO_TCP);
-
- // if we fetched an invalid socket descriptor
- if ( socketFd <= 0 ) {
-
- // see what error we got
- switch ( errno ) {
- case EPROTONOSUPPORT:
- case EAFNOSUPPORT:
- case EINVAL:
- m_socketError = TcpSocket::UnsupportedSocketOperationError;
- m_errorString = "protocol not supported";
- break;
- case ENFILE:
- case EMFILE:
- case ENOBUFS:
- case ENOMEM:
- m_socketError = TcpSocket::SocketResourceError;
- m_errorString = "out of resources";
- break;
- case EACCES:
- m_socketError = TcpSocket::SocketAccessError;
- m_errorString = "permission denied";
- break;
- default:
- break;
- }
-
- // return failure
- return false;
- }
-
- // otherwise, store our socket FD & return success
- m_socketDescriptor = socketFd;
- return true;
+// // get protocol value for requested protocol type
+// const int protocolNum = ( (protocol == HostAddress::IPv6Protocol) ? AF_INET6 : AF_INET );
+
+// // attempt to create socket
+// int socketFd = socket(protocolNum, SOCK_STREAM, IPPROTO_TCP);
+
+// // if we fetched an invalid socket descriptor
+// if ( socketFd <= 0 ) {
+
+// // see what error we got
+// switch ( errno ) {
+// case EPROTONOSUPPORT:
+// case EAFNOSUPPORT:
+// case EINVAL:
+// m_socketError = TcpSocket::UnsupportedSocketOperationError;
+// m_errorString = "protocol not supported";
+// break;
+// case ENFILE:
+// case EMFILE:
+// case ENOBUFS:
+// case ENOMEM:
+// m_socketError = TcpSocket::SocketResourceError;
+// m_errorString = "out of resources";
+// break;
+// case EACCES:
+// m_socketError = TcpSocket::SocketAccessError;
+// m_errorString = "permission denied";
+// break;
+// default:
+// break;
+// }
+
+// // return failure
+// return false;
+// }
+
+// // otherwise, store our socket FD & return success
+// m_socketDescriptor = socketFd;
+// return true;
}
-bool TcpSocketEngine::nativeFetchConnectionParameters(void) {
-
- // reset addresses/ports
- m_localAddress.Clear();
- m_remoteAddress.Clear();
- m_localPort = 0;
- m_remotePort = 0;
-
- // skip (return failure) if invalid socket FD
- if ( m_socketDescriptor == -1 )
- return false;
-
- sockaddr sa;
- BT_SOCKLEN_T sockAddrSize = sizeof(sa);
-
- // fetch local address info
- memset(&sa, 0, sizeof(sa));
- if ( getsockname(m_socketDescriptor, &sa, &sockAddrSize) == 0 ) {
- getPortAndAddress(&sa, m_localPort, m_localAddress);
- }
- else if ( errno == EBADF ) {
- m_socketError = TcpSocket::UnsupportedSocketOperationError;
- m_errorString = "invalid socket descriptor";
- return false;
- }
-
- // fetch remote address
- if ( getpeername(m_socketDescriptor, &sa, &sockAddrSize) == 0 )
- getPortAndAddress(&sa, m_remotePort, m_remoteAddress);
-
- // return success
- return true;
-}
+//bool TcpSocketEngine::nativeFetchConnectionParameters(void) {
+
+// // reset addresses/ports
+// m_localAddress.Clear();
+// m_remoteAddress.Clear();
+// m_localPort = 0;
+// m_remotePort = 0;
+
+// // skip (return failure) if invalid socket FD
+// if ( m_socketDescriptor == -1 )
+// return false;
+
+// sockaddr sa;
+// BT_SOCKLEN_T sockAddrSize = sizeof(sa);
+
+// // fetch local address info
+// memset(&sa, 0, sizeof(sa));
+// if ( getsockname(m_socketDescriptor, &sa, &sockAddrSize) == 0 ) {
+// getPortAndAddress(&sa, m_localPort, m_localAddress);
+// }
+// else if ( errno == EBADF ) {
+// m_socketError = TcpSocket::UnsupportedSocketOperationError;
+// m_errorString = "invalid socket descriptor";
+// return false;
+// }
+
+// // fetch remote address
+// if ( getpeername(m_socketDescriptor, &sa, &sockAddrSize) == 0 )
+// getPortAndAddress(&sa, m_remotePort, m_remoteAddress);
+
+// // return success
+// return true;
+//}
size_t TcpSocketEngine::nativeNumBytesAvailable(void) const {
- // fetch number of bytes, return 0 on error
- int numBytes(0);
- if ( ioctl(m_socketDescriptor, FIONREAD, (char*)&numBytes) < 0 )
- return 0;
- return static_cast<size_t>(numBytes);
+// // fetch number of bytes, return 0 on error
+// int numBytes(0);
+// if ( ioctl(m_socketDescriptor, FIONREAD, (char*)&numBytes) < 0 )
+// return 0;
+// return static_cast<size_t>(numBytes);
}
int64_t TcpSocketEngine::nativeRead(char* dest, size_t max) {
- if ( !IsValid() )
- return -1;
-
- ssize_t ret = read(m_socketDescriptor, dest, max);
- if ( ret < 0 ) {
- ret = -1;
- switch ( errno ) {
- case EAGAIN :
- // No data was available for reading
- ret = -2;
- break;
- case ECONNRESET :
- ret = 0;
- break;
- default:
- break;
- }
- }
-
- return static_cast<int64_t>(ret);
+// if ( !IsValid() )
+// return -1;
+
+// ssize_t ret = read(m_socketDescriptor, dest, max);
+// if ( ret < 0 ) {
+// ret = -1;
+// switch ( errno ) {
+// case EAGAIN :
+// // No data was available for reading
+// ret = -2;
+// break;
+// case ECONNRESET :
+// ret = 0;
+// break;
+// default:
+// break;
+// }
+// }
+
+// return static_cast<int64_t>(ret);
}
// negative value for msecs will block (forever) until
int TcpSocketEngine::nativeSelect(int msecs, bool isRead) const {
- // set up FD set
- fd_set fds;
- FD_ZERO(&fds);
- FD_SET(m_socketDescriptor, &fds);
-
- // setup our timeout
- timeval tv;
- tv.tv_sec = msecs / 1000;
- tv.tv_usec = (msecs % 1000) * 1000;
-
- // do 'select'
- int ret;
- if ( isRead )
- ret = select(m_socketDescriptor + 1, &fds, 0, 0, (msecs < 0 ? 0 : &tv));
- else
- ret = select(m_socketDescriptor + 1, 0, &fds, 0, (msecs < 0 ? 0 : &tv));
- return ret;
+// // set up FD set
+// fd_set fds;
+// FD_ZERO(&fds);
+// FD_SET(m_socketDescriptor, &fds);
+
+// // setup our timeout
+// timeval tv;
+// tv.tv_sec = msecs / 1000;
+// tv.tv_usec = (msecs % 1000) * 1000;
+
+// // do 'select'
+// int ret;
+// if ( isRead )
+// ret = select(m_socketDescriptor + 1, &fds, 0, 0, (msecs < 0 ? 0 : &tv));
+// else
+// ret = select(m_socketDescriptor + 1, 0, &fds, 0, (msecs < 0 ? 0 : &tv));
+// return ret;
}
int64_t TcpSocketEngine::nativeWrite(const char* data, size_t length) {
- ssize_t writtenBytes = write(m_socketDescriptor, data, length);
- if ( writtenBytes < 0 ) {
- switch (errno) {
- case EPIPE:
- case ECONNRESET:
- writtenBytes = -1;
- m_socketError = TcpSocket::RemoteHostClosedError;
- m_errorString = "remote host closed connection";
- Close();
- break;
- case EAGAIN:
- writtenBytes = 0;
- break;
- default:
- break;
- }
- }
-
- return static_cast<int64_t>(writtenBytes);
+// ssize_t writtenBytes = write(m_socketDescriptor, data, length);
+// if ( writtenBytes < 0 ) {
+// switch (errno) {
+// case EPIPE:
+// case ECONNRESET:
+// writtenBytes = -1;
+// m_socketError = TcpSocket::RemoteHostClosedError;
+// m_errorString = "remote host closed connection";
+// Close();
+// break;
+// case EAGAIN:
+// writtenBytes = 0;
+// break;
+// default:
+// break;
+// }
+// }
+
+// return static_cast<int64_t>(writtenBytes);
}