/* * put client socket in non blocking mode and * create a prelude_io object for IO abstraction. * * Tell server-logic to handle event on the newly accepted client. */ static int setup_client_socket(server_generic_t *server, server_generic_client_t *cdata, int client) { int ret; #ifdef HAVE_TCP_WRAPPERS if ( server->sa->sa_family != AF_UNIX ) { ret = tcpd_auth(cdata, client); if ( ret < 0 ) return -1; } #endif /* * set client socket non blocking. */ #if ! ((defined _WIN32 || defined __WIN32__) && !defined __CYGWIN__) ret = fcntl(client, F_SETFL, O_NONBLOCK); if ( ret < 0 ) return prelude_error_verbose(PRELUDE_ERROR_GENERIC, "could not set non blocking mode for client: %s", strerror(errno)); fcntl(client, F_SETFD, fcntl(client, F_GETFD) | FD_CLOEXEC); #endif ret = prelude_io_new(&cdata->fd); if ( ret < 0 ) return ret; prelude_io_set_sys_io(cdata->fd, client); cdata->msg = NULL; cdata->state = 0; return 0; }
static int process_event(prelude_client_profile_t *cp, int server_sock, prelude_io_t *fd, gnutls_x509_privkey_t key, gnutls_x509_crt_t cacrt, gnutls_x509_crt_t crt) { char buf[512]; void *inaddr; socklen_t len; int ret, csock; union { struct sockaddr sa; #ifndef HAVE_IPV6 struct sockaddr_in addr; # define ADDR_PORT(x) (x).sin_port #else struct sockaddr_in6 addr; # define ADDR_PORT(x) (x).sin6_port #endif } addr; len = sizeof(addr.addr); csock = accept(server_sock, &addr.sa, &len); if ( csock < 0 ) { fprintf(stderr, "accept returned an error: %s.\n", strerror(errno)); return -1; } inaddr = prelude_sockaddr_get_inaddr(&addr.sa); if ( ! inaddr ) return -1; inet_ntop(addr.sa.sa_family, inaddr, buf, sizeof(buf)); snprintf(buf + strlen(buf), sizeof(buf) - strlen(buf), ":%u", ntohs(ADDR_PORT(addr.addr))); prelude_io_set_sys_io(fd, csock); fprintf(stderr, "\nConnection from %s...\n", buf); ret = handle_client_connection("", cp, fd, key, cacrt, crt); if ( ret == 0 ) fprintf(stderr, "%s successfully registered.\n", buf); prelude_io_close(fd); return ret; }
static int send_queued_alert(server_generic_client_t *client) { int ret; do { ret = gnutls_alert_send(prelude_io_get_fdptr(client->fd), GNUTLS_AL_FATAL, client->alert); } while ( ret < 0 && ret == GNUTLS_E_INTERRUPTED ); if ( ret == GNUTLS_E_AGAIN ) { server_generic_notify_write_enable(client); return 0; } client->alert = 0; gnutls_deinit(prelude_io_get_fdptr(client->fd)); prelude_io_set_sys_io(client->fd, prelude_io_get_fd(client->fd)); return 1; }