Skip to content

Commit

Permalink
Channel complete close before reconnect (#615)
Browse files Browse the repository at this point in the history
* checkpoint

* update [email protected]

* adjust logging

* remove old check
  • Loading branch information
ekoby authored Jan 30, 2024
1 parent c749ffc commit 9297dce
Show file tree
Hide file tree
Showing 3 changed files with 29 additions and 23 deletions.
2 changes: 1 addition & 1 deletion deps/CMakeLists.txt
Original file line number Diff line number Diff line change
Expand Up @@ -8,7 +8,7 @@ else ()

FetchContent_Declare(tlsuv
GIT_REPOSITORY https://github.com/openziti/tlsuv.git
GIT_TAG v0.28.1
GIT_TAG v0.28.2
)
FetchContent_MakeAvailable(tlsuv)

Expand Down
1 change: 1 addition & 0 deletions inc_internal/zt_internal.h
Original file line number Diff line number Diff line change
Expand Up @@ -83,6 +83,7 @@ typedef struct ziti_channel {
uint32_t id;
char token[UUID_STR_LEN];
tlsuv_stream_t *connection;
bool reconnect;

// multi purpose timer:
// - reconnect timeout if not connected
Expand Down
49 changes: 27 additions & 22 deletions library/channel.c
Original file line number Diff line number Diff line change
Expand Up @@ -87,7 +87,7 @@ static void on_tls_close(uv_handle_t *s);
static inline void close_connection(ziti_channel_t *ch) {
if (ch->connection) {
tlsuv_stream_t *conn = ch->connection;
ch->connection = NULL;
CH_LOG(DEBUG, "closing TLS[%p]", conn);
tlsuv_stream_close(conn, on_tls_close);
}
}
Expand Down Expand Up @@ -120,13 +120,14 @@ struct msg_receiver {
};

static void ch_init_stream(ziti_channel_t *ch) {
if (ch->connection == NULL) {
ch->connection = calloc(1, sizeof(*ch->connection));
tlsuv_stream_init(ch->loop, ch->connection, ch->ctx->tlsCtx);
tlsuv_stream_keepalive(ch->connection, true, 30);
tlsuv_stream_nodelay(ch->connection, true);
ch->connection->data = ch;
}
assert(ch->connection == NULL);

ch->connection = calloc(1, sizeof(*ch->connection));
tlsuv_stream_init(ch->loop, ch->connection, ch->ctx->tlsCtx);
tlsuv_stream_keepalive(ch->connection, true, 30);
tlsuv_stream_nodelay(ch->connection, true);
ch->connection->data = ch;
ch->reconnect = false;
}

int ziti_channel_prepare(ziti_channel_t *ch) {
Expand Down Expand Up @@ -210,8 +211,15 @@ int ziti_close_channels(struct ziti_ctx *ztx, int err) {

static void on_tls_close(uv_handle_t *s) {
tlsuv_stream_t *tls = (tlsuv_stream_t *) s;
ziti_channel_t *ch = tls->data;
ch->connection = NULL;

tlsuv_stream_free(tls);
free(tls);

if (ch->reconnect) {
reconnect_channel(ch, true);
}
}

int ziti_channel_close(ziti_channel_t *ch, int err) {
Expand Down Expand Up @@ -739,8 +747,10 @@ static void reconnect_cb(uv_timer_t *t) {
if (ztx->api_session == NULL || ztx->api_session->token == NULL || ztx->api_session_state != ZitiApiSessionStateFullyAuthenticated) {
CH_LOG(ERROR, "ziti context is not fully authenticated (api_session_state[%d]), delaying re-connect", ztx->api_session_state);
reconnect_channel(ch, false);
}
else {
} else if (ch->connection != NULL) {
CH_LOG(DEBUG, "connection still closing, deferring reconnect");
ch->reconnect = true;
} else {
ch->msg_seq = 0;

uv_connect_t *req = calloc(1, sizeof(uv_connect_t));
Expand Down Expand Up @@ -864,20 +874,13 @@ static void on_channel_data(uv_stream_t *s, ssize_t len, const uv_buf_t *buf) {
tlsuv_stream_read_stop(ssl);
CH_LOG(VERBOSE, "blocked until messages are processed");
return;
case UV_EOF:
case UV_ECONNRESET:
case UV_ECONNABORTED:
case UV_ECONNREFUSED:
case UV_EPIPE:
CH_LOG(INFO, "channel was closed [%zd/%s]", len, uv_strerror(len));

default:
CH_LOG(INFO, "channel disconnected [%zd/%s]", len, uv_strerror(len));
// propagate close
on_channel_close(ch, ZITI_CONNABORT, len);
on_channel_close(ch, ZITI_GATEWAY_UNAVAILABLE, len);
close_connection(ch);
break;

default:
CH_LOG(ERROR, "unhandled error on_data [%zd/%s]", len, uv_strerror(len));
on_channel_close(ch, ZITI_CONNABORT, len);
}
} else if (len == 0) {
// sometimes SSL message has no payload
Expand Down Expand Up @@ -915,7 +918,9 @@ static void on_channel_connect_internal(uv_connect_t *req, int status) {
free(r);
}

close_connection(ch);
if (status != UV_ECANCELED) {
close_connection(ch);
}

if (ch->state != Closed) {
ch->state = Disconnected;
Expand Down

0 comments on commit 9297dce

Please sign in to comment.