/* Copyright (C) 2019 C. McEnroe * * This program is free software: you can redistribute it and/or modify * it under the terms of the GNU Affero General Public License as published by * the Free Software Foundation, either version 3 of the License, or * (at your option) any later version. * * This program is distributed in the hope that it will be useful, * but WITHOUT ANY WARRANTY; without even the implied warranty of * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the * GNU Affero General Public License for more details. * * You should have received a copy of the GNU Affero General Public License * along with this program. If not, see . */ #include #include #include #include #include #include #include #include #include "bounce.h" static struct tls *client; int serverConnect(const char *host, const char *port) { int error; struct tls_config *config = tls_config_new(); error = tls_config_set_ciphers(config, "compat"); if (error) errx(EX_SOFTWARE, "tls_config"); client = tls_client(); if (!client) errx(EX_SOFTWARE, "tls_client"); error = tls_configure(client, config); if (error) errx(EX_SOFTWARE, "tls_configure: %s", tls_error(client)); tls_config_free(config); struct addrinfo *head; struct addrinfo hints = { .ai_family = AF_UNSPEC, .ai_socktype = SOCK_STREAM, .ai_protocol = IPPROTO_TCP, }; error = getaddrinfo(host, port, &hints, &head); if (error) errx(EX_NOHOST, "%s:%s: %s", host, port, gai_strerror(error)); int sock = -1; for (struct addrinfo *ai = head; ai; ai = ai->ai_next) { sock = socket(ai->ai_family, ai->ai_socktype, ai->ai_protocol); if (sock < 0) err(EX_OSERR, "socket"); error = connect(sock, ai->ai_addr, ai->ai_addrlen); if (!error) break; close(sock); sock = -1; } if (sock < 0) err(EX_UNAVAILABLE, "%s:%s", host, port); freeaddrinfo(head); error = tls_connect_socket(client, sock, host); if (error) errx(EX_PROTOCOL, "tls_connect: %s", tls_error(client)); return sock; }