Browse code

dispatcher: safety to avoid division by 0 for latency operations

(cherry picked from commit cf105d5af78963759825f5eaf9feb767c047a49c)

Daniel-Constantin Mierla authored on 29/04/2021 12:47:36
Showing 1 changed files
... ...
@@ -2733,7 +2733,8 @@ int ds_mark_dst(struct sip_msg *msg, int state)
2733 2733
 	return (ret == 0) ? 1 : -1;
2734 2734
 }
2735 2735
 
2736
-void latency_stats_init(ds_latency_stats_t *latency_stats, int latency, int count) {
2736
+void latency_stats_init(ds_latency_stats_t *latency_stats, int latency, int count)
2737
+{
2737 2738
 	latency_stats->stdev = 0.0f;
2738 2739
 	latency_stats->m2 = 0.0f;
2739 2740
 	latency_stats->max = latency;
... ...
@@ -2743,14 +2744,17 @@ void latency_stats_init(ds_latency_stats_t *latency_stats, int latency, int coun
2743 2744
 	latency_stats->count = count;
2744 2745
 }
2745 2746
 
2746
-static inline void latency_stats_update(ds_latency_stats_t *latency_stats, int latency) {
2747
+#define _VOR1(v) ((v)?(v):1)
2748
+
2749
+static inline void latency_stats_update(ds_latency_stats_t *latency_stats, int latency)
2750
+{
2747 2751
 	int training_count = 10000;
2748 2752
 
2749 2753
 	/* after 2^21 ~24 days at 1s interval, the average becomes a weighted average */
2750 2754
 	if (latency_stats->count < 2097152) {
2751 2755
 		latency_stats->count++;
2752 2756
 	} else { /* We adjust the sum of squares used by the oneline algorithm proportionally */
2753
-		latency_stats->m2 -= latency_stats->m2/latency_stats->count;
2757
+		latency_stats->m2 -= latency_stats->m2/_VOR1(latency_stats->count);
2754 2758
 	}
2755 2759
 
2756 2760
 	if (latency_stats->count == 1)
... ...
@@ -2771,10 +2775,10 @@ static inline void latency_stats_update(ds_latency_stats_t *latency_stats, int l
2771 2775
 		float delta;
2772 2776
 		float delta2;
2773 2777
 		delta = latency - latency_stats->average;
2774
-		latency_stats->average += delta/latency_stats->count;
2778
+		latency_stats->average += delta/_VOR1(latency_stats->count);
2775 2779
 		delta2 = latency - latency_stats->average;
2776 2780
 		latency_stats->m2 += ((double)delta)*delta2;
2777
-		latency_stats->stdev = sqrt(latency_stats->m2 / (latency_stats->count-1));
2781
+		latency_stats->stdev = sqrt(latency_stats->m2 / _VOR1(latency_stats->count-1));
2778 2782
 	}
2779 2783
 	/* exponentialy weighted moving average */
2780 2784
 	if (latency_stats->count < 10) {
... ...
@@ -2793,7 +2797,8 @@ typedef struct congestion_control_state {
2793 2797
 	int apply_rweights;
2794 2798
 } congestion_control_state_t;
2795 2799
 
2796
-int ds_update_weighted_congestion_control(congestion_control_state_t *cc, int weight, ds_latency_stats_t *latency_stats)
2800
+int ds_update_weighted_congestion_control(congestion_control_state_t *cc,
2801
+		int weight, ds_latency_stats_t *latency_stats)
2797 2802
 {
2798 2803
 	int active_weight = 0;
2799 2804
 	int congestion_ms = latency_stats->estimate - latency_stats->average;
... ...
@@ -2894,7 +2899,7 @@ int ds_update_latency(int group, str *address, int code)
2894 2899
 			ds_latency_stats_t *latency_stats = &ds_dest->latency_stats;
2895 2900
 			congestion_ms = latency_stats->estimate - latency_stats->average;
2896 2901
 			/* We multiply by 2^4 to keep enough precision */
2897
-			active_weight = (cc.total_congestion_ms << 4) / congestion_ms;
2902
+			active_weight = (cc.total_congestion_ms << 4) / _VOR1(congestion_ms);
2898 2903
 			if (ds_dest->attrs.rweight != active_weight) {
2899 2904
 				cc.apply_rweights = 1;
2900 2905
 				ds_dest->attrs.rweight = active_weight;