diff options
author | Daniel Baumann <daniel.baumann@progress-linux.org> | 2024-04-13 21:12:02 +0000 |
---|---|---|
committer | Daniel Baumann <daniel.baumann@progress-linux.org> | 2024-04-13 21:12:02 +0000 |
commit | 77e50caaf2ef81cd91075cf836fed0e75718ffb4 (patch) | |
tree | 53b7b411290b63192fc9e924a3b6b65cdf67e9d0 /debian/vendor-h2o/include/h2o/socket | |
parent | Adding upstream version 1.8.3. (diff) | |
download | dnsdist-77e50caaf2ef81cd91075cf836fed0e75718ffb4.tar.xz dnsdist-77e50caaf2ef81cd91075cf836fed0e75718ffb4.zip |
Adding debian version 1.8.3-2.debian/1.8.3-2
Signed-off-by: Daniel Baumann <daniel.baumann@progress-linux.org>
Diffstat (limited to '')
-rw-r--r-- | debian/vendor-h2o/include/h2o/socket.h | 403 | ||||
-rw-r--r-- | debian/vendor-h2o/include/h2o/socket/evloop.h | 74 | ||||
-rw-r--r-- | debian/vendor-h2o/include/h2o/socket/uv-binding.h | 44 | ||||
-rw-r--r-- | debian/vendor-h2o/include/h2o/socketpool.h | 120 |
4 files changed, 641 insertions, 0 deletions
diff --git a/debian/vendor-h2o/include/h2o/socket.h b/debian/vendor-h2o/include/h2o/socket.h new file mode 100644 index 0000000..9727e34 --- /dev/null +++ b/debian/vendor-h2o/include/h2o/socket.h @@ -0,0 +1,403 @@ +/* + * Copyright (c) 2014-2016 DeNA Co., Ltd., Kazuho Oku, Fastly, Inc. + * + * 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 h2o__socket_h +#define h2o__socket_h + +#ifdef __cplusplus +extern "C" { +#endif + +#include <stdint.h> +#include <sys/socket.h> +#include <openssl/ssl.h> +#include "h2o/cache.h" +#include "h2o/memory.h" +#include "h2o/openssl_backport.h" +#include "h2o/string_.h" + +#ifndef H2O_USE_LIBUV +#if H2O_USE_SELECT || H2O_USE_EPOLL || H2O_USE_KQUEUE +#define H2O_USE_LIBUV 0 +#else +#define H2O_USE_LIBUV 1 +#endif +#endif + +#if OPENSSL_VERSION_NUMBER >= 0x10002000L +#define H2O_USE_ALPN 1 +#define H2O_USE_NPN 1 +#elif OPENSSL_VERSION_NUMBER >= 0x10001000L +#define H2O_USE_ALPN 0 +#define H2O_USE_NPN 1 +#else +#define H2O_USE_ALPN 0 +#define H2O_USE_NPN 0 +#endif + +typedef struct st_h2o_sliding_counter_t { + uint64_t average; + struct { + uint64_t sum; + uint64_t slots[8]; + size_t index; + } prev; + struct { + uint64_t start_at; + } cur; +} h2o_sliding_counter_t; + +static int h2o_sliding_counter_is_running(h2o_sliding_counter_t *counter); +static void h2o_sliding_counter_start(h2o_sliding_counter_t *counter, uint64_t now); +void h2o_sliding_counter_stop(h2o_sliding_counter_t *counter, uint64_t now); + +#define H2O_SOCKET_INITIAL_INPUT_BUFFER_SIZE 4096 + +typedef struct st_h2o_socket_t h2o_socket_t; + +typedef void (*h2o_socket_cb)(h2o_socket_t *sock, const char *err); + +#if H2O_USE_LIBUV +#include "socket/uv-binding.h" +#else +#include "socket/evloop.h" +#endif + +struct st_h2o_socket_peername_t { + socklen_t len; + struct sockaddr addr; +}; + +enum { + H2O_SOCKET_LATENCY_OPTIMIZATION_STATE_TBD = 0, + H2O_SOCKET_LATENCY_OPTIMIZATION_STATE_NEEDS_UPDATE, + H2O_SOCKET_LATENCY_OPTIMIZATION_STATE_DISABLED, + H2O_SOCKET_LATENCY_OPTIMIZATION_STATE_DETERMINED +}; + +/** + * abstraction layer for sockets (SSL vs. TCP) + */ +struct st_h2o_socket_t { + void *data; + struct st_h2o_socket_ssl_t *ssl; + h2o_buffer_t *input; + /** + * total bytes read (above the TLS layer) + */ + size_t bytes_read; + /** + * total bytes written (above the TLS layer) + */ + size_t bytes_written; + struct { + void (*cb)(void *data); + void *data; + } on_close; + struct { + h2o_socket_cb read; + h2o_socket_cb write; + } _cb; + struct st_h2o_socket_peername_t *_peername; + struct { + uint8_t state; /* one of H2O_SOCKET_LATENCY_STATE_* */ + uint8_t notsent_is_minimized : 1; + uint16_t suggested_tls_payload_size; + size_t suggested_write_size; /* SIZE_MAX if no need to optimize for latency */ + } _latency_optimization; +}; + +typedef struct st_h2o_socket_export_t { + int fd; + struct st_h2o_socket_ssl_t *ssl; + h2o_buffer_t *input; +} h2o_socket_export_t; + +/** + * sets the conditions to enable the optimization + */ +typedef struct st_h2o_socket_latency_optimization_conditions_t { + /** + * in milliseconds + */ + unsigned min_rtt; + /** + * percent ratio + */ + unsigned max_additional_delay; + /** + * in number of octets + */ + unsigned max_cwnd; +} h2o_socket_latency_optimization_conditions_t; + +typedef void (*h2o_socket_ssl_resumption_get_async_cb)(h2o_socket_t *sock, h2o_iovec_t session_id); +typedef void (*h2o_socket_ssl_resumption_new_cb)(h2o_iovec_t session_id, h2o_iovec_t session_data); +typedef void (*h2o_socket_ssl_resumption_remove_cb)(h2o_iovec_t session_id); + +extern h2o_buffer_mmap_settings_t h2o_socket_buffer_mmap_settings; +extern __thread h2o_buffer_prototype_t h2o_socket_buffer_prototype; + +extern const char *h2o_socket_error_out_of_memory; +extern const char *h2o_socket_error_io; +extern const char *h2o_socket_error_closed; +extern const char *h2o_socket_error_conn_fail; +extern const char *h2o_socket_error_ssl_no_cert; +extern const char *h2o_socket_error_ssl_cert_invalid; +extern const char *h2o_socket_error_ssl_cert_name_mismatch; +extern const char *h2o_socket_error_ssl_decode; + +/** + * returns the loop + */ +h2o_loop_t *h2o_socket_get_loop(h2o_socket_t *sock); +/** + * detaches a socket from loop. + */ +int h2o_socket_export(h2o_socket_t *sock, h2o_socket_export_t *info); +/** + * attaches a socket onto a loop. + */ +h2o_socket_t *h2o_socket_import(h2o_loop_t *loop, h2o_socket_export_t *info); +/** + * destroys an exported socket info. + */ +void h2o_socket_dispose_export(h2o_socket_export_t *info); +/** + * closes the socket + */ +void h2o_socket_close(h2o_socket_t *sock); +/** + * Schedules a callback to be notify we the socket can be written to + */ +void h2o_socket_notify_write(h2o_socket_t *sock, h2o_socket_cb cb); +/** + * Obtain the underlying fd of a sock struct + */ +int h2o_socket_get_fd(h2o_socket_t *sock); +/** + * Set/Unset the H2O_SOCKET_FLAG_DONT_READ flag. + * Setting it allows to be simply notified rather than having the data + * automatically be read. + */ +void h2o_socket_dont_read(h2o_socket_t *sock, int dont_read); +/** + * connects to peer + */ +h2o_socket_t *h2o_socket_connect(h2o_loop_t *loop, struct sockaddr *addr, socklen_t addrlen, h2o_socket_cb cb); +/** + * prepares for latency-optimized write and returns the number of octets that should be written, or SIZE_MAX if failed to prepare + */ +static size_t h2o_socket_prepare_for_latency_optimized_write(h2o_socket_t *sock, + const h2o_socket_latency_optimization_conditions_t *conditions); +size_t h2o_socket_do_prepare_for_latency_optimized_write(h2o_socket_t *sock, + const h2o_socket_latency_optimization_conditions_t *conditions); +/** + * writes given data to socket + * @param sock the socket + * @param bufs an array of buffers + * @param bufcnt length of the buffer array + * @param cb callback to be called when write is complete + */ +void h2o_socket_write(h2o_socket_t *sock, h2o_iovec_t *bufs, size_t bufcnt, h2o_socket_cb cb); +/** + * starts polling on the socket (for read) and calls given callback when data arrives + * @param sock the socket + * @param cb callback to be called when data arrives + * @note callback is called when any data arrives at the TCP level so that the + * applications can update their timeout counters. In other words, there is no + * guarantee that _new_ data is available when the callback gets called (e.g. + * in cases like receiving a partial SSL record or a corrupt TCP packet). + */ +void h2o_socket_read_start(h2o_socket_t *sock, h2o_socket_cb cb); +/** + * stops polling on the socket (for read) + * @param sock the socket + */ +void h2o_socket_read_stop(h2o_socket_t *sock); +/** + * returns a boolean value indicating whether if there is a write is under operation + */ +static int h2o_socket_is_writing(h2o_socket_t *sock); +/** + * returns a boolean value indicating whether if the socket is being polled for read + */ +static int h2o_socket_is_reading(h2o_socket_t *sock); +/** + * returns the length of the local address obtained (or 0 if failed) + */ +socklen_t h2o_socket_getsockname(h2o_socket_t *sock, struct sockaddr *sa); +/** + * returns the length of the remote address obtained (or 0 if failed) + */ +socklen_t h2o_socket_getpeername(h2o_socket_t *sock, struct sockaddr *sa); +/** + * sets the remote address (used for overriding the value) + */ +void h2o_socket_setpeername(h2o_socket_t *sock, struct sockaddr *sa, socklen_t len); +/** + * + */ +const char *h2o_socket_get_ssl_protocol_version(h2o_socket_t *sock); +int h2o_socket_get_ssl_session_reused(h2o_socket_t *sock); +const char *h2o_socket_get_ssl_cipher(h2o_socket_t *sock); +int h2o_socket_get_ssl_cipher_bits(h2o_socket_t *sock); +h2o_iovec_t h2o_socket_get_ssl_session_id(h2o_socket_t *sock); +const char *h2o_socket_get_ssl_server_name(const h2o_socket_t *sock); +static h2o_iovec_t h2o_socket_log_ssl_protocol_version(h2o_socket_t *sock, h2o_mem_pool_t *pool); +static h2o_iovec_t h2o_socket_log_ssl_session_reused(h2o_socket_t *sock, h2o_mem_pool_t *pool); +static h2o_iovec_t h2o_socket_log_ssl_cipher(h2o_socket_t *sock, h2o_mem_pool_t *pool); +h2o_iovec_t h2o_socket_log_ssl_cipher_bits(h2o_socket_t *sock, h2o_mem_pool_t *pool); +h2o_iovec_t h2o_socket_log_ssl_session_id(h2o_socket_t *sock, h2o_mem_pool_t *pool); + +/** + * compares socket addresses + */ +int h2o_socket_compare_address(struct sockaddr *x, struct sockaddr *y); +/** + * getnameinfo (buf should be NI_MAXHOST in length), returns SIZE_MAX if failed + */ +size_t h2o_socket_getnumerichost(struct sockaddr *sa, socklen_t salen, char *buf); +/** + * returns the port number, or -1 if failed + */ +int32_t h2o_socket_getport(struct sockaddr *sa); +/** + * performs SSL handshake on a socket + * @param sock the socket + * @param ssl_ctx SSL context + * @param handshake_cb callback to be called when handshake is complete + */ +void h2o_socket_ssl_handshake(h2o_socket_t *sock, SSL_CTX *ssl_ctx, const char *server_name, h2o_socket_cb handshake_cb); +/** + * resumes SSL handshake with given session data + * @param sock the socket + * @param session_data session data (or {NULL,0} if not available) + */ +void h2o_socket_ssl_resume_server_handshake(h2o_socket_t *sock, h2o_iovec_t session_data); +/** + * registers callbacks to be called for handling session data + */ +void h2o_socket_ssl_async_resumption_init(h2o_socket_ssl_resumption_get_async_cb get_cb, h2o_socket_ssl_resumption_new_cb new_cb); +/** + * setups the SSL context to use the async resumption + */ +void h2o_socket_ssl_async_resumption_setup_ctx(SSL_CTX *ctx); +/** + * returns the name of the protocol selected using either NPN or ALPN (ALPN has the precedence). + * @param sock the socket + */ +h2o_iovec_t h2o_socket_ssl_get_selected_protocol(h2o_socket_t *sock); +/** + * + */ +struct st_ptls_context_t *h2o_socket_ssl_get_picotls_context(SSL_CTX *ossl); +/** + * associates a picotls context to SSL_CTX + */ +void h2o_socket_ssl_set_picotls_context(SSL_CTX *ossl, struct st_ptls_context_t *ptls); +/** + * + */ +h2o_cache_t *h2o_socket_ssl_get_session_cache(SSL_CTX *ctx); +/** + * + */ +void h2o_socket_ssl_set_session_cache(SSL_CTX *ctx, h2o_cache_t *cache); +/** + * + */ +void h2o_socket_ssl_destroy_session_cache_entry(h2o_iovec_t value); +/** + * registers the protocol list to be used for ALPN + */ +void h2o_ssl_register_alpn_protocols(SSL_CTX *ctx, const h2o_iovec_t *protocols); +/** + * registers the protocol list to be used for NPN + */ +void h2o_ssl_register_npn_protocols(SSL_CTX *ctx, const char *protocols); + +void h2o_socket__write_pending(h2o_socket_t *sock); +void h2o_socket__write_on_complete(h2o_socket_t *sock, int status); + +/* inline defs */ + +inline int h2o_socket_is_writing(h2o_socket_t *sock) +{ + return sock->_cb.write != NULL; +} + +inline int h2o_socket_is_reading(h2o_socket_t *sock) +{ + return sock->_cb.read != NULL; +} + +inline size_t h2o_socket_prepare_for_latency_optimized_write(h2o_socket_t *sock, + const h2o_socket_latency_optimization_conditions_t *conditions) +{ + switch (sock->_latency_optimization.state) { + case H2O_SOCKET_LATENCY_OPTIMIZATION_STATE_TBD: + case H2O_SOCKET_LATENCY_OPTIMIZATION_STATE_NEEDS_UPDATE: + return h2o_socket_do_prepare_for_latency_optimized_write(sock, conditions); + default: + return sock->_latency_optimization.suggested_write_size; + } +} + +inline h2o_iovec_t h2o_socket_log_ssl_protocol_version(h2o_socket_t *sock, h2o_mem_pool_t *pool) +{ + const char *s = h2o_socket_get_ssl_protocol_version(sock); + return s != NULL ? h2o_iovec_init(s, strlen(s)) : h2o_iovec_init(NULL, 0); +} + +inline h2o_iovec_t h2o_socket_log_ssl_session_reused(h2o_socket_t *sock, h2o_mem_pool_t *pool) +{ + switch (h2o_socket_get_ssl_session_reused(sock)) { + case 0: + return h2o_iovec_init(H2O_STRLIT("0")); + case 1: + return h2o_iovec_init(H2O_STRLIT("1")); + default: + return h2o_iovec_init(NULL, 0); + } +} + +inline h2o_iovec_t h2o_socket_log_ssl_cipher(h2o_socket_t *sock, h2o_mem_pool_t *pool) +{ + const char *s = h2o_socket_get_ssl_cipher(sock); + return s != NULL ? h2o_iovec_init(s, strlen(s)) : h2o_iovec_init(NULL, 0); +} + +inline int h2o_sliding_counter_is_running(h2o_sliding_counter_t *counter) +{ + return counter->cur.start_at != 0; +} + +inline void h2o_sliding_counter_start(h2o_sliding_counter_t *counter, uint64_t now) +{ + counter->cur.start_at = now; +} + +#ifdef __cplusplus +} +#endif + +#endif diff --git a/debian/vendor-h2o/include/h2o/socket/evloop.h b/debian/vendor-h2o/include/h2o/socket/evloop.h new file mode 100644 index 0000000..61ff29a --- /dev/null +++ b/debian/vendor-h2o/include/h2o/socket/evloop.h @@ -0,0 +1,74 @@ +/* + * Copyright (c) 2014 DeNA Co., Ltd. + * + * 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 h2o__evloop_h +#define h2o__evloop_h + +#include "h2o/linklist.h" + +#define H2O_SOCKET_FLAG_IS_DISPOSED 0x1 +#define H2O_SOCKET_FLAG_IS_READ_READY 0x2 +#define H2O_SOCKET_FLAG_IS_WRITE_NOTIFY 0x4 +#define H2O_SOCKET_FLAG_IS_POLLED_FOR_READ 0x8 +#define H2O_SOCKET_FLAG_IS_POLLED_FOR_WRITE 0x10 +#define H2O_SOCKET_FLAG_DONT_READ 0x20 +#define H2O_SOCKET_FLAG_IS_CONNECTING 0x40 +#define H2O_SOCKET_FLAG_IS_ACCEPTED_CONNECTION 0x80 +#define H2O_SOCKET_FLAG__EPOLL_IS_REGISTERED 0x1000 + +typedef struct st_h2o_evloop_t { + struct st_h2o_evloop_socket_t *_pending_as_client; + struct st_h2o_evloop_socket_t *_pending_as_server; + struct { + struct st_h2o_evloop_socket_t *head; + struct st_h2o_evloop_socket_t **tail_ref; + } _statechanged; + uint64_t _now; + h2o_linklist_t _timeouts; /* list of h2o_timeout_t */ + h2o_sliding_counter_t exec_time_counter; +} h2o_evloop_t; + +typedef h2o_evloop_t h2o_loop_t; + +struct st_h2o_timeout_backend_properties_t { + char _dummy; /* sizeof(empty_struct) differs bet. C (GCC extension) and C++ */ +}; + +h2o_socket_t *h2o_evloop_socket_create(h2o_evloop_t *loop, int fd, int flags); +h2o_socket_t *h2o_evloop_socket_accept(h2o_socket_t *listener); + +h2o_evloop_t *h2o_evloop_create(void); +void h2o_evloop_destroy(h2o_evloop_t *loop); +int h2o_evloop_run(h2o_evloop_t *loop, int32_t max_wait); + +/* inline definitions */ + +static inline uint64_t h2o_now(h2o_evloop_t *loop) +{ + return loop->_now; +} + +static inline uint64_t h2o_evloop_get_execution_time(h2o_evloop_t *loop) +{ + return loop->exec_time_counter.average; +} + +#endif diff --git a/debian/vendor-h2o/include/h2o/socket/uv-binding.h b/debian/vendor-h2o/include/h2o/socket/uv-binding.h new file mode 100644 index 0000000..ad28122 --- /dev/null +++ b/debian/vendor-h2o/include/h2o/socket/uv-binding.h @@ -0,0 +1,44 @@ +/* + * Copyright (c) 2014 DeNA Co., Ltd. + * + * 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 h2o__uv_binding_h +#define h2o__uv_binding_h + +#include <uv.h> + +#if !(defined(UV_VERSION_MAJOR) && UV_VERSION_MAJOR == 1) +#error "libh2o (libuv binding) requires libuv version 1.x.y" +#endif + +typedef uv_loop_t h2o_loop_t; + +struct st_h2o_timeout_backend_properties_t { + uv_timer_t timer; +}; + +h2o_socket_t *h2o_uv_socket_create(uv_stream_t *stream, uv_close_cb close_cb); + +static inline uint64_t h2o_now(uv_loop_t *loop) +{ + return uv_now(loop); +} + +#endif diff --git a/debian/vendor-h2o/include/h2o/socketpool.h b/debian/vendor-h2o/include/h2o/socketpool.h new file mode 100644 index 0000000..cc4161d --- /dev/null +++ b/debian/vendor-h2o/include/h2o/socketpool.h @@ -0,0 +1,120 @@ +/* + * Copyright (c) 2014 DeNA Co., Ltd. + * + * 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 h2o__socket_pool_h +#define h2o__socket_pool_h + +#ifdef __cplusplus +extern "C" { +#endif + +#include <netinet/in.h> +#include <arpa/inet.h> +#include <pthread.h> +#include "h2o/linklist.h" +#include "h2o/multithread.h" +#include "h2o/socket.h" +#include "h2o/timeout.h" + +typedef enum en_h2o_socketpool_type_t { H2O_SOCKETPOOL_TYPE_NAMED, H2O_SOCKETPOOL_TYPE_SOCKADDR } h2o_socketpool_type_t; + +typedef struct st_h2o_socketpool_t { + + /* read-only vars */ + h2o_socketpool_type_t type; + struct { + h2o_iovec_t host; + union { + /* used to specify servname passed to getaddrinfo */ + h2o_iovec_t named_serv; + /* if type is sockaddr, the `host` is not resolved but is used for TLS SNI and hostname verification */ + struct { + struct sockaddr_storage bytes; + socklen_t len; + } sockaddr; + }; + } peer; + int is_ssl; + size_t capacity; + uint64_t timeout; /* in milliseconds (UINT64_MAX if not set) */ + struct { + h2o_loop_t *loop; + h2o_timeout_t timeout; + h2o_timeout_entry_t entry; + } _interval_cb; + + /* vars that are modified by multiple threads */ + struct { + size_t count; /* synchronous operations should be used to access the variable */ + pthread_mutex_t mutex; + h2o_linklist_t sockets; /* guarded by the mutex; list of struct pool_entry_t defined in socket/pool.c */ + } _shared; +} h2o_socketpool_t; + +typedef struct st_h2o_socketpool_connect_request_t h2o_socketpool_connect_request_t; + +typedef void (*h2o_socketpool_connect_cb)(h2o_socket_t *sock, const char *errstr, void *data); +/** + * initializes a socket loop + */ +void h2o_socketpool_init_by_address(h2o_socketpool_t *pool, struct sockaddr *sa, socklen_t salen, int is_ssl, size_t capacity); +/** + * initializes a socket loop + */ +void h2o_socketpool_init_by_hostport(h2o_socketpool_t *pool, h2o_iovec_t host, uint16_t port, int is_ssl, size_t capacity); +/** + * disposes of a socket loop + */ +void h2o_socketpool_dispose(h2o_socketpool_t *pool); +/** + * sets a close timeout for the sockets being pooled + */ +void h2o_socketpool_set_timeout(h2o_socketpool_t *pool, h2o_loop_t *loop, uint64_t msec); +/** + * connects to the peer (or returns a pooled connection) + */ +void h2o_socketpool_connect(h2o_socketpool_connect_request_t **req, h2o_socketpool_t *pool, h2o_loop_t *loop, + h2o_multithread_receiver_t *getaddr_receiver, h2o_socketpool_connect_cb cb, void *data); +/** + * cancels a connect request + */ +void h2o_socketpool_cancel_connect(h2o_socketpool_connect_request_t *req); +/** + * returns an idling socket to the socket pool + */ +int h2o_socketpool_return(h2o_socketpool_t *pool, h2o_socket_t *sock); +/** + * determines if a socket belongs to the socket pool + */ +static int h2o_socketpool_is_owned_socket(h2o_socketpool_t *pool, h2o_socket_t *sock); + +/* inline defs */ + +inline int h2o_socketpool_is_owned_socket(h2o_socketpool_t *pool, h2o_socket_t *sock) +{ + return sock->on_close.data == pool; +} + +#ifdef __cplusplus +} +#endif + +#endif |