static int unix_server_start(server_generic_t *server) { int ret; struct sockaddr_un *sa = (struct sockaddr_un *) server->sa; server->sock = socket(AF_UNIX, SOCK_STREAM, 0); if ( server->sock < 0 ) return prelude_error_verbose(PRELUDE_ERROR_GENERIC, "error creating UNIX socket: %s", strerror(errno)); ret = is_unix_socket_already_used(server->sock, sa, server->slen); if ( ret < 0 ) { close(server->sock); return ret; } ret = generic_server(server->sock, server->sa, server->slen); if ( ret < 0 ) { close(server->sock); return ret; } /* * Everyone should be able to access the filesystem object * representing our socket. */ ret = chmod(sa->sun_path, S_IRWXU|S_IRWXG|S_IRWXO); if ( ret < 0 ) return prelude_error_verbose(PRELUDE_ERROR_GENERIC, "could not set permission on UNIX socket: %s", strerror(errno)); return 0; }
static int inet_server_start(server_generic_t *server, struct sockaddr *addr, socklen_t addrlen) { int ret, on = 1; server->sock = socket(server->sa->sa_family, SOCK_STREAM, IPPROTO_TCP); if ( server->sock < 0 ) return prelude_error_verbose(PRELUDE_ERROR_GENERIC, "error creating socket: %s", strerror(errno)); #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 is bound. */ if ( server->sa->sa_family == AF_INET6 ) { ret = setsockopt(server->sock, IPPROTO_IPV6, IPV6_V6ONLY, (void *) &on, sizeof(int)); if ( ret < 0 ) { ret = prelude_error_verbose(PRELUDE_ERROR_GENERIC, "could not set IPV6_V6ONLY: %s.\n", strerror(errno)); goto err; } } #endif ret = setsockopt(server->sock, SOL_SOCKET, SO_REUSEADDR, &on, sizeof(int)); if ( ret < 0 ) { ret = prelude_error_verbose(PRELUDE_ERROR_GENERIC, "error setting SO_REUSEADDR: %s", strerror(errno)); goto err; } ret = generic_server(server->sock, addr, addrlen); if ( ret < 0 ) goto err; return 0; err: close(server->sock); return ret; }
static int inet_server_start(server_generic_t *server, struct sockaddr *addr, socklen_t addrlen) { int ret, on = 1; server->sock = socket(server->sa->sa_family, SOCK_STREAM, IPPROTO_TCP); if ( server->sock < 0 ) return prelude_error_verbose(PRELUDE_ERROR_GENERIC, "error creating socket: %s", strerror(errno)); ret = setsockopt(server->sock, SOL_SOCKET, SO_REUSEADDR, &on, sizeof(int)); if ( ret < 0 ) { ret = prelude_error_verbose(PRELUDE_ERROR_GENERIC, "error setting SO_REUSEADDR: %s", strerror(errno)); goto err; } ret = generic_server(server->sock, addr, addrlen); if ( ret < 0 ) goto err; return 0; err: close(server->sock); return ret; }