| |
| # Usage: calc_metric <source> <target> <wait-time> [<metric_offset>] |
| calc_metric() { |
| local metric_offset=${4:-0} |
| local output_file="/tmp/cost.$2" |
| local ping_result avg_delay packet_loss_rate |
| |
| # Send a probe every 2 seconds |
| if ! ping_result="`ping.bsd -nq -s $PING_PAYLOAD_SIZE -t $3 -i 2 -S \"$1\" -- \"$2\"`"; then |
| # Node is down... |
| rm -f "$output_file" |
| echo 65535 > "$output_file" |
| return |
| fi |
| |
| # 从ping结果中提取平均延迟和丢包率 |
| avg_delay="`printf %s \"$ping_result\" | sed -En 's#^(round-trip|rtt) min/avg/max/(stddev|mdev) = [0-9.]+/([0-9.]+)(/[0-9.]+|/nan){2} ms\$#\\3#p'`" |
| if |
| if [ -n "$avg_delay" ]; then |
| packet_loss_rate="`printf %s \"$ping_result\" | sed -En 's/.+ ([0-9.]+)% packet loss(\$|,.+)/\\1/p'`" |
| if [ -n "$packet_loss_rate" ]; then |
| false |
| elif printf %s "$ping_result" | grep -Eq -- "-- somebody.+ packets!"; then |
| packet_loss_rate=0 |
| false |
| fi |
| fi |
| then |
| printf 'Failed to parse ping.bsd(8) output:\n%s\n' "$ping_result" 1>&2 |
| rm -f "$output_file" |
| echo 65535 > "$output_file" |
| return |
| fi |
| |
| # 设置参数值 |
| |
| # gamma 调整丢包率的影响,使之成为一个非线性的因素。具体来说,它决定了 |
| # 丢包率被提升到 delta 次方后的影响强度。通过调整 gamma 可以控制丢包率 |
| # 在整体度量值中的相对权重,从而在某种程度上模拟丢包对网络性能的实际影 |
| # 响。 |
| local gamma=0.2 |
| |
| # delta 是丢包率影响的非线性调节器。将丢包率提升到 delta 次方可以让我 |
| # 们模拟丢包率增加对网络性能影响的加速或减速效应。例如,一个较高的 |
| # delta 值意味着随着丢包率的增加delta 量值的贡献将超线性增长, |
| # 反映了在丢包率较高时对性能的更大影响。 |
| local delta=3 |
| |
| # theta 直接乘丢包率,代表了丢包本身对延迟的直接加成影响。这反映了每个 |
| # 百分比的丢包对总延迟的直接贡献,模拟了由于丢包导致的重传等待时间。 |
| # 通过调整 theta, 我们可以控制丢包率对度量值的线性贡献, |
| # 以此来模拟重传对延迟的影响。 |
| local theta=10 |
| |
| # 以毫秒为单位的延迟阈值,该值以内视为等效。 |
| local fine_grain_delay_step=40 |
| |
| rm -f "$output_file" |
| printf %s\\n \ |
| "metric = $avg_delay + $gamma * ($packet_loss_rate ^ $delta) + $theta * $packet_loss_rate" \ |
| "scale = 0" \ |
| "metric = metric / 1 + 1 - (metric % 1 == 0)" \ |
| "metric = metric / $fine_grain_delay_step + 1" \ |
| "metric = metric + $metric_offset" \ |
| "if(metric > 65535) metric = 65535" \ |
| "if(metric <= 0) metric = 1" \ |
| "metric" \ |
| | bc > "$output_file" |
| } |