Example #1
0
static GPResult
gpiStartConnect(
  GPConnection * connection,
  GPIOperation * operation
)
{
	struct sockaddr_in address;
	int rcode;
	//int len;
	GPIConnection * iconnection = (GPIConnection*)*connection;
	struct hostent * host;
	
	GSUdpErrorCode anError;
	strncpy(iconnection->mHeader, GPI_UDP_HEADER, GS_UDP_MSG_HEADER_LEN);

	if (!gsUdpEngineIsInitialized())
	{
		unsigned short peerPort = GPI_PEER_PORT;
		gsDebugFormat(GSIDebugCat_GP, GSIDebugType_Network, GSIDebugLevel_Notice, 
			"Initializing UDP Layer\n");
		anError = gsUdpEngineInitialize(peerPort, 0, 0, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL);
		if (anError != GS_UDP_NO_ERROR)
		{
			while (anError != GS_UDP_NO_ERROR && peerPort < GPI_PEER_PORT + 100)
			{
				gsDebugFormat(GSIDebugCat_GP, GSIDebugType_Network, GSIDebugLevel_Comment, 
					"Port %d failed, trying next port\n", peerPort);
				anError = gsUdpEngineInitialize(++peerPort, 0, 0, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL);
			}
			if (anError != GS_UDP_NO_ERROR)
			{
				gsDebugFormat(GSIDebugCat_GP, GSIDebugType_Network, GSIDebugLevel_HotError, 
					"Tryed all 100 ports after default port, giving up.\n");
				CallbackFatalError(connection, GP_NETWORK_ERROR, GP_UDP_LAYER, 
					"There was error starting the UDP layer.");
			}
		}	
		if (!iconnection->firewall)
		{
			iconnection->peerPort = peerPort;
		}
	}
	else
	{
		gsDebugFormat(GSIDebugCat_GP, GSIDebugType_Network, GSIDebugLevel_Notice, 
			"UDP Layer already initialized, using existing port.\n");
		iconnection->peerPort = gsUdpEngineGetLocalPort();
	}
	anError = gsUdpEngineAddMsgHandler(iconnection->mHeader, iconnection->mHeader, NULL, gpiPeerAcceptedCallback, gpiPeerLeftCallback, 
		gpiPeerPingReplyCallback, gpiPeerMessageCallback, connection);
	if (anError != GS_UDP_NO_ERROR)
	{
		CallbackFatalError(connection, GP_NETWORK_ERROR, GP_UDP_LAYER, "There was an error starting the UDP Layer.");
	}
	if(iconnection->firewall)
	{
		
		/*
		// Create the peer listening socket.
		////////////////////////////////////
		iconnection->peerSocket = socket(AF_INET, SOCK_STREAM, 0);
		if(iconnection->peerSocket == INVALID_SOCKET)
			CallbackFatalError(connection, GP_NETWORK_ERROR, GP_NETWORK, "There was an error creating a socket.");

		// Make it non-blocking.
		////////////////////////
		rcode = SetSockBlocking(iconnection->peerSocket,0);
		if (rcode == 0)
			CallbackFatalError(connection, GP_NETWORK_ERROR, GP_NETWORK, "There was an error making a socket non-blocking.");
		// Bind the socket.
		///////////////////
		memset(&address, 0, sizeof(address));
		address.sin_family = AF_INET;
		rcode = bind(iconnection->peerSocket, (struct sockaddr *)&address, sizeof(struct sockaddr_in));
		if(gsiSocketIsError(rcode))
			CallbackFatalError(connection, GP_NETWORK_ERROR, GP_NETWORK, "There was an error binding a socket.");

		// Start listening on the socket.
		/////////////////////////////////
		rcode = listen(iconnection->peerSocket, SOMAXCONN);
		if(gsiSocketIsError(rcode))
			CallbackFatalError(connection, GP_NETWORK_ERROR, GP_NETWORK, "There was an error listening on a socket.");

		// Get the socket's port.
		/////////////////////////
		len = sizeof(struct sockaddr_in);
		rcode = getsockname(iconnection->peerSocket, (struct sockaddr *)&address, &len);

		if (gsiSocketIsError(rcode))
			CallbackFatalError(connection, GP_NETWORK_ERROR, GP_NETWORK, "There was an error getting a socket's addres.");
		iconnection->peerPort = address.sin_port;
		*/
		
			
		iconnection->peerPort = 0;
	}
	/*
	else
	{
		// Deprecated TCP code; Replaced by UDP Layer
		// No local port.
		/////////////////
		//iconnection->peerSocket = INVALID_SOCKET;
		
		// Set to nothing because NN will determine this
		//////////////////////////
		//iconnection->peerPort = 0;
	}
	*/
	

	
	// Create the cm socket.
	////////////////////////
	iconnection->cmSocket = socket(AF_INET, SOCK_STREAM, 0);
	if(iconnection->cmSocket == INVALID_SOCKET)
		CallbackFatalError(connection, GP_NETWORK_ERROR, GP_NETWORK, "There was an error creating a socket.");

	// Make it non-blocking.
	////////////////////////
	rcode = SetSockBlocking(iconnection->cmSocket,0);
	if(rcode == 0)
		CallbackFatalError(connection, GP_NETWORK_ERROR, GP_NETWORK, "There was an error making a socket non-blocking.");
/* 
	// Bind the socket.
	///////////////////
	memset(&address, 0, sizeof(address));
	address.sin_family = AF_INET;
	rcode = bind(iconnection->cmSocket, (struct sockaddr *)&address, sizeof(struct sockaddr_in));
	if (gsiSocketIsError(rcode))
		CallbackFatalError(connection, GP_NETWORK_ERROR, GP_NETWORK, "There was an error binding a socket.");
*/
	memset(&address, 0, sizeof(address));
	address.sin_family = AF_INET;
	// Get the server host.
	///////////////////////
	if (inet_addr(GPConnectionManagerHostname) == INADDR_NONE)
	{
		host = gethostbyname(GPConnectionManagerHostname);
		if(host == NULL)
			CallbackFatalError(connection, GP_NETWORK_ERROR, GP_NETWORK, "Could not resolve connection mananger host name.");
		address.sin_addr.s_addr = *(unsigned int *)host->h_addr_list[0];
		//printf("Resolved Hostname and copied address:  %s\n", inet_ntoa(address.sin_addr));
	}
	else
	{
		address.sin_addr.s_addr = inet_addr(GPConnectionManagerHostname);
		//printf("Using hardcoded address: %s", GPConnectionManagerHostname);
	}

	// Connect the socket.
	//////////////////////
	assert(address.sin_addr.s_addr != 0);
	address.sin_port = htons(GPI_CONNECTION_MANAGER_PORT);
	rcode = connect(iconnection->cmSocket, (struct sockaddr *)&address, sizeof(struct sockaddr_in));
	if (gsiSocketIsError(rcode))
	{
		int error = GOAGetLastError(iconnection->cmSocket);
		if((error != WSAEWOULDBLOCK) && (error != WSAEINPROGRESS) && (error != WSAETIMEDOUT))
		{
			CallbackFatalError(connection, GP_NETWORK_ERROR, GP_NETWORK, "There was an error connecting a socket.");
		}
	}

	// We're waiting for the connect to complete.
	/////////////////////////////////////////////
	operation->state = GPI_CONNECTING;
	iconnection->connectState = GPI_CONNECTING;

	return GP_NO_ERROR;
}
Example #2
0
/***************
** CONNECTING **
***************/
void ghiDoConnecting
(
	GHIConnection * connection
)
{
	int rcode;
	SOCKADDR_IN address;
	int writeFlag;
	int exceptFlag;

	gsDebugFormat(GSIDebugCat_HTTP, GSIDebugType_State, GSIDebugLevel_Comment, "Connecting\n");

	// If we don't have a socket yet, set it up.
	////////////////////////////////////////////
	if(connection->socket == INVALID_SOCKET)
	{
		// Create the socket.
		/////////////////////
		connection->socket = socket(AF_INET, SOCK_STREAM, IPPROTO_TCP);
		if(connection->socket == INVALID_SOCKET)
		{
			connection->completed = GHTTPTrue;
			connection->result = GHTTPSocketFailed;
			connection->socketError = GOAGetLastError(connection->socket);
			return;
		}

		// Set the socket to non-blocking.
		//////////////////////////////////
		if(!SetSockBlocking(connection->socket, 0))
		{
			connection->completed = GHTTPTrue;
			connection->result = GHTTPSocketFailed;
			connection->socketError = GOAGetLastError(connection->socket);
			return;
		}

		// If throttling, use a small receive buffer.
		/////////////////////////////////////////////
		if(connection->throttle)
			SetReceiveBufferSize(connection->socket, ghiThrottleBufferSize);

		// Setup the server address.
		////////////////////////////
		memset(&address, 0, sizeof(SOCKADDR_IN));
		address.sin_family = AF_INET;
		if (connection->proxyOverrideServer)
			address.sin_port = htons(connection->proxyOverridePort);
		else if(ghiProxyAddress)
			address.sin_port = htons(ghiProxyPort);
		else
			address.sin_port = htons(connection->serverPort);
		address.sin_addr.s_addr = connection->serverIP;

		// Start the connect.
		/////////////////////
		//rcode = connect(connection->socket, (SOCKADDR *)&address, sizeof(SOCKADDR_IN));
		rcode = connect(connection->socket, (SOCKADDR *)&address, sizeof(address));
		if(gsiSocketIsError(rcode))
		{
			int socketError = GOAGetLastError(connection->socket);
			if((socketError != WSAEWOULDBLOCK) && (socketError != WSAEINPROGRESS) && (socketError != WSAETIMEDOUT))
			{
				connection->completed = GHTTPTrue;
				connection->result = GHTTPConnectFailed;
				connection->socketError = socketError;
				return;
			}
		}
	}

	// Check if the connect has completed.
	//////////////////////////////////////
	rcode = GSISocketSelect(connection->socket, NULL, &writeFlag, &exceptFlag);
	if((gsiSocketIsError(rcode)) || ((rcode == 1) && exceptFlag))
	{
		connection->completed = GHTTPTrue;
		connection->result = GHTTPConnectFailed;
		if(gsiSocketIsError(rcode))
			connection->socketError = GOAGetLastError(connection->socket);
		else
			connection->socketError = 0;
		return;
	}

	// Check if we're connected.
	////////////////////////////
	if((rcode == 1) && writeFlag)
	{
		// Progress.
		////////////
		if (connection->encryptor.mEngine == GHTTPEncryptionEngine_None)
			connection->state = GHTTPSendingRequest;
		else
			connection->state = GHTTPSecuringSession;
		ghiCallProgressCallback(connection, NULL, 0);
	}
} 
Example #3
0
// Try to connect to a remote sever using SOCK_STREAM
// 1. Input:
//  <1> host : server host name or ip address
//  <2> port : server port
//  <3> timeout : in ms
//    - if < 0 block forever
//    - if = 0 non-block
//    - if > 0 timeout
//  <4> retry : currently doesn't support
// 2. Output
//  <2> if success return sock_fd, else return -1
int ConnectTo(const char* host, const char* port, int timeout, int retry) {
  if (!host || !port) {
    app_error("server address or port cannot be empty!.\n");
    return -1;
  }

  // given server address and port number, return the basic info about the
  // server
  struct addrinfo hints, *server_info = NULL;
  memset(&hints, 0, sizeof(hints));
  hints.ai_family = AF_UNSPEC;
  hints.ai_socktype = SOCK_STREAM;

  int ret;
  if ((ret = getaddrinfo(host, port, &hints, &server_info)) != 0) {
    ai_error(ret);
    return -1;
  }

  // Timeout Settings
  struct timeval tv, *tv_ptr;
  if (timeout < 0) {
    tv_ptr = NULL;
  } else {
    tv.tv_sec = timeout / 1000;
    tv.tv_usec = timeout % 1000;
    tv_ptr = &tv;
  }

  // Loop through all the results and connect to the first we can
  fd_set write_fds;
  int sock_fd;
  struct addrinfo* p;
  for (p = server_info; p != NULL; p = p->ai_next) {
    if ((sock_fd = socket(p->ai_family, p->ai_socktype, p->ai_protocol)) == -1) {
      perror("client: socket");
      continue;
    }

    if (SetSockNonBlocking(sock_fd) < 0) {
      close(sock_fd);
      unix_error("ConnectTo: SetSockNonBlocking:");
    }

    if (connect(sock_fd, p->ai_addr, p->ai_addrlen) < 0) {
      if (errno == EINPROGRESS) {
        FD_ZERO(&write_fds);
        FD_SET(sock_fd, &write_fds);
        switch (select(sock_fd + 1, NULL, &write_fds, NULL, tv_ptr)) {
          case -1:
            perror("ConnectTo: select:");
            close(sock_fd);
            continue;

          case 0:
          DebugStr("ConnectTo: select: timeout\n");
            close(sock_fd);
            continue;
        }

        int error;
        socklen_t len = sizeof(error);

        if (getsockopt(sock_fd, SOL_SOCKET, SO_ERROR, &error, &len) < 0)  {
          perror("ConnectTo: getsockopt");
          close(sock_fd);
          continue;
        }

        if (error) {
          DebugStr("ConnectTo: %s\n", strerror(error));
          close(sock_fd);
          continue;
        }

      } else {
        DebugStr("ConnectTo: connect:");
        close(sock_fd);
        continue;
      }
    }
    break;
  }

  if (!p) {
    DebugStr("failed to connect to (%s, %s)\n", host, port);
    if (server_info) {
      freeaddrinfo(server_info);
    }
    return -1;
  }

  if (SetSockBlocking(sock_fd) < 0) {
    close(sock_fd);
    unix_error("ConnectTo: SetSockBlocking");
  }

  {
    const int MAXSIZE = 100;
    char *str = Malloc(MAXSIZE);
    inet_ntop(p->ai_family, get_in_addr((struct sockaddr *)p->ai_addr),
              str, MAXSIZE);
    DebugStr("connected to %s\n", str);
    freeaddrinfo(server_info);
    Free(str);
  }
  return sock_fd;
}