/** * Helper function to resolve a connected socket. * @param runp information about the socket to try not * @return the opened socket or INVALID_SOCKET */ static SOCKET ConnectLoopProc(addrinfo *runp) { const char *type = NetworkAddress::SocketTypeAsString(runp->ai_socktype); const char *family = NetworkAddress::AddressFamilyAsString(runp->ai_family); const char *address = NetworkAddress(runp->ai_addr, (int)runp->ai_addrlen).GetAddressAsString(); SOCKET sock = socket(runp->ai_family, runp->ai_socktype, runp->ai_protocol); if (sock == INVALID_SOCKET) { DEBUG(net, 1, "[%s] could not create %s socket: %s", type, family, strerror(errno)); return INVALID_SOCKET; } if (!SetNoDelay(sock)) DEBUG(net, 1, "[%s] setting TCP_NODELAY failed", type); if (connect(sock, runp->ai_addr, (int)runp->ai_addrlen) != 0) { DEBUG(net, 1, "[%s] could not connect %s socket: %s", type, family, strerror(errno)); closesocket(sock); return INVALID_SOCKET; } /* Connection succeeded */ if (!SetNonBlocking(sock)) DEBUG(net, 0, "[%s] setting non-blocking mode failed", type); DEBUG(net, 1, "[%s] connected to %s", type, address); return sock; }
bool CMySocketTCPClient::Connect() { if (GetType() != TCP_CLIENT) return false; if (IsConnected()) return false; m_s = ::socket(AF_INET, SOCK_STREAM, IPPROTO_TCP); if (FSOCK_ISERROR(m_s)) { FSOCK_CLOSE(m_s); return false; } SetNoDelay(TRUE); int rc = connect(m_s, (SOCKADDR*)&m_addr, sizeof(m_addr)); if (FSOCK_ISERROR(rc)) { FSOCK_CLOSE(m_s); return false; } m_bConnected = true; return true; }
TCPSocket::TCPSocket( Socket socket, IPv4Address destination ) : TCPSocket::TCPSocket( ) { m_Socket = socket; m_Destination = destination; m_Connected = true; SetBlockingMode( false ); SetNoDelay(); }
bool TCPSocket::Connect( const IPv4Address& destination ) { //Set up the socket m_Socket = static_cast< int >( socket( AF_INET, SOCK_STREAM, IPPROTO_TCP ) ); // Adress Family = INET and the protocol to be used is TCP if ( m_Socket <= 0 ) { LogErrorMessage( "Failed to create socket", "TCPSocket" ); return false; } SetBlockingMode( false ); // Try to connect Logger::Log( "Attempting to connect to " + destination.GetPrintableAddressAndPort(), "TCPSocket", LogSeverity::INFO_MSG ); sockaddr_in addr = destination.GetSockAddr(); timeval timeOut; timeOut.tv_sec = CONNECTION_TIMEOUT_SECONDS; timeOut.tv_usec = 0; fd_set set; FD_ZERO( &set ); FD_SET( m_Socket, &set ); int returnVal; if ( ( returnVal = connect( m_Socket, ( sockaddr * )&addr, sizeof( sockaddr_in ) ) ) == INVALID_SOCKET ) { if ( !SHOULD_WAIT_FOR_TIMEOUT ) return false; } returnVal = select( static_cast<int>( m_Socket + 1 ), NULL, &set, NULL, &timeOut ); if ( returnVal > 0 ) // A socket was connected { m_Destination = destination; m_Connected = true; SetNoDelay(); Logger::Log( "Connection attempt to " + destination.GetPrintableAddressAndPort() + " was successfull!", "TCPSocket", LogSeverity::INFO_MSG ); return true; } else if ( returnVal == 0 ) { Logger::Log( "Connection attempt to " + destination.GetPrintableAddressAndPort() + " timed out", "TCPSocket", LogSeverity::INFO_MSG ); return false; } else { LogErrorMessage( "Connection attempt to " + destination.GetPrintableAddressAndPort() + " failed", "TCPSocket" ); return false; } }
/** * Helper function to resolve a listening. * @param runp information about the socket to try not * @return the opened socket or INVALID_SOCKET */ static SOCKET ListenLoopProc(addrinfo *runp) { const char *type = NetworkAddress::SocketTypeAsString(runp->ai_socktype); const char *family = NetworkAddress::AddressFamilyAsString(runp->ai_family); const char *address = NetworkAddress(runp->ai_addr, (int)runp->ai_addrlen).GetAddressAsString(); SOCKET sock = socket(runp->ai_family, runp->ai_socktype, runp->ai_protocol); if (sock == INVALID_SOCKET) { DEBUG(net, 0, "[%s] could not create %s socket on port %s: %s", type, family, address, strerror(errno)); return INVALID_SOCKET; } if (runp->ai_socktype == SOCK_STREAM && !SetNoDelay(sock)) { DEBUG(net, 3, "[%s] setting TCP_NODELAY failed for port %s", type, address); } int on = 1; /* The (const char*) cast is needed for windows!! */ if (setsockopt(sock, SOL_SOCKET, SO_REUSEADDR, (const char*)&on, sizeof(on)) == -1) { DEBUG(net, 3, "[%s] could not set reusable %s sockets for port %s: %s", type, family, address, strerror(errno)); } if (runp->ai_family == AF_INET6 && setsockopt(sock, IPPROTO_IPV6, IPV6_V6ONLY, (const char*)&on, sizeof(on)) == -1) { DEBUG(net, 3, "[%s] could not disable IPv4 over IPv6 on port %s: %s", type, address, strerror(errno)); } if (bind(sock, runp->ai_addr, (int)runp->ai_addrlen) != 0) { DEBUG(net, 1, "[%s] could not bind on %s port %s: %s", type, family, address, strerror(errno)); closesocket(sock); return INVALID_SOCKET; } if (runp->ai_socktype != SOCK_DGRAM && listen(sock, 1) != 0) { DEBUG(net, 1, "[%s] could not listen at %s port %s: %s", type, family, address, strerror(errno)); closesocket(sock); return INVALID_SOCKET; } /* Connection succeeded */ if (!SetNonBlocking(sock)) DEBUG(net, 0, "[%s] setting non-blocking mode failed for %s port %s", type, family, address); DEBUG(net, 1, "[%s] listening on %s port %s", type, family, address); return sock; }
/** * Resolve this address into a socket * @param family the type of 'protocol' (IPv4, IPv6) * @param socktype the type of socket (TCP, UDP, etc) * @param flags the flags to send to getaddrinfo * @param sockets the list of sockets to add the sockets to * @param func the inner working while looping over the address info * @return the resolved socket or INVALID_SOCKET. */ SOCKET NetworkAddress::Resolve(int family, int socktype, int flags, SocketList *sockets, LoopProc func) { if (func != ConnectLoopProc) { return INVALID_SOCKET; } else { SOCKET sock = socket(PF_INET, SOCK_STREAM, IPPROTO_TCP); if (sock == INVALID_SOCKET) { throw "Unable to connect"; } if (!SetNoDelay(sock)) { DEBUG(net, 1, "setting TCP_NODELAY failed"); } printf("schedule connect: %d\n", sock); emscripten_async_call(async_connect, (void *)sock, 10000); return sock; } }
int ServerProxy::handleNewXConnectionFromProxy(int channelId) { // // Connect to the real X server. // int retryConnect = control -> OptionServerRetryConnect; int xServerFd; for (;;) { xServerFd = socket(xServerAddrFamily_, SOCK_STREAM, PF_UNSPEC); if (xServerFd < 0) { #ifdef PANIC *logofs << "ServerProxy: PANIC! Call to socket failed. " << "Error is " << EGET() << " '" << ESTR() << "'.\n" << logofs_flush; #endif cerr << "Error" << ": Call to socket failed. " << "Error is " << EGET() << " '" << ESTR() << "'.\n"; return -1; } #ifdef TEST *logofs << "ServerProxy: Trying to connect to X server '" << xServerDisplay_ << "'.\n" << logofs_flush; #endif int result = connect(xServerFd, xServerAddr_, xServerAddrLength_); getNewTimestamp(); if (result < 0) { #ifdef WARNING *logofs << "ServerProxy: WARNING! Connection to '" << xServerDisplay_ << "' failed with error '" << ESTR() << "'. Retrying.\n" << logofs_flush; #endif close(xServerFd); if (--retryConnect == 0) { #ifdef PANIC *logofs << "ServerProxy: PANIC! Connection to '" << xServerDisplay_ << "' for channel ID#" << channelId << " failed. Error is " << EGET() << " '" << ESTR() << "'.\n" << logofs_flush; #endif cerr << "Error" << ": Connection to '" << xServerDisplay_ << "' failed. Error is " << EGET() << " '" << ESTR() << "'.\n"; close(xServerFd); return -1; } if (activeChannels_.getSize() == 0) { sleep(2); } else { sleep(1); } } else { break; } } assignChannelMap(channelId, xServerFd); #ifdef TEST *logofs << "ServerProxy: X server descriptor FD#" << xServerFd << " mapped to channel ID#" << channelId << ".\n" << logofs_flush; #endif // // Turn queuing off for path proxy-to-X-server. // if (control -> OptionServerNoDelay == 1) { SetNoDelay(xServerFd, control -> OptionServerNoDelay); } // // If requested, set the size of the TCP send // and receive buffers. // if (control -> OptionServerSendBuffer != -1) { SetSendBuffer(xServerFd, control -> OptionServerSendBuffer); } if (control -> OptionServerReceiveBuffer != -1) { SetReceiveBuffer(xServerFd, control -> OptionServerReceiveBuffer); } if (allocateTransport(xServerFd, channelId) < 0) { return -1; } // // Starting from protocol level 3 client and server // caches are created in proxy and shared between all // channels. If remote proxy has older protocol level // pointers are NULL and channels must create their // own instances. // channels_[channelId] = new ServerChannel(transports_[channelId], compressor_); if (channels_[channelId] == NULL) { deallocateTransport(channelId); return -1; } increaseChannels(channelId); // // Propagate channel stores and caches to the new // channel. // channels_[channelId] -> setOpcodes(opcodeStore_); channels_[channelId] -> setStores(clientStore_, serverStore_); channels_[channelId] -> setCaches(clientCache_, serverCache_); int port = atoi(fontServerPort_); if (port > 0) { channels_[channelId] -> setPorts(port); } // // Let channel configure itself according // to control parameters. // channels_[channelId] -> handleConfiguration(); // // Check if we have successfully loaded the // selected cache and, if not, remove it // from disk. // handleCheckLoad(); return 1; }