diff --git a/deps/CMakeLists.txt b/deps/CMakeLists.txt index a9baf570..fb5b888d 100644 --- a/deps/CMakeLists.txt +++ b/deps/CMakeLists.txt @@ -4,7 +4,7 @@ include(FetchContent) FetchContent_Declare(uv-mbed GIT_REPOSITORY https://github.com/openziti/uv-mbed.git - GIT_TAG v0.14.7 + GIT_TAG v0.14.8 ) set(ENABLE_UM_TESTS OFF CACHE BOOL "" FORCE) FetchContent_MakeAvailable(uv-mbed) diff --git a/inc_internal/zt_internal.h b/inc_internal/zt_internal.h index cf033cc7..c0dff533 100644 --- a/inc_internal/zt_internal.h +++ b/inc_internal/zt_internal.h @@ -1,4 +1,4 @@ -// Copyright (c) 2022. NetFoundry, Inc. +// Copyright (c) 2022. NetFoundry Inc. // // Licensed under the Apache License, Version 2.0 (the "License"); // you may not use this file except in compliance with the License. @@ -78,7 +78,7 @@ typedef struct ziti_channel { uint32_t id; char token[UUID_STR_LEN]; - uv_mbed_t connection; + uv_mbed_t *connection; // multi purpose timer: // - reconnect timeout if not connected diff --git a/library/channel.c b/library/channel.c index e2e1d005..f6db1ed7 100644 --- a/library/channel.c +++ b/library/channel.c @@ -130,10 +130,11 @@ static int ziti_channel_init(struct ziti_ctx *ctx, ziti_channel_t *ch, uint32_t LIST_INIT(&ch->waiters); - uv_mbed_init(ch->loop, &ch->connection, tls); - uv_mbed_keepalive(&ch->connection, true, ctx->opts->router_keepalive); - uv_mbed_nodelay(&ch->connection, true); - ch->connection.data = ch; + ch->connection = calloc(1, sizeof(*ch->connection)); + uv_mbed_init(ch->loop, ch->connection, tls); + uv_mbed_keepalive(ch->connection, true, ctx->opts->router_keepalive); + uv_mbed_nodelay(ch->connection, true); + ch->connection->data = ch; ch->timer = calloc(1, sizeof(uv_timer_t)); uv_timer_init(ch->loop, ch->timer); @@ -154,37 +155,48 @@ void ziti_channel_free(ziti_channel_t *ch) { } int ziti_close_channels(struct ziti_ctx *ztx, int err) { - ziti_channel_t *ch; const char *url; - MODEL_MAP_FOREACH(url, ch, &ztx->channels) { - ZTX_LOG(DEBUG, "closing channel[%s]: %s", url, ziti_errorstr(err)); - ziti_channel_close(ch, err); + model_list ch_ids = {0}; + MODEL_MAP_FOR(it, ztx->channels) { + model_list_append(&ch_ids, model_map_it_key(it)); + } + + MODEL_LIST_FOR(it, ch_ids) { + url = model_list_it_element(it); + ziti_channel_t *ch = model_map_get(&ztx->channels, url); + if (ch != NULL) { + ZTX_LOG(DEBUG, "closing channel[%s]: %s", url, ziti_errorstr(err)); + ziti_channel_close(ch, err); + } } + model_list_clear(&ch_ids, NULL); return ZITI_OK; } static void close_handle_cb(uv_handle_t *h) { uv_mbed_t *mbed = (uv_mbed_t *) h; - ziti_channel_t *ch = mbed->data; - - ziti_on_channel_event(ch, EdgeRouterRemoved, ch->ctx); - uv_mbed_free(mbed); - ziti_channel_free(ch); - free(ch); + free(mbed); } int ziti_channel_close(ziti_channel_t *ch, int err) { int r = 0; if (ch->state != Closed) { CH_LOG(INFO, "closing[%s]", ch->name); - ch->state = Closed; on_channel_close(ch, err, 0); uv_close((uv_handle_t *) ch->timer, (uv_close_cb) free); ch->timer = NULL; - r = uv_mbed_close(&ch->connection, close_handle_cb); + ch->connection->data = NULL; + uv_mbed_close(ch->connection, close_handle_cb); + + ch->state = Closed; + + ziti_on_channel_event(ch, EdgeRouterRemoved, ch->ctx); + + ziti_channel_free(ch); + free(ch); } return r; } @@ -346,7 +358,7 @@ int ziti_channel_send(ziti_channel_t *ch, uint32_t content, const hdr_t *hdrs, i } req->data = ziti_write; ziti_write->payload = msg_buf; - int rc = uv_mbed_write(req, &ch->connection, &buf, on_channel_send); + int rc = uv_mbed_write(req, ch->connection, &buf, on_channel_send); if (rc != 0) { on_channel_send(req, rc); } @@ -405,7 +417,7 @@ ziti_channel_send_for_reply(ziti_channel_t *ch, uint32_t content, const hdr_t *h NEWP(req, uv_write_t); req->data = wr; - int rc = uv_mbed_write(req, &wr->ch->connection, &wr->buf, on_write); + int rc = uv_mbed_write(req, wr->ch->connection, &wr->buf, on_write); if (rc != 0) { on_write(req, rc); } @@ -584,7 +596,7 @@ static void latency_timeout(uv_timer_t *t) { ch->latency_waiter = NULL; ch->latency = UINT64_MAX; - uv_mbed_close(&ch->connection, NULL); + uv_mbed_close(ch->connection, NULL); on_channel_close(ch, ZITI_TIMEOUT, UV_ETIMEDOUT); } @@ -640,7 +652,7 @@ static void hello_reply_cb(void *ctx, message *msg, int err) { ch->state = Disconnected; ch->notify_cb(ch, EdgeRouterUnavailable, ch->notify_ctx); - uv_mbed_close(&ch->connection, NULL); + uv_mbed_close(ch->connection, NULL); reconnect_channel(ch, false); } @@ -674,12 +686,12 @@ static void ch_connect_timeout(uv_timer_t *t) { } ch->state = Disconnected; - if (ch->connection.conn_req == NULL) { + if (ch->connection->conn_req == NULL) { // diagnostics CH_LOG(WARN, "diagnostics: no conn_req in connect timeout"); } reconnect_channel(ch, false); - uv_mbed_close(&ch->connection, NULL); + uv_mbed_close(ch->connection, NULL); } static void reconnect_cb(uv_timer_t *t) { @@ -698,9 +710,9 @@ static void reconnect_cb(uv_timer_t *t) { ch->state = Connecting; - ch->connection.data = ch; + ch->connection->data = ch; CH_LOG(DEBUG, "connecting to %s:%d", ch->host, ch->port); - int rc = uv_mbed_connect(req, &ch->connection, ch->host, ch->port, on_channel_connect_internal); + int rc = uv_mbed_connect(req, ch->connection, ch->host, ch->port, on_channel_connect_internal); if (rc != 0) { on_channel_connect_internal(req, rc); } @@ -856,7 +868,7 @@ static void on_channel_connect_internal(uv_connect_t *req, int status) { send_hello(ch, ch->ctx->api_session); } else { CH_LOG(WARN, "api session invalidated, while connecting"); - uv_mbed_close(&ch->connection, NULL); + uv_mbed_close(ch->connection, NULL); reconnect_channel(ch, false); } } else { diff --git a/library/internal_model.c b/library/internal_model.c index 8670dfd6..8883788f 100644 --- a/library/internal_model.c +++ b/library/internal_model.c @@ -1,18 +1,16 @@ -/* -Copyright (c) 2020 NetFoundry, Inc. - -Licensed under the Apache License, Version 2.0 (the "License"); -you may not use this file except in compliance with the License. -You may obtain a copy of the License at - -https://www.apache.org/licenses/LICENSE-2.0 - -Unless required by applicable law or agreed to in writing, software -distributed under the License is distributed on an "AS IS" BASIS, -WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. -See the License for the specific language governing permissions and -limitations under the License. -*/ +// Copyright (c) 2020-2022. NetFoundry Inc. +// +// Licensed under the Apache License, Version 2.0 (the "License"); +// you may not use this file except in compliance with the License. +// You may obtain a copy of the License at +// +// https://www.apache.org/licenses/LICENSE-2.0 +// +// Unless required by applicable law or agreed to in writing, software +// distributed under the License is distributed on an "AS IS" BASIS, +// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +// See the License for the specific language governing permissions and +// limitations under the License. #include @@ -24,12 +22,19 @@ limitations under the License. typedef uint32_t in_addr_t; #define strcasecmp stricmp #else + #include + #endif #include #include "ziti/ziti_buffer.h" +#define null_checks(lh, rh) \ + if ((lh) == (rh)) { return 0; } \ + if ((lh) == NULL) { return -1; } \ + if ((rh) == NULL) { return 1; } + IMPL_MODEL(ziti_posture_query, ZITI_POSTURE_QUERY_MODEL) IMPL_MODEL(ziti_posture_query_set, ZITI_POSTURE_QUERY_SET_MODEL) @@ -142,6 +147,8 @@ int ziti_service_get_config(ziti_service *service, const char *cfg_type, void *c } static int cmp_ziti_address0(ziti_address *lh, ziti_address *rh) { + null_checks(lh, rh) + if (lh->type != rh->type) { return (int) lh->type - (int) rh->type; } diff --git a/library/posture.c b/library/posture.c index 0771dc0f..997f7825 100644 --- a/library/posture.c +++ b/library/posture.c @@ -1,18 +1,16 @@ -/* -Copyright (c) 2019-2020 NetFoundry, Inc. - -Licensed under the Apache License, Version 2.0 (the "License"); -you may not use this file except in compliance with the License. -You may obtain a copy of the License at - -https://www.apache.org/licenses/LICENSE-2.0 - -Unless required by applicable law or agreed to in writing, software -distributed under the License is distributed on an "AS IS" BASIS, -WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. -See the License for the specific language governing permissions and -limitations under the License. -*/ +// Copyright (c) 2019-2022. NetFoundry Inc. +// +// Licensed under the Apache License, Version 2.0 (the "License"); +// you may not use this file except in compliance with the License. +// You may obtain a copy of the License at +// +// https://www.apache.org/licenses/LICENSE-2.0 +// +// Unless required by applicable law or agreed to in writing, software +// distributed under the License is distributed on an "AS IS" BASIS, +// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +// See the License for the specific language governing permissions and +// limitations under the License. #include "posture.h" #include @@ -127,6 +125,9 @@ void ziti_posture_init(ziti_context ztx, long interval_secs) { NEWP(pc, struct posture_checks); NEWP(timer, uv_timer_t); + uv_timer_init(ztx->loop, timer); + timer->data = ztx; + uv_unref((uv_handle_t *) timer); pc->timer = timer; pc->interval = (double) interval_secs; @@ -139,10 +140,7 @@ void ziti_posture_init(ziti_context ztx, long interval_secs) { } if (!uv_is_active((uv_handle_t *) ztx->posture_checks->timer)) { - uv_timer_init(ztx->loop, ztx->posture_checks->timer); - ztx->posture_checks->timer->data = ztx; uv_timer_start(ztx->posture_checks->timer, ziti_pr_ticker_cb, MILLIS(interval_secs), MILLIS(interval_secs)); - uv_unref((uv_handle_t *) ztx->posture_checks->timer); } } @@ -152,8 +150,8 @@ static void ziti_posture_checks_timer_free(uv_handle_t *handle) { void ziti_posture_checks_free(struct posture_checks *pcs) { if (pcs != NULL) { - uv_timer_stop(pcs->timer); uv_close((uv_handle_t *) pcs->timer, ziti_posture_checks_timer_free); + pcs->timer = NULL; model_map_clear(&pcs->responses, (_free_f) ziti_pr_free_pr_info_members); model_map_clear(&pcs->error_states, NULL); FREE(pcs->previous_api_session_id); diff --git a/library/ziti.c b/library/ziti.c index 5e2f2e2f..a8002d33 100644 --- a/library/ziti.c +++ b/library/ziti.c @@ -298,11 +298,15 @@ static void logout_cb(void *resp, const ziti_error *err, void *ctx) { ziti_set_unauthenticated(ztx); + ziti_close_channels(ztx, ZITI_DISABLED); + model_map_clear(&ztx->sessions, (_free_f) free_ziti_net_session); model_map_clear(&ztx->services, (_free_f) free_ziti_service); if (ztx->closing) { shutdown_and_free(ztx); + } else { + update_ctrl_status(ztx, ZITI_DISABLED, ziti_errorstr(ZITI_DISABLED)); } } @@ -335,8 +339,9 @@ static void ziti_stop_internal(ziti_context ztx, void *data) { uv_close((uv_handle_t *) ztx->api_session_timer, (uv_close_cb) free); ztx->api_session_timer = NULL; - if (ztx->posture_checks && ztx->posture_checks->timer) { - uv_timer_stop(ztx->posture_checks->timer); + if (ztx->posture_checks) { + ziti_posture_checks_free(ztx->posture_checks); + ztx->posture_checks = NULL; } // close all channels @@ -357,7 +362,6 @@ static void ziti_stop_internal(ziti_context ztx, void *data) { // logout ziti_ctrl_logout(&ztx->controller, logout_cb, ztx); - } } diff --git a/library/ziti_ctrl.c b/library/ziti_ctrl.c index 2ee7861b..9767e082 100644 --- a/library/ziti_ctrl.c +++ b/library/ziti_ctrl.c @@ -1,18 +1,16 @@ -/* -Copyright 2019 NetFoundry, Inc. - -Licensed under the Apache License, Version 2.0 (the "License"); -you may not use this file except in compliance with the License. -You may obtain a copy of the License at - -https://www.apache.org/licenses/LICENSE-2.0 - -Unless required by applicable law or agreed to in writing, software -distributed under the License is distributed on an "AS IS" BASIS, -WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. -See the License for the specific language governing permissions and -limitations under the License. -*/ +// Copyright (c) 2022. NetFoundry Inc. +// +// Licensed under the Apache License, Version 2.0 (the "License"); +// you may not use this file except in compliance with the License. +// You may obtain a copy of the License at +// +// https://www.apache.org/licenses/LICENSE-2.0 +// +// Unless required by applicable law or agreed to in writing, software +// distributed under the License is distributed on an "AS IS" BASIS, +// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +// See the License for the specific language governing permissions and +// limitations under the License. #include #include @@ -206,9 +204,10 @@ static void ctrl_version_cb(ziti_version *v, ziti_error *e, struct ctrl_resp *re } if (v) { - resp->ctrl->version.version = strdup(v->version); - resp->ctrl->version.revision = strdup(v->revision); - resp->ctrl->version.build_date = strdup(v->build_date); + free_ziti_version(&ctrl->version); + ctrl->version.version = strdup(v->version); + ctrl->version.revision = strdup(v->revision); + ctrl->version.build_date = strdup(v->build_date); if (v->api_versions) { api_path *path = model_map_get(&v->api_versions->edge, "v1");