Ejemplo n.º 1
0
// 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
}
Ejemplo n.º 2
0
// 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
}