Exemplo n.º 1
0
void server_generic_log_client(server_generic_client_t *cnx, prelude_log_t priority, const char *fmt, ...)
{
        va_list ap;
        int ret = 0;
        prelude_string_t *out;
        char addr[128] = { 0 };

        prelude_string_new(&out);

        if ( ((struct sockaddr *) &cnx->sa)->sa_family == AF_UNIX )
                snprintf(addr, sizeof(addr), "unix");

        else {
                void *in_addr;
                const char *str;
                unsigned int port;

#ifdef HAVE_IPV6
                port = ntohs(cnx->sa.sin6_port);
#else
                port = ntohs(cnx->sa.sin_port);
#endif
                in_addr = prelude_sockaddr_get_inaddr((struct sockaddr *) &cnx->sa);
                if ( ! in_addr )
                        goto out;

                str = inet_ntop(((struct sockaddr *)&cnx->sa)->sa_family, in_addr, addr, sizeof(addr));
                if ( str )
                        snprintf(addr + strlen(addr), sizeof(addr) - strlen(addr), ":%u", port);
        }

        if ( cnx->ident && cnx->permission ) {
                ret = prelude_string_sprintf(out, " 0x%" PRELUDE_PRIx64, cnx->ident);
                if ( ret < 0 )
                        goto out;

                ret = prelude_connection_permission_to_string(cnx->permission, out);
        }

        ret = prelude_string_sprintf(out, "]: ");
        if ( ret < 0  )
                goto out;

        va_start(ap, fmt);
        ret = prelude_string_vprintf(out, fmt, ap);
        va_end(ap);

        prelude_log(priority, "[%s%s", addr, prelude_string_get_string(out));

    out:
        prelude_string_destroy(out);
}
Exemplo n.º 2
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;
}
Exemplo n.º 3
0
static int sg_bind_common(server_generic_t *server, unsigned int port)
{
        char out[128];
        void *in_addr;

#if ! ((defined _WIN32 || defined __WIN32__) && !defined __CYGWIN__)
        fcntl(server->sock, F_SETFD, fcntl(server->sock, F_GETFD) | FD_CLOEXEC);

        if ( server->sa->sa_family == AF_UNIX )
                prelude_log(PRELUDE_LOG_INFO, "server started (listening on %s).\n",
                            ((struct sockaddr_un *) server->sa)->sun_path);
        else {
#endif
                in_addr = prelude_sockaddr_get_inaddr(server->sa);
                assert(in_addr);

                inet_ntop(server->sa->sa_family, in_addr, out, sizeof(out));
                prelude_log(PRELUDE_LOG_INFO, "server started (listening on %s port %u).\n", out, port);
#if ! ((defined _WIN32 || defined __WIN32__) && !defined __CYGWIN__)
        }
#endif

        return 0;
}
Exemplo n.º 4
0
static int setup_server(const char *addr, unsigned int port, struct pollfd *pfd, size_t *size)
{
        size_t i = 0;
        char buf[1024];
        struct addrinfo hints, *ai, *ai_start;
        int sock, ret, on = 1;

        snprintf(buf, sizeof(buf), "%u", port);
        memset(&hints, 0, sizeof(hints));

        hints.ai_flags = AI_PASSIVE;
        hints.ai_socktype = SOCK_STREAM;
        hints.ai_protocol = IPPROTO_TCP;
        hints.ai_family = AF_UNSPEC;

#ifdef AI_ADDRCONFIG
        hints.ai_flags |= AI_ADDRCONFIG;
#endif

        ret = getaddrinfo(addr, buf, &hints, &ai);
        if ( ret != 0 ) {
                fprintf(stderr, "could not resolve %s: %s.\n", addr ? addr : "",
                        (ret == EAI_SYSTEM) ? strerror(errno) : gai_strerror(ret));
                return -1;
        }

        for ( ai_start = ai; ai && i < *size; ai = ai->ai_next ) {
                inet_ntop(ai->ai_family, prelude_sockaddr_get_inaddr(ai->ai_addr), buf, sizeof(buf));

                sock = socket(ai->ai_family, ai->ai_socktype, ai->ai_protocol);
                if ( sock < 0 ) {
                        fprintf(stderr, "could not open socket for '%s': %s.\n", buf, strerror(errno));
                        break;
                }

#ifdef IPV6_V6ONLY
                /*
                 * There is a problem on Linux system where getaddrinfo() return address in
                 * the wrong sort order (IPv4 first, IPv6 next).
                 *
                 * As a result we first bind IPv4 addresses, but then we get an error for
                 * dual-stacked addresses, when the IPv6 addresses come second. When an
                 * address is dual-stacked, we thus end-up listening only to the IPv4
                 * instance.
                 *
                 * The error happen on dual-stack Linux system, because mapping the IPv6
                 * address will actually attempt to bind both the IPv4 and IPv6 address.
                 *
                 * In order to prevent this problem, we set the IPV6_V6ONLY option so that
                 * only the IPv6 address will be bound.
                 */
                if ( ai->ai_family == AF_INET6 ) {
                        ret = setsockopt(sock, IPPROTO_IPV6, IPV6_V6ONLY, (void *) &on, sizeof(int));
                        if ( ret < 0 )
                                fprintf(stderr, "could not set IPV6_V6ONLY: %s.\n", strerror(errno));
                }
#endif

                ret = setsockopt(sock, SOL_SOCKET, SO_REUSEADDR, (void *) &on, sizeof(int));
                if ( ret < 0 )
                        fprintf(stderr, "could not set SO_REUSEADDR: %s.\n", strerror(errno));

                ret = bind(sock, ai->ai_addr, ai->ai_addrlen);
                if ( ret < 0 ) {
                        close(sock);
                        fprintf(stderr, "could not bind to '%s': %s.\n", buf, strerror(errno));
                        break;
                }

                ret = listen(sock, 1);
                if ( ret < 0 ) {
                        close(sock);
                        fprintf(stderr, "could not listen on '%s': %s.\n", buf, strerror(errno));
                        break;
                }

                fprintf(stderr, "Waiting for peers install request on %s:%u...\n",
                        buf, ntohs(((struct sockaddr_in *) ai->ai_addr)->sin_port));

                pfd[i].fd = sock;
                pfd[i].events = POLLIN;

                i++;
        }

        if ( i == 0 ) {
                fprintf(stderr, "could not find any address to listen on.\n");
                return -1;
        }

        freeaddrinfo(ai_start);
        *size = i;

        return ret;
}