summaryrefslogtreecommitdiffstats
path: root/debian/vendor-h2o/include/h2o/socket
diff options
context:
space:
mode:
Diffstat (limited to '')
-rw-r--r--debian/vendor-h2o/include/h2o/socket.h403
-rw-r--r--debian/vendor-h2o/include/h2o/socket/evloop.h74
-rw-r--r--debian/vendor-h2o/include/h2o/socket/uv-binding.h44
-rw-r--r--debian/vendor-h2o/include/h2o/socketpool.h120
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