#define ACT_SKIP 2
#define ACT_CALL 3
+enum TLSState {
+ SBUF_TLS_NONE,
+ SBUF_TLS_DO_HANDSHAKE,
+ SBUF_TLS_IN_HANDSHAKE,
+ SBUF_TLS_OK,
+};
+
enum WaitType {
W_NONE = 0,
W_CONNECT,
static bool sbuf_call_proto(SBuf *sbuf, int event) /* _MUSTCHECK */;
static bool sbuf_actual_recv(SBuf *sbuf, unsigned len) _MUSTCHECK;
static bool sbuf_after_connect_check(SBuf *sbuf) _MUSTCHECK;
+static bool handle_tls_handshake(SBuf *sbuf) /* _MUSTCHECK */;
static inline IOBuf *get_iobuf(SBuf *sbuf) { return sbuf->io; }
/* notify proto that all is sent */
if (sbuf_is_empty(sbuf))
sbuf_call_proto(sbuf, SBUF_EV_FLUSH);
+
+ if (sbuf->tls_state == SBUF_TLS_DO_HANDSHAKE) {
+ sbuf->pkt_action = SBUF_TLS_IN_HANDSHAKE;
+ handle_tls_handshake(sbuf);
+ }
}
/* check if there is any error pending on socket */
} else if (err == TLS_WANT_POLLOUT) {
return sbuf_use_callback_once(sbuf, EV_WRITE, sbuf_tls_handshake_cb);
} else if (err == 0) {
+ sbuf->tls_state = SBUF_TLS_OK;
sbuf_call_proto(sbuf, SBUF_EV_TLS_READY);
return true;
} else {
{
int err;
+ if (!sbuf_pause(sbuf))
+ return false;
+
sbuf->ops = &tls_sbufio_ops;
err = tls_accept_fds(client_accept_base, &sbuf->tls, sbuf->sock, sbuf->sock);
return false;
}
- return handle_tls_handshake(sbuf);
+ sbuf->tls_state = SBUF_TLS_DO_HANDSHAKE;
+ return true;
}
/*
struct tls *ctls;
int err;
+ if (!sbuf_pause(sbuf))
+ return false;
+
if (cf_server_tls_sslmode != SSLMODE_VERIFY_FULL)
hostname = NULL;
return false;
}
- return handle_tls_handshake(sbuf);
+ sbuf->tls_state = SBUF_TLS_DO_HANDSHAKE;
+ return true;
}
/*
{
ssize_t out = 0;
+ if (sbuf->tls_state != SBUF_TLS_OK) {
+ errno = EIO;
+ return -1;
+ }
+
out = tls_read(sbuf->tls, dst, len);
log_noise("tls_read: req=%u out=%d", len, (int)out);
if (out >= 0) {
{
ssize_t out;
+ if (sbuf->tls_state != SBUF_TLS_OK) {
+ errno = EIO;
+ return -1;
+ }
+
out = tls_write(sbuf->tls, data, len);
log_noise("tls_write: req=%u out=%d", len, (int)out);
if (out >= 0) {