Пример #1
0
int grpc_pick_unused_port(void) {
  /* We repeatedly pick a port and then see whether or not it is
     available for use both as a TCP socket and a UDP socket.  First, we
     pick a random large port number.  For subsequent
     iterations, we bind to an anonymous port and let the OS pick the
     port number.  The random port picking reduces the probability of
     races with other processes on kernels that want to reuse the same
     port numbers over and over. */

  /* In alternating iterations we try UDP ports before TCP ports UDP
     ports -- it could be the case that this machine has been using up
     UDP ports and they are scarcer. */

  /* Type of port to first pick in next iteration */
  int is_tcp = 1;
  int try = 0;

  for (;;) {
    int port;
    try++;
    if (try == 1) {
      port = getpid() % (65536 - 30000) + 30000;
    } else if (try <= NUM_RANDOM_PORTS_TO_PICK) {
      port = rand() % (65536 - 30000) + 30000;
    } else {
      port = 0;
    }

    if (has_port_been_chosen(port)) {
      continue;
    }

    if (!is_port_available(&port, is_tcp)) {
      continue;
    }

    GPR_ASSERT(port > 0);
    /* Check that the port # is free for the other type of socket also */
    if (!is_port_available(&port, !is_tcp)) {
      /* In the next iteration try to bind to the other type first
         because perhaps it is more rare. */
      is_tcp = !is_tcp;
      continue;
    }

    chose_port(port);
    return port;
  }
Пример #2
0
int grpc_pick_unused_port(void) {
  /* We repeatedly pick a port and then see whether or not it is
     available for use both as a TCP socket and a UDP socket.  First, we
     pick a random large port number.  For subsequent
     iterations, we bind to an anonymous port and let the OS pick the
     port number.  The random port picking reduces the probability of
     races with other processes on kernels that want to reuse the same
     port numbers over and over. */

  /* In alternating iterations we trial UDP ports before TCP ports UDP
     ports -- it could be the case that this machine has been using up
     UDP ports and they are scarcer. */

  /* Type of port to first pick in next iteration */
  int is_tcp = 1;
  int trial = 0;

  char *env = gpr_getenv("GRPC_TEST_PORT_SERVER");
  if (env) {
    int port = grpc_pick_port_using_server(env);
    gpr_free(env);
    if (port != 0) {
      return port;
    }
  }

  for (;;) {
    int port;
    trial++;
    if (trial == 1) {
      port = _getpid() % (65536 - 30000) + 30000;
    } else if (trial <= NUM_RANDOM_PORTS_TO_PICK) {
      port = rand() % (65536 - 30000) + 30000;
    } else {
      port = 0;
    }

    if (has_port_been_chosen(port)) {
      continue;
    }

    if (!is_port_available(&port, is_tcp)) {
      continue;
    }

    GPR_ASSERT(port > 0);
    /* Check that the port # is free for the other type of socket also */
    if (!is_port_available(&port, !is_tcp)) {
      /* In the next iteration trial to bind to the other type first
         because perhaps it is more rare. */
      is_tcp = !is_tcp;
      continue;
    }

    /* TODO(ctiller): consider caching this port in some structure, to avoid
       handing it out again */

    chose_port(port);
    return port;
  }

  /* The port iterator reached the end without finding a suitable port. */
  return 0;
}