librats 2.3.3 → 2.3.4

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
@@ -0,0 +1,903 @@
1
+ #include "librats/bittorrent/utp_stream.h"
2
+
3
+ #include "librats/bittorrent/log.h"
4
+
5
+ #include <algorithm>
6
+ #include <cstdlib>
7
+ #include <cstring>
8
+ #include <limits>
9
+ #include <random>
10
+
11
+ namespace librats::bittorrent::utp {
12
+
13
+ namespace {
14
+
15
+ /// The wire carries a 32-bit microsecond clock. Its epoch is irrelevant — the peer
16
+ /// only ever subtracts two readings of *its own* clock from ours — so a steady
17
+ /// clock truncated to 32 bits is exactly right, and immune to the wall clock being
18
+ /// stepped underneath a live connection.
19
+ std::uint32_t micros(Stream::Clock::time_point t) noexcept {
20
+ using namespace std::chrono;
21
+ return std::uint32_t(duration_cast<microseconds>(t.time_since_epoch()).count() & 0xffffffffu);
22
+ }
23
+
24
+ std::uint16_t random_seq() {
25
+ static thread_local std::mt19937 rng{std::random_device{}()};
26
+ return std::uint16_t(std::uniform_int_distribution<std::uint32_t>(1, 0xfffe)(rng));
27
+ }
28
+
29
+ /// uTorrent has been observed sending an uninitialised INT_MAX here; treat it as
30
+ /// "no sample" rather than as 35 minutes of queuing delay.
31
+ constexpr std::uint32_t kBogusDelay = 0x7fffffffu;
32
+
33
+ constexpr std::uint32_t kNoRtt = (std::numeric_limits<std::uint32_t>::max)();
34
+
35
+ } // namespace
36
+
37
+ // ---- DelayHistory ------------------------------------------------------------
38
+
39
+ std::uint32_t DelayHistory::add_sample(std::uint32_t sample, bool step) {
40
+ if (!initialized()) {
41
+ for (auto& h : history_) h = sample;
42
+ base_ = sample;
43
+ num_samples_ = 0;
44
+ }
45
+ if (num_samples_ < 0xfffe) ++num_samples_;
46
+
47
+ // Wrapping compares throughout: the samples are 32-bit clock differences, so a
48
+ // sample taken either side of the clock's wrap must still order correctly.
49
+ if (seq_less_u32(sample, base_)) {
50
+ base_ = sample;
51
+ history_[index_] = sample;
52
+ } else if (seq_less_u32(sample, history_[index_])) {
53
+ history_[index_] = sample;
54
+ }
55
+
56
+ const std::uint32_t ret = sample - base_;
57
+
58
+ // Only step the ring when the connection has actually been busy. On an idle
59
+ // link a handful of samples say nothing about the path's true minimum, and
60
+ // stepping on them would throw away a good base for a bad one.
61
+ if (step && num_samples_ > 120) {
62
+ num_samples_ = 0;
63
+ index_ = std::uint16_t((index_ + 1) % kHistorySize);
64
+ history_[index_] = sample;
65
+ base_ = sample;
66
+ for (auto h : history_) {
67
+ if (seq_less_u32(h, base_)) base_ = h;
68
+ }
69
+ }
70
+ return ret;
71
+ }
72
+
73
+ void DelayHistory::adjust_base(int change) {
74
+ base_ += std::uint32_t(change);
75
+ // Make the adjustment stick: a history slot below the new base would pull it
76
+ // straight back down on the next step.
77
+ for (auto& h : history_) {
78
+ if (seq_less_u32(h, base_)) h = base_;
79
+ }
80
+ }
81
+
82
+ // ---- SlidingAverage ----------------------------------------------------------
83
+
84
+ void SlidingAverage::add_sample(int s) {
85
+ s *= 64; // fixed point
86
+ const int deviation = num_samples_ > 0 ? std::abs(mean_ - s) : 0;
87
+ if (num_samples_ < kInvertedGain) ++num_samples_;
88
+ mean_ += (s - mean_) / num_samples_;
89
+ // The deviation always has one sample fewer than the mean — you need two
90
+ // readings before the first deviation exists.
91
+ if (num_samples_ > 1) deviation_ += (deviation - deviation_) / (num_samples_ - 1);
92
+ }
93
+
94
+ // ---- Stream: construction & lifecycle ----------------------------------------
95
+
96
+ Stream::Stream(Host& host, std::uint16_t recv_id, std::uint16_t send_id)
97
+ : host_(host), recv_id_(recv_id), send_id_(send_id) {
98
+ // Start at one packet's worth of window, which is also LEDBAT's floor: the
99
+ // controller never takes cwnd below one MSS, so a stream can always make
100
+ // progress without waiting for a timeout.
101
+ cwnd_ = std::int64_t(kMaxPayload) << 16;
102
+ }
103
+
104
+ void Stream::connect(const Address& to, Clock::time_point now) {
105
+ remote_ = to;
106
+ last_history_step_ = now;
107
+ send_syn(now);
108
+ }
109
+
110
+ void Stream::send_syn(Clock::time_point now) {
111
+ seq_nr_ = random_seq();
112
+ acked_seq_nr_ = std::uint16_t(seq_nr_ - 1);
113
+ loss_seq_nr_ = acked_seq_nr_;
114
+ fast_resend_seq_nr_ = seq_nr_;
115
+ ack_nr_ = 0;
116
+
117
+ outbuf_.push_back(OutPacket{seq_nr_, PacketType::Syn, Bytes{}, {}, 0, false, false});
118
+ transmit(outbuf_.back(), now);
119
+ seq_nr_ = std::uint16_t(seq_nr_ + 1);
120
+
121
+ state_ = State::SynSent;
122
+ timeout_ = now + std::chrono::milliseconds(kConnectTimeoutMs);
123
+ }
124
+
125
+ void Stream::close(Clock::time_point now) {
126
+ if (out_eof_ || state_ == State::Closed) return;
127
+ out_eof_ = true;
128
+ closed_at_ = now;
129
+
130
+ if (state_ != State::Connected) {
131
+ // Never got far enough for a FIN to mean anything. A half-open dial is torn
132
+ // down silently; anything further along gets a reset so the peer stops
133
+ // retransmitting into a socket that no longer exists.
134
+ if (state_ == State::SynSent) send_reset_packet(now);
135
+ state_ = State::Closed;
136
+ return;
137
+ }
138
+
139
+ // The FIN is not queued here: it has to take the sequence number *after* the
140
+ // last byte, and whatever is still in pending_ has not been given one yet (they
141
+ // are assigned as packets go out, not as bytes arrive). Emitting it now would
142
+ // number it ahead of data the peer has yet to see, and that peer would then
143
+ // stop reading at the FIN and discard the rest. pump() releases it once the
144
+ // queue behind it has drained; out_eof_ also disables Nagle, so the tail packet
145
+ // no longer waits for anything.
146
+ pump(now);
147
+ }
148
+
149
+ void Stream::reset(Clock::time_point now) {
150
+ if (state_ == State::Closed) return;
151
+ if (state_ != State::Idle) send_reset_packet(now);
152
+ state_ = State::Closed;
153
+ out_eof_ = true;
154
+ closed_at_ = now;
155
+ }
156
+
157
+ bool Stream::reapable(Clock::time_point now) const noexcept {
158
+ if (state_ == State::Closed) return true;
159
+ if (!out_eof_) return false;
160
+ // Our FIN is out. Once it has been acknowledged and the peer's own FIN has
161
+ // arrived there is nothing left to say; otherwise linger briefly so a lost FIN
162
+ // still gets retransmitted rather than leaving the peer hanging.
163
+ if (outbuf_.empty() && in_eof_) return true;
164
+ return now - closed_at_ > kLinger;
165
+ }
166
+
167
+ void Stream::fail(const std::string& why) {
168
+ if (error_) return;
169
+ error_ = true;
170
+ state_ = State::Closed;
171
+ if (obs_) obs_->on_utp_error(why);
172
+ }
173
+
174
+ // ---- Stream: sending ---------------------------------------------------------
175
+
176
+ std::uint32_t Stream::advertised_window() const noexcept {
177
+ const std::size_t used = recv_bytes_ + inbuf_bytes_;
178
+ return used >= kRecvBufferCapacity ? 0u : std::uint32_t(kRecvBufferCapacity - used);
179
+ }
180
+
181
+ std::size_t Stream::window_available() const noexcept {
182
+ std::size_t win = (std::min)(std::size_t(cwnd_ >> 16), std::size_t(adv_wnd_));
183
+ // Zero-window persist: if the peer has closed its window and nothing is in
184
+ // flight, nothing would ever prompt it to tell us the window reopened — the
185
+ // update it sent could itself have been lost. Force one packet through so the
186
+ // conversation cannot stall permanently.
187
+ if (probe_) win = (std::max)(win, kMaxPayload);
188
+ return win > bytes_in_flight_ ? win - bytes_in_flight_ : 0;
189
+ }
190
+
191
+ std::size_t Stream::write_sack(std::uint8_t* out) const {
192
+ std::memset(out, 0, kSackBytes);
193
+ // Bit i names ack_nr_ + 2 + i: the packet after the hole at ack_nr_ + 1, which
194
+ // is by definition the one we are missing.
195
+ for (std::size_t i = 0; i < kSackBytes * 8; ++i) {
196
+ if (inbuf_.count(std::uint16_t(ack_nr_ + 2 + i)) != 0) {
197
+ out[i / 8] = std::uint8_t(out[i / 8] | (1u << (i % 8)));
198
+ }
199
+ }
200
+ return kSackBytes;
201
+ }
202
+
203
+ void Stream::emit(PacketType type, std::uint16_t seq, const std::uint8_t* payload,
204
+ std::size_t payload_len, Clock::time_point now, bool with_sack) {
205
+ Header h;
206
+ h.type = type;
207
+ // The one asymmetry in the protocol: a SYN goes out under the id its sender
208
+ // expects the *answer* on, everything after it under the peer's id.
209
+ h.connection_id = (type == PacketType::Syn) ? recv_id_ : send_id_;
210
+ h.timestamp = micros(now);
211
+ h.timestamp_diff = reply_micro_;
212
+ h.wnd_size = advertised_window();
213
+ h.seq_nr = seq;
214
+ h.ack_nr = ack_nr_;
215
+
216
+ const bool sack = with_sack && has_sack();
217
+ h.extension = sack ? std::uint8_t(ExtensionType::Sack) : 0;
218
+ write_header(scratch_, h);
219
+
220
+ std::size_t off = kHeaderSize;
221
+ if (sack) {
222
+ scratch_[off++] = 0; // no further extension
223
+ scratch_[off++] = std::uint8_t(kSackBytes); // record length
224
+ off += write_sack(scratch_ + off);
225
+ }
226
+ if (payload_len > 0) {
227
+ std::memcpy(scratch_ + off, payload, payload_len);
228
+ off += payload_len;
229
+ }
230
+ host_.utp_send(remote_, scratch_, off);
231
+ ++out_packets_;
232
+ }
233
+
234
+ void Stream::transmit(OutPacket& p, Clock::time_point now) {
235
+ p.send_time = now;
236
+ ++p.transmissions;
237
+ if (!p.in_flight) {
238
+ p.in_flight = true;
239
+ bytes_in_flight_ += p.payload.size();
240
+ }
241
+ emit(p.type, p.seq, p.payload.data(), p.payload.size(), now, /*with_sack=*/true);
242
+ }
243
+
244
+ void Stream::send_state(Clock::time_point now) {
245
+ // A pure acknowledgement consumes no sequence number, which is why seq_nr_ (the
246
+ // number of the packet we have *not* sent yet) is the right thing to put in it.
247
+ emit(PacketType::State, seq_nr_, nullptr, 0, now, /*with_sack=*/true);
248
+ deferred_ack_ = false;
249
+ }
250
+
251
+ void Stream::send_reset_packet(Clock::time_point now) {
252
+ emit(PacketType::Reset, random_seq(), nullptr, 0, now, /*with_sack=*/false);
253
+ }
254
+
255
+ void Stream::defer_ack() {
256
+ if (deferred_ack_) return;
257
+ deferred_ack_ = true;
258
+ host_.utp_defer_ack(*this);
259
+ }
260
+
261
+ void Stream::send_deferred_ack(Clock::time_point now) {
262
+ if (!deferred_ack_ || state_ == State::Closed || error_) { deferred_ack_ = false; return; }
263
+ send_state(now);
264
+ }
265
+
266
+ Stream::IoResult Stream::write(const ByteView* slices, std::size_t count,
267
+ Clock::time_point now) {
268
+ if (error_ || state_ == State::Closed) return {0, Status::Error};
269
+ if (out_eof_) return {0, Status::Error};
270
+
271
+ std::size_t taken = 0;
272
+ bool full = false;
273
+ for (std::size_t i = 0; i < count && !full; ++i) {
274
+ const std::uint8_t* p = slices[i].data();
275
+ std::size_t n = slices[i].size();
276
+ while (n > 0) {
277
+ const std::size_t queued = pending_bytes_ + bytes_in_flight_ + taken;
278
+ if (queued >= kSendHighWater) { full = true; break; }
279
+ const std::size_t room = kSendHighWater - queued;
280
+
281
+ // Grow the tail chunk up to a full packet before starting another. All
282
+ // but the last chunk are therefore full, which is what lets pump()
283
+ // decide "send now" from the front chunk's size alone.
284
+ if (pending_.empty() || pending_.back().size() >= kMaxPayload) {
285
+ pending_.emplace_back();
286
+ pending_.back().reserve(kMaxPayload);
287
+ }
288
+ Bytes& tail = pending_.back();
289
+ const std::size_t take = (std::min)((std::min)(kMaxPayload - tail.size(), n), room);
290
+ tail.insert(tail.end(), p, p + take);
291
+ p += take;
292
+ n -= take;
293
+ taken += take;
294
+ }
295
+ }
296
+
297
+ pending_bytes_ += taken;
298
+ pump(now);
299
+
300
+ if (taken == 0) {
301
+ write_blocked_ = true;
302
+ return {0, Status::WouldBlock};
303
+ }
304
+ // A short write is still backpressure: remember it so the reopening of the
305
+ // window wakes the writer rather than leaving it waiting on nothing.
306
+ if (pending_bytes_ + bytes_in_flight_ >= kSendHighWater) write_blocked_ = true;
307
+ return {taken, Status::Ok};
308
+ }
309
+
310
+ void Stream::pump(Clock::time_point now) {
311
+ if (state_ != State::Connected && state_ != State::FinSent) return;
312
+
313
+ // Retransmissions first, in order. A timeout writes every outstanding packet off
314
+ // (clearing in_flight) and resets the window to one; this is what puts them back
315
+ // on the wire, one per ack as the window reopens. Sending only the oldest and
316
+ // waiting for the next timeout to reach the one behind it would crawl at one
317
+ // packet per RTO — a stall in everything but name on a path that loses anything.
318
+ for (auto& p : outbuf_) {
319
+ if (p.acked || p.in_flight) continue;
320
+ if (window_available() < p.payload.size()) return;
321
+ transmit(p, now);
322
+ }
323
+
324
+ while (!pending_.empty()) {
325
+ Bytes& front = pending_.front();
326
+ // Nagle: a part-full packet waits while anything is unacknowledged, so a
327
+ // burst of small messages leaves as one packet instead of one each. It is
328
+ // released the moment the link goes quiet — which, with an ack always on
329
+ // its way, is never longer than a round trip.
330
+ if (front.size() < kMaxPayload && bytes_in_flight_ > 0 && !out_eof_) break;
331
+ if (window_available() < front.size()) break;
332
+
333
+ outbuf_.push_back(OutPacket{seq_nr_, PacketType::Data, std::move(front), {}, 0, false, false});
334
+ pending_.pop_front();
335
+ pending_bytes_ -= outbuf_.back().payload.size();
336
+ seq_nr_ = std::uint16_t(seq_nr_ + 1);
337
+ transmit(outbuf_.back(), now);
338
+ }
339
+
340
+ // Everything the caller wrote is now numbered and on the wire, so the FIN can
341
+ // take the next sequence number and genuinely mean "that was the last byte".
342
+ // It carries no payload, so no window has to have room for it.
343
+ if (out_eof_ && pending_.empty() && state_ == State::Connected) {
344
+ outbuf_.push_back(OutPacket{seq_nr_, PacketType::Fin, Bytes{}, {}, 0, false, false});
345
+ transmit(outbuf_.back(), now);
346
+ seq_nr_ = std::uint16_t(seq_nr_ + 1);
347
+ state_ = State::FinSent;
348
+ timeout_ = now + std::chrono::milliseconds(packet_timeout());
349
+ }
350
+ }
351
+
352
+ // ---- Stream: receiving -------------------------------------------------------
353
+
354
+ Stream::IoResult Stream::read(ByteSpan into) {
355
+ std::size_t copied = 0;
356
+ while (copied < into.size() && !recv_q_.empty()) {
357
+ Bytes& front = recv_q_.front();
358
+ const std::size_t avail = front.size() - recv_head_;
359
+ const std::size_t take = (std::min)(avail, into.size() - copied);
360
+ std::memcpy(into.data() + copied, front.data() + recv_head_, take);
361
+ copied += take;
362
+ recv_head_ += take;
363
+ recv_bytes_ -= take;
364
+ if (recv_head_ == front.size()) {
365
+ recv_q_.pop_front();
366
+ recv_head_ = 0;
367
+ }
368
+ }
369
+ if (copied > 0) return {copied, Status::Ok};
370
+ if (error_) return {0, Status::Error};
371
+ // Only report end-of-stream once everything before the FIN has been delivered:
372
+ // a FIN that overtook a retransmission must not truncate the stream.
373
+ if (in_eof_ && recv_q_.empty() && ack_nr_ == in_eof_seq_nr_) return {0, Status::Eof};
374
+ return {0, Status::WouldBlock};
375
+ }
376
+
377
+ void Stream::deliver(const std::uint8_t* data, std::size_t len) {
378
+ if (len == 0) return;
379
+ recv_q_.emplace_back(data, data + len);
380
+ recv_bytes_ += len;
381
+ }
382
+
383
+ void Stream::consume_data(const Header& h, const std::uint8_t* payload, std::size_t len) {
384
+ if (h.type != PacketType::Data) return;
385
+ if (in_eof_ && ack_nr_ == in_eof_seq_nr_) return; // everything is already in
386
+
387
+ // A peer that ignores the window we advertised gets its packets dropped rather
388
+ // than being allowed to grow our buffers without bound.
389
+ if (recv_bytes_ + inbuf_bytes_ + len > kRecvBufferCapacity) return;
390
+
391
+ if (h.seq_nr == std::uint16_t(ack_nr_ + 1)) {
392
+ deliver(payload, len);
393
+ ack_nr_ = h.seq_nr;
394
+ // The packet that arrived may have been the hole everything else was
395
+ // queued behind, so drain the reorder buffer as far as it now reaches.
396
+ for (;;) {
397
+ auto it = inbuf_.find(std::uint16_t(ack_nr_ + 1));
398
+ if (it == inbuf_.end()) break;
399
+ inbuf_bytes_ -= it->second.size();
400
+ deliver(it->second.data(), it->second.size());
401
+ ack_nr_ = std::uint16_t(ack_nr_ + 1);
402
+ inbuf_.erase(it);
403
+ }
404
+ } else {
405
+ if (!seq_less(ack_nr_, h.seq_nr)) return; // already delivered
406
+ if (len == 0) return;
407
+ if (inbuf_.count(h.seq_nr) != 0) return; // already buffered
408
+ inbuf_.emplace(h.seq_nr, Bytes(payload, payload + len));
409
+ inbuf_bytes_ += len;
410
+ }
411
+ }
412
+
413
+ // ---- Stream: acknowledgement -------------------------------------------------
414
+
415
+ Stream::OutPacket* Stream::packet_at(std::uint16_t seq) {
416
+ if (outbuf_.empty()) return nullptr;
417
+ const int idx = seq_diff(seq, outbuf_.front().seq);
418
+ if (idx < 0 || std::size_t(idx) >= outbuf_.size()) return nullptr;
419
+ return &outbuf_[std::size_t(idx)];
420
+ }
421
+
422
+ void Stream::ack_packet(OutPacket& p, Clock::time_point now, std::uint32_t& min_rtt) {
423
+ p.acked = true;
424
+ if (p.in_flight) {
425
+ bytes_in_flight_ -= p.payload.size();
426
+ p.in_flight = false;
427
+ }
428
+ // Karn's algorithm: a retransmitted packet gives an ambiguous sample (we cannot
429
+ // tell which copy was acknowledged), so it contributes nothing to the estimate.
430
+ if (p.transmissions == 1) {
431
+ using namespace std::chrono;
432
+ auto us = duration_cast<microseconds>(now - p.send_time).count();
433
+ if (us < 0) us = 0;
434
+ min_rtt = (std::min)(min_rtt, std::uint32_t(us));
435
+ rtt_.add_sample(int(us / 1000));
436
+ }
437
+ }
438
+
439
+ void Stream::pop_acked_front() {
440
+ while (!outbuf_.empty() && outbuf_.front().acked) {
441
+ acked_seq_nr_ = outbuf_.front().seq;
442
+ outbuf_.pop_front();
443
+ }
444
+ }
445
+
446
+ void Stream::process_ack(std::uint16_t ack_nr, Clock::time_point now,
447
+ int& acked_bytes, std::uint32_t& min_rtt) {
448
+ for (std::uint16_t s = std::uint16_t(acked_seq_nr_ + 1);; s = std::uint16_t(s + 1)) {
449
+ if (fast_resend_seq_nr_ == s) fast_resend_seq_nr_ = std::uint16_t(s + 1);
450
+ if (OutPacket* p = packet_at(s); p != nullptr && !p->acked) {
451
+ acked_bytes += int(p->payload.size());
452
+ ack_packet(*p, now, min_rtt);
453
+ }
454
+ if (s == ack_nr) break;
455
+ }
456
+ pop_acked_front();
457
+ if (outbuf_.empty()) duplicate_acks_ = 0;
458
+ }
459
+
460
+ void Stream::process_sack(std::uint16_t packet_ack, const std::uint8_t* bitmap, std::size_t len,
461
+ Clock::time_point now, int& acked_bytes, std::uint32_t& min_rtt) {
462
+ if (len == 0) return;
463
+
464
+ // At most five candidates: past that the loss is severe enough that the
465
+ // retransmit timer is the right recovery mechanism, not fast resend.
466
+ std::uint16_t to_resend[5];
467
+ int num_to_resend = 0;
468
+
469
+ // The packet at packet_ack + 1 is the hole the SACK exists to describe.
470
+ if (!seq_less(std::uint16_t(packet_ack + 1), fast_resend_seq_nr_)) {
471
+ to_resend[num_to_resend++] = std::uint16_t(packet_ack + 1);
472
+ }
473
+
474
+ std::uint16_t ack = std::uint16_t(packet_ack + 2);
475
+ bool done = false;
476
+ for (std::size_t i = 0; i < len && !done; ++i) {
477
+ const std::uint8_t bits = bitmap[i];
478
+ for (int b = 0; b < 8; ++b) {
479
+ if (bits & (1u << b)) {
480
+ if (OutPacket* p = packet_at(ack); p != nullptr && !p->acked) {
481
+ acked_bytes += int(p->payload.size());
482
+ ack_packet(*p, now, min_rtt);
483
+ }
484
+ } else if (!seq_less(ack, fast_resend_seq_nr_) && num_to_resend < 5) {
485
+ to_resend[num_to_resend++] = ack;
486
+ }
487
+ ack = std::uint16_t(ack + 1);
488
+ // Bits past the last packet we sent describe nothing.
489
+ if (ack == seq_nr_) { done = true; break; }
490
+ }
491
+ }
492
+
493
+ pop_acked_front();
494
+ if (outbuf_.empty()) duplicate_acks_ = 0;
495
+
496
+ // Scan back from the end of the bitmap counting acknowledged packets: only a
497
+ // hole with more than kDupAckLimit acked packets *behind* it is loss rather
498
+ // than reordering, and only holes before that point may be resent.
499
+ std::uint16_t last_resend = std::uint16_t(packet_ack + 1 + len * 8);
500
+ int dups = 0;
501
+ for (std::size_t i = len; i > 0; --i) {
502
+ const std::uint8_t bits = bitmap[i - 1];
503
+ std::uint8_t mask = 0x80;
504
+ for (int k = 0; k < 8; ++k) {
505
+ if (mask & bits) ++dups;
506
+ if (dups > kDupAckLimit) break;
507
+ last_resend = std::uint16_t(last_resend - 1);
508
+ mask >>= 1;
509
+ }
510
+ if (dups > kDupAckLimit) break;
511
+ }
512
+ if (dups <= kDupAckLimit) num_to_resend = 0;
513
+ while (num_to_resend > 0 && !seq_less(to_resend[num_to_resend - 1], last_resend)) --num_to_resend;
514
+
515
+ bool cut_cwnd = true;
516
+ for (int i = 0; i < num_to_resend; ++i) {
517
+ OutPacket* p = packet_at(to_resend[i]);
518
+ if (p == nullptr || p->acked) continue;
519
+ // One window cut per loss event, not per lost packet.
520
+ if (cut_cwnd) {
521
+ experienced_loss(to_resend[i], now);
522
+ cut_cwnd = false;
523
+ }
524
+ resend(*p, now, /*fast=*/true);
525
+ duplicate_acks_ = 0;
526
+ fast_resend_seq_nr_ = std::uint16_t(to_resend[i] + 1);
527
+ }
528
+ }
529
+
530
+ void Stream::resend(OutPacket& p, Clock::time_point now, bool fast) {
531
+ (void)fast;
532
+ if (p.acked) return;
533
+ // A retransmission is not new data in flight; it replaces what was already
534
+ // counted, so the accounting only changes when the packet had been written off
535
+ // by a timeout (which clears in_flight).
536
+ transmit(p, now);
537
+ }
538
+
539
+ // ---- Stream: congestion control ----------------------------------------------
540
+
541
+ void Stream::experienced_loss(std::uint16_t seq, Clock::time_point now) {
542
+ // Loss arrives in bursts, and a burst inside one round trip is one event. Two
543
+ // guards enforce that: only a packet sent *after* the last cut can cause the
544
+ // next one, and no two cuts happen inside kCwndReduceTimerMs.
545
+ if (seq_less(seq, std::uint16_t(loss_seq_nr_ + 1))) return;
546
+ if (next_loss_ >= now) return;
547
+ next_loss_ = now + std::chrono::milliseconds(kCwndReduceTimerMs);
548
+
549
+ cwnd_ = (std::max)(cwnd_ * kLossMultiplier / 100, std::int64_t(kMaxPayload) << 16);
550
+ loss_seq_nr_ = seq_nr_;
551
+
552
+ if (slow_start_) {
553
+ // Set the threshold to the window *after* the cut, so the next slow start
554
+ // stops before overshooting into the same loss again.
555
+ ssthresh_ = std::int32_t(cwnd_ >> 16);
556
+ slow_start_ = false;
557
+ }
558
+ }
559
+
560
+ void Stream::do_ledbat(int acked_bytes, int delay, int in_flight) {
561
+ if (in_flight <= 0 || acked_bytes <= 0) return;
562
+
563
+ const int target_delay = (std::max)(1, kTargetDelayUs);
564
+
565
+ // Only steer the window when the application is actually trying to fill it.
566
+ // Growing an idle connection's window would let it burst at an unproven rate
567
+ // the moment it has something to send.
568
+ const bool cwnd_saturated =
569
+ (std::int64_t(bytes_in_flight_) + acked_bytes + std::int64_t(kMaxPayload)) > (cwnd_ >> 16);
570
+
571
+ // Both fixed point, 16 fractional bits. window_factor scales the update by the
572
+ // share of the window this ack covers, so the formula applies once per RTT
573
+ // however many acks that RTT is split into.
574
+ const std::int64_t window_factor = (std::int64_t(acked_bytes) * (1 << 16)) / in_flight;
575
+ const std::int64_t delay_factor = (std::int64_t(target_delay - delay) * (1 << 16)) / target_delay;
576
+ std::int64_t scaled_gain;
577
+
578
+ if (delay >= target_delay && slow_start_) {
579
+ // We have found the path's queuing point; stop doubling.
580
+ ssthresh_ = std::int32_t((cwnd_ >> 16) / 2);
581
+ slow_start_ = false;
582
+ }
583
+
584
+ const std::int64_t linear_gain = ((window_factor * delay_factor) >> 16) * std::int64_t(kGainFactor);
585
+
586
+ if (cwnd_saturated) {
587
+ const std::int64_t exponential_gain = std::int64_t(acked_bytes) * (1 << 16);
588
+ if (slow_start_) {
589
+ if (ssthresh_ != 0 && ((cwnd_ + exponential_gain) >> 16) > ssthresh_) {
590
+ // Doubling would take us past the threshold we already learned the
591
+ // hard way; walk in linearly from here instead.
592
+ slow_start_ = false;
593
+ scaled_gain = linear_gain;
594
+ } else {
595
+ scaled_gain = (std::max)(exponential_gain, linear_gain);
596
+ }
597
+ } else {
598
+ scaled_gain = linear_gain;
599
+ }
600
+ } else {
601
+ scaled_gain = 0;
602
+ }
603
+
604
+ if (scaled_gain >= (std::numeric_limits<std::int64_t>::max)() - cwnd_) {
605
+ scaled_gain = (std::numeric_limits<std::int64_t>::max)() - cwnd_ - 1;
606
+ }
607
+
608
+ // RFC 6817 floors the window at one MSS. BEP 29 allows it to reach zero, but
609
+ // then only a timeout can restart the flow — a full second of silence to
610
+ // recover from a delay spike that has probably already passed.
611
+ if ((cwnd_ + scaled_gain) >> 16 < std::int64_t(kMaxPayload)) {
612
+ cwnd_ = std::int64_t(kMaxPayload) << 16;
613
+ } else {
614
+ cwnd_ += scaled_gain;
615
+ }
616
+
617
+ }
618
+
619
+ int Stream::packet_timeout() const {
620
+ // No RTT estimate exists before the handshake completes, so guess conservatively.
621
+ if (state_ == State::Idle || state_ == State::SynSent) return kConnectTimeoutMs;
622
+ if (num_timeouts_ >= 7) return 60000;
623
+ int timeout = (std::max)(kMinTimeoutMs, rtt_.mean() + rtt_.avg_deviation() * 2);
624
+ if (num_timeouts_ > 0) timeout += (1 << (num_timeouts_ - 1)) * 1000;
625
+ return (std::min)(timeout, 60000);
626
+ }
627
+
628
+ // ---- Stream: the incoming packet ---------------------------------------------
629
+
630
+ bool Stream::on_packet(const std::uint8_t* data, std::size_t len,
631
+ const Address& from, Clock::time_point now) {
632
+ if (state_ == State::Closed || error_) return false;
633
+
634
+ Header h;
635
+ if (!parse_header(data, len, h)) return false;
636
+ if (std::uint8_t(h.type) >= kNumPacketTypes) return false;
637
+ // A SYN names the id its sender will listen on, so it is the one packet whose
638
+ // connection_id is not ours.
639
+ if (h.type != PacketType::Syn && h.connection_id != recv_id_) return false;
640
+ if (state_ != State::Idle && h.type == PacketType::Syn) return true; // duplicate SYN
641
+
642
+ if (state_ == State::Idle && h.type == PacketType::Syn) remote_ = from;
643
+
644
+ const bool step = last_history_step_ == Clock::time_point{}
645
+ || now - last_history_step_ > std::chrono::minutes(1);
646
+ if (step) last_history_step_ = now;
647
+
648
+ // Measure how long their packet took to reach us. The absolute number is
649
+ // meaningless (unrelated clocks); what we do with it is reflect it back in
650
+ // every packet we send, which is what feeds *their* congestion control.
651
+ std::uint32_t their_delay = 0;
652
+ if (h.timestamp != 0) {
653
+ reply_micro_ = micros(now) - h.timestamp;
654
+ const std::uint32_t prev_base = their_delay_hist_.initialized() ? their_delay_hist_.base() : 0;
655
+ their_delay = their_delay_hist_.add_sample(reply_micro_, step);
656
+ const int base_change = int(their_delay_hist_.base() - prev_base);
657
+ // Their base delay fell: the two clocks are drifting apart rather than the
658
+ // path improving, so shift our own base by the same amount to compensate.
659
+ if (prev_base != 0 && base_change < 0 && base_change > -10000 && delay_hist_.initialized()) {
660
+ delay_hist_.adjust_base(-base_change);
661
+ }
662
+ }
663
+ (void)their_delay;
664
+
665
+ const bool state_or_fin = h.type == PacketType::State || h.type == PacketType::Fin;
666
+ // seq_nr_ is the number of the packet we have *not* sent yet, so the last one
667
+ // we did send is seq_nr_ - 1. An ack beyond it acknowledges something that does
668
+ // not exist — a third party's injection, or a confused peer. Drop it, but do
669
+ // not tear the connection down over it.
670
+ const std::uint16_t cmp_seq_nr = std::uint16_t(seq_nr_ - 1);
671
+ if ((state_ != State::Idle || h.type != PacketType::Syn)
672
+ && (seq_less(cmp_seq_nr, h.ack_nr)
673
+ || seq_less(h.ack_nr, std::uint16_t(acked_seq_nr_ - kDupAckLimit)))) {
674
+ return true;
675
+ }
676
+
677
+ // Anything claiming to come after a FIN we have already seen is bogus; a STATE
678
+ // or FIN carrying the FIN's own sequence number is the legitimate exception.
679
+ if (in_eof_ && seq_less(in_eof_seq_nr_, h.seq_nr)
680
+ && !(in_eof_seq_nr_ == h.seq_nr && state_or_fin)) {
681
+ return true;
682
+ }
683
+
684
+ // A reset is judged on its ack_nr alone. Its seq_nr is deliberately random (it
685
+ // ends a stream rather than carrying a place in one), so it has to be handled
686
+ // before the reordering window below would throw it away as impossibly far
687
+ // ahead. What keeps it from being a way to tear down any connection you can
688
+ // guess an id for is the ack: it must name something we really sent, which
689
+ // together with the source-address check is a window an off-path attacker
690
+ // cannot practically hit.
691
+ if (h.type == PacketType::Reset) {
692
+ if (seq_less(cmp_seq_nr, h.ack_nr)) return true; // not acking anything we sent
693
+ fail("connection reset by peer");
694
+ return true;
695
+ }
696
+
697
+ // Too far ahead to ever fit in the reorder buffer: either an attack or a
698
+ // connection so damaged that dropping this is the least of its problems.
699
+ const std::uint32_t max_reorder = (std::max)(std::uint32_t(16), std::uint32_t(kRecvBufferCapacity / 1100));
700
+ if (state_ != State::Idle && state_ != State::SynSent
701
+ && seq_less(std::uint16_t(ack_nr_ + max_reorder), h.seq_nr)) {
702
+ return true;
703
+ }
704
+
705
+ const std::uint32_t sample = h.timestamp_diff == kBogusDelay ? 0 : h.timestamp_diff;
706
+ std::uint32_t delay = 0;
707
+ if (sample != 0) {
708
+ delay = delay_hist_.add_sample(sample, step);
709
+ delay_samples_[delay_sample_idx_++] = delay;
710
+ if (delay_sample_idx_ >= kDelaySampleCount) delay_sample_idx_ = 0;
711
+ }
712
+
713
+ int acked_bytes = 0;
714
+ const std::size_t prev_in_flight = bytes_in_flight_;
715
+ adv_wnd_ = h.wnd_size;
716
+
717
+ // Only a STATE counts towards duplicate acks: a stream of DATA packets carries
718
+ // whatever ack number happens to be current, which says nothing about loss in
719
+ // the other direction.
720
+ if (h.ack_nr == acked_seq_nr_ && !outbuf_.empty() && h.type == PacketType::State) {
721
+ ++duplicate_acks_;
722
+ }
723
+
724
+ std::uint32_t min_rtt = kNoRtt;
725
+ if (state_ != State::Idle && seq_less(acked_seq_nr_, h.ack_nr)) {
726
+ process_ack(h.ack_nr, now, acked_bytes, min_rtt);
727
+ }
728
+
729
+ const std::size_t header_size = walk_extensions(data, len, h, [&](const Extension& e) {
730
+ if (e.type == ExtensionType::Sack) {
731
+ process_sack(h.ack_nr, e.data, e.len, now, acked_bytes, min_rtt);
732
+ }
733
+ // ExtensionType::CloseReason is deliberately ignored — see utp_stream.h.
734
+ });
735
+ if (header_size == 0) return true; // malformed extension chain
736
+
737
+ // A packet that made it this far is proof the peer is alive; reset the
738
+ // retransmit clock. Done after the acks, since they change packet_timeout().
739
+ num_timeouts_ = 0;
740
+ timeout_ = now + std::chrono::milliseconds(packet_timeout());
741
+
742
+ if (duplicate_acks_ >= kDupAckLimit
743
+ && std::uint16_t(acked_seq_nr_ + 1) == fast_resend_seq_nr_) {
744
+ OutPacket* p = packet_at(fast_resend_seq_nr_);
745
+ fast_resend_seq_nr_ = std::uint16_t(fast_resend_seq_nr_ + 1);
746
+ if (p != nullptr && !p->acked) {
747
+ experienced_loss(p->seq, now);
748
+ resend(*p, now, /*fast=*/true);
749
+ }
750
+ }
751
+
752
+ const std::uint8_t* payload = data + header_size;
753
+ const std::size_t payload_size = len - header_size;
754
+
755
+ if (h.type == PacketType::Fin) {
756
+ // A duplicate FIN still has to be acknowledged, or the peer keeps sending it.
757
+ if (h.seq_nr == std::uint16_t(ack_nr_ + 1) || h.seq_nr == ack_nr_) ack_nr_ = h.seq_nr;
758
+ if (!in_eof_) {
759
+ in_eof_ = true;
760
+ in_eof_seq_nr_ = h.seq_nr;
761
+ }
762
+ confirmed_ = true;
763
+ defer_ack();
764
+ if (obs_ != nullptr) obs_->on_utp_readable();
765
+ return true;
766
+ }
767
+
768
+ const std::uint32_t prev_out_packets = out_packets_;
769
+
770
+ switch (state_) {
771
+ case State::Idle: {
772
+ if (h.type != PacketType::Syn) break;
773
+ // The responder's half of the handshake. Our send id must be the id the
774
+ // SYN named, or the manager routed this to the wrong stream.
775
+ if (send_id_ != h.connection_id) return false;
776
+ state_ = State::Connected;
777
+ remote_ = from;
778
+ ack_nr_ = h.seq_nr;
779
+ seq_nr_ = random_seq();
780
+ acked_seq_nr_ = std::uint16_t(seq_nr_ - 1);
781
+ loss_seq_nr_ = acked_seq_nr_;
782
+ fast_resend_seq_nr_ = seq_nr_;
783
+ defer_ack();
784
+ break;
785
+ }
786
+ case State::SynSent: {
787
+ // Nothing but the answer to our SYN is interesting here.
788
+ if (h.ack_nr != std::uint16_t(seq_nr_ - 1)) break;
789
+ state_ = State::Connected;
790
+ // ack_nr_ is uninitialised until now; a STATE carries the sequence
791
+ // number it *will* use next, so step back one to keep it in order.
792
+ ack_nr_ = (h.type == PacketType::Data) ? h.seq_nr : std::uint16_t(h.seq_nr - 1);
793
+ confirmed_ = true;
794
+ timeout_ = now + std::chrono::milliseconds(packet_timeout());
795
+ if (obs_ != nullptr) obs_->on_utp_connected();
796
+ if (error_ || state_ == State::Closed) return true;
797
+ [[fallthrough]];
798
+ }
799
+ case State::Connected:
800
+ case State::FinSent: {
801
+ if (sample != 0 && acked_bytes > 0 && prev_in_flight > 0) {
802
+ // The lowest of the last three samples, clamped by the round-trip
803
+ // time: a one-way delay cannot exceed the round trip, and taking the
804
+ // minimum filters out the spikes a single scheduling hiccup causes.
805
+ delay = *std::min_element(std::begin(delay_samples_), std::end(delay_samples_));
806
+ if (delay > min_rtt) delay = min_rtt;
807
+ do_ledbat(acked_bytes, int(delay), int(prev_in_flight));
808
+ }
809
+
810
+ consume_data(h, payload, payload_size);
811
+ // Past every check, so the source address is not spoofed: whoever is
812
+ // there answered with sequence numbers only the real peer could know.
813
+ if (h.type != PacketType::Syn) confirmed_ = true;
814
+
815
+ pump(now);
816
+
817
+ // We owe an ack for anything that consumed a sequence number. If pump()
818
+ // put a packet on the wire it already carried one; otherwise defer it to
819
+ // the end of this receive burst so N packets cost one ack, not N.
820
+ if (payload_size > 0 && out_packets_ == prev_out_packets) defer_ack();
821
+ break;
822
+ }
823
+ case State::Closed:
824
+ break;
825
+ }
826
+
827
+ if (obs_ != nullptr && !error_) {
828
+ // Anything the reader could act on — bytes, or the end of the stream.
829
+ if (recv_bytes_ > 0 || (in_eof_ && ack_nr_ == in_eof_seq_nr_)) obs_->on_utp_readable();
830
+ if (write_blocked_ && pending_bytes_ + bytes_in_flight_ < kSendHighWater) {
831
+ write_blocked_ = false;
832
+ obs_->on_utp_writable();
833
+ }
834
+ }
835
+ return true;
836
+ }
837
+
838
+ // ---- Stream: the timer -------------------------------------------------------
839
+
840
+ void Stream::tick(Clock::time_point now) {
841
+ if (state_ == State::Closed || error_) return;
842
+ if (now < timeout_) return;
843
+
844
+ // Nothing in flight but data waiting: the peer's window is shut and the update
845
+ // reopening it may never come. Probe with one packet regardless — the classic
846
+ // TCP persist timer, and the only thing standing between us and a permanent stall.
847
+ if (outbuf_.empty() && !pending_.empty()) {
848
+ probe_ = true;
849
+ pump(now);
850
+ probe_ = false;
851
+ timeout_ = now + std::chrono::milliseconds(packet_timeout());
852
+ return;
853
+ }
854
+
855
+ if (!outbuf_.empty()) ++num_timeouts_;
856
+
857
+ const int max_resends = state_ == State::SynSent ? kSynResends
858
+ : out_eof_ ? kFinResends
859
+ : kNumResends;
860
+ // A peer we have never heard from fails on its first timeout: the address may
861
+ // simply be wrong, and there is no reason to spend three retransmissions on it.
862
+ if (num_timeouts_ > max_resends || (num_timeouts_ > 0 && !confirmed_)) {
863
+ if (state_ == State::FinSent) {
864
+ // Our close never got acknowledged. Nothing is owed to anyone here.
865
+ state_ = State::Closed;
866
+ return;
867
+ }
868
+ fail("connection timed out");
869
+ return;
870
+ }
871
+
872
+ if (!outbuf_.empty()) {
873
+ // Back to one packet. An idle connection only decays its window, since a
874
+ // timeout there says nothing about the path — we simply weren't using it.
875
+ if (bytes_in_flight_ == 0 && (cwnd_ >> 16) >= std::int64_t(kMaxPayload)) {
876
+ cwnd_ = (std::max)(cwnd_ * 2 / 3, std::int64_t(kMaxPayload) << 16);
877
+ } else {
878
+ cwnd_ = std::int64_t(kMaxPayload) << 16;
879
+ }
880
+ // Don't charge the window again for packets that just timed out together,
881
+ // and re-enter slow start: with an ssthresh now known, ramping back up is
882
+ // both fast and bounded.
883
+ loss_seq_nr_ = seq_nr_;
884
+ slow_start_ = true;
885
+
886
+ // Everything outstanding is written off. pump() then puts the oldest back on
887
+ // the wire immediately and the rest as acks reopen the window, rather than
888
+ // dumping the whole flight into a path that has just shown it cannot take it.
889
+ for (auto& p : outbuf_) {
890
+ if (p.in_flight) {
891
+ bytes_in_flight_ -= p.payload.size();
892
+ p.in_flight = false;
893
+ }
894
+ }
895
+ const OutPacket& oldest = outbuf_.front();
896
+ if (fast_resend_seq_nr_ == oldest.seq) fast_resend_seq_nr_ = std::uint16_t(oldest.seq + 1);
897
+ pump(now);
898
+ }
899
+
900
+ timeout_ = now + std::chrono::milliseconds(packet_timeout());
901
+ }
902
+
903
+ } // namespace librats::bittorrent::utp