// receiver calls OnRead every time a packet is received // OnRead returns true, if the roundtrip estimate has changed func (t *receiverRoundtripEstimator) OnRead(ff *dccp.FeedforwardHeader) bool { // Read RoundtripReportOption // Currently RoundtripReportOption is allowed on any packet type var report *RoundtripReportOption for _, opt := range ff.Options { if report = DecodeRoundtripReportOption(opt); report != nil { break } } if report == nil { t.amb.E(dccp.EventWarn, "Missing roundtrip report opt", ff) return false } // Sanity checks rtt := dccp.NanoFromTenMicro(report.Roundtrip) if rtt <= 0 || rtt > 30e9 { t.amb.E(dccp.EventWarn, "Invalid roundtrip report opt", ff) return false } // Update RTT estimate t.rtt, t.rttTime = rtt, ff.Time t.amb.E(dccp.EventMatch, fmt.Sprintf("Report —> RTT=%s", dccp.Nstoa(t.rtt)), ff, RoundtripSample(RoundtripReportSample, t.rtt), RoundtripReportCheckpoint) return true }
// Sender calls OnRead for every arriving Ack packet. // OnRead returns true if the RTT estimate has changed. func (t *senderRoundtripEstimator) OnRead(fb *dccp.FeedbackHeader) bool { // Read ElapsedTimeOption if fb.Type != dccp.Ack && fb.Type != dccp.DataAck { return false } var elapsed *dccp.ElapsedTimeOption for _, opt := range fb.Options { if elapsed = dccp.DecodeElapsedTimeOption(opt); elapsed != nil { break } } if elapsed == nil { t.amb.E(dccp.EventWarn, "Missing elapsed opt", fb) return false } // Update RTT estimate s := t.find(fb.AckNo) if s == nil { return false } elapsedNS := dccp.NanoFromTenMicro(elapsed.Elapsed) // Elapsed time at receiver in nanoseconds if elapsedNS < 0 { t.amb.E(dccp.EventWarn, "Invalid elapsed opt", fb) return false } est := (fb.Time - s.Time - elapsedNS) if est <= 0 { t.amb.E(dccp.EventWarn, "Invalid elapsed opt", fb) return false } est_old := t.estimate if est_old == 0 { t.estimate = est } else { t.estimate = (est*SenderRoundtripWeightNew + est_old*SenderRoundtripWeightOld) / (SenderRoundtripWeightNew + SenderRoundtripWeightOld) } t.amb.E(dccp.EventMatch, fmt.Sprintf("Elapsed —> RTT=%s", dccp.Nstoa(t.estimate)), fb, RoundtripSample(RoundtripElapsedSample, t.estimate), RoundtripElapsedCheckpoint) return true }