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); }
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 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; }
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; }