Ejemplo n.º 1
0
/* This function handles the post connection specific actions that are needed
 * after a socket has been initialized(normal socket or ssl socket). */
static void post_handle_connection(struct fdinfo sinfo)
{
    /*
     * Are we executing a command? If so then don't add this guy
     * to our descriptor list or set.
     */
    if (o.cmdexec) {
        if (o.keepopen)
            netrun(&sinfo, o.cmdexec);
        else
            netexec(&sinfo, o.cmdexec);
    } else {
        /* Now that a client is connected, pay attention to stdin. */
        if (!stdin_eof)
            FD_SET(STDIN_FILENO, &master_readfds);
        if (!o.sendonly) {
            /* add to our lists */
            FD_SET(sinfo.fd, &master_readfds);
            /* add it to our list of fds for maintaining maxfd */
#ifdef HAVE_OPENSSL
            /* Don't add it twice (see handle_connection above) */
            if (!o.ssl)
#endif
            if (add_fdinfo(&client_fdlist, &sinfo) < 0)
                bye("add_fdinfo() failed.");
        }
        FD_SET(sinfo.fd, &master_broadcastfds);
        if (add_fdinfo(&broadcast_fdlist, &sinfo) < 0)
            bye("add_fdinfo() failed.");

        if (o.chat)
            chat_announce_connect(sinfo.fd, &sinfo.remoteaddr);
    }
}
Ejemplo n.º 2
0
/* Add a descriptor to the list. Use this when you are only adding to the list
 * for the side effect of increasing fdmax, and don't care about fdinfo
 * members. */
int add_fd(fd_list_t *fdl, int fd)
{
    struct fdinfo info = { 0 };

    info.fd = fd;

    return add_fdinfo(fdl, &info);
}
Ejemplo n.º 3
0
/* Accept a connection on a listening socket. Allow or deny the connection.
   Fork a command if o.cmdexec is set. Otherwise, add the new socket to the
   watch set. */
static void handle_connection(int socket_accept)
{
    union sockaddr_u remoteaddr;
    socklen_t ss_len;
    struct fdinfo s = { 0 };
    int conn_count;

    zmem(&s, sizeof(s));
    zmem(&remoteaddr, sizeof(remoteaddr.storage));

    ss_len = sizeof(remoteaddr.storage);

    errno = 0;
    s.fd = accept(socket_accept, &remoteaddr.sockaddr, &ss_len);

    if (s.fd < 0) {
        if (o.debug)
            logdebug("Error in accept: %s\n", strerror(errno));

        close(s.fd);
        return;
    }

    if (o.verbose) {
#if HAVE_SYS_UN_H
        if (remoteaddr.sockaddr.sa_family == AF_UNIX)
            loguser("Connection from a client on Unix domain socket.\n");
        else
#endif
        if (o.chat)
            loguser("Connection from %s on file descriptor %d.\n", inet_socktop(&remoteaddr), s.fd);
        else
            loguser("Connection from %s.\n", inet_socktop(&remoteaddr));
    }

    if (!o.keepopen && !o.broker) {
        int i;
        for (i = 0; i < num_listenaddrs; i++) {
            Close(listen_socket[i]);
            FD_CLR(listen_socket[i], &master_readfds);
            rm_fd(&client_fdlist, listen_socket[i]);
        }
    }

    if (o.verbose) {
#if HAVE_SYS_UN_H
        if (remoteaddr.sockaddr.sa_family == AF_UNIX)
            loguser("Connection from %s.\n", remoteaddr.un.sun_path);
        else
#endif
            loguser("Connection from %s:%hu.\n", inet_socktop(&remoteaddr), inet_port(&remoteaddr));
    }

    /* Check conditions that might cause us to deny the connection. */
    conn_count = get_conn_count();
    if (conn_count >= o.conn_limit) {
        if (o.verbose)
            loguser("New connection denied: connection limit reached (%d)\n", conn_count);
        Close(s.fd);
        return;
    }
    if (!allow_access(&remoteaddr)) {
        if (o.verbose)
            loguser("New connection denied: not allowed\n");
        Close(s.fd);
        return;
    }

    s.remoteaddr = remoteaddr;

    conn_inc++;

    unblock_socket(s.fd);

#ifdef HAVE_OPENSSL
    if (o.ssl) {
        /* Add the socket to the necessary descriptor lists. */
        FD_SET(s.fd, &sslpending_fds);
        FD_SET(s.fd, &master_readfds);
        FD_SET(s.fd, &master_writefds);
        /* Add it to our list of fds too for maintaining maxfd. */
        if (add_fdinfo(&client_fdlist, &s) < 0)
            bye("add_fdinfo() failed.");
    } else
#endif
        post_handle_connection(s);
}