TCPSocket *TCPSocket::connect(SockAddress dest, int port) throw(SocketConnectionRefused) { TCPSocket *sock; if(dest.type() == SockAddress::V4) { sock = new TCPSocket(::socket(AF_INET, SOCK_STREAM, 0)); struct sockaddr_in address; address.sin_family = AF_INET; address.sin_addr.s_addr = htonl(dest.v4toUint()); address.sin_port = htons(port); memset(&(address.sin_zero), 0, 8); if(::connect(sock->getSocket(), (struct sockaddr*)&address, sizeof(address)) == -1) throw SocketConnectionRefused(); } else throw SocketConnectionRefused(); return sock; }
SocketPort::SocketPort(SocketService *svc, TCPSocket &tcp) : Socket(accept(tcp.getSocket(), NULL, NULL)) { detect_pending = true; detect_output = false; detect_disconnect = true; #ifdef WIN32 // FIXME: error handling event = CreateEvent(NULL,TRUE,FALSE,NULL); #endif next = prev = NULL; service = NULL; // FIXME: use macro here and in other files... #ifndef WIN32 if(so > -1) #else if(so != INVALID_SOCKET) #endif { setError(false); if( svc ) svc->attach(this); } }
uint16_t networkWriter(void *userdata, uint8_t *data, uint16_t length) { if(userdata == NULL) { return 0; } TCPSocket *tcps = (TCPSocket *)userdata; std::vector<uint8_t> buffer(data, data + length); boost::system::error_code ignored_error; ssize_t result = boost::asio::write(*(tcps->getSocket()), boost::asio::buffer(buffer), ignored_error); if(result < 0) { result = 0; } return (uint16_t)result; }
void SocketPort::init(SocketService *svc,TCPSocket &tcp) { Socket::init(accept(tcp.getSocket(),NULL,NULL)); detect_pending = true; detect_output = false; detect_disconnect = true; next = prev = NULL; service = NULL; // FIXME: use macro here and in other files... if(so > -1) { setError(false); if( svc ) svc->attach(this); } }
int16_t networkReader(void *userdata) { if(userdata == NULL) { return 0; } TCPSocket *tcps = (TCPSocket *)userdata; uint8_t data[1]; ssize_t result = 0; try { result = boost::asio::read(*(tcps->getSocket()), boost::asio::buffer(data, 1)); } catch (std::exception& e) { return -2; } if(result <= 0) { return -1; } else { return (uint16_t)data[0]; } }
void TCPStream::connect(TCPSocket &tcpip) { tpport_t port; endStream(); family = IPV4; so = accept(tcpip.getSocket(), NULL, NULL); if(so == INVALID_SOCKET) return; IPV4Host host = getPeer(&port); if(!tcpip.onAccept(host, port)) { endSocket(); iostream::clear(ios::failbit | rdstate()); return; } segmentBuffering(tcpip.getSegmentSize()); Socket::state = CONNECTED; }
TCPStream::TCPStream(TCPSocket &server, bool throwflag, timeout_t to) : streambuf(), Socket(accept(server.getSocket(), NULL, NULL)) ,iostream((streambuf *)this) ,bufsize(0) ,gbuf(NULL) ,pbuf(NULL) { tpport_t port; family = IPV4; timeout = to; setError(throwflag); IPV4Host host = getPeer(&port); if(!server.onAccept(host, port)) { endSocket(); error(errConnectRejected); iostream::clear(ios::failbit | rdstate()); return; } segmentBuffering(server.getSegmentSize()); Socket::state = CONNECTED; }
TCPSocket *TCPSocket::connect(const char *host, int port) throw(SocketUnknownHost, SocketConnectionRefused) { TCPSocket *sock = new TCPSocket(::socket(AF_INET, SOCK_STREAM, 0)); // Hostname resolution struct sockaddr_in address; struct hostent* h = ::gethostbyname(host); if(h == NULL) throw SocketUnknownHost(); address.sin_family = AF_INET; address.sin_addr = *((struct in_addr *)h->h_addr); address.sin_port = htons(port); memset(&(address.sin_zero), 0, 8); if(::connect(sock->getSocket(), (struct sockaddr*)&address, sizeof(address)) == -1) throw SocketConnectionRefused(); return sock; }
TCPStream::TCPStream(TCPSocket &server, bool throwflag, timeout_t to) : streambuf(), Socket(accept(server.getSocket(), NULL, NULL)), #ifdef OLD_IOSTREAM iostream() #else iostream((streambuf *)this) #endif ,bufsize(0) ,gbuf(NULL) ,pbuf(NULL) { tpport_t port; family = IPV4; #ifdef OLD_IOSTREAM init((streambuf *)this); #endif timeout = to; setError(throwflag); IPV4Host host = getPeer(&port); if(!server.onAccept(host, port)) { endSocket(); error(errConnectRejected); iostream::clear(ios::failbit | rdstate()); return; } segmentBuffering(server.getSegmentSize()); Socket::state = CONNECTED; } #ifdef CCXX_IPV6 TCPStream::TCPStream(TCPV6Socket &server, bool throwflag, timeout_t to) : streambuf(), Socket(accept(server.getSocket(), NULL, NULL)), #ifdef OLD_IOSTREAM iostream() #else iostream((streambuf *)this) #endif ,bufsize(0) ,gbuf(NULL) ,pbuf(NULL) { tpport_t port; family = IPV6; #ifdef OLD_IOSTREAM init((streambuf *)this); #endif timeout = to; setError(throwflag); IPV6Host host = getIPV6Peer(&port); if(!server.onAccept(host, port)) { endSocket(); error(errConnectRejected); iostream::clear(ios::failbit | rdstate()); return; } segmentBuffering(server.getSegmentSize()); Socket::state = CONNECTED; } #endif TCPStream::TCPStream(const IPV4Host &host, tpport_t port, unsigned size, bool throwflag, timeout_t to) : streambuf(), Socket(AF_INET, SOCK_STREAM, IPPROTO_TCP), #ifdef OLD_IOSTREAM iostream(), #else iostream((streambuf *)this), #endif bufsize(0),gbuf(NULL),pbuf(NULL) { #ifdef OLD_IOSTREAM init((streambuf *)this); #endif family = IPV4; timeout = to; setError(throwflag); connect(host, port, size); } #ifdef CCXX_IPV6 TCPStream::TCPStream(const IPV6Host &host, tpport_t port, unsigned size, bool throwflag, timeout_t to) : streambuf(), Socket(AF_INET6, SOCK_STREAM, IPPROTO_TCP), #ifdef OLD_IOSTREAM iostream(), #else iostream((streambuf *)this), #endif bufsize(0),gbuf(NULL),pbuf(NULL) { family = IPV6; #ifdef OLD_IOSTREAM init((streambuf *)this); #endif timeout = to; setError(throwflag); connect(host, port, size); } #endif TCPStream::~TCPStream() { #ifdef CCXX_EXCEPTIONS try { endStream(); } catch( ... ) { if ( ! std::uncaught_exception()) throw;}; #else endStream(); #endif } #ifdef HAVE_GETADDRINFO void TCPStream::connect(const char *target, unsigned mss) { char namebuf[128]; char *cp; struct addrinfo hint, *list = NULL, *next, *first; bool connected = false; snprintf(namebuf, sizeof(namebuf), "%s", target); cp = strrchr(namebuf, '/'); if(!cp) cp = strrchr(namebuf, ':'); if(!cp) { endStream(); connectError(); return; } *(cp++) = 0; memset(&hint, 0, sizeof(hint)); hint.ai_family = family; hint.ai_socktype = SOCK_STREAM; hint.ai_protocol = IPPROTO_TCP; if(getaddrinfo(namebuf, cp, &hint, &list) || !list) { endStream(); connectError(); return; } first = list; #ifdef TCP_MAXSEG if(mss) setsockopt(so, IPPROTO_TCP, TCP_MAXSEG, (char *)&mss, sizeof(mss)); #endif while(list) { if(!::connect(so, list->ai_addr, (socklen_t)list->ai_addrlen)) { connected = true; break; } next = list->ai_next; list = next; } freeaddrinfo(first); if(!connected) { endStream(); connectError(); return; } segmentBuffering(mss); Socket::state = CONNECTED; }