bool
SocketServer::setup(SocketServer::Service * service, 
		    unsigned short * port,
		    const char * intface){
  DBUG_ENTER("SocketServer::setup");
  DBUG_PRINT("enter",("interface=%s, port=%u", intface, *port));
  struct sockaddr_in servaddr;
  memset(&servaddr, 0, sizeof(servaddr));
  servaddr.sin_family = AF_INET;
  servaddr.sin_addr.s_addr = htonl(INADDR_ANY);
  servaddr.sin_port = htons(*port);
  
  if(intface != 0){
    if(Ndb_getInAddr(&servaddr.sin_addr, intface))
      DBUG_RETURN(false);
  }
  
  const NDB_SOCKET_TYPE sock = my_socket_create(AF_INET, SOCK_STREAM, 0);
  if (!my_socket_valid(sock))
  {
    DBUG_PRINT("error",("socket() - %d - %s",
			socket_errno, strerror(socket_errno)));
    DBUG_RETURN(false);
  }

  DBUG_PRINT("info",("NDB_SOCKET: " MY_SOCKET_FORMAT,
                     MY_SOCKET_FORMAT_VALUE(sock)));

  if (my_socket_reuseaddr(sock, true) == -1)
  {
    DBUG_PRINT("error",("setsockopt() - %d - %s",
			errno, strerror(errno)));
    NDB_CLOSE_SOCKET(sock);
    DBUG_RETURN(false);
  }

  if (my_bind_inet(sock, &servaddr) == -1) {
    DBUG_PRINT("error",("bind() - %d - %s",
			socket_errno, strerror(socket_errno)));
    NDB_CLOSE_SOCKET(sock);
    DBUG_RETURN(false);
  }

  /* Get the port we bound to */
  if(my_socket_get_port(sock, port))
  {
    ndbout_c("An error occurred while trying to find out what"
	     " port we bound to. Error: %d - %s",
             socket_errno, strerror(socket_errno));
    my_socket_close(sock);
    DBUG_RETURN(false);
  }

  DBUG_PRINT("info",("bound to %u", *port));

  if (my_listen(sock, m_maxSessions > 32 ? 32 : m_maxSessions) == -1)
  {
    DBUG_PRINT("error",("listen() - %d - %s",
			socket_errno, strerror(socket_errno)));
    my_socket_close(sock);
    DBUG_RETURN(false);
  }

  ServiceInstance i;
  i.m_socket = sock;
  i.m_service = service;
  m_services.push_back(i);

  // Increase size to allow polling all listening ports
  m_services_poller.set_max_count(m_services.size());

  DBUG_RETURN(true);
}
Esempio n. 2
0
NDB_SOCKET_TYPE
SocketClient::connect(const char *toaddress, unsigned short toport)
{
  if (!my_socket_valid(m_sockfd))
  {
    if (!init())
    {
      return m_sockfd;
    }
  }

  if (toaddress)
  {
    if (m_server_name)
      free(m_server_name);
    m_server_name = strdup(toaddress);
    m_port = toport;
    memset(&m_servaddr, 0, sizeof(m_servaddr));
    m_servaddr.sin_family = AF_INET;
    m_servaddr.sin_port = htons(toport);
    // Convert ip address presentation format to numeric format
    if (Ndb_getInAddr(&m_servaddr.sin_addr, m_server_name))
    {
      my_socket_close(m_sockfd);
      my_socket_invalidate(&m_sockfd);
      return m_sockfd;
    }
  }

  // Set socket non blocking
  if (my_socket_nonblock(m_sockfd, true) < 0)
  {
    my_socket_close(m_sockfd);
    my_socket_invalidate(&m_sockfd);
    return m_sockfd;
  }

  // Start non blocking connect
  int r = my_connect_inet(m_sockfd, &m_servaddr);
  if (r == 0)
    goto done; // connected immediately.

  if (r < 0 && NONBLOCKERR(my_socket_errno())) {
    // Start of non blocking connect failed
    my_socket_close(m_sockfd);
    my_socket_invalidate(&m_sockfd);
    return m_sockfd;
  }

  if (ndb_poll(m_sockfd, true, true, true,
               m_connect_timeout_millisec > 0 ?
               m_connect_timeout_millisec : -1) <= 0)
  {
    // Nothing has happened on the socket after timeout
    // or an error occured
    my_socket_close(m_sockfd);
    my_socket_invalidate(&m_sockfd);
    return m_sockfd;
  }

  // Activity detected on the socket

  {
    // Check socket level error code
    int so_error = 0;
    SOCKET_SIZE_TYPE len= sizeof(so_error);
    if (my_getsockopt(m_sockfd, SOL_SOCKET, SO_ERROR, &so_error, &len) < 0)
    {
      my_socket_close(m_sockfd);
      my_socket_invalidate(&m_sockfd);
      return m_sockfd;
    }

    if (so_error)
    {
      my_socket_close(m_sockfd);
      my_socket_invalidate(&m_sockfd);
      return m_sockfd;
    }
  }

done:
  if (my_socket_nonblock(m_sockfd, true) < 0)
  {
    my_socket_close(m_sockfd);
    my_socket_invalidate(&m_sockfd);
    return m_sockfd;
  }

  if (m_auth) {
    if (!m_auth->client_authenticate(m_sockfd))
    {
      my_socket_close(m_sockfd);
      my_socket_invalidate(&m_sockfd);
      return m_sockfd;
    }
  }
  NDB_SOCKET_TYPE sockfd = m_sockfd;

  my_socket_invalidate(&m_sockfd);

  return sockfd;
}