diff --git a/code/bngblaster/src/bbl_config.c b/code/bngblaster/src/bbl_config.c index b69205ac..33fc2e0d 100644 --- a/code/bngblaster/src/bbl_config.c +++ b/code/bngblaster/src/bbl_config.c @@ -1703,6 +1703,10 @@ json_parse_config(json_t *root, bbl_ctx_s *ctx) { if (json_is_number(value)) { ctx->config.igmp_max_join_delay = json_number_value(value); } + value = json_object_get(section, "robustness-interval"); + if (json_is_number(value)) { + ctx->config.igmp_robustness_interval = json_number_value(value); + } } /* Access Line Configuration */ @@ -2274,6 +2278,7 @@ bbl_config_init_defaults (bbl_ctx_s *ctx) { ctx->config.igmp_source = 0; ctx->config.igmp_group_count = 1; ctx->config.igmp_zap_wait = true; + ctx->config.igmp_robustness_interval = 1000; ctx->config.traffic_autostart = true; ctx->config.session_traffic_autostart = true; } diff --git a/code/bngblaster/src/bbl_ctrl.c b/code/bngblaster/src/bbl_ctrl.c index 3121f21e..67d20f95 100644 --- a/code/bngblaster/src/bbl_ctrl.c +++ b/code/bngblaster/src/bbl_ctrl.c @@ -501,14 +501,20 @@ bbl_ctrl_zapping_stats(int fd, bbl_ctx_s *ctx, uint32_t session_id __attribute__ json_unpack(arguments, "{s:b}", "reset", &reset); bbl_stats_generate_multicast(ctx, &stats, reset); - root = json_pack("{ss si s{si si si si si si si si si si si}}", + root = json_pack("{ss si s{si si si si si si si si si si si si si si si si si}}", "status", "ok", "code", 200, "zapping-stats", "join-delay-ms-min", stats.min_join_delay, "join-delay-ms-avg", stats.avg_join_delay, "join-delay-ms-max", stats.max_join_delay, - "join-delay-violations", stats.max_join_delay_violations, + "join-delay-violations", stats.join_delay_violations, + "join-delay-violations-threshold", ctx->config.igmp_max_join_delay, + "join-delay-violations-125ms", stats.join_delay_violations_125ms, + "join-delay-violations-250ms", stats.join_delay_violations_250ms, + "join-delay-violations-500ms", stats.join_delay_violations_500ms, + "join-delay-violations-1s", stats.join_delay_violations_1s, + "join-delay-violations-2s", stats.join_delay_violations_2s, "join-count", stats.zapping_join_count, "leave-delay-ms-min", stats.min_leave_delay, "leave-delay-ms-avg", stats.avg_leave_delay, diff --git a/code/bngblaster/src/bbl_ctx.h b/code/bngblaster/src/bbl_ctx.h index ed7efe79..5eb77a93 100644 --- a/code/bngblaster/src/bbl_ctx.h +++ b/code/bngblaster/src/bbl_ctx.h @@ -291,6 +291,7 @@ typedef struct bbl_ctx_ uint16_t igmp_zap_count; uint16_t igmp_zap_wait; uint16_t igmp_max_join_delay; + uint16_t igmp_robustness_interval; /* Multicast Traffic */ bool send_multicast_traffic; diff --git a/code/bngblaster/src/bbl_interface.c b/code/bngblaster/src/bbl_interface.c index 24a477d0..c6dcb998 100644 --- a/code/bngblaster/src/bbl_interface.c +++ b/code/bngblaster/src/bbl_interface.c @@ -51,7 +51,8 @@ bbl_interface_lock(bbl_ctx_s *ctx, char *interface_name) lock_pid = pid; lock_file = fopen(lock_path, "w"); if(!lock_file) { - LOG(ERROR, "Failed to open interface lock file %s\n", lock_path); + LOG(ERROR, "Failed to open interface lock file %s %s (%d)\n", + lock_path, strerror(errno), errno); return false; } fprintf(lock_file, "%d", lock_pid); diff --git a/code/bngblaster/src/bbl_rx.c b/code/bngblaster/src/bbl_rx.c index 39fc4fbc..eeb77457 100644 --- a/code/bngblaster/src/bbl_rx.c +++ b/code/bngblaster/src/bbl_rx.c @@ -129,7 +129,19 @@ bbl_igmp_zapping(timer_s *timer) session->stats.avg_join_delay = session->zapping_join_delay_sum / session->zapping_join_count; if(ctx->config.igmp_max_join_delay && join_delay > ctx->config.igmp_max_join_delay) { - session->stats.max_join_delay_violations++; + session->stats.join_delay_violations++; + } + + if(join_delay > 2000) { + session->stats.join_delay_violations_2s++; + } else if(join_delay > 1000) { + session->stats.join_delay_violations_1s++; + } else if(join_delay > 500) { + session->stats.join_delay_violations_500ms++; + } else if(join_delay > 250) { + session->stats.join_delay_violations_250ms++; + } else if(join_delay > 125) { + session->stats.join_delay_violations_125ms++; } LOG(IGMP, "IGMP (ID: %u) ZAPPING %u ms join delay for group %s\n", diff --git a/code/bngblaster/src/bbl_session.h b/code/bngblaster/src/bbl_session.h index b1d4d4da..f2c29f25 100644 --- a/code/bngblaster/src/bbl_session.h +++ b/code/bngblaster/src/bbl_session.h @@ -336,7 +336,12 @@ typedef struct bbl_session_ uint32_t min_join_delay; uint32_t avg_join_delay; uint32_t max_join_delay; - uint32_t max_join_delay_violations; + uint32_t join_delay_violations; + uint32_t join_delay_violations_125ms; + uint32_t join_delay_violations_250ms; + uint32_t join_delay_violations_500ms; + uint32_t join_delay_violations_1s; + uint32_t join_delay_violations_2s; uint32_t min_leave_delay; uint32_t avg_leave_delay; diff --git a/code/bngblaster/src/bbl_stats.c b/code/bngblaster/src/bbl_stats.c index 9a9b6bce..70a38e99 100644 --- a/code/bngblaster/src/bbl_stats.c +++ b/code/bngblaster/src/bbl_stats.c @@ -91,7 +91,13 @@ bbl_stats_generate_multicast(bbl_ctx_s *ctx, bbl_stats_t *stats, bool reset) { } } - stats->max_join_delay_violations += session->stats.max_join_delay_violations; + stats->join_delay_violations += session->stats.join_delay_violations; + stats->join_delay_violations_125ms += session->stats.join_delay_violations_125ms; + stats->join_delay_violations_250ms += session->stats.join_delay_violations_250ms; + stats->join_delay_violations_500ms += session->stats.join_delay_violations_500ms; + stats->join_delay_violations_1s += session->stats.join_delay_violations_1s; + stats->join_delay_violations_2s += session->stats.join_delay_violations_2s; + stats->zapping_join_count += session->zapping_join_count; stats->zapping_leave_count += session->zapping_leave_count; @@ -104,7 +110,12 @@ bbl_stats_generate_multicast(bbl_ctx_s *ctx, bbl_stats_t *stats, bool reset) { session->stats.min_join_delay = 0; session->stats.avg_join_delay = 0; session->stats.max_join_delay = 0; - session->stats.max_join_delay_violations = 0; + session->stats.join_delay_violations = 0; + session->stats.join_delay_violations_125ms = 0; + session->stats.join_delay_violations_250ms = 0; + session->stats.join_delay_violations_500ms = 0; + session->stats.join_delay_violations_1s = 0; + session->stats.join_delay_violations_2s = 0; session->stats.min_leave_delay = 0; session->stats.avg_leave_delay = 0; session->stats.max_leave_delay = 0; @@ -546,21 +557,24 @@ bbl_stats_stdout(bbl_ctx_s *ctx, bbl_stats_t * stats) { if(ctx->config.igmp_zap_interval > 0) { printf("\nIGMP Zapping Stats:\n"); printf(" Join Delay:\n"); - printf(" MIN: %u ms\n", stats->min_join_delay); - printf(" AVG: %u ms\n", stats->avg_join_delay); - printf(" MAX: %u ms\n", stats->max_join_delay); - + printf(" COUNT: %u\n", stats->zapping_join_count); + printf(" MIN: %ums\n", stats->min_join_delay); + printf(" AVG: %ums\n", stats->avg_join_delay); + printf(" MAX: %ums\n", stats->max_join_delay); + printf(" VIOLATIONS:\n"); if(ctx->config.igmp_max_join_delay) { - printf(" VIOLATIONS: %u/%u (> %u ms)\n", - stats->max_join_delay_violations, - stats->zapping_join_count, - ctx->config.igmp_max_join_delay); + printf(" > %u ms: %u\n", ctx->config.igmp_max_join_delay, stats->join_delay_violations); } - + printf(" > 125ms: %u\n", stats->join_delay_violations_125ms); + printf(" > 250ms: %u\n", stats->join_delay_violations_250ms); + printf(" > 500ms: %u\n", stats->join_delay_violations_500ms); + printf(" > 1s: %u\n", stats->join_delay_violations_1s); + printf(" > 2s: %u\n", stats->join_delay_violations_2s); printf(" Leave Delay:\n"); - printf(" MIN: %u ms\n", stats->min_leave_delay); - printf(" AVG: %u ms\n", stats->avg_leave_delay); - printf(" MAX: %u ms\n", stats->max_leave_delay); + printf(" COUNT: %u\n", stats->zapping_leave_count); + printf(" MIN: %ums\n", stats->min_leave_delay); + printf(" AVG: %ums\n", stats->avg_leave_delay); + printf(" MAX: %ums\n", stats->max_leave_delay); printf(" Multicast:\n"); printf(" Overlap: %u packets\n", stats->mc_old_rx_after_first_new); printf(" Not Received: %u\n", stats->mc_not_received); @@ -851,7 +865,15 @@ bbl_stats_json(bbl_ctx_s *ctx, bbl_stats_t * stats) { json_object_set(jobj_sub, "zapping-join-delay-ms-min", json_integer(stats->min_join_delay)); json_object_set(jobj_sub, "zapping-join-delay-ms-avg", json_integer(stats->avg_join_delay)); json_object_set(jobj_sub, "zapping-join-delay-ms-max", json_integer(stats->max_join_delay)); - json_object_set(jobj_sub, "zapping-join-delay-violations", json_integer(stats->max_join_delay_violations)); + if(ctx->config.igmp_max_join_delay) { + json_object_set(jobj_sub, "zapping-join-delay-violations", json_integer(stats->join_delay_violations)); + json_object_set(jobj_sub, "zapping-join-delay-violations-threshold", json_integer(ctx->config.igmp_max_join_delay)); + } + json_object_set(jobj_sub, "zapping-join-delay-violations-125ms", json_integer(stats->join_delay_violations_125ms)); + json_object_set(jobj_sub, "zapping-join-delay-violations-250ms", json_integer(stats->join_delay_violations_250ms)); + json_object_set(jobj_sub, "zapping-join-delay-violations-500ms", json_integer(stats->join_delay_violations_500ms)); + json_object_set(jobj_sub, "zapping-join-delay-violations-1s", json_integer(stats->join_delay_violations_1s)); + json_object_set(jobj_sub, "zapping-join-delay-violations-2s", json_integer(stats->join_delay_violations_2s)); json_object_set(jobj_sub, "zapping-join-count", json_integer(stats->zapping_join_count)); json_object_set(jobj_sub, "zapping-leave-delay-ms-min", json_integer(stats->min_leave_delay)); json_object_set(jobj_sub, "zapping-leave-delay-ms-avg", json_integer(stats->avg_leave_delay)); diff --git a/code/bngblaster/src/bbl_stats.h b/code/bngblaster/src/bbl_stats.h index cd64a0d2..1aa969eb 100644 --- a/code/bngblaster/src/bbl_stats.h +++ b/code/bngblaster/src/bbl_stats.h @@ -27,7 +27,13 @@ typedef struct bbl_stats_ { uint32_t min_join_delay; /* IGMP join delay */ uint32_t avg_join_delay; /* IGMP join delay */ uint32_t max_join_delay; /* IGMP join delay */ - uint32_t max_join_delay_violations; + + uint32_t join_delay_violations; + uint32_t join_delay_violations_125ms; + uint32_t join_delay_violations_250ms; + uint32_t join_delay_violations_500ms; + uint32_t join_delay_violations_1s; + uint32_t join_delay_violations_2s; uint32_t min_leave_delay; /* IGMP leave delay */ uint32_t avg_leave_delay; /* IGMP leave delay */ diff --git a/code/bngblaster/src/bbl_tx.c b/code/bngblaster/src/bbl_tx.c index 38279977..9e8f2a51 100644 --- a/code/bngblaster/src/bbl_tx.c +++ b/code/bngblaster/src/bbl_tx.c @@ -414,7 +414,12 @@ bbl_encode_packet_igmp(bbl_session_s *session) session->send_requests &= ~BBL_SEND_IGMP; return IGNORED; } - timer_add(&ctx->timer_root, &session->timer_igmp, "IGMP", 1, 0, session, &bbl_igmp_timeout); + + timer_add(&ctx->timer_root, &session->timer_igmp, "IGMP", + (ctx->config.igmp_robustness_interval / 1000), + (ctx->config.igmp_robustness_interval % 1000) * MSEC, + session, &bbl_igmp_timeout); + session->stats.igmp_tx++; interface->stats.igmp_tx++; return encode_ethernet(session->write_buf, &session->write_idx, ð);