/**
 * 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;
}
示例#3
0
TCPSocket::TCPSocket( Socket socket, IPv4Address destination ) : TCPSocket::TCPSocket( )
{
	m_Socket		= socket;
	m_Destination	= destination;
	m_Connected		= true;

	SetBlockingMode( false );
	SetNoDelay();
}
示例#4
0
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;
}
示例#6
0
/**
 * 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;
	}
}
示例#7
0
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;
}