diff options
author | Daniel Baumann <daniel.baumann@progress-linux.org> | 2024-05-30 02:50:01 +0000 |
---|---|---|
committer | Daniel Baumann <daniel.baumann@progress-linux.org> | 2024-05-30 02:50:01 +0000 |
commit | 91275eb478ceb58083426099b6da3f4c7e189f19 (patch) | |
tree | 260f7d2fa77408b38c5cea96b320b9b0b6713ff2 /debian/vendor-h2o/deps/picotls/t/cli.c | |
parent | Merging upstream version 1.9.4. (diff) | |
download | dnsdist-91275eb478ceb58083426099b6da3f4c7e189f19.tar.xz dnsdist-91275eb478ceb58083426099b6da3f4c7e189f19.zip |
Merging debian version 1.9.4-1.
Signed-off-by: Daniel Baumann <daniel.baumann@progress-linux.org>
Diffstat (limited to 'debian/vendor-h2o/deps/picotls/t/cli.c')
-rw-r--r-- | debian/vendor-h2o/deps/picotls/t/cli.c | 392 |
1 files changed, 0 insertions, 392 deletions
diff --git a/debian/vendor-h2o/deps/picotls/t/cli.c b/debian/vendor-h2o/deps/picotls/t/cli.c deleted file mode 100644 index fc73499..0000000 --- a/debian/vendor-h2o/deps/picotls/t/cli.c +++ /dev/null @@ -1,392 +0,0 @@ -/* - * Copyright (c) 2016 DeNA Co., Ltd., Kazuho Oku - * - * Permission is hereby granted, free of charge, to any person obtaining a copy - * of this software and associated documentation files (the "Software"), to - * deal in the Software without restriction, including without limitation the - * rights to use, copy, modify, merge, publish, distribute, sublicense, and/or - * sell copies of the Software, and to permit persons to whom the Software is - * furnished to do so, subject to the following conditions: - * - * The above copyright notice and this permission notice shall be included in - * all copies or substantial portions of the Software. - * - * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR - * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, - * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE - * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER - * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING - * FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS - * IN THE SOFTWARE. - */ -#ifndef _XOPEN_SOURCE -#define _XOPEN_SOURCE 700 /* required for glibc to use getaddrinfo, etc. */ -#endif - -#include <arpa/inet.h> -#include <assert.h> -#include <errno.h> -#include <fcntl.h> -#include <getopt.h> -#include <inttypes.h> -#include <stdio.h> -#include <string.h> -#include <sys/select.h> -#include <sys/socket.h> -#include <sys/stat.h> -#include <sys/time.h> -#include <sys/types.h> -#include <unistd.h> -#include <openssl/err.h> -#include <openssl/evp.h> -#include <openssl/engine.h> -#include <openssl/pem.h> -#include "picotls.h" -#include "picotls/openssl.h" -#include "util.h" - -static void shift_buffer(ptls_buffer_t *buf, size_t delta) -{ - if (delta != 0) { - assert(delta <= buf->off); - if (delta != buf->off) - memmove(buf->base, buf->base + delta, buf->off - delta); - buf->off -= delta; - } -} - -static int handle_connection(int sockfd, ptls_context_t *ctx, const char *server_name, const char *input_file, - ptls_handshake_properties_t *hsprop) -{ - ptls_t *tls = ptls_new(ctx, server_name == NULL); - ptls_buffer_t rbuf, encbuf, ptbuf; - char bytebuf[16384]; - enum { IN_HANDSHAKE, IN_1RTT, IN_SHUTDOWN } state = IN_HANDSHAKE; - int inputfd = 0, ret = 0; - size_t early_bytes_sent = 0; - ssize_t ioret; - - ptls_buffer_init(&rbuf, "", 0); - ptls_buffer_init(&encbuf, "", 0); - ptls_buffer_init(&ptbuf, "", 0); - - fcntl(sockfd, F_SETFL, O_NONBLOCK); - - if (input_file != NULL) { - if ((inputfd = open(input_file, O_RDONLY)) == -1) { - fprintf(stderr, "failed to open file:%s:%s\n", input_file, strerror(errno)); - ret = 1; - goto Exit; - } - } - if (server_name != NULL) { - ptls_set_server_name(tls, server_name, 0); - if ((ret = ptls_handshake(tls, &encbuf, NULL, NULL, hsprop)) != PTLS_ERROR_IN_PROGRESS) { - fprintf(stderr, "ptls_handshake:%d\n", ret); - ret = 1; - goto Exit; - } - } - - while (1) { - /* check if data is available */ - fd_set readfds, writefds, exceptfds; - int maxfd = 0; - struct timeval timeout; - do { - FD_ZERO(&readfds); - FD_ZERO(&writefds); - FD_ZERO(&exceptfds); - FD_SET(sockfd, &readfds); - if (encbuf.off != 0) - FD_SET(sockfd, &writefds); - FD_SET(sockfd, &exceptfds); - maxfd = sockfd + 1; - if (inputfd != -1) { - FD_SET(inputfd, &readfds); - FD_SET(inputfd, &exceptfds); - if (maxfd <= inputfd) - maxfd = inputfd + 1; - } - timeout.tv_sec = encbuf.off != 0 ? 0 : 3600; - timeout.tv_usec = 0; - } while (select(maxfd, &readfds, &writefds, &exceptfds, &timeout) == -1); - - /* consume incoming messages */ - if (FD_ISSET(sockfd, &readfds) || FD_ISSET(sockfd, &exceptfds)) { - size_t off = 0, leftlen; - while ((ioret = read(sockfd, bytebuf, sizeof(bytebuf))) == -1 && errno == EINTR) - ; - if (ioret == -1 && (errno == EWOULDBLOCK || errno == EAGAIN)) { - /* no data */ - ioret = 0; - } else if (ioret <= 0) { - goto Exit; - } - while ((leftlen = ioret - off) != 0) { - if (state == IN_HANDSHAKE) { - if ((ret = ptls_handshake(tls, &encbuf, bytebuf + off, &leftlen, hsprop)) == 0) { - state = IN_1RTT; - /* release data sent as early-data, if server accepted it */ - if (hsprop->client.early_data_accepted_by_peer) - shift_buffer(&ptbuf, early_bytes_sent); - if (ptbuf.off != 0) { - if ((ret = ptls_send(tls, &encbuf, ptbuf.base, ptbuf.off)) != 0) { - fprintf(stderr, "ptls_send(1rtt):%d\n", ret); - goto Exit; - } - ptbuf.off = 0; - } - } else if (ret == PTLS_ERROR_IN_PROGRESS) { - /* ok */ - } else { - fprintf(stderr, "ptls_handshake:%d\n", ret); - goto Exit; - } - } else { - if ((ret = ptls_receive(tls, &rbuf, bytebuf + off, &leftlen)) == 0) { - if (rbuf.off != 0) { - write(1, rbuf.base, rbuf.off); - rbuf.off = 0; - } - } else if (ret == PTLS_ERROR_IN_PROGRESS) { - /* ok */ - } else { - fprintf(stderr, "ptls_receive:%d\n", ret); - goto Exit; - } - } - off += leftlen; - } - } - - /* read input (and send if possible) */ - if (inputfd != -1 && (FD_ISSET(inputfd, &readfds) || FD_ISSET(inputfd, &exceptfds))) { - while ((ioret = read(inputfd, bytebuf, sizeof(bytebuf))) == -1 && errno == EINTR) - ; - if (ioret > 0) { - ptls_buffer_pushv(&ptbuf, bytebuf, ioret); - if (state == IN_HANDSHAKE) { - size_t send_amount = 0; - if (hsprop->client.max_early_data_size != NULL) { - size_t max_can_be_sent = *hsprop->client.max_early_data_size; - if (max_can_be_sent > ptbuf.off) - max_can_be_sent = ptbuf.off; - send_amount = max_can_be_sent - early_bytes_sent; - } - if (send_amount != 0) { - if ((ret = ptls_send(tls, &encbuf, ptbuf.base, send_amount)) != 0) { - fprintf(stderr, "ptls_send(early_data):%d\n", ret); - goto Exit; - } - early_bytes_sent += send_amount; - } - } else { - if ((ret = ptls_send(tls, &encbuf, bytebuf, ioret)) != 0) { - fprintf(stderr, "ptls_send(1rtt):%d\n", ret); - goto Exit; - } - ptbuf.off = 0; - } - } else { - /* closed */ - if (input_file != NULL) - close(inputfd); - inputfd = -1; - } - } - - /* send any data */ - if (encbuf.off != 0) { - while ((ioret = write(sockfd, encbuf.base, encbuf.off)) == -1 && errno == EINTR) - ; - if (ioret == -1 && (errno == EWOULDBLOCK || errno == EAGAIN)) { - /* no data */ - } else if (ioret <= 0) { - goto Exit; - } else { - shift_buffer(&encbuf, ioret); - } - } - - /* close the sender side when necessary */ - if (state == IN_1RTT && inputfd == -1) { - /* FIXME send close_alert */ - shutdown(sockfd, SHUT_WR); - state = IN_SHUTDOWN; - } - } - -Exit: - if (sockfd != -1) - close(sockfd); - if (input_file != NULL && inputfd != -1) - close(inputfd); - ptls_buffer_dispose(&rbuf); - ptls_buffer_dispose(&encbuf); - ptls_buffer_dispose(&ptbuf); - ptls_free(tls); - return ret != 0; -} - -static int run_server(struct sockaddr *sa, socklen_t salen, ptls_context_t *ctx, const char *input_file, - ptls_handshake_properties_t *hsprop) -{ - int listen_fd, conn_fd, on = 1; - - if ((listen_fd = socket(sa->sa_family, SOCK_STREAM, 0)) == -1) { - perror("socket(2) failed"); - return 1; - } - if (setsockopt(listen_fd, SOL_SOCKET, SO_REUSEADDR, &on, sizeof(on)) != 0) { - perror("setsockopt(SO_REUSEADDR) failed"); - return 1; - } - if (bind(listen_fd, sa, salen) != 0) { - perror("bind(2) failed"); - return 1; - } - if (listen(listen_fd, SOMAXCONN) != 0) { - perror("listen(2) failed"); - return 1; - } - - while (1) { - if ((conn_fd = accept(listen_fd, NULL, 0)) != -1) - handle_connection(conn_fd, ctx, NULL, input_file, hsprop); - } - - return 0; -} - -static int run_client(struct sockaddr *sa, socklen_t salen, ptls_context_t *ctx, const char *server_name, const char *input_file, - ptls_handshake_properties_t *hsprop) -{ - int fd; - - if ((fd = socket(sa->sa_family, SOCK_STREAM, 0)) == 1) { - perror("socket(2) failed"); - return 1; - } - if (connect(fd, sa, salen) != 0) { - perror("connect(2) failed"); - return 1; - } - - return handle_connection(fd, ctx, server_name, input_file, hsprop); -} - -static void usage(const char *cmd) -{ - printf("Usage: %s [options] host port\n" - "\n" - "Options:\n" - " -4 force IPv4\n" - " -6 force IPv6\n" - " -c certificate-file\n" - " -i file a file to read from and send to the peer (default: stdin)\n" - " -k key-file specifies the credentials to be used for running the\n" - " server. If omitted, the command runs as a client.\n" - " -l log-file file to log traffic secrets\n" - " -n negotiates the key exchange method (i.e. wait for HRR)\n" - " -s session-file file to read/write the session ticket\n" - " -S require public key exchange when resuming a session\n" - " -e when resuming a session, send first 8,192 bytes of input\n" - " as early data\n" - " -v verify peer using the default certificates\n" - " -h print this help\n" - "\n", - cmd); -} - -int main(int argc, char **argv) -{ - ERR_load_crypto_strings(); - OpenSSL_add_all_algorithms(); -#if !defined(OPENSSL_NO_ENGINE) - /* Load all compiled-in ENGINEs */ - ENGINE_load_builtin_engines(); - ENGINE_register_all_ciphers(); - ENGINE_register_all_digests(); -#endif - - ptls_context_t ctx = {ptls_openssl_random_bytes, &ptls_get_time, ptls_openssl_key_exchanges, ptls_openssl_cipher_suites}; - ptls_handshake_properties_t hsprop = {{{{NULL}}}}; - const char *host, *port, *file = NULL; - int use_early_data = 0, ch; - struct sockaddr_storage sa; - socklen_t salen; - int family = 0; - - while ((ch = getopt(argc, argv, "46c:i:k:nes:Sl:vh")) != -1) { - switch (ch) { - case '4': - family = AF_INET; - break; - case '6': - family = AF_INET6; - break; - case 'c': - load_certificate_chain(&ctx, optarg); - break; - case 'i': - file = optarg; - break; - case 'k': - load_private_key(&ctx, optarg); - break; - case 'n': - hsprop.client.negotiate_before_key_exchange = 1; - break; - case 'e': - use_early_data = 1; - break; - case 's': - setup_session_file(&ctx, &hsprop, optarg); - break; - case 'S': - ctx.require_dhe_on_psk = 1; - break; - case 'l': - setup_log_secret(&ctx, optarg); - break; - case 'v': - setup_verify_certificate(&ctx); - break; - default: - usage(argv[0]); - exit(1); - } - } - argc -= optind; - argv += optind; - if (ctx.certificates.count != 0 || ctx.sign_certificate != NULL) { - /* server */ - if (ctx.certificates.count == 0 || ctx.sign_certificate == NULL) { - fprintf(stderr, "-c and -k options must be used together\n"); - return 1; - } - setup_session_cache(&ctx); - } else { - /* client */ - if (use_early_data) { - static size_t max_early_data_size; - hsprop.client.max_early_data_size = &max_early_data_size; - } - } - if (argc != 2) { - fprintf(stderr, "missing host and port\n"); - return 1; - } - host = (--argc, *argv++); - port = (--argc, *argv++); - - if (resolve_address((struct sockaddr *)&sa, &salen, host, port, family, SOCK_STREAM, IPPROTO_TCP) != 0) - exit(1); - - if (ctx.certificates.count != 0) { - return run_server((struct sockaddr *)&sa, salen, &ctx, file, &hsprop); - } else { - return run_client((struct sockaddr *)&sa, salen, &ctx, host, file, &hsprop); - } -} |