Commit 5665bb51 authored by Grigorii Demidov's avatar Grigorii Demidov Committed by Petr Spacek

daemon: unificate tls structures to avod code duplication

parent 931c1e66
......@@ -239,8 +239,7 @@ static void tcp_recv(uv_stream_t *handle, ssize_t nread, const uv_buf_t *buf)
* so the whole message reassembly and demuxing logic is inside worker */
int ret = 0;
if (s->has_tls) {
ret = s->outgoing ? tls_client_process(worker, handle, (const uint8_t *)buf->base, nread) :
tls_process(worker, handle, (const uint8_t *)buf->base, nread);
ret = tls_process(worker, handle, (const uint8_t *)buf->base, nread);
} else {
ret = worker_process_tcp(worker, handle, (const uint8_t *)buf->base, nread);
}
......@@ -298,7 +297,8 @@ static void _tcp_accept(uv_stream_t *master, int status, bool tls)
session->has_tls = tls;
if (tls && !session->tls_ctx) {
session->tls_ctx = tls_new(master->loop->data);
session->tls_ctx->session = session;
session->tls_ctx->c.session = session;
session->tls_ctx->c.handshake_state = TLS_HS_IN_PROGRESS;
}
uv_timer_t *timer = &session->timeout;
uv_timer_start(timer, tcp_timeout_trigger, KR_CONN_RTT_MAX/2, KR_CONN_RTT_MAX/2);
......
This diff is collapsed.
......@@ -47,60 +47,62 @@ struct tls_client_paramlist_entry {
struct worker_ctx;
struct qr_task;
/* gnutls_record_recv and gnutls_record_send */
struct tls_ctx_t {
gnutls_session_t tls_session;
bool handshake_done;
struct session *session;
/* for reading from the network */
const uint8_t *buf;
ssize_t nread;
ssize_t consumed;
uint8_t recv_buf[4096];
struct tls_credentials *credentials;
struct worker_ctx *worker;
struct qr_task *task;
};
typedef enum tls_client_hs_state {
TLS_HS_NOT_STARTED = 0,
TLS_HS_IN_PROGRESS,
TLS_HS_DONE,
TLS_HS_CLOSING,
TLS_HS_LAST
} tls_client_hs_state_t;
} tls_hs_state_t;
typedef int (*tls_handshake_cb) (struct session *session, int status);
struct tls_client_ctx_t {
struct tls_common_ctx {
bool client_side;
gnutls_session_t tls_session;
tls_client_hs_state_t handshake_state;
tls_hs_state_t handshake_state;
struct session *session;
tls_handshake_cb handshake_cb;
/* for reading from the network */
const uint8_t *buf;
ssize_t nread;
ssize_t consumed;
uint8_t recv_buf[4096];
const struct tls_client_paramlist_entry *params;
tls_handshake_cb handshake_cb;
struct worker_ctx *worker;
struct qr_task *task;
};
struct tls_ctx_t {
/*
* Since pointer to tls_ctx_t needs to be casted
* to tls_ctx_common in some functions,
* this field must be always at first position
*/
struct tls_common_ctx c;
struct tls_credentials *credentials;
};
struct tls_client_ctx_t {
/*
* Since pointer to tls_client_ctx_t needs to be casted
* to tls_ctx_common in some functions,
* this field must be always at first position
*/
struct tls_common_ctx c;
const struct tls_client_paramlist_entry *params;
};
/*! Create an empty TLS context in query context */
struct tls_ctx_t* tls_new(struct worker_ctx *worker);
/*! Close a TLS context (call gnutls_bye()) */
void tls_close(struct tls_ctx_t *ctx);
void tls_close(struct tls_common_ctx *ctx);
/*! Release a TLS context */
void tls_free(struct tls_ctx_t* tls);
/*! Push new data to TLS context for sending */
int tls_push(struct qr_task *task, uv_handle_t* handle, knot_pkt_t * pkt,
bool server_side);
int tls_push(struct qr_task *task, uv_handle_t* handle, knot_pkt_t * pkt);
/*! Unwrap incoming data from a TLS stream and pass them to TCP session.
* @return the number of newly-completed requests (>=0) or an error code
......@@ -126,6 +128,12 @@ void tls_credentials_log_pins(struct tls_credentials *tls_credentials);
/*! Generate new ephemeral TLS credentials. */
struct tls_credentials * tls_get_ephemeral_credentials(struct engine *engine);
/*! Get TLS handshake state. */
tls_hs_state_t tls_get_hs_state(const struct tls_common_ctx *ctx);
/*! Set TLS handshake state. */
int tls_set_hs_state(struct tls_common_ctx *ctx, tls_hs_state_t state);
/*! Set TLS authentication parameters for given address. */
int tls_client_params_set(map_t *tls_client_paramlist,
const char *addr, uint16_t port,
......@@ -138,23 +146,13 @@ int tls_client_params_free(map_t *tls_client_paramlist);
struct tls_client_ctx_t *tls_client_ctx_new(const struct tls_client_paramlist_entry *entry,
struct worker_ctx *worker);
int tls_client_process(struct worker_ctx *worker, uv_stream_t *handle,
const uint8_t *buf, ssize_t nread);
/*! Free client TLS context */
void tls_client_ctx_free(struct tls_client_ctx_t *ctx);
int tls_client_connect_start(struct tls_client_ctx_t *ctx, struct session *session,
int tls_client_connect_start(struct tls_client_ctx_t *client_ctx,
struct session *session,
tls_handshake_cb handshake_cb);
void tls_client_close(struct tls_client_ctx_t *ctx);
int tls_client_push(struct qr_task *task, uv_handle_t *handle, knot_pkt_t *pkt);
tls_client_hs_state_t tls_client_get_hs_state(const struct tls_client_ctx_t *ctx);
int tls_client_set_hs_state(struct tls_client_ctx_t *ctx, tls_client_hs_state_t state);
int tls_client_ctx_set_params(struct tls_client_ctx_t *ctx,
const struct tls_client_paramlist_entry *entry,
struct session *session);
......@@ -367,10 +367,10 @@ static void session_close(struct session *session)
if (!uv_is_closing((uv_handle_t *)&session->timeout)) {
uv_timer_stop(&session->timeout);
if (session->tls_client_ctx) {
tls_client_close(session->tls_client_ctx);
tls_close(&session->tls_client_ctx->c);
}
if (session->tls_ctx) {
tls_close(session->tls_ctx);
tls_close(&session->tls_ctx->c);
}
session->timeout.data = session;
......@@ -897,12 +897,11 @@ static void on_nontask_write(uv_write_t *req, int status)
ssize_t worker_gnutls_push(gnutls_transport_ptr_t h, const void *buf, size_t len)
{
struct tls_ctx_t *t = (struct tls_ctx_t *)h;
struct tls_common_ctx *t = (struct tls_common_ctx *)h;
const uv_buf_t uv_buf[1] = {
{ (char *)buf, len }
};
VERBOSE_MSG(NULL,"[tls] push %zu <%p>\n", len, h);
if (t == NULL) {
errno = EFAULT;
return -1;
......@@ -911,63 +910,8 @@ ssize_t worker_gnutls_push(gnutls_transport_ptr_t h, const void *buf, size_t len
assert(t->session && t->session->handle &&
t->session->handle->type == UV_TCP);
struct worker_ctx *worker = t->worker;
assert(worker);
void *ioreq = worker_iohandle_borrow(worker);
if (!ioreq) {
errno = EFAULT;
return -1;
}
uv_write_t *write_req = (uv_write_t *)ioreq;
struct qr_task *task = t->task;
uv_write_cb write_cb = on_task_write;
if (t->handshake_done) {
assert(task);
} else {
task = NULL;
write_cb = on_nontask_write;
}
write_req->data = task;
ssize_t ret = -1;
int res = uv_write(write_req, (uv_stream_t *)t->session->handle, uv_buf, 1, write_cb);
if (res == 0) {
if (task) {
qr_task_ref(task); /* Pending ioreq on current task */
}
if (worker->too_many_open &&
worker->stats.rconcurrent <
worker->rconcurrent_highwatermark - 10) {
worker->too_many_open = false;
}
ret = len;
} else {
VERBOSE_MSG(NULL,"[tls] uv_write: %s\n", uv_strerror(res));
iorequest_release(worker, ioreq);
errno = EIO;
/* TODO ret == UV_EMFILE */
}
return ret;
}
ssize_t worker_gnutls_client_push(gnutls_transport_ptr_t h, const void *buf, size_t len)
{
struct tls_client_ctx_t *t = (struct tls_client_ctx_t *)h;
const uv_buf_t uv_buf[1] = {
{ (char *)buf, len }
};
VERBOSE_MSG(NULL,"[tls client] push %zu <%p>\n", len, h);
if (t == NULL) {
errno = EFAULT;
return -1;
}
assert(t->session && t->session->handle &&
t->session->handle->type == UV_TCP);
VERBOSE_MSG(NULL,"[%s] push %zu <%p>\n",
t->client_side ? "tls-client" : "tls", len, h);
struct worker_ctx *worker = t->worker;
assert(worker);
......@@ -1004,7 +948,8 @@ ssize_t worker_gnutls_client_push(gnutls_transport_ptr_t h, const void *buf, siz
}
ret = len;
} else {
VERBOSE_MSG(NULL,"[tls_client] uv_write: %s\n", uv_strerror(res));
VERBOSE_MSG(NULL,"[%s] uv_write: %s\n",
t->client_side ? "tls-client" : "tls", uv_strerror(res));
iorequest_release(worker, ioreq);
errno = EIO;
/* TODO ret == UV_EMFILE */
......@@ -1012,7 +957,8 @@ ssize_t worker_gnutls_client_push(gnutls_transport_ptr_t h, const void *buf, siz
return ret;
}
static int qr_task_send(struct qr_task *task, uv_handle_t *handle, struct sockaddr *addr, knot_pkt_t *pkt)
static int qr_task_send(struct qr_task *task, uv_handle_t *handle,
struct sockaddr *addr, knot_pkt_t *pkt)
{
if (!handle) {
return qr_task_on_send(task, handle, kr_error(EIO));
......@@ -1030,7 +976,7 @@ static int qr_task_send(struct qr_task *task, uv_handle_t *handle, struct sockad
return ret;
}
}
return tls_push(task, handle, pkt, !session->outgoing);
return tls_push(task, handle, pkt);
}
int ret = 0;
......@@ -1127,9 +1073,6 @@ static int session_next_waiting_send(struct session *session)
static int session_tls_hs_cb(struct session *session, int status)
{
VERBOSE_MSG(NULL, "=> server: '%s' TLS handshake has %s\n",
kr_straddr(&session->peer.ip), status ? "failed" : "completed");
struct worker_ctx *worker = get_worker();
union inaddr *peer = &session->peer;
int deletion_res = worker_del_tcp_waiting(worker, &peer->ip);
......@@ -2050,8 +1993,14 @@ int worker_process_tcp(struct worker_ctx *worker, uv_stream_t *handle,
if (session->tls_client_ctx) {
/* Avoid gnutls_bye() call */
tls_client_set_hs_state(session->tls_client_ctx,
TLS_HS_NOT_STARTED);
tls_set_hs_state(&session->tls_client_ctx->c,
TLS_HS_NOT_STARTED);
}
if (session->tls_ctx) {
/* Avoid gnutls_bye() call */
tls_set_hs_state(&session->tls_ctx->c,
TLS_HS_NOT_STARTED);
}
if (session->outgoing && session->buffering) {
......
Markdown is supported
0% or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment