/** * @file sock.c * @note Copyright (C) 2020 Richard Cochran * @note SPDX-License-Identifier: GPL-2.0+ */ #include #include #include #include #include "print.h" #include "sock.h" typedef void *so_t; int sock_open(const char *server, const char *port) { int i, err, family[2] = { AF_INET, AF_INET6 }, fd; struct addrinfo hints, *result = NULL; socklen_t addrlen; memset(&hints, 0, sizeof(hints)); hints.ai_flags = AI_CANONNAME; hints.ai_socktype = SOCK_STREAM; for (i = 0; i < 2; i++) { hints.ai_family = family[i]; err = getaddrinfo(server, port, &hints, &result); if (err) { pr_debug("%s: getaddrinfo failed family %d: %s", __func__, hints.ai_family, gai_strerror(err)); result = NULL; } else { break; } } if (!result) { return -1; } addrlen = (socklen_t) result->ai_addrlen; pr_debug("%s: connecting to server %s canonical %s", __func__, server, result->ai_canonname); fd = socket(result->ai_family, SOCK_STREAM, result->ai_protocol); if (fd < 0) { pr_err("%s: socket failed: %m", __func__); goto failed; } if (connect(fd, result->ai_addr, addrlen) < 0) { pr_err("%s: connect failed: %m", __func__); close(fd); fd = -1; } failed: freeaddrinfo(result); return fd; }