#pragma once
#include "common.hpp"
#include "ssl_common.hpp"
#include "mkcert.hpp"
#include "config.hpp"
#include "pool.hpp"
#include "poll.hpp"
#include "hash.hpp"
#include "hooks.hpp"
event_t getcert(ssl_t*, X509*&); ///< perform handshake and retrieve certificate: EVENT_IN/_OUT: need i/o, EVENT_NONE: some error, EVENT_CLOSE: handshake finished and cert set (if any)
bool ssl_sni(const char*, size_t, char*&); ///< tries initial client handshake r/o, true if successfully read. the detected sni can be set even in case of error. XXX: re-using the ssl state did not work due to intermediate BIO switching to fds?
ssl_t* ssl_get(); ///< create initial ssl usable for SNI peeking
ssl_t* ssl_get(ssl_ctx_t*, int fd, buf_t* rbuf=NULL); ///< create per-conn ssl from per-cert ctx and attach to fd (ts), optionally take over already read client helo data.
ssl_t* ssl_get(const char*, int fd); ///< creates ssl for upstream connections using the SNI, if available (ts)
void ssl_del(ssl_t*, bool shutdown=true); ///< frees data, optional ssl shutdown, does not close fd (ts)
event_t ssl_accept(ssl_t*); ///< done upon EVENT_NONE, error upon EVENT_CLOSE, I/O events otherwise
event_t ssl_shutdown(ssl_t*); ///< done upon EVENT_NONE (whether successful or not), I/O events otherwise
ssize_t ssl_read(ssl_t*, char*, size_t); ///< make sure to handle ERESTART indicating WANT_WRITE (e.g upon (intermediate) handshakes/negotiations)
ssize_t ssl_write(ssl_t*, const char*, size_t); ///< make sure to handle ERESTART indicating WANT_READ (e.g upon (intermediate) handshakes/negotiations)