void runCloseTest(bool abortive) {
  Server server;

  int sock = createConnectedSocket(server.port());

  std::thread stopper([&server, abortive] {
    std::this_thread::sleep_for(std::chrono::milliseconds(200));
    server.stop(abortive);
    server.join();
  });

  char c;
  int r = read(sock, &c, 1);
  if (abortive) {
    int e = errno;
    EXPECT_EQ(-1, r);
    EXPECT_EQ(ECONNRESET, e);
  } else {
    EXPECT_EQ(0, r);
  }

  close(sock);

  stopper.join();

  EXPECT_EQ(0, server.closeClients(false));  // closed by server when it exited
}
void runKillTest(bool abortive) {
  Server server;

  int sock = createConnectedSocket(server.port());

  std::thread killer([&server, abortive] {
    std::this_thread::sleep_for(std::chrono::milliseconds(200));
    shutdownSocketSet.shutdownAll(abortive);
    server.join();
  });

  char c;
  int r = read(sock, &c, 1);

  // "abortive" is just a hint for ShutdownSocketSet, so accept both
  // behaviors
  if (abortive) {
    if (r == -1) {
      EXPECT_EQ(ECONNRESET, errno);
    } else {
      EXPECT_EQ(r, 0);
    }
  } else {
    EXPECT_EQ(0, r);
  }

  close(sock);

  killer.join();

  // NOT closed by server when it exited
  EXPECT_EQ(1, server.closeClients(false));
}
Esempio n. 3
0
/* request, and deinitialize */
tRedirectStatus tspDoEchoRequest(char *address, tBrokerAddressType address_type, tConf *conf, uint32_t *distance) {
  rttengine_stat_t *engine = NULL;
  struct addrinfo *address_info = NULL;
  struct addrinfo *address_info_root = NULL;
  pal_socket_t sfd;
  tSocketAddressStatus socket_address_status = SOCKET_ADDRESS_OK;
  tRedirectStatus status = TSP_REDIRECT_OK;

  /* Initilalize some stuff */
  *distance = 0;

  /* Get an address structure and see if we have the right address family */
  socket_address_status = getSocketAddress(address, address_type, conf->tunnel_mode, &address_info_root, &address_info);

  /* Wrong family, log and modify the distance so it goes at the end of the sorted list */
  if (socket_address_status == SOCKET_ADDRESS_WRONG_FAMILY) {
    *distance = ECHO_REQUEST_WRONG_FAMILY_ADJUST;
    Display(LOG_LEVEL_1, ELError, "tspDoEchoRequest", GOGO_STR_RDR_WRONG_ADDRESS_FAMILY, address);
  }
  /* There was some kind of error, adjust the distance to make it go after the brokers that */
  /* could be timed properly. */
  else if (socket_address_status == SOCKET_ADDRESS_ERROR) {
    *distance = ECHO_REQUEST_ERROR_ADJUST;
    if (address_info_root != NULL) {
      freeaddrinfo(address_info_root);
    }
    Display(LOG_LEVEL_1, ELError, "tspDoEchoRequest", GOGO_STR_RDR_ERROR_GET_SOCKADDRESS, address);
    return TSP_REDIRECT_ECHO_REQUEST_ERROR;
  }
  /* Could not resolve, this is treated the same as an error */
  else if (socket_address_status == SOCKET_ADDRESS_PROBLEM_RESOLVING) {
    *distance = ECHO_REQUEST_ERROR_ADJUST;
    if (address_info_root != NULL) {
      freeaddrinfo(address_info_root);
    }
    Display(LOG_LEVEL_1, ELError, "tspDoEchoRequest", GOGO_STR_RDR_ERROR_RESOLVING_DN, address);
    return TSP_REDIRECT_ECHO_REQUEST_ERROR;
  }

  /* Connect to the address */
  if ((sfd = createConnectedSocket(address_info)) == -1) {
    *distance += ECHO_REQUEST_ERROR_ADJUST;
    if (address_info_root != NULL) {
      freeaddrinfo(address_info_root);
    }
    destroySocket(sfd);
    Display(LOG_LEVEL_1, ELError, "tspDoEchoRequest", GOGO_STR_RDR_ERROR_CONNECT_SOCKET, address);
    return TSP_REDIRECT_ECHO_REQUEST_ERROR;
  }

  if (address_info_root != NULL) {
    freeaddrinfo(address_info_root);
  }

  /* Create a stat engine */
  if ((engine = createStatEngine()) == NULL) {
    *distance += ECHO_REQUEST_ERROR_ADJUST;
    destroySocket(sfd);
    Display(LOG_LEVEL_1, ELError, "tspDoEchoRequest", GOGO_STR_RDR_ERROR_CREATE_STAT_ENGINE, address);
    return TSP_REDIRECT_ECHO_REQUEST_ERROR;
  }

  /* Initialize the stat engine */
  if (rttengine_init(engine) != 1) {
    *distance += ECHO_REQUEST_ERROR_ADJUST;
    destroySocket(sfd);
    pal_free(engine);
    Display(LOG_LEVEL_1, ELError, "tspDoEchoRequest", GOGO_STR_RDR_ERROR_INIT_STAT_ENGINE, address);
    return TSP_REDIRECT_ECHO_REQUEST_ERROR;
  }

  /* Calculate the roundtrip time */
  status = timeEchoRequestReply(sfd, address, engine, distance);

  /* Destroy the socket */
  destroySocket(sfd);

  /* Uninitialize the stat engine */
  rttengine_deinit(engine, NULL, NULL);

  /* Free the stat engine */
  pal_free(engine);

  return status;
}