nghttp2/src/shrpx_connection.h

204 lines
6.5 KiB
C++

/*
* nghttp2 - HTTP/2 C Library
*
* Copyright (c) 2015 Tatsuhiro Tsujikawa
*
* 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 SHRPX_CONNECTION_H
#define SHRPX_CONNECTION_H
#include "shrpx_config.h"
#include <sys/uio.h>
#include <ev.h>
#include <openssl/ssl.h>
#ifdef ENABLE_HTTP3
# include <ngtcp2/ngtcp2_crypto.h>
#endif // ENABLE_HTTP3
#include "shrpx_rate_limit.h"
#include "shrpx_error.h"
#include "memchunk.h"
namespace shrpx {
struct MemcachedRequest;
namespace tls {
struct TLSSessionCache;
} // namespace tls
enum class TLSHandshakeState {
NORMAL,
WAIT_FOR_SESSION_CACHE,
GOT_SESSION_CACHE,
CANCEL_SESSION_CACHE,
WRITE_STARTED,
};
struct TLSConnection {
DefaultMemchunks wbuf;
DefaultPeekMemchunks rbuf;
// Stores TLSv1.3 early data.
DefaultMemchunks earlybuf;
SSL *ssl;
SSL_SESSION *cached_session;
MemcachedRequest *cached_session_lookup_req;
tls::TLSSessionCache *client_session_cache;
ev_tstamp last_write_idle;
size_t warmup_writelen;
// length passed to SSL_write and SSL_read last time. This is
// required since these functions require the exact same parameters
// on non-blocking I/O.
size_t last_writelen, last_readlen;
TLSHandshakeState handshake_state;
bool initial_handshake_done;
bool reneg_started;
// true if ssl is prepared to do handshake as server.
bool server_handshake;
// true if ssl is initialized as server, and client requested
// signed_certificate_timestamp extension.
bool sct_requested;
// true if TLSv1.3 early data has been completely received. Since
// SSL_read_early_data acts like SSL_do_handshake, this field may be
// true even if the negotiated TLS version is TLSv1.2 or earlier.
// This value is also true if this is client side connection for
// convenience.
bool early_data_finish;
};
struct TCPHint {
size_t write_buffer_size;
uint32_t rwin;
};
template <typename T> using EVCb = void (*)(struct ev_loop *, T *, int);
using IOCb = EVCb<ev_io>;
using TimerCb = EVCb<ev_timer>;
struct Connection {
Connection(struct ev_loop *loop, int fd, SSL *ssl, MemchunkPool *mcpool,
ev_tstamp write_timeout, ev_tstamp read_timeout,
const RateLimitConfig &write_limit,
const RateLimitConfig &read_limit, IOCb writecb, IOCb readcb,
TimerCb timeoutcb, void *data, size_t tls_dyn_rec_warmup_threshold,
ev_tstamp tls_dyn_rec_idle_timeout, Proto proto);
~Connection();
void disconnect();
void prepare_client_handshake();
void prepare_server_handshake();
int tls_handshake();
int tls_handshake_simple();
int write_tls_pending_handshake();
int check_http2_requirement();
// All write_* and writev_clear functions return number of bytes
// written. If nothing cannot be written (e.g., there is no
// allowance in RateLimit or underlying connection blocks), return
// 0. SHRPX_ERR_NETWORK is returned in case of error.
//
// All read_* functions return number of bytes read. If nothing
// cannot be read (e.g., there is no allowance in Ratelimit or
// underlying connection blocks), return 0. SHRPX_ERR_EOF is
// returned in case of EOF and no data was read. Otherwise
// SHRPX_ERR_NETWORK is return in case of error.
ssize_t write_tls(const void *data, size_t len);
ssize_t read_tls(void *data, size_t len);
size_t get_tls_write_limit();
// Updates the number of bytes written in warm up period.
void update_tls_warmup_writelen(size_t n);
// Tells there is no immediate write now. This triggers timer to
// determine fallback to short record size mode.
void start_tls_write_idle();
ssize_t write_clear(const void *data, size_t len);
ssize_t writev_clear(struct iovec *iov, int iovcnt);
ssize_t read_clear(void *data, size_t len);
// Read at most |len| bytes of data from socket without rate limit.
ssize_t read_nolim_clear(void *data, size_t len);
// Peek at most |len| bytes of data from socket without rate limit.
ssize_t peek_clear(void *data, size_t len);
void handle_tls_pending_read();
void set_ssl(SSL *ssl);
int get_tcp_hint(TCPHint *hint) const;
// These functions are provided for read timer which is frequently
// restarted. We do a trick to make a bit more efficient than just
// calling ev_timer_again().
// Restarts read timer with timeout value |t|.
void again_rt(ev_tstamp t);
// Restarts read timer without chainging timeout.
void again_rt();
// Returns true if read timer expired.
bool expired_rt();
#ifdef ENABLE_HTTP3
// This must be the first member of Connection.
ngtcp2_crypto_conn_ref conn_ref;
#endif // ENABLE_HTTP3
TLSConnection tls;
ev_io wev;
ev_io rev;
ev_timer wt;
ev_timer rt;
RateLimit wlimit;
RateLimit rlimit;
struct ev_loop *loop;
void *data;
int fd;
size_t tls_dyn_rec_warmup_threshold;
ev_tstamp tls_dyn_rec_idle_timeout;
// Application protocol used over the connection. This field is not
// used in this object at the moment. The rest of the program may
// use this value when it is useful.
Proto proto;
// The point of time when last read is observed. Note: since we use
// |rt| as idle timer, the activity is not limited to read.
ev_tstamp last_read;
// Timeout for read timer |rt|.
ev_tstamp read_timeout;
};
#ifdef ENABLE_HTTP3
static_assert(std::is_standard_layout<Connection>::value,
"Conneciton is not standard layout");
#endif // ENABLE_HTTP3
// Creates BIO_method shared by all SSL objects.
BIO_METHOD *create_bio_method();
} // namespace shrpx
#endif // SHRPX_CONNECTION_H