Module: kamailio
Branch: master
Commit: cf105d5af78963759825f5eaf9feb767c047a49c
URL:
https://github.com/kamailio/kamailio/commit/cf105d5af78963759825f5eaf9feb76…
Author: Daniel-Constantin Mierla <miconda(a)gmail.com>
Committer: Daniel-Constantin Mierla <miconda(a)gmail.com>
Date: 2021-04-29T14:47:36+02:00
dispatcher: safety to avoid division by 0 for latency operations
---
Modified: src/modules/dispatcher/dispatch.c
---
Diff:
https://github.com/kamailio/kamailio/commit/cf105d5af78963759825f5eaf9feb76…
Patch:
https://github.com/kamailio/kamailio/commit/cf105d5af78963759825f5eaf9feb76…
---
diff --git a/src/modules/dispatcher/dispatch.c b/src/modules/dispatcher/dispatch.c
index 80944e4b05..78ece3fffe 100644
--- a/src/modules/dispatcher/dispatch.c
+++ b/src/modules/dispatcher/dispatch.c
@@ -2733,7 +2733,8 @@ int ds_mark_dst(struct sip_msg *msg, int state)
return (ret == 0) ? 1 : -1;
}
-void latency_stats_init(ds_latency_stats_t *latency_stats, int latency, int count) {
+void latency_stats_init(ds_latency_stats_t *latency_stats, int latency, int count)
+{
latency_stats->stdev = 0.0f;
latency_stats->m2 = 0.0f;
latency_stats->max = latency;
@@ -2743,14 +2744,17 @@ void latency_stats_init(ds_latency_stats_t *latency_stats, int
latency, int coun
latency_stats->count = count;
}
-static inline void latency_stats_update(ds_latency_stats_t *latency_stats, int latency)
{
+#define _VOR1(v) ((v)?(v):1)
+
+static inline void latency_stats_update(ds_latency_stats_t *latency_stats, int latency)
+{
int training_count = 10000;
/* after 2^21 ~24 days at 1s interval, the average becomes a weighted average */
if (latency_stats->count < 2097152) {
latency_stats->count++;
} else { /* We adjust the sum of squares used by the oneline algorithm proportionally
*/
- latency_stats->m2 -= latency_stats->m2/latency_stats->count;
+ latency_stats->m2 -= latency_stats->m2/_VOR1(latency_stats->count);
}
if (latency_stats->count == 1)
@@ -2771,10 +2775,10 @@ static inline void latency_stats_update(ds_latency_stats_t
*latency_stats, int l
float delta;
float delta2;
delta = latency - latency_stats->average;
- latency_stats->average += delta/latency_stats->count;
+ latency_stats->average += delta/_VOR1(latency_stats->count);
delta2 = latency - latency_stats->average;
latency_stats->m2 += ((double)delta)*delta2;
- latency_stats->stdev = sqrt(latency_stats->m2 / (latency_stats->count-1));
+ latency_stats->stdev = sqrt(latency_stats->m2 /
_VOR1(latency_stats->count-1));
}
/* exponentialy weighted moving average */
if (latency_stats->count < 10) {
@@ -2793,7 +2797,8 @@ typedef struct congestion_control_state {
int apply_rweights;
} congestion_control_state_t;
-int ds_update_weighted_congestion_control(congestion_control_state_t *cc, int weight,
ds_latency_stats_t *latency_stats)
+int ds_update_weighted_congestion_control(congestion_control_state_t *cc,
+ int weight, ds_latency_stats_t *latency_stats)
{
int active_weight = 0;
int congestion_ms = latency_stats->estimate - latency_stats->average;
@@ -2894,7 +2899,7 @@ int ds_update_latency(int group, str *address, int code)
ds_latency_stats_t *latency_stats = &ds_dest->latency_stats;
congestion_ms = latency_stats->estimate - latency_stats->average;
/* We multiply by 2^4 to keep enough precision */
- active_weight = (cc.total_congestion_ms << 4) / congestion_ms;
+ active_weight = (cc.total_congestion_ms << 4) / _VOR1(congestion_ms);
if (ds_dest->attrs.rweight != active_weight) {
cc.apply_rweights = 1;
ds_dest->attrs.rweight = active_weight;