Skip to content

Commit

Permalink
Merge pull request #954 from openziti/tunnel.dump
Browse files Browse the repository at this point in the history
add ip_dump ipc command
  • Loading branch information
scareything authored Sep 16, 2024
2 parents 004007b + 21746df commit 8b9f046
Show file tree
Hide file tree
Showing 11 changed files with 274 additions and 22 deletions.
4 changes: 3 additions & 1 deletion lib/ziti-tunnel-cbs/CMakeLists.txt
Original file line number Diff line number Diff line change
Expand Up @@ -13,7 +13,9 @@ add_library(ziti-tunnel-cbs-c STATIC
ziti_dns.c
dns_msg.c
dns_host.c
dns_host.h)
dns_host.h
ziti_tunnel_model.c
)

target_compile_definitions(ziti-tunnel-cbs-c
PRIVATE ZITI_LOG_MODULE="tunnel-cbs"
Expand Down
5 changes: 5 additions & 0 deletions lib/ziti-tunnel-cbs/include/ziti/ziti_tunnel_cbs.h
Original file line number Diff line number Diff line change
Expand Up @@ -52,6 +52,7 @@ DECLARE_MODEL(tunneler_app_data, TUNNELER_APP_DATA_MODEL)

#define TUNNEL_COMMANDS(XX,...) \
XX(ZitiDump, __VA_ARGS__) \
XX(IpDump, __VA_ARGS__) \
XX(LoadIdentity, __VA_ARGS__) \
XX(ListIdentities, __VA_ARGS__) \
XX(IdentityOnOff, __VA_ARGS__) \
Expand Down Expand Up @@ -104,6 +105,9 @@ XX(identities, tunnel_identity_info, array, Identities, __VA_ARGS__)
XX(identifier, string, none, Identifier, __VA_ARGS__) \
XX(dump_path, string, none, DumpPath, __VA_ARGS__)

#define TNL_IP_DUMP(XX, ...) \
XX(dump_path, string, none, DumpPath, __VA_ARGS__)

#define TNL_ENABLE_MFA(XX, ...) \
XX(identifier, string, none, Identifier, __VA_ARGS__)

Expand Down Expand Up @@ -179,6 +183,7 @@ DECLARE_MODEL(tunnel_load_identity, TNL_LOAD_IDENTITY)
DECLARE_MODEL(tunnel_identity_info, TNL_IDENTITY_INFO)
DECLARE_MODEL(tunnel_identity_lst, TNL_IDENTITY_LIST)
DECLARE_MODEL(tunnel_ziti_dump, TNL_ZITI_DUMP)
DECLARE_MODEL(tunnel_ip_dump, TNL_IP_DUMP)
DECLARE_MODEL(tunnel_on_off_identity, TNL_ON_OFF_IDENTITY)
DECLARE_MODEL(tunnel_enable_mfa, TNL_ENABLE_MFA)
DECLARE_MODEL(tunnel_mfa_enrol_res, TNL_MFA_ENROL_RES)
Expand Down
111 changes: 96 additions & 15 deletions lib/ziti-tunnel-cbs/ziti_tunnel_ctrl.c
Original file line number Diff line number Diff line change
Expand Up @@ -113,7 +113,10 @@ static ziti_context get_ziti(const char *identifier) {
return inst ? inst->ztx : NULL;
}

static int ziti_dump_to_log_op(void* stringsBuilder, const char *fmt, ...) {
typedef int (*dump_printer)(void *printer_ctx, const char *, ...);
typedef void (*dumper)(void *dumper_ctx, dump_printer printer, void *printer_ctx);

static int dump_to_log_op(void *stringsBuilder, const char *fmt, ...) {
static char line[4096];

va_list vargs;
Expand All @@ -125,21 +128,20 @@ static int ziti_dump_to_log_op(void* stringsBuilder, const char *fmt, ...) {
return -1;
}
// write/append to the buffer
strncat(stringsBuilder, line, sizeof(line));
strncat(stringsBuilder, line, sizeof(line)); // todo suss
return 0;
}

static void ziti_dump_to_log(void *ctx) {
static void dump_to_log(dumper dump, void *dump_ctx) {
char* buffer;
buffer = malloc(MAXBUFFERLEN*sizeof(char));
buffer[0] = 0;
//actually invoke ziti_dump here
ziti_dump(ctx, ziti_dump_to_log_op, buffer);
ZITI_LOG(INFO, "ziti dump to log %s", buffer);
dump(dump_ctx, dump_to_log_op, buffer);
ZITI_LOG(INFO, "dump to log %s", buffer);
free(buffer);
}

static int ziti_dump_to_file_op(void* fp, const char *fmt, ...) {
static int dump_to_file_op(void* fp, const char *fmt, ...) {
static char line[4096];

va_list vargs;
Expand All @@ -151,7 +153,7 @@ static int ziti_dump_to_file_op(void* fp, const char *fmt, ...) {
return 0;
}

static void ziti_dump_to_file(void *ctx, char* outputFile) {
static void dump_to_file(dumper dump, void *dump_ctx, char* outputFile) {
FILE *fp;
fp = fopen(outputFile, "w+");
if(fp == NULL)
Expand All @@ -166,14 +168,38 @@ static void ziti_dump_to_file(void *ctx, char* outputFile) {
struct tm* start_tm = gmtime(&dump_time.tv_sec);
strftime(time_str, sizeof(time_str), "%a %b %d %Y, %X %p", start_tm);

fprintf(fp, "Ziti Dump starting: %s\n",time_str);
fprintf(fp, "Dump starting: %s\n",time_str);

//actually invoke ziti_dump here
ziti_dump(ctx, ziti_dump_to_file_op, fp);
dump(dump_ctx, dump_to_file_op, fp);
fflush(fp);
fclose(fp);
}

static void ip_dump(const tunnel_ip_stats *stats, dump_printer printer, void *printer_ctx) {
int i;

printer(printer_ctx, "\n=================\nMemory Pools:\n");
printer(printer_ctx, "%-16s%-12s%-12s%-12s\n", "Pool Name", "In Use", "Max Used", "Limit");
tunnel_ip_mem_pool_array pools = stats->pools;
for (i = 0; pools[i] != NULL; i++) {
printer(printer_ctx, "%-16s%-12d%-12d%-12d\n", pools[i]->name, pools[i]->used, pools[i]->max, pools[i]->avail);
}

printer(printer_ctx, "\n=================\nIP Connections:\n");
printer(printer_ctx, "%-12s%-48s%-48s%-16s%-24s\n",
"Protocol", "Local Address", "Remote Address", "State", "Ziti Service");
tunnel_ip_conn_array conns = stats->connections;
char local_addr[64];
char remote_addr[64];
for (i = 0; conns[i] != NULL; i++) {
snprintf(local_addr, sizeof(local_addr), "%s:%d", conns[i]->local_ip, conns[i]->local_port);
snprintf(remote_addr, sizeof(remote_addr), "%s:%d", conns[i]->remote_ip, conns[i]->remote_port);
printer(printer_ctx, "%-12s%-48s%-48s%-16s%-24s\n",
conns[i]->protocol, local_addr, remote_addr, conns[i]->state, conns[i]->service);
}

}

static void disconnect_identity(ziti_context ziti_ctx, void *tnlr_ctx) {
ZITI_LOG(INFO, "Disconnecting Identity %s", ziti_get_identity(ziti_ctx)->name);
remove_intercepts(ziti_ctx, tnlr_ctx);
Expand Down Expand Up @@ -275,7 +301,7 @@ static int process_cmd(const tunnel_command *cmd, command_cb cb, void *ctx) {
#ifndef MAXPATHLEN
#define MAXPATHLEN 1024
#endif
ZITI_LOG(INFO, "ziti dump started ");
ZITI_LOG(INFO, "ziti dump started");
tunnel_ziti_dump dump = {0};
if (cmd->data != NULL && parse_tunnel_ziti_dump(&dump, cmd->data, strlen(cmd->data)) < 0) {
result.success = false;
Expand All @@ -298,14 +324,15 @@ static int process_cmd(const tunnel_command *cmd, command_cb cb, void *ctx) {
}
bool success = true;
if (dump.dump_path == NULL) {
ziti_dump_to_log(inst->ztx);
dump_to_log((dumper) ziti_dump, inst->ztx);
} else {
char dump_file[MAXPATHLEN];
char* dump_path = realpath(dump.dump_path, NULL);

if (dump_path != NULL) {
snprintf(dump_file, sizeof(dump_file), "%s/%s.ziti", dump_path, identity->name);
ziti_dump_to_file(inst->ztx, dump_file);
dump_to_file((dumper) ziti_dump, inst->ztx, dump_file);
free(dump_path);
} else {
ZITI_LOG(WARN, "Could not generate the ziti dump file, because the path is not found");
success = false;
Expand All @@ -331,6 +358,55 @@ static int process_cmd(const tunnel_command *cmd, command_cb cb, void *ctx) {
break;
}

case TunnelCommand_IpDump: {
ZITI_LOG(INFO, "ip dump started");
tunnel_ip_dump dump = {0};
if (cmd->data != NULL && parse_tunnel_ip_dump(&dump, cmd->data, strlen(cmd->data)) < 0) {
result.success = false;
result.error = "invalid command";
free_tunnel_ip_dump(&dump);
break;
}
tunnel_ip_stats stats = {0};
ziti_tunnel_get_ip_stats(&stats);
result.data = tunnel_ip_stats_to_json(&stats, MODEL_JSON_COMPACT, NULL);
bool success = true;
if (dump.dump_path == NULL) {
dump_to_log((dumper) ip_dump, &stats);
} else {
char dump_file[MAXPATHLEN];
char* dump_path = realpath(dump.dump_path, NULL);
if (dump_path != NULL) {
uv_timeval64_t now;
uv_gettimeofday(&now);
struct tm *tm = gmtime(&now.tv_sec);
snprintf(dump_file, sizeof(dump_file), "%s/%04d-%02d-%02dT%02d:%02d:%02d.%03dZ.ip_dump", dump_path,
1900 + tm->tm_year, tm->tm_mon + 1, tm->tm_mday,
tm->tm_hour, tm->tm_min, tm->tm_sec, now.tv_usec / 1000);
dump_to_file((dumper) ip_dump, &stats, dump_file);
free(dump_path);
} else {
ZITI_LOG(WARN, "Could not generate the ip dump file, because the path is not found");
success = false;
}
}
if (success) {
result.success = true;
result.code = IPC_SUCCESS;
} else {
result.success = false;
result.code = IPC_ERROR;
}
if (!result.success) {
result.error = "ip dump failed";
ZITI_LOG(WARN, "%s", result.error);
} else {
ZITI_LOG(INFO, "ip dump finished");
}
free_tunnel_ip_stats(&stats);
break;
}

case TunnelCommand_EnableMFA: {
tunnel_enable_mfa enable_mfa_cmd = {0};
if (cmd->data != NULL && parse_tunnel_enable_mfa(&enable_mfa_cmd, cmd->data, strlen(cmd->data)) < 0) {
Expand Down Expand Up @@ -426,7 +502,6 @@ static int process_cmd(const tunnel_command *cmd, command_cb cb, void *ctx) {
return 0;
}

default: result.error = "command not implemented";
case TunnelCommand_SubmitMFA: {
tunnel_submit_mfa auth = {0};
if (cmd->data == NULL || parse_tunnel_submit_mfa(&auth, cmd->data, strlen(cmd->data)) < 0) {
Expand Down Expand Up @@ -603,6 +678,11 @@ static int process_cmd(const tunnel_command *cmd, command_cb cb, void *ctx) {
ZITI_LOG(VERBOSE, "Unknown tunnel command received");
break;
}

default: {
result.error = "command not implemented";
break;
}
}

cb(&result, ctx);
Expand Down Expand Up @@ -1335,6 +1415,7 @@ IMPL_MODEL(tunnel_identity_info, TNL_IDENTITY_INFO)
IMPL_MODEL(tunnel_identity_lst, TNL_IDENTITY_LIST)
IMPL_MODEL(tunnel_on_off_identity, TNL_ON_OFF_IDENTITY)
IMPL_MODEL(tunnel_ziti_dump, TNL_ZITI_DUMP)
IMPL_MODEL(tunnel_ip_dump, TNL_IP_DUMP)
IMPL_MODEL(tunnel_enable_mfa, TNL_ENABLE_MFA)
IMPL_MODEL(tunnel_mfa_enrol_res, TNL_MFA_ENROL_RES)
IMPL_MODEL(tunnel_submit_mfa, TNL_SUBMIT_MFA)
Expand Down
23 changes: 23 additions & 0 deletions lib/ziti-tunnel-cbs/ziti_tunnel_model.c
Original file line number Diff line number Diff line change
@@ -0,0 +1,23 @@
/*
Copyright 2024 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 <ziti/ziti_tunnel_cbs.h>

// ******* TUNNEL MODEL
IMPL_MODEL(tunnel_service_control, TUNNEL_SERVICE_CONTROL)
IMPL_MODEL(tunnel_set_log_level, TUNNEL_SET_LOG_LEVEL)
IMPL_MODEL(tunnel_tun_ip_v4, TUNNEL_TUN_IP_V4)
IMPL_MODEL(tunnel_add_identity, TUNNEL_ADD_IDENTITY)
25 changes: 25 additions & 0 deletions lib/ziti-tunnel/include/ziti/ziti_tunnel.h
Original file line number Diff line number Diff line change
Expand Up @@ -201,6 +201,31 @@ extern void ziti_tunnel_set_log_level(int lvl);
typedef void (*ziti_tunnel_async_fn)(uv_loop_t *loop, void *ctx);
extern void ziti_tunnel_async_send(tunneler_context tctx, ziti_tunnel_async_fn f, void *arg);

#define TNL_IP_MEM_POOL(XX, ...) \
XX(name, string, none, Name, __VA_ARGS__) \
XX(max, int, none, Max, __VA_ARGS__) \
XX(used, int, none, Used, __VA_ARGS__) \
XX(avail, int, none, Avail, __VA_ARGS__)

#define TNL_IP_CONN(XX, ...) \
XX(protocol, string, none, Protocol, __VA_ARGS__) \
XX(local_ip, string, none, LocalIP, __VA_ARGS__) \
XX(local_port, int, none, LocalPort, __VA_ARGS__) \
XX(remote_ip, string, none, RemoteIP, __VA_ARGS__) \
XX(remote_port, int, none, RemotePort, __VA_ARGS__) \
XX(state, string, none, State, __VA_ARGS__) \
XX(service, string, none, Service, __VA_ARGS__)

#define TNL_IP_STATS(XX, ...) \
XX(pools, tunnel_ip_mem_pool, array, Pools, __VA_ARGS__) \
XX(connections, tunnel_ip_conn, array, Connections, __VA_ARGS__)

DECLARE_MODEL(tunnel_ip_mem_pool, TNL_IP_MEM_POOL)
DECLARE_MODEL(tunnel_ip_conn, TNL_IP_CONN)
DECLARE_MODEL(tunnel_ip_stats, TNL_IP_STATS)

extern void ziti_tunnel_get_ip_stats(tunnel_ip_stats *stats);

#ifdef __cplusplus
}
#endif
Expand Down
16 changes: 16 additions & 0 deletions lib/ziti-tunnel/tunnel_tcp.c
Original file line number Diff line number Diff line change
Expand Up @@ -460,4 +460,20 @@ struct io_ctx_list_s *tunneler_tcp_active(const void *zi_ctx) {
}

return l;
}

void tunneler_tcp_get_conn(tunnel_ip_conn *conn, struct tcp_pcb *pcb) {
if (!conn || !pcb) return;
conn->protocol = strdup("tcp");
conn->local_ip = strdup(ipaddr_ntoa(&pcb->local_ip));
conn->local_port = pcb->local_port;
conn->remote_ip = strdup(ipaddr_ntoa(&pcb->remote_ip));
conn->remote_port = pcb->remote_port;
conn->state = strdup(tcp_state_str(pcb->state));
const char *service = "unknown";
struct io_ctx_s *io = pcb->callback_arg;
if (io && io->tnlr_io && io->tnlr_io->service_name) {
service = io->tnlr_io->service_name;
}
conn->service = strdup(service);
}
2 changes: 2 additions & 0 deletions lib/ziti-tunnel/tunnel_tcp.h
Original file line number Diff line number Diff line change
Expand Up @@ -38,4 +38,6 @@ extern int tunneler_tcp_close_write(struct tcp_pcb *pcb);
/** return list of io contexts for active connections to the given service. caller must free the returned pointer */
extern struct io_ctx_list_s *tunneler_tcp_active(const void *zi_ctx);

extern void tunneler_tcp_get_conn(tunnel_ip_conn *conn, struct tcp_pcb *pcb);

#endif //ZITI_TUNNELER_SDK_TUNNELER_TCP_H
16 changes: 16 additions & 0 deletions lib/ziti-tunnel/tunnel_udp.c
Original file line number Diff line number Diff line change
Expand Up @@ -284,4 +284,20 @@ struct io_ctx_list_s *tunneler_udp_active(const void *zi_ctx) {
}

return l;
}

void tunneler_udp_get_conn(tunnel_ip_conn *conn, struct udp_pcb *pcb) {
if (!conn || !pcb) return;
conn->protocol = strdup("udp");
conn->local_ip = strdup(ipaddr_ntoa(&pcb->local_ip));
conn->local_port = pcb->local_port;
conn->remote_ip = strdup(ipaddr_ntoa(&pcb->remote_ip));
conn->remote_port = pcb->remote_port;
conn->state = strdup("");
const char *service = "unknown";
struct io_ctx_s *io = pcb->recv_arg;
if (io && io->tnlr_io && io->tnlr_io->service_name) {
service = io->tnlr_io->service_name;
}
conn->service = strdup(service);
}
1 change: 1 addition & 0 deletions lib/ziti-tunnel/tunnel_udp.h
Original file line number Diff line number Diff line change
Expand Up @@ -29,4 +29,5 @@ extern int tunneler_udp_close(struct udp_pcb *pcb);
/** return list of io contexts for active connections to the given service. caller must free the returned pointer */
extern struct io_ctx_list_s *tunneler_udp_active(const void *zi_ctx);

extern void tunneler_udp_get_conn(tunnel_ip_conn *conn, struct udp_pcb *pcb);
#endif //ZITI_TUNNELER_SDK_TUNNELER_UDP_H
Loading

0 comments on commit 8b9f046

Please sign in to comment.