예제 #1
0
int grpc_tcp_server_add_port(grpc_tcp_server *s, const void *addr,
                             int addr_len) {
  int allocated_port = -1;
  unsigned i;
  SOCKET sock;
  struct sockaddr_in6 addr6_v4mapped;
  struct sockaddr_in6 wildcard;
  struct sockaddr *allocated_addr = NULL;
  struct sockaddr_storage sockname_temp;
  socklen_t sockname_len;
  int port;

  /* Check if this is a wildcard port, and if so, try to keep the port the same
     as some previously created listener. */
  if (grpc_sockaddr_get_port(addr) == 0) {
    for (i = 0; i < s->nports; i++) {
      sockname_len = sizeof(sockname_temp);
      if (0 == getsockname(s->ports[i].socket->socket,
                           (struct sockaddr *) &sockname_temp,
                           &sockname_len)) {
        port = grpc_sockaddr_get_port((struct sockaddr *) &sockname_temp);
        if (port > 0) {
          allocated_addr = malloc(addr_len);
          memcpy(allocated_addr, addr, addr_len);
          grpc_sockaddr_set_port(allocated_addr, port);
          addr = allocated_addr;
          break;
        }
      }
    }
  }

  if (grpc_sockaddr_to_v4mapped(addr, &addr6_v4mapped)) {
    addr = (const struct sockaddr *)&addr6_v4mapped;
    addr_len = sizeof(addr6_v4mapped);
  }

  /* Treat :: or 0.0.0.0 as a family-agnostic wildcard. */
  if (grpc_sockaddr_is_wildcard(addr, &port)) {
    grpc_sockaddr_make_wildcard6(port, &wildcard);

    addr = (struct sockaddr *) &wildcard;
    addr_len = sizeof(wildcard);
  }

  sock = WSASocket(AF_INET6, SOCK_STREAM, IPPROTO_TCP, NULL, 0,
                   WSA_FLAG_OVERLAPPED);
  if (sock == INVALID_SOCKET) {
    char *utf8_message = gpr_format_message(WSAGetLastError());
    gpr_log(GPR_ERROR, "unable to create socket: %s", utf8_message);
    gpr_free(utf8_message);
  }

  allocated_port = add_socket_to_server(s, sock, addr, addr_len);
  gpr_free(allocated_addr);

  return allocated_port;
}
예제 #2
0
static void test_sockaddr_is_wildcard(void) {
  struct sockaddr_in wild4;
  struct sockaddr_in6 wild6;
  struct sockaddr_in6 wild_mapped;
  struct sockaddr dummy;
  int port;

  gpr_log(GPR_INFO, "%s", "test_sockaddr_is_wildcard");

  /* Generate wildcards. */
  grpc_sockaddr_make_wildcards(555, &wild4, &wild6);
  GPR_ASSERT(
      grpc_sockaddr_to_v4mapped((const struct sockaddr *)&wild4, &wild_mapped));

  /* Test 0.0.0.0:555 */
  port = -1;
  GPR_ASSERT(grpc_sockaddr_is_wildcard((const struct sockaddr *)&wild4, &port));
  GPR_ASSERT(port == 555);
  memset(&wild4.sin_addr.s_addr, 0xbd, 1);
  GPR_ASSERT(
      !grpc_sockaddr_is_wildcard((const struct sockaddr *)&wild4, &port));

  /* Test [::]:555 */
  port = -1;
  GPR_ASSERT(grpc_sockaddr_is_wildcard((const struct sockaddr *)&wild6, &port));
  GPR_ASSERT(port == 555);
  memset(&wild6.sin6_addr.s6_addr, 0xbd, 1);
  GPR_ASSERT(
      !grpc_sockaddr_is_wildcard((const struct sockaddr *)&wild6, &port));

  /* Test [::ffff:0.0.0.0]:555 */
  port = -1;
  GPR_ASSERT(
      grpc_sockaddr_is_wildcard((const struct sockaddr *)&wild_mapped, &port));
  GPR_ASSERT(port == 555);
  memset(&wild_mapped.sin6_addr.s6_addr, 0xbd, 1);
  GPR_ASSERT(
      !grpc_sockaddr_is_wildcard((const struct sockaddr *)&wild_mapped, &port));

  /* Test AF_UNSPEC. */
  port = -1;
  memset(&dummy, 0, sizeof(dummy));
  GPR_ASSERT(!grpc_sockaddr_is_wildcard(&dummy, &port));
  GPR_ASSERT(port == -1);
}
예제 #3
0
grpc_error *grpc_tcp_server_add_port(grpc_tcp_server *s,
                                     const grpc_resolved_address *addr,
                                     int *port) {
  // This function is mostly copied from tcp_server_windows.c
  grpc_tcp_listener *sp = NULL;
  uv_tcp_t *handle;
  grpc_resolved_address addr6_v4mapped;
  grpc_resolved_address wildcard;
  grpc_resolved_address *allocated_addr = NULL;
  grpc_resolved_address sockname_temp;
  unsigned port_index = 0;
  int status;
  grpc_error *error = GRPC_ERROR_NONE;

  if (s->tail != NULL) {
    port_index = s->tail->port_index + 1;
  }

  /* Check if this is a wildcard port, and if so, try to keep the port the same
     as some previously created listener. */
  if (grpc_sockaddr_get_port(addr) == 0) {
    for (sp = s->head; sp; sp = sp->next) {
      sockname_temp.len = sizeof(struct sockaddr_storage);
      if (0 == uv_tcp_getsockname(sp->handle,
                                  (struct sockaddr *)&sockname_temp.addr,
                                  (int *)&sockname_temp.len)) {
        *port = grpc_sockaddr_get_port(&sockname_temp);
        if (*port > 0) {
          allocated_addr = gpr_malloc(sizeof(grpc_resolved_address));
          memcpy(allocated_addr, addr, sizeof(grpc_resolved_address));
          grpc_sockaddr_set_port(allocated_addr, *port);
          addr = allocated_addr;
          break;
        }
      }
    }
  }

  if (grpc_sockaddr_to_v4mapped(addr, &addr6_v4mapped)) {
    addr = &addr6_v4mapped;
  }

  /* Treat :: or 0.0.0.0 as a family-agnostic wildcard. */
  if (grpc_sockaddr_is_wildcard(addr, port)) {
    grpc_sockaddr_make_wildcard6(*port, &wildcard);

    addr = &wildcard;
  }

  handle = gpr_malloc(sizeof(uv_tcp_t));
  status = uv_tcp_init(uv_default_loop(), handle);
  if (status == 0) {
    error = add_socket_to_server(s, handle, addr, port_index, &sp);
  } else {
    error = GRPC_ERROR_CREATE_FROM_STATIC_STRING(
        "Failed to initialize UV tcp handle");
    error =
        grpc_error_set_str(error, GRPC_ERROR_STR_OS_ERROR,
                           grpc_slice_from_static_string(uv_strerror(status)));
  }

  gpr_free(allocated_addr);

  if (error != GRPC_ERROR_NONE) {
    grpc_error *error_out = GRPC_ERROR_CREATE_REFERENCING_FROM_STATIC_STRING(
        "Failed to add port to server", &error, 1);
    GRPC_ERROR_UNREF(error);
    error = error_out;
    *port = -1;
  } else {
    GPR_ASSERT(sp != NULL);
    *port = sp->port;
  }
  return error;
}
예제 #4
0
grpc_tcp_listener *grpc_tcp_server_add_port(grpc_tcp_server *s,
        const void *addr, size_t addr_len) {
    grpc_tcp_listener *sp;
    grpc_tcp_listener *sp2 = NULL;
    int fd;
    grpc_dualstack_mode dsmode;
    struct sockaddr_in6 addr6_v4mapped;
    struct sockaddr_in wild4;
    struct sockaddr_in6 wild6;
    struct sockaddr_in addr4_copy;
    struct sockaddr *allocated_addr = NULL;
    struct sockaddr_storage sockname_temp;
    socklen_t sockname_len;
    int port;

    if (((struct sockaddr *)addr)->sa_family == AF_UNIX) {
        unlink_if_unix_domain_socket(addr);
    }

    /* Check if this is a wildcard port, and if so, try to keep the port the same
       as some previously created listener. */
    if (grpc_sockaddr_get_port(addr) == 0) {
        for (sp = s->head; sp; sp = sp->next) {
            sockname_len = sizeof(sockname_temp);
            if (0 == getsockname(sp->fd, (struct sockaddr *)&sockname_temp,
                                 &sockname_len)) {
                port = grpc_sockaddr_get_port((struct sockaddr *)&sockname_temp);
                if (port > 0) {
                    allocated_addr = malloc(addr_len);
                    memcpy(allocated_addr, addr, addr_len);
                    grpc_sockaddr_set_port(allocated_addr, port);
                    addr = allocated_addr;
                    break;
                }
            }
        }
    }

    sp = NULL;

    if (grpc_sockaddr_to_v4mapped(addr, &addr6_v4mapped)) {
        addr = (const struct sockaddr *)&addr6_v4mapped;
        addr_len = sizeof(addr6_v4mapped);
    }

    /* Treat :: or 0.0.0.0 as a family-agnostic wildcard. */
    if (grpc_sockaddr_is_wildcard(addr, &port)) {
        grpc_sockaddr_make_wildcards(port, &wild4, &wild6);

        /* Try listening on IPv6 first. */
        addr = (struct sockaddr *)&wild6;
        addr_len = sizeof(wild6);
        fd = grpc_create_dualstack_socket(addr, SOCK_STREAM, 0, &dsmode);
        sp = add_socket_to_server(s, fd, addr, addr_len);
        if (fd >= 0 && dsmode == GRPC_DSMODE_DUALSTACK) {
            goto done;
        }

        /* If we didn't get a dualstack socket, also listen on 0.0.0.0. */
        if (port == 0 && sp != NULL) {
            grpc_sockaddr_set_port((struct sockaddr *)&wild4, sp->port);
            sp2 = sp;
        }
        addr = (struct sockaddr *)&wild4;
        addr_len = sizeof(wild4);
    }

    fd = grpc_create_dualstack_socket(addr, SOCK_STREAM, 0, &dsmode);
    if (fd < 0) {
        gpr_log(GPR_ERROR, "Unable to create socket: %s", strerror(errno));
    }
    if (dsmode == GRPC_DSMODE_IPV4 &&
            grpc_sockaddr_is_v4mapped(addr, &addr4_copy)) {
        addr = (struct sockaddr *)&addr4_copy;
        addr_len = sizeof(addr4_copy);
    }
    sp = add_socket_to_server(s, fd, addr, addr_len);
    if (sp != NULL) sp->sibling = sp2;
    if (sp2 != NULL) sp2->is_sibling = 1;

done:
    gpr_free(allocated_addr);
    return sp;
}
예제 #5
0
파일: udp_server.c 프로젝트: mdsteele/grpc
int grpc_udp_server_add_port(grpc_udp_server *s,
                             const grpc_resolved_address *addr,
                             grpc_udp_server_read_cb read_cb,
                             grpc_udp_server_write_cb write_cb,
                             grpc_udp_server_orphan_cb orphan_cb) {
  grpc_udp_listener *sp;
  int allocated_port1 = -1;
  int allocated_port2 = -1;
  int fd;
  grpc_dualstack_mode dsmode;
  grpc_resolved_address addr6_v4mapped;
  grpc_resolved_address wild4;
  grpc_resolved_address wild6;
  grpc_resolved_address addr4_copy;
  grpc_resolved_address *allocated_addr = NULL;
  grpc_resolved_address sockname_temp;
  int port;

  /* Check if this is a wildcard port, and if so, try to keep the port the same
     as some previously created listener. */
  if (grpc_sockaddr_get_port(addr) == 0) {
    for (sp = s->head; sp; sp = sp->next) {
      sockname_temp.len = sizeof(struct sockaddr_storage);
      if (0 == getsockname(sp->fd, (struct sockaddr *)sockname_temp.addr,
                           (socklen_t *)&sockname_temp.len)) {
        port = grpc_sockaddr_get_port(&sockname_temp);
        if (port > 0) {
          allocated_addr = gpr_malloc(sizeof(grpc_resolved_address));
          memcpy(allocated_addr, addr, sizeof(grpc_resolved_address));
          grpc_sockaddr_set_port(allocated_addr, port);
          addr = allocated_addr;
          break;
        }
      }
    }
  }

  if (grpc_sockaddr_to_v4mapped(addr, &addr6_v4mapped)) {
    addr = &addr6_v4mapped;
  }

  /* Treat :: or 0.0.0.0 as a family-agnostic wildcard. */
  if (grpc_sockaddr_is_wildcard(addr, &port)) {
    grpc_sockaddr_make_wildcards(port, &wild4, &wild6);

    /* Try listening on IPv6 first. */
    addr = &wild6;
    // TODO(rjshade): Test and propagate the returned grpc_error*:
    GRPC_ERROR_UNREF(grpc_create_dualstack_socket_using_factory(
        s->socket_factory, addr, SOCK_DGRAM, IPPROTO_UDP, &dsmode, &fd));
    allocated_port1 =
        add_socket_to_server(s, fd, addr, read_cb, write_cb, orphan_cb);
    if (fd >= 0 && dsmode == GRPC_DSMODE_DUALSTACK) {
      goto done;
    }

    /* If we didn't get a dualstack socket, also listen on 0.0.0.0. */
    if (port == 0 && allocated_port1 > 0) {
      grpc_sockaddr_set_port(&wild4, allocated_port1);
    }
    addr = &wild4;
  }

  // TODO(rjshade): Test and propagate the returned grpc_error*:
  GRPC_ERROR_UNREF(grpc_create_dualstack_socket_using_factory(
      s->socket_factory, addr, SOCK_DGRAM, IPPROTO_UDP, &dsmode, &fd));
  if (fd < 0) {
    gpr_log(GPR_ERROR, "Unable to create socket: %s", strerror(errno));
  }
  if (dsmode == GRPC_DSMODE_IPV4 &&
      grpc_sockaddr_is_v4mapped(addr, &addr4_copy)) {
    addr = &addr4_copy;
  }
  allocated_port2 =
      add_socket_to_server(s, fd, addr, read_cb, write_cb, orphan_cb);

done:
  gpr_free(allocated_addr);
  return allocated_port1 >= 0 ? allocated_port1 : allocated_port2;
}
예제 #6
0
int grpc_udp_server_add_port(grpc_udp_server *s, const void *addr,
                             size_t addr_len, grpc_udp_server_read_cb read_cb) {
  int allocated_port1 = -1;
  int allocated_port2 = -1;
  unsigned i;
  int fd;
  grpc_dualstack_mode dsmode;
  struct sockaddr_in6 addr6_v4mapped;
  struct sockaddr_in wild4;
  struct sockaddr_in6 wild6;
  struct sockaddr_in addr4_copy;
  struct sockaddr *allocated_addr = NULL;
  struct sockaddr_storage sockname_temp;
  socklen_t sockname_len;
  int port;

  if (((struct sockaddr *)addr)->sa_family == AF_UNIX) {
    unlink_if_unix_domain_socket(addr);
  }

  /* Check if this is a wildcard port, and if so, try to keep the port the same
     as some previously created listener. */
  if (grpc_sockaddr_get_port(addr) == 0) {
    for (i = 0; i < s->nports; i++) {
      sockname_len = sizeof(sockname_temp);
      if (0 == getsockname(s->ports[i].fd, (struct sockaddr *)&sockname_temp,
                           &sockname_len)) {
        port = grpc_sockaddr_get_port((struct sockaddr *)&sockname_temp);
        if (port > 0) {
          allocated_addr = malloc(addr_len);
          memcpy(allocated_addr, addr, addr_len);
          grpc_sockaddr_set_port(allocated_addr, port);
          addr = allocated_addr;
          break;
        }
      }
    }
  }

  if (grpc_sockaddr_to_v4mapped(addr, &addr6_v4mapped)) {
    addr = (const struct sockaddr *)&addr6_v4mapped;
    addr_len = sizeof(addr6_v4mapped);
  }

  /* Treat :: or 0.0.0.0 as a family-agnostic wildcard. */
  if (grpc_sockaddr_is_wildcard(addr, &port)) {
    grpc_sockaddr_make_wildcards(port, &wild4, &wild6);

    /* Try listening on IPv6 first. */
    addr = (struct sockaddr *)&wild6;
    addr_len = sizeof(wild6);
    fd = grpc_create_dualstack_socket(addr, SOCK_DGRAM, IPPROTO_UDP, &dsmode);
    allocated_port1 = add_socket_to_server(s, fd, addr, addr_len, read_cb);
    if (fd >= 0 && dsmode == GRPC_DSMODE_DUALSTACK) {
      goto done;
    }

    /* If we didn't get a dualstack socket, also listen on 0.0.0.0. */
    if (port == 0 && allocated_port1 > 0) {
      grpc_sockaddr_set_port((struct sockaddr *)&wild4, allocated_port1);
    }
    addr = (struct sockaddr *)&wild4;
    addr_len = sizeof(wild4);
  }

  fd = grpc_create_dualstack_socket(addr, SOCK_DGRAM, IPPROTO_UDP, &dsmode);
  if (fd < 0) {
    gpr_log(GPR_ERROR, "Unable to create socket: %s", strerror(errno));
  }
  if (dsmode == GRPC_DSMODE_IPV4 &&
      grpc_sockaddr_is_v4mapped(addr, &addr4_copy)) {
    addr = (struct sockaddr *)&addr4_copy;
    addr_len = sizeof(addr4_copy);
  }
  allocated_port2 = add_socket_to_server(s, fd, addr, addr_len, read_cb);

done:
  gpr_free(allocated_addr);
  return allocated_port1 >= 0 ? allocated_port1 : allocated_port2;
}
예제 #7
0
grpc_error *grpc_tcp_server_add_port(grpc_tcp_server *s, const void *addr,
                                     size_t addr_len, int *out_port) {
  grpc_tcp_listener *sp;
  grpc_tcp_listener *sp2 = NULL;
  int fd;
  grpc_dualstack_mode dsmode;
  struct sockaddr_in6 addr6_v4mapped;
  struct sockaddr_in wild4;
  struct sockaddr_in6 wild6;
  struct sockaddr_in addr4_copy;
  struct sockaddr *allocated_addr = NULL;
  struct sockaddr_storage sockname_temp;
  socklen_t sockname_len;
  int port;
  unsigned port_index = 0;
  unsigned fd_index = 0;
  grpc_error *errs[2] = {GRPC_ERROR_NONE, GRPC_ERROR_NONE};
  if (s->tail != NULL) {
    port_index = s->tail->port_index + 1;
  }
  grpc_unlink_if_unix_domain_socket((struct sockaddr *)addr);

  /* Check if this is a wildcard port, and if so, try to keep the port the same
     as some previously created listener. */
  if (grpc_sockaddr_get_port(addr) == 0) {
    for (sp = s->head; sp; sp = sp->next) {
      sockname_len = sizeof(sockname_temp);
      if (0 == getsockname(sp->fd, (struct sockaddr *)&sockname_temp,
                           &sockname_len)) {
        port = grpc_sockaddr_get_port((struct sockaddr *)&sockname_temp);
        if (port > 0) {
          allocated_addr = gpr_malloc(addr_len);
          memcpy(allocated_addr, addr, addr_len);
          grpc_sockaddr_set_port(allocated_addr, port);
          addr = allocated_addr;
          break;
        }
      }
    }
  }

  sp = NULL;

  if (grpc_sockaddr_to_v4mapped(addr, &addr6_v4mapped)) {
    addr = (const struct sockaddr *)&addr6_v4mapped;
    addr_len = sizeof(addr6_v4mapped);
  }

  /* Treat :: or 0.0.0.0 as a family-agnostic wildcard. */
  if (grpc_sockaddr_is_wildcard(addr, &port)) {
    grpc_sockaddr_make_wildcards(port, &wild4, &wild6);

    /* Try listening on IPv6 first. */
    addr = (struct sockaddr *)&wild6;
    addr_len = sizeof(wild6);
    errs[0] = grpc_create_dualstack_socket(addr, SOCK_STREAM, 0, &dsmode, &fd);
    if (errs[0] == GRPC_ERROR_NONE) {
      errs[0] = add_socket_to_server(s, fd, addr, addr_len, port_index,
                                     fd_index, &sp);
      if (fd >= 0 && dsmode == GRPC_DSMODE_DUALSTACK) {
        goto done;
      }
      if (sp != NULL) {
        ++fd_index;
      }
      /* If we didn't get a dualstack socket, also listen on 0.0.0.0. */
      if (port == 0 && sp != NULL) {
        grpc_sockaddr_set_port((struct sockaddr *)&wild4, sp->port);
      }
    }
    addr = (struct sockaddr *)&wild4;
    addr_len = sizeof(wild4);
  }

  errs[1] = grpc_create_dualstack_socket(addr, SOCK_STREAM, 0, &dsmode, &fd);
  if (errs[1] == GRPC_ERROR_NONE) {
    if (dsmode == GRPC_DSMODE_IPV4 &&
        grpc_sockaddr_is_v4mapped(addr, &addr4_copy)) {
      addr = (struct sockaddr *)&addr4_copy;
      addr_len = sizeof(addr4_copy);
    }
    sp2 = sp;
    errs[1] =
        add_socket_to_server(s, fd, addr, addr_len, port_index, fd_index, &sp);
    if (sp2 != NULL && sp != NULL) {
      sp2->sibling = sp;
      sp->is_sibling = 1;
    }
  }

done:
  gpr_free(allocated_addr);
  if (sp != NULL) {
    *out_port = sp->port;
    GRPC_ERROR_UNREF(errs[0]);
    GRPC_ERROR_UNREF(errs[1]);
    return GRPC_ERROR_NONE;
  } else {
    *out_port = -1;
    char *addr_str = grpc_sockaddr_to_uri(addr);
    grpc_error *err = grpc_error_set_str(
        GRPC_ERROR_CREATE_REFERENCING("Failed to add port to server", errs,
                                      GPR_ARRAY_SIZE(errs)),
        GRPC_ERROR_STR_TARGET_ADDRESS, addr_str);
    GRPC_ERROR_UNREF(errs[0]);
    GRPC_ERROR_UNREF(errs[1]);
    gpr_free(addr_str);
    return err;
  }
}