From e09306d59c89d70c7ee83abc0507c343aa0f6409 Mon Sep 17 00:00:00 2001 From: eugene Date: Thu, 13 Jun 2024 11:09:40 -0400 Subject: [PATCH 1/2] add HA controller details to ZitiCtxEvent --- inc_internal/ziti_ctrl.h | 9 ++- inc_internal/zt_internal.h | 14 +--- includes/ziti/model_collections.h | 2 +- includes/ziti/ziti_events.h | 11 ++- library/auth_queries.c | 2 +- library/bind.c | 2 +- library/channel.c | 51 ++++++------ library/connect.c | 7 +- library/legacy_auth.c | 2 +- library/oidc.c | 1 + library/ziti.c | 125 ++++++++++++++---------------- library/ziti_ctrl.c | 61 +++++++++------ library/zitilib.c | 14 ++-- programs/ziti-prox-c/proxy.c | 50 +++++++----- 14 files changed, 186 insertions(+), 165 deletions(-) diff --git a/inc_internal/ziti_ctrl.h b/inc_internal/ziti_ctrl.h index 332c8261..ab185d12 100644 --- a/inc_internal/ziti_ctrl.h +++ b/inc_internal/ziti_ctrl.h @@ -33,6 +33,8 @@ extern const char* const PC_ENDPOINT_STATE_TYPE; typedef void (*ziti_ctrl_redirect_cb)(const char *new_address, void *ctx); +typedef void (*ziti_ctrl_change_cb)(void *ctx, const model_map *endpoints); + typedef void (*ctrl_version_cb)(const ziti_version *, const ziti_error *, void *); typedef void(*routers_cb)(ziti_service_routers *srv_routers, const ziti_error *, void *); @@ -58,8 +60,9 @@ typedef struct ziti_controller_s { bool has_token; char *instance_id; + ziti_ctrl_change_cb change_cb; ziti_ctrl_redirect_cb redirect_cb; - void *redirect_ctx; + void *cb_ctx; } ziti_controller; int ziti_ctrl_init(uv_loop_t *loop, ziti_controller *ctrl, model_list *urls, tls_context *tls); @@ -70,7 +73,9 @@ int ziti_ctrl_cancel(ziti_controller *ctrl); void ziti_ctrl_set_page_size(ziti_controller *ctrl, unsigned int size); -void ziti_ctrl_set_redirect_cb(ziti_controller *ctrl, ziti_ctrl_redirect_cb cb, void *ctx); +void ziti_ctrl_set_callbacks(ziti_controller *ctrl, void *ctx, + ziti_ctrl_redirect_cb redirect_cb, + ziti_ctrl_change_cb change_cb); int ziti_ctrl_close(ziti_controller *ctrl); diff --git a/inc_internal/zt_internal.h b/inc_internal/zt_internal.h index 2f3afa95..f6608251 100644 --- a/inc_internal/zt_internal.h +++ b/inc_internal/zt_internal.h @@ -34,8 +34,6 @@ #include -//#define SIZEOF(arr) (sizeof(arr) / sizeof((arr)[0])) - #if !defined(UUID_STR_LEN) #define UUID_STR_LEN 37 #endif @@ -52,10 +50,6 @@ typedef struct ziti_channel ziti_channel_t; typedef void (*reply_cb)(void *ctx, message *m, int err); -typedef void (*send_cb)(int status, void *ctx); - -typedef void (*ch_connect_cb)(ziti_channel_t *ch, void *ctx, int status); - typedef void (*ch_notify_state)(ziti_channel_t *ch, ziti_router_status status, void *ctx); typedef int ch_state; @@ -108,7 +102,7 @@ typedef struct ziti_channel { ch_notify_state notify_cb; void *notify_ctx; -} ziti_channel_t; +}; struct ziti_write_req_s { struct ziti_conn *conn; @@ -320,8 +314,6 @@ extern "C" { ziti_controller *ztx_get_controller(ziti_context ztx); -bool ziti_is_session_valid(ziti_context ztx, ziti_session *session, const char *service_id, ziti_session_type type); - void ziti_invalidate_session(ziti_context ztx, const char *service_id, ziti_session_type type); void ziti_on_channel_event(ziti_channel_t *ch, ziti_router_status status, ziti_context ztx); @@ -346,9 +338,9 @@ int ziti_channel_prepare(ziti_channel_t *ch); int ziti_channel_close(ziti_channel_t *ch, int err); -void ziti_channel_add_receiver(ziti_channel_t *ch, int id, void *receiver, void (*receive_f)(void *, message *, int)); +void ziti_channel_add_receiver(ziti_channel_t *ch, uint32_t id, void *receiver, void (*receive_f)(void *, message *, int)); -void ziti_channel_rem_receiver(ziti_channel_t *ch, int id); +void ziti_channel_rem_receiver(ziti_channel_t *ch, uint32_t id); int ziti_channel_send_message(ziti_channel_t *ch, message *msg, struct ziti_write_req_s *ziti_write); diff --git a/includes/ziti/model_collections.h b/includes/ziti/model_collections.h index 01bdef9d..57c8f221 100644 --- a/includes/ziti/model_collections.h +++ b/includes/ziti/model_collections.h @@ -109,7 +109,7 @@ ZITI_FUNC void *model_list_it_element(model_list_iter it); #define MODEL_LIST_FOR(it, m) for(model_list_iter it = model_list_iterator(&(m)); (it) != NULL; (it) = model_list_it_next(it)) -#define MODEL_LIST_FOREACH(el, list) for(model_list_iter it = model_list_iterator(&(list)); \ +#define MODEL_LIST_FOREACH(el, list) for(model_list_iter it = model_list_iterator((model_list*)&(list)); \ (it) != NULL && (((el) = model_list_it_element(it)), true); \ (it) = model_list_it_next(it)) diff --git a/includes/ziti/ziti_events.h b/includes/ziti/ziti_events.h index d52cd58f..24ca9672 100644 --- a/includes/ziti/ziti_events.h +++ b/includes/ziti/ziti_events.h @@ -56,6 +56,15 @@ typedef enum { struct ziti_context_event { int ctrl_status; const char *err; + size_t ctrl_count; + struct ctrl_detail_s *ctrl_details; +}; + +struct ctrl_detail_s { + const char *id; + const char *url; + bool online; + bool active; }; struct ziti_api_event { @@ -120,7 +129,7 @@ typedef struct ziti_event_s { struct ziti_service_event service; struct ziti_mfa_auth_event mfa_auth_event; struct ziti_api_event api; - } event; + }; } ziti_event_t; #ifdef __cplusplus diff --git a/library/auth_queries.c b/library/auth_queries.c index 6027df1f..e86d9f2d 100644 --- a/library/auth_queries.c +++ b/library/auth_queries.c @@ -114,7 +114,7 @@ void ziti_auth_query_mfa_process(ziti_mfa_auth_ctx *mfa_auth_ctx) { ziti_event_t ev = { .type = ZitiMfaAuthEvent, - .event.mfa_auth_event = { + .mfa_auth_event = { .auth_query_mfa = mfa_auth_ctx->auth_query_mfa, } }; diff --git a/library/bind.c b/library/bind.c index 94136683..9475862b 100644 --- a/library/bind.c +++ b/library/bind.c @@ -432,7 +432,7 @@ static void bind_reply_cb(void *ctx, message *msg, int code) { if (code == ZITI_OK && msg->header.content == ContentTypeStateConnected) { CONN_LOG(TRACE, "received msg ct[%X] code[%d]", msg->header.content, code); CONN_LOG(DEBUG, "bound successfully over ch[%s]", b->ch->url); - ziti_channel_add_receiver(b->ch, (int)conn->conn_id, b, + ziti_channel_add_receiver(b->ch, conn->conn_id, b, (void (*)(void *, message *, int)) on_message); b->bound = true; } else { diff --git a/library/channel.c b/library/channel.c index 39599303..ec7193fb 100644 --- a/library/channel.c +++ b/library/channel.c @@ -236,7 +236,7 @@ int ziti_channel_close(ziti_channel_t *ch, int err) { return 0; } -void ziti_channel_add_receiver(ziti_channel_t *ch, int id, void *receiver, void (*receive_f)(void *, message *, int)) { +void ziti_channel_add_receiver(ziti_channel_t *ch, uint32_t id, void *receiver, void (*receive_f)(void *, message *, int)) { NEWP(r, struct msg_receiver); r->id = id; r->receiver = receiver; @@ -246,7 +246,7 @@ void ziti_channel_add_receiver(ziti_channel_t *ch, int id, void *receiver, void CH_LOG(DEBUG, "added receiver[%d]", id); } -void ziti_channel_rem_receiver(ziti_channel_t *ch, int id) { +void ziti_channel_rem_receiver(ziti_channel_t *ch, uint32_t id) { struct msg_receiver *r = model_map_removel(&ch->receivers, id); if (r) { @@ -328,12 +328,8 @@ int ziti_channel_update_token(ziti_channel_t *ch) { } const char* token = ziti_get_api_session_token(ch->ztx); - - uint8_t true_val = 1; ziti_channel_send_for_reply(ch, ContentTypeUpdateTokenType, NULL, 0, token, strlen(token), token_update_cb, ch); - - return ZITI_OK; } @@ -696,9 +692,9 @@ static void hello_reply_cb(void *ctx, message *msg, int err) { } if (success) { - uint8_t *erVersion = ""; + const char *erVersion = ""; size_t erVersionLen = strlen(erVersion); - message_get_bytes_header(msg, HelloVersionHeader, &erVersion, &erVersionLen); + message_get_bytes_header(msg, HelloVersionHeader, (uint8_t **) &erVersion, &erVersionLen); CH_LOG(INFO, "connected. EdgeRouter version: %.*s", (int) erVersionLen, erVersion); ch->state = Connected; FREE(ch->version); @@ -891,30 +887,31 @@ static void on_channel_data(uv_stream_t *s, ssize_t len, const uv_buf_t *buf) { tlsuv_stream_t *ssl = (tlsuv_stream_t *) s; ziti_channel_t *ch = ssl->data; + if (len == UV_ENOBUFS) { + tlsuv_stream_read_stop(ssl); + CH_LOG(VERBOSE, "blocked until messages are processed"); + return; + } + if (len < 0) { free(buf->base); - switch (len) { - case UV_ENOBUFS: - tlsuv_stream_read_stop(ssl); - CH_LOG(VERBOSE, "blocked until messages are processed"); - return; - - default: - CH_LOG(INFO, "channel disconnected [%zd/%s]", len, uv_strerror(len)); - // propagate close - on_channel_close(ch, ZITI_CONNABORT, len); - close_connection(ch); - break; - } - } else if (len == 0) { + CH_LOG(INFO, "channel disconnected [%zd/%s]", len, uv_strerror(len)); + // propagate close + on_channel_close(ch, ZITI_CONNABORT, len); + close_connection(ch); + return; + } + + if (len == 0) { // sometimes SSL message has no payload free(buf->base); - } else { - CH_LOG(TRACE, "on_data [len=%zd]", len); - ch->last_read = uv_now(ch->loop); - buffer_append(ch->incoming, buf->base, (uint32_t) len); - process_inbound(ch); + return; } + + CH_LOG(TRACE, "on_data [len=%zd]", len); + ch->last_read = uv_now(ch->loop); + buffer_append(ch->incoming, buf->base, (uint32_t) len); + process_inbound(ch); } static void on_channel_connect_internal(uv_connect_t *req, int status) { diff --git a/library/connect.c b/library/connect.c index 59cda728..d4b148f8 100644 --- a/library/connect.c +++ b/library/connect.c @@ -374,9 +374,10 @@ static bool ziti_connect(struct ziti_ctx *ztx, ziti_session *session, struct zit if (ch == NULL) continue; if (ch->state == Connected) { - if (ch->latency < best_latency) { + uint64_t latency = ziti_channel_latency(ch); + if (latency < best_latency) { best_ch = ch; - best_latency = ch->latency; + best_latency = latency; } } @@ -388,7 +389,7 @@ static bool ziti_connect(struct ziti_ctx *ztx, ziti_session *session, struct zit if (best_ch) { CONN_LOG(DEBUG, "selected ch[%s@%s] for best latency(%llu ms)", best_ch->name, best_ch->url, - (unsigned long long) best_ch->latency); + (unsigned long long) best_latency); ziti_channel_start_connection(conn, best_ch, session); result = true; } else { diff --git a/library/legacy_auth.c b/library/legacy_auth.c index e8086584..b30ce2c7 100644 --- a/library/legacy_auth.c +++ b/library/legacy_auth.c @@ -87,7 +87,7 @@ int legacy_auth_refresh(ziti_auth_method_t *self) { assert(auth->ctx); assert(auth->cb); - uv_timer_start(&auth->timer, auth_timer_cb, 0, 0); + return uv_timer_start(&auth->timer, auth_timer_cb, 0, 0); } diff --git a/library/oidc.c b/library/oidc.c index 0364d1f4..ba125549 100644 --- a/library/oidc.c +++ b/library/oidc.c @@ -356,6 +356,7 @@ int oidc_client_close(oidc_client_t *clt, oidc_close_cb cb) { tlsuv_http_close(&clt->http, http_close_cb); uv_close((uv_handle_t *) clt->timer, (uv_close_cb) free); clt->timer = NULL; + return 0; } static void oidc_client_set_tokens(oidc_client_t *clt, json_object *tok_json) { diff --git a/library/ziti.c b/library/ziti.c index 0cc48ee3..6ce9e589 100644 --- a/library/ziti.c +++ b/library/ziti.c @@ -48,13 +48,8 @@ static const char *ALL_CONFIG_TYPES[] = { struct ziti_init_req { ziti_context ztx; bool start; - int init_status; }; -const int API_SESSION_MINIMUM_REFRESH_DELAY_SECONDS = 60; -const int API_SESSION_DELAY_WINDOW_SECONDS = 60; -const int API_SESSION_EXPIRATION_TOO_SMALL_SECONDS = 120; - int code_to_error(const char *code); static void update_ctrl_status(ziti_context ztx, int code, const char *msg); @@ -120,29 +115,6 @@ ziti_controller* ztx_get_controller(ziti_context ztx) { return &ztx->ctrl; } -static int parse_getopt(const char *q, const char *opt, char *out, size_t maxout) { - size_t optlen = strlen(opt); - do { - // found it - if (strncasecmp(q, opt, optlen) == 0 && (q[optlen] == '=' || q[optlen] == 0)) { - const char *val = q + optlen + 1; - char *end = strchr(val, '&'); - int vlen = (int) (end == NULL ? strlen(val) : end - val); - snprintf(out, maxout, "%*.*s", vlen, vlen, val); - return ZITI_OK; - - } else { // skip to next '&' - q = strchr(q, '&'); - if (q == NULL) { - break; - } - q += 1; - } - } while (q != NULL); - out[0] = '\0'; - return ZITI_INVALID_CONFIG; -} - static int init_tls_from_config(tls_context *tls, ziti_config *cfg) { PREP(ziti); @@ -301,7 +273,7 @@ void ziti_set_partially_authenticated(ziti_context ztx, const ziti_auth_query_mf ZTX_LOG(DEBUG, "setting api_session_state[%d] to %d", ztx->auth_state, ZitiAuthStatePartiallyAuthenticated); ziti_event_t ev = { .type = ZitiMfaAuthEvent, - .event.mfa_auth_event = { + .mfa_auth_event = { .auth_query_mfa = mfa_q, } }; @@ -435,17 +407,17 @@ static void ziti_stop_internal(ziti_context ztx, void *data) { ziti_service *svc; ziti_event_t ev = {0}; ev.type = ZitiServiceEvent; - ev.event.service.removed = calloc(model_map_size(&ztx->services) + 1, sizeof(ziti_service *)); + ev.service.removed = calloc(model_map_size(&ztx->services) + 1, sizeof(ziti_service *)); int idx = 0; it = model_map_iterator(&ztx->services); while (it) { - ev.event.service.removed[idx++] = model_map_it_value(it); + ev.service.removed[idx++] = model_map_it_value(it); it = model_map_it_remove(it); } ztx->auth_method->stop(ztx->auth_method); ziti_send_event(ztx, &ev); - free_ziti_service_array(&ev.event.service.removed); + free_ziti_service_array(&ev.service.removed); ziti_ctrl_cancel(ztx_get_controller(ztx)); // logout @@ -472,12 +444,38 @@ static void ziti_start_internal(ziti_context ztx, void *init_req) { } } -static void on_ctrl_change(const char *new_addr, void *ctx) { +static void on_ctrl_list_change(ziti_context ztx, const model_map *endpoints) { + if (ztx->opts.event_cb && (ztx->opts.events & ZitiContextEvent)) { + size_t count = model_map_size(endpoints); + struct ctrl_detail_s *details = (count > 0) ? calloc(count, sizeof(struct ctrl_detail_s)) : NULL; + size_t idx = 0; + const char *url; + ziti_controller_detail *d; + MODEL_MAP_FOREACH(url, d, endpoints) { + details[idx].url = url; + details[idx].id = d->id; + details[idx].online = d->is_online; + idx++; + } + ziti_send_event(ztx, &(ziti_event_t){ + .type = ZitiContextEvent, + .ctx = { + .err = NULL, + .ctrl_count = count, + .ctrl_details = details, + }, + }); + + free(details); + } +} + +static void on_ctrl_redirect(const char *new_addr, void *ctx) { ziti_context ztx = ctx; ziti_event_t ev = { .type = ZitiAPIEvent, - .event.api.new_ctrl_address = new_addr, + .api.new_ctrl_address = new_addr, }; ziti_send_event(ztx, &ev); } @@ -498,12 +496,13 @@ static void ziti_init_async(ziti_context ztx, void *data) { int rc = ziti_ctrl_init(loop, &ztx->ctrl, &ztx->config.controllers, ztx->tlsCtx); if (rc != 0) { ZITI_LOG(ERROR, "no valid controllers found"); - ev.event.ctx.ctrl_status = rc; + ev.ctx.ctrl_status = rc; ziti_send_event(ztx, &ev); return; } - ziti_ctrl_set_redirect_cb(ztx_get_controller(ztx), on_ctrl_change, ztx); + ziti_ctrl_set_callbacks(ztx_get_controller(ztx), ztx, on_ctrl_redirect, + (ziti_ctrl_change_cb) on_ctrl_list_change); if (ztx->opts.api_page_size != 0) { ziti_ctrl_set_page_size(ztx_get_controller(ztx), ztx->opts.api_page_size); } @@ -523,7 +522,7 @@ static void ziti_init_async(ziti_context ztx, void *data) { if (init_req->start) { ziti_start_internal(ztx, NULL); } else { - ev.event.ctx.ctrl_status = ZITI_DISABLED; + ev.ctx.ctrl_status = ZITI_DISABLED; ziti_send_event(ztx, &ev); } free(init_req); @@ -599,8 +598,8 @@ static void free_ztx(uv_handle_t *h) { ziti_event_t ev = {0}; ev.type = ZitiContextEvent; - ev.event.ctx.ctrl_status = ZITI_DISABLED; - ev.event.ctx.err = ziti_errorstr(ZITI_DISABLED); + ev.ctx.ctrl_status = ZITI_DISABLED; + ev.ctx.err = ziti_errorstr(ZITI_DISABLED); ziti_send_event(ztx, &ev); @@ -732,7 +731,7 @@ void ziti_dump(ziti_context ztx, int (*printer)(void *arg, const char *fmt, ...) MODEL_MAP_FOREACH(url, ch, &ztx->channels) { printer(ctx, "ch[%d](%s@%s) ", ch->id, ch->name, url); if (ziti_channel_is_connected(ch)) { - printer(ctx, "connected [latency=%" PRIu64 "]\n", ch->latency); + printer(ctx, "connected [latency=%" PRIu64 "]\n", ziti_channel_latency(ch)); } else { printer(ctx, "Disconnected\n"); @@ -1106,7 +1105,7 @@ static void update_services(ziti_service_array services, const ziti_error *error size_t chIdx = 0, addIdx = 0, remIdx = 0; ziti_event_t ev = { .type = ZitiServiceEvent, - .event.service = { + .service = { .removed = calloc(current_size + 1, sizeof(ziti_service *)), .changed = calloc(current_size + 1, sizeof(ziti_service *)), .added = calloc(idx + 1, sizeof(ziti_service *)), @@ -1120,7 +1119,7 @@ static void update_services(ziti_service_array services, const ziti_error *error if (updt != NULL) { if (is_service_updated(ztx, updt, model_map_it_value(it)) != 0) { - ev.event.service.changed[chIdx++] = updt; + ev.service.changed[chIdx++] = updt; } else { // no changes detected, just discard it free_ziti_service(updt); @@ -1132,7 +1131,7 @@ static void update_services(ziti_service_array services, const ziti_error *error // service was removed ZTX_LOG(DEBUG, "service[%s] is not longer available", model_map_it_key(it)); s = model_map_it_value(it); - ev.event.service.removed[remIdx++] = s; + ev.service.removed[remIdx++] = s; ziti_session *session = model_map_remove(&ztx->sessions, s->id); if (session) { @@ -1147,21 +1146,21 @@ static void update_services(ziti_service_array services, const ziti_error *error it = model_map_iterator(&updates); while (it != NULL) { s = model_map_it_value(it); - ev.event.service.added[addIdx++] = s; + ev.service.added[addIdx++] = s; it = model_map_it_remove(it); } // process updates - for (idx = 0; ev.event.service.changed[idx] != NULL; idx++) { - s = ev.event.service.changed[idx]; + for (idx = 0; ev.service.changed[idx] != NULL; idx++) { + s = ev.service.changed[idx]; ziti_service *old = model_map_set(&ztx->services, s->name, s); free_ziti_service(old); FREE(old); } // process additions - for (idx = 0; ev.event.service.added[idx] != NULL; idx++) { - s = ev.event.service.added[idx]; + for (idx = 0; ev.service.added[idx] != NULL; idx++) { + s = ev.service.added[idx]; model_map_set(&ztx->services, s->name, s); } @@ -1175,15 +1174,15 @@ static void update_services(ziti_service_array services, const ziti_error *error } // cleanup - for (idx = 0; ev.event.service.removed[idx] != NULL; idx++) { - s = ev.event.service.removed[idx]; + for (idx = 0; ev.service.removed[idx] != NULL; idx++) { + s = ev.service.removed[idx]; free_ziti_service(s); free(s); } - free(ev.event.service.removed); - free(ev.event.service.added); - free(ev.event.service.changed); + free(ev.service.removed); + free(ev.service.added); + free(ev.service.changed); model_map_clear(&updates, NULL); model_map_clear(&ztx->service_forced_updates, NULL); @@ -1345,14 +1344,13 @@ static void update_identity_data(ziti_identity_data *data, const ziti_error *err free_ziti_identity_data(ztx->identity_data); FREE(ztx->identity_data); ztx->identity_data = data; - update_ctrl_status(ztx, ZITI_OK, NULL); } - update_ctrl_status(ztx, FIELD_OR_ELSE(err, err, 0), FIELD_OR_ELSE(err, message, NULL)); + update_ctrl_status(ztx, FIELD_OR_ELSE(err, err, ZITI_OK), FIELD_OR_ELSE(err, message, NULL)); } static void on_create_cert(ziti_create_api_cert_resp *resp, const ziti_error *e, void *ctx) { - ziti_context ztx = ctx;; + ziti_context ztx = ctx; if (e) { ZTX_LOG(ERROR, "failed to create session cert: %d/%s", e->err, e->message); } else { @@ -1401,7 +1399,7 @@ static void ca_bundle_cb(char *pkcs7, const ziti_error *err, void *ctx) { if (load_tls(&ztx->config, &new_tls) == 0) { ziti_send_event(ztx, &(ziti_event_t){ .type = ZitiAPIEvent, - .event.api = { + .api = { .new_ca_bundle = new_pem, } }); @@ -1431,7 +1429,7 @@ static void update_ctrl_status(ziti_context ztx, int errCode, const char *errMsg if (ztx->ctrl_status != errCode && ztx->enabled) { ziti_event_t ev = { .type = ZitiContextEvent, - .event.ctx = { + .ctx = { .ctrl_status = errCode, .err = errMsg, }}; @@ -1440,15 +1438,6 @@ static void update_ctrl_status(ziti_context ztx, int errCode, const char *errMsg } } -bool ziti_is_session_valid(ziti_context ztx, ziti_session *session, const char *service_id, ziti_session_type type) { - if (session == NULL) return false; - - if (type == ziti_session_types.Bind) return true; - - ziti_session *s = model_map_get(&ztx->sessions, service_id); - return s == session; -} - void ziti_invalidate_session(ziti_context ztx, const char *service_id, ziti_session_type type) { if (type == ziti_session_types.Dial) { ziti_session *s = model_map_remove(&ztx->sessions, service_id); @@ -1512,7 +1501,7 @@ void ztx_prepare(uv_prepare_t *prep) { void ziti_on_channel_event(ziti_channel_t *ch, ziti_router_status status, ziti_context ztx) { ziti_event_t ev = { .type = ZitiRouterEvent, - .event.router = { + .router = { .name = ch->name, .address = ch->host, .version = ch->version, diff --git a/library/ziti_ctrl.c b/library/ziti_ctrl.c index 0e77c568..aae17d09 100644 --- a/library/ziti_ctrl.c +++ b/library/ziti_ctrl.c @@ -241,7 +241,7 @@ static void ctrl_default_cb(void *s, const ziti_error *e, struct ctrl_resp *resp tlsuv_http_set_url(ctrl->client, ctrl->url); if (resp->ctrl->redirect_cb) { - ctrl->redirect_cb(ctrl->url, ctrl->redirect_ctx); + ctrl->redirect_cb(ctrl->url, ctrl->cb_ctx); } } @@ -254,31 +254,45 @@ static void internal_ctrl_list_cb(ziti_controller_detail_array arr, const ziti_e ziti_controller_detail *d; if (err) { CTRL_LOG(WARN, "failed to get list of HA controllers: %s", err->message); + return; } - else { - model_map old = ctrl->endpoints; - ctrl->endpoints = (model_map){0}; - FOR (d, arr) { - api_address *addr = NULL; - MODEL_LIST_FOREACH(addr, d->apis.edge) { - CTRL_LOG(VERBOSE, "%s/%s", addr->version, addr->url); - if (addr && strcmp(addr->version, "v1") == 0) { - break; - } - addr = NULL; + + bool change = false; + model_map old = ctrl->endpoints; + ctrl->endpoints = (model_map){0}; + FOR (d, arr) { + api_address *addr = NULL; + MODEL_LIST_FOREACH(addr, d->apis.edge) { + CTRL_LOG(VERBOSE, "%s/%s", addr->version, addr->url); + if (addr && strcmp(addr->version, "v1") == 0) { + break; } + addr = NULL; + } - if (addr != NULL) { - if (strcmp(addr->url, ctrl->url) == 0) { - ctrl->url = addr->url; - } - model_map_set(&ctrl->endpoints, addr->url, d); + if (addr != NULL) { + if (strcmp(addr->url, ctrl->url) == 0) { + ctrl->url = addr->url; + } + model_map_set(&ctrl->endpoints, addr->url, d); + + ziti_controller_detail *old_detail = model_map_remove(&old, addr->url); + if (old_detail == NULL) { // new controller discovered + change = true; + } else { + change = change || (old_detail->is_online != d->is_online); + free_ziti_controller_detail_ptr(old_detail); } } - model_map_clear(&old, (void (*)(void *)) free_ziti_controller_detail_ptr); } - + // if some old details are still in the old map, controller(s) was(ere) removed + change = change || (model_map_size(&old) > 0); + model_map_clear(&old, (void (*)(void *)) free_ziti_controller_detail_ptr); free(arr); + + if (change) { + ctrl->change_cb(ctrl->cb_ctx, &ctrl->endpoints); + } } static void internal_version_cb(ziti_version *v, ziti_error *e, struct ctrl_resp *resp) { @@ -572,9 +586,12 @@ void ziti_ctrl_set_page_size(ziti_controller *ctrl, unsigned int size) { ctrl->page_size = size; } -void ziti_ctrl_set_redirect_cb(ziti_controller *ctrl, ziti_ctrl_redirect_cb cb, void *ctx) { - ctrl->redirect_cb = cb; - ctrl->redirect_ctx = ctx; +void ziti_ctrl_set_callbacks(ziti_controller *ctrl, void *ctx, + ziti_ctrl_redirect_cb redirect_cb, + ziti_ctrl_change_cb change_cb) { + ctrl->change_cb = change_cb; + ctrl->redirect_cb = redirect_cb; + ctrl->cb_ctx = ctx; } static void on_http_close(tlsuv_http_t *clt) { diff --git a/library/zitilib.c b/library/zitilib.c index 3604b436..2f2fad03 100644 --- a/library/zitilib.c +++ b/library/zitilib.c @@ -146,7 +146,7 @@ static void on_ctx_event(ziti_context ztx, const ziti_event_t *ev) { ztx_wrap_t *wrap = ziti_app_ctx(ztx); future_t *f; if (ev->type == ZitiContextEvent) { - int err = ev->event.ctx.ctrl_status; + int err = ev->ctx.ctrl_status; if (err == ZITI_OK) { wrap->ztx = ztx; model_list_iter it = model_list_iterator(&wrap->futures); @@ -171,14 +171,14 @@ static void on_ctx_event(ziti_context ztx, const ziti_event_t *ev) { } } else if (ev->type == ZitiServiceEvent) { - for (int i = 0; ev->event.service.removed && ev->event.service.removed[i] != NULL; i++) { - ziti_intercept_cfg_v1 *intercept = model_map_remove(&wrap->intercepts, ev->event.service.removed[i]->name); + for (int i = 0; ev->service.removed && ev->service.removed[i] != NULL; i++) { + ziti_intercept_cfg_v1 *intercept = model_map_remove(&wrap->intercepts, ev->service.removed[i]->name); free_ziti_intercept_cfg_v1(intercept); FREE(intercept); } - for (int i = 0; ev->event.service.changed && ev->event.service.changed[i] != NULL; i++) { - ziti_service *s = ev->event.service.changed[i]; + for (int i = 0; ev->service.changed && ev->service.changed[i] != NULL; i++) { + ziti_service *s = ev->service.changed[i]; ziti_intercept_cfg_v1 *intercept = alloc_ziti_intercept_cfg_v1(); if (ziti_service_get_config(s, ZITI_INTERCEPT_CFG_V1, intercept, (parse_service_cfg_f) parse_ziti_intercept_cfg_v1) == ZITI_OK) { @@ -189,8 +189,8 @@ static void on_ctx_event(ziti_context ztx, const ziti_event_t *ev) { FREE(intercept); } - for (int i = 0; ev->event.service.added && ev->event.service.added[i] != NULL; i++) { - ziti_service *s = ev->event.service.added[i]; + for (int i = 0; ev->service.added && ev->service.added[i] != NULL; i++) { + ziti_service *s = ev->service.added[i]; ziti_intercept_cfg_v1 *intercept = alloc_ziti_intercept_cfg_v1(); ziti_client_cfg_v1 clt_cfg = {0}; diff --git a/programs/ziti-prox-c/proxy.c b/programs/ziti-prox-c/proxy.c index 2b3542f1..d848c5f5 100644 --- a/programs/ziti-prox-c/proxy.c +++ b/programs/ziti-prox-c/proxy.c @@ -426,39 +426,49 @@ static void on_ziti_event(ziti_context ztx, const ziti_event_t *event) { struct proxy_app_ctx *app_ctx = ziti_app_ctx(ztx); switch (event->type) { case ZitiAPIEvent: - if (event->event.api.new_ctrl_address) ZITI_LOG(INFO, "update API URL to %s", event->event.api.new_ctrl_address); - if (event->event.api.new_ca_bundle) ZITI_LOG(INFO, "update CA bundle to %s", event->event.api.new_ca_bundle); + if (event->api.new_ctrl_address) ZITI_LOG(INFO, "update API URL to %s", event->api.new_ctrl_address); + if (event->api.new_ca_bundle) ZITI_LOG(INFO, "update CA bundle to %s", event->api.new_ca_bundle); break; case ZitiContextEvent: - if (event->event.ctx.ctrl_status == ZITI_OK) { + if (event->ctx.ctrl_status == ZITI_OK) { const ziti_version *ctrl_ver = ziti_get_controller_version(ztx); const ziti_identity *proxy_id = ziti_get_identity(ztx); ZITI_LOG(INFO, "controller version = %s(%s)[%s]", ctrl_ver->version, ctrl_ver->revision, ctrl_ver->build_date); - ZITI_LOG(INFO, "proxy identity = <%s>[%s]@%s", proxy_id->name, proxy_id->id, ziti_get_controller(ztx)); + if (proxy_id) { + ZITI_LOG(INFO, "proxy identity = <%s>[%s]", proxy_id->name, proxy_id->id); + } app_ctx->ziti = ztx; + + for (int i = 0; i < event->ctx.ctrl_count; i++) { + ZITI_LOG(INFO, "ctrl[%s/%s]@%s", + event->ctx.ctrl_details[i].id, + event->ctx.ctrl_details[i].online ? "online" : "offline", + event->ctx.ctrl_details[i].url + ); + } } else { - ZITI_LOG(ERROR, "controller is not available: %s/%s", ziti_errorstr(event->event.ctx.ctrl_status), - event->event.ctx.err); + ZITI_LOG(ERROR, "controller is not available: %s/%s", ziti_errorstr(event->ctx.ctrl_status), + event->ctx.err); } break; case ZitiServiceEvent: - if (event->event.service.removed != NULL) { - for (ziti_service **sp = event->event.service.removed; *sp != NULL; sp++) { + if (event->service.removed != NULL) { + for (ziti_service **sp = event->service.removed; *sp != NULL; sp++) { service_check_cb(ztx, *sp, ZITI_SERVICE_UNAVAILABLE, app_ctx); } } - if (event->event.service.added != NULL) { - for (ziti_service **sp = event->event.service.added; *sp != NULL; sp++) { + if (event->service.added != NULL) { + for (ziti_service **sp = event->service.added; *sp != NULL; sp++) { service_check_cb(ztx, *sp, ZITI_OK, app_ctx); } } - if (event->event.service.changed != NULL) { - for (ziti_service **sp = event->event.service.changed; *sp != NULL; sp++) { + if (event->service.changed != NULL) { + for (ziti_service **sp = event->service.changed; *sp != NULL; sp++) { ziti_service *service = *sp; service_check_cb(ztx, *sp, ZITI_OK, app_ctx); @@ -478,23 +488,23 @@ static void on_ziti_event(ziti_context ztx, const ziti_event_t *event) { break; case ZitiRouterEvent: - switch (event->event.router.status) { + switch (event->router.status) { case EdgeRouterAdded: - ZITI_LOG(INFO, "ziti added edge router %s address=%s", event->event.router.name, - event->event.router.address); + ZITI_LOG(INFO, "ziti added edge router %s address=%s", event->router.name, + event->router.address); break; case EdgeRouterConnected: - ZITI_LOG(INFO, "ziti connected to edge router %s, version = %s", event->event.router.name, - event->event.router.version); + ZITI_LOG(INFO, "ziti connected to edge router %s, version = %s", event->router.name, + event->router.version); break; case EdgeRouterDisconnected: - ZITI_LOG(INFO, "ziti disconnected from edge router %s", event->event.router.name); + ZITI_LOG(INFO, "ziti disconnected from edge router %s", event->router.name); break; case EdgeRouterRemoved: - ZITI_LOG(INFO, "ziti removed edge router %s", event->event.router.name); + ZITI_LOG(INFO, "ziti removed edge router %s", event->router.name); break; case EdgeRouterUnavailable: - ZITI_LOG(INFO, "edge router %s is not available", event->event.router.name); + ZITI_LOG(INFO, "edge router %s is not available", event->router.name); break; } break; From c0cc3307e5a64b6e5aa1775efb5d3f30b8ba853f Mon Sep 17 00:00:00 2001 From: eugene Date: Thu, 13 Jun 2024 15:39:56 -0400 Subject: [PATCH 2/2] fix events in samples --- programs/host-proxy/host-proxy.c | 2 +- programs/sample-bridge/ziti-ncat.c | 2 +- programs/sample-host/sample-host.c | 6 +++--- programs/sample_http_link/sample_http_link.c | 2 +- programs/sample_wttr/sample_wttr.c | 2 +- tests/integ/legacy-auth.cpp | 2 +- tests/ziti_src_tests.cpp | 2 +- 7 files changed, 9 insertions(+), 9 deletions(-) diff --git a/programs/host-proxy/host-proxy.c b/programs/host-proxy/host-proxy.c index a88604fe..b4fd7c9c 100644 --- a/programs/host-proxy/host-proxy.c +++ b/programs/host-proxy/host-proxy.c @@ -80,7 +80,7 @@ void on_ziti_event(ziti_context ztx, const ziti_event_t *event) { struct app_ctx *ctx = ziti_app_ctx(ztx); if (event->type == ZitiServiceEvent) { - const struct ziti_service_event *se = &event->event.service; + const struct ziti_service_event *se = &event->service; for (int i = 0; se->added[i] != NULL; i++) { ziti_service *s = se->added[i]; if ((s->perm_flags & ZITI_CAN_BIND) == 0) { diff --git a/programs/sample-bridge/ziti-ncat.c b/programs/sample-bridge/ziti-ncat.c index 0f138a4d..3ca4af15 100644 --- a/programs/sample-bridge/ziti-ncat.c +++ b/programs/sample-bridge/ziti-ncat.c @@ -36,7 +36,7 @@ void on_connect(ziti_connection conn, int status) { } void on_ziti_event(ziti_context ztx, const ziti_event_t *ev) { - if (ev->type == ZitiContextEvent && ev->event.ctx.ctrl_status == ZITI_OK) { + if (ev->type == ZitiContextEvent && ev->ctx.ctrl_status == ZITI_OK) { zcat_opts *opts = ziti_app_ctx(ztx); ziti_connection zconn; ziti_conn_init(ztx, &zconn, NULL); diff --git a/programs/sample-host/sample-host.c b/programs/sample-host/sample-host.c index 684e3f23..eaa4d58b 100644 --- a/programs/sample-host/sample-host.c +++ b/programs/sample-host/sample-host.c @@ -158,10 +158,10 @@ static void on_signal(uv_signal_t *h, int signal) { static void on_ziti_init(ziti_context ztx, const ziti_event_t *ev) { if (ev->type != ZitiContextEvent) return; - if (ev->event.ctx.ctrl_status == ZITI_PARTIALLY_AUTHENTICATED) return; + if (ev->ctx.ctrl_status == ZITI_PARTIALLY_AUTHENTICATED) return; - if (ev->event.ctx.ctrl_status != ZITI_OK) { - DIE(ev->event.ctx.ctrl_status); + if (ev->ctx.ctrl_status != ZITI_OK) { + DIE(ev->ctx.ctrl_status); return; } diff --git a/programs/sample_http_link/sample_http_link.c b/programs/sample_http_link/sample_http_link.c index 77780345..d3af9121 100644 --- a/programs/sample_http_link/sample_http_link.c +++ b/programs/sample_http_link/sample_http_link.c @@ -59,7 +59,7 @@ void body_cb(tlsuv_http_req_t *req, char *body, ssize_t len) { void on_ziti_init(ziti_context ztx, const ziti_event_t *ev) { - DIE(ev->event.ctx.ctrl_status); + DIE(ev->ctx.ctrl_status); ziti = ztx; ziti_src_init(loop, &zs, "httpbin", ziti); diff --git a/programs/sample_wttr/sample_wttr.c b/programs/sample_wttr/sample_wttr.c index a8150f84..6673540f 100644 --- a/programs/sample_wttr/sample_wttr.c +++ b/programs/sample_wttr/sample_wttr.c @@ -74,7 +74,7 @@ void on_connect(ziti_connection conn, int status) { } void on_ziti_init(ziti_context ztx, const ziti_event_t *ev) { - DIE(ev->event.ctx.ctrl_status); + DIE(ev->ctx.ctrl_status); ziti = ztx; ziti_connection conn; diff --git a/tests/integ/legacy-auth.cpp b/tests/integ/legacy-auth.cpp index b5570a05..f7fc09a4 100644 --- a/tests/integ/legacy-auth.cpp +++ b/tests/integ/legacy-auth.cpp @@ -230,7 +230,7 @@ TEST_CASE("ztx-legacy-auth", "[integ]") { opts.app_ctx = &test_context; opts.events = ZitiContextEvent; opts.event_cb = [](ziti_context ztx, const ziti_event_t *event){ - printf("got event: %d => %s \n", event->type, event->event.ctx.err); + printf("got event: %d => %s \n", event->type, event->ctx.err); auto test_ctx = (test_context_s*)ziti_app_ctx(ztx); test_ctx->event = event->type; }; diff --git a/tests/ziti_src_tests.cpp b/tests/ziti_src_tests.cpp index 544befe2..e715f7c2 100644 --- a/tests/ziti_src_tests.cpp +++ b/tests/ziti_src_tests.cpp @@ -45,7 +45,7 @@ TEST_CASE("httpbin.ziti:ziti_src", "[integ]") { auto t = (source_test*)ziti_app_ctx(ztx); switch (ev->type) { case ZitiContextEvent: { - auto ctx_ev = ev->event.ctx; + auto ctx_ev = ev->ctx; t->ztx = ztx; if (!t->done && ctx_ev.ctrl_status != ZITI_OK) t->err = ctx_ev.ctrl_status;