Esempio n. 1
0
END_TEST

START_TEST (inet_listen_test) {
  int fd, mode, sockfd = -1, port = INPORT_ANY, res;
  conn_t *conn;

  res = pr_inet_listen(NULL, NULL, 5, 0);
  fail_unless(res < 0, "Failed to handle null arguments");
  fail_unless(errno == EINVAL, "Expected EINVAL (%d), got %s (%d)", EINVAL,
    strerror(errno), errno);

  res = pr_inet_resetlisten(NULL, NULL);
  fail_unless(res < 0, "Failed to handle null arguments");
  fail_unless(errno == EINVAL, "Expected EINVAL (%d), got %s (%d)", EINVAL,
    strerror(errno), errno);

  conn = pr_inet_create_conn(p, sockfd, NULL, port, FALSE);
  fail_unless(conn != NULL, "Failed to create conn: %s", strerror(errno));

  fd = conn->listen_fd;
  conn->listen_fd = 777;
  res = pr_inet_listen(p, conn, 5, 0);
  fail_unless(res < 0, "Succeeded in listening on conn unexpectedly");
  fail_unless(errno == EBADF, "Expected EBADF (%d), got %s (%d)", EBADF,
    strerror(errno), errno);

  mode = conn->mode;
  res = pr_inet_resetlisten(p, conn);
  fail_unless(res < 0, "Succeeded in resetting listening on conn unexpectedly");
  fail_unless(errno == EBADF, "Expected EBADF (%d), got %s (%d)", EBADF,
    strerror(errno), errno);

  conn->listen_fd = fd;
  conn->mode = mode;

  res = pr_inet_listen(p, conn, 5, 0);
  fail_unless(res == 0, "Failed to listen on conn: %s", strerror(errno));

  res = pr_inet_resetlisten(p, conn);
  fail_unless(res == 0, "Failed to reset listen mode: %s", strerror(errno));

  res = pr_inet_listen(p, conn, 5, 0);
  fail_unless(res < 0, "Failed to handle already-listening socket");
  fail_unless(errno == EPERM, "Expected EPERM (%d), got %s (%d)", EPERM,
    strerror(errno), errno);

  pr_inet_close(p, conn);
}
Esempio n. 2
0
int pr_ipbind_listen(fd_set *readfds) {
  int listen_flags = PR_INET_LISTEN_FL_FATAL_ON_ERROR, maxfd = 0;
  register unsigned int i = 0;

  /* sanity check */
  if (!readfds)
    return -1;

  FD_ZERO(readfds);

  if (!binding_pool) {
    binding_pool = make_sub_pool(permanent_pool);
    pr_pool_tag(binding_pool, "Bindings Pool");
  }

  /* Reset the listener list. */
  if (!listener_list) {
    listener_list = make_array(binding_pool, 1, sizeof(conn_t *));

  } else {
    /* Nasty hack to "clear" the list by making it think it has no
     * elements.
     */
    listener_list->nelts = 0;
  }

  /* Slower than the hash lookup, but...we have to check each and every
   * ipbind in the table.
   */
  for (i = 0; i < PR_BINDINGS_TABLE_SIZE; i++) {
    pr_ipbind_t *ipbind = NULL;

    for (ipbind = ipbind_table[i]; ipbind; ipbind = ipbind->ib_next) {

      /* Skip inactive bindings, but only if SocketBindTight is in effect. */
      if (SocketBindTight &&
          !ipbind->ib_isactive)
        continue;

      if (ipbind->ib_listener) {

        if (ipbind->ib_listener->mode == CM_NONE) {
          pr_inet_listen(ipbind->ib_listener->pool, ipbind->ib_listener,
            tcpBackLog, listen_flags);
        }

        if (ipbind->ib_listener->mode == CM_ACCEPT) {
          if (pr_inet_resetlisten(ipbind->ib_listener->pool,
              ipbind->ib_listener) < 0) {
            pr_trace_msg(trace_channel, 3,
              "error resetting %s#%u for listening: %s",
              pr_netaddr_get_ipstr(ipbind->ib_addr), ipbind->ib_port,
              strerror(errno));
          }
        }

        if (ipbind->ib_listener->mode == CM_LISTEN) {
          FD_SET(ipbind->ib_listener->listen_fd, readfds);
          if (ipbind->ib_listener->listen_fd > maxfd)
            maxfd = ipbind->ib_listener->listen_fd;

          /* Add this to the listener list as well. */
          *((conn_t **) push_array(listener_list)) = ipbind->ib_listener;
        }
      }
    }
  }

  return maxfd;
}