Ton

Форк
0
/
SenderPackets.cpp 
144 строки · 3.6 Кб
1
/*
2
    This file is part of TON Blockchain Library.
3

4
    TON Blockchain Library is free software: you can redistribute it and/or modify
5
    it under the terms of the GNU Lesser General Public License as published by
6
    the Free Software Foundation, either version 2 of the License, or
7
    (at your option) any later version.
8

9
    TON Blockchain Library is distributed in the hope that it will be useful,
10
    but WITHOUT ANY WARRANTY; without even the implied warranty of
11
    MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
12
    GNU Lesser General Public License for more details.
13

14
    You should have received a copy of the GNU Lesser General Public License
15
    along with TON Blockchain Library.  If not, see <http://www.gnu.org/licenses/>.
16

17
    Copyright 2017-2020 Telegram Systems LLP
18
*/
19

20
#include "SenderPackets.h"
21

22
#include "td/utils/bits.h"
23

24
namespace ton {
25
namespace rldp2 {
26
td::uint32 SenderPackets::next_seqno() const {
27
  return last_seqno_ + 1;
28
}
29

30
SenderPackets::DropUpdate SenderPackets::drop_packets(const Limits &limits) {
31
  while (!packets.empty()) {
32
    auto &packet = packets.front();
33
    if (!limits.should_drop(packet)) {
34
      break;
35
    }
36
    mark_ack_or_lost(packet);
37
    packets.pop();
38
  }
39
  DropUpdate update;
40
  update.new_ack = total_ack_ - last_total_ack_;
41
  update.new_lost = total_lost_ - last_total_lost_;
42
  last_total_ack_ = total_ack_;
43
  last_total_lost_ = total_lost_;
44
  update.o_loss_at = std::move(last_loss_);
45
  return update;
46
}
47

48
SenderPackets::Update SenderPackets::on_ack(Ack ack) {
49
  ack.max_seqno = td::min(ack.max_seqno, last_seqno_);
50
  ack.received_count = td::min(ack.received_count, ack.max_seqno);
51

52
  // TODO: seqno of rldp and seqno of a packet must be completly separate seqnos
53
  Update update;
54
  if (received_count_ < ack.received_count) {
55
    update.new_received = ack.received_count - received_count_;
56
    left_ack_ += update.new_received;
57
    left_ack_ = td::min(left_ack_, in_flight_count_);
58
    received_count_ = ack.received_count;
59
  }
60

61
  if (max_packet_.seqno > ack.max_seqno) {
62
    return update;
63
  }
64

65
  auto packet = get_packet(ack.max_seqno);
66
  if (!packet) {
67
    return update;
68
  }
69

70
  if (max_packet_.seqno < ack.max_seqno) {
71
    update.was_max_updated = true;
72
    max_packet_ = *packet;
73
  }
74

75
  for (td::uint32 i : td::BitsRange(ack.received_mask)) {
76
    if (ack.max_seqno < i) {
77
      break;
78
    }
79
    auto seqno = ack.max_seqno - i;
80
    auto packet = get_packet(seqno);
81
    if (!packet) {
82
      break;
83
    }
84
    mark_ack(*packet);
85
  }
86

87
  return update;
88
}
89
void SenderPackets::mark_ack_or_lost(Packet &packet) {
90
  if (left_ack_) {
91
    mark_ack(packet);
92
  } else {
93
    mark_lost(packet);
94
  }
95
}
96

97
void SenderPackets::mark_lost(Packet &packet) {
98
  if (!packet.is_in_flight) {
99
    return;
100
  }
101
  total_lost_++;
102
  in_flight_count_--;
103
  packet.is_in_flight = false;
104
  last_loss_ = packet.sent_at;
105
}
106

107
void SenderPackets::mark_ack(Packet &packet) {
108
  if (!packet.is_in_flight) {
109
    return;
110
  }
111
  if (left_ack_ > 0) {
112
    left_ack_--;
113
  }
114
  total_ack_++;
115
  in_flight_count_--;
116
  packet.is_in_flight = false;
117
}
118

119
SenderPackets::Packet *SenderPackets::get_packet(td::uint32 seqno) {
120
  if (packets.empty()) {
121
    return nullptr;
122
  }
123
  auto front_seqno = packets.front().seqno;
124
  if (front_seqno > seqno) {
125
    return nullptr;
126
  }
127
  td::uint32 index = seqno - front_seqno;
128
  if (index >= packets.size()) {
129
    return nullptr;
130
  }
131
  auto packet = packets.data() + index;
132
  CHECK(packet->seqno == seqno);
133
  return packet;
134
}
135

136
void SenderPackets::send(Packet packet) {
137
  CHECK(next_seqno() == packet.seqno);
138
  packets.push(packet);
139
  last_seqno_++;
140
  in_flight_count_ += packet.is_in_flight;
141
}
142

143
}  // namespace rldp2
144
}  // namespace ton
145

Использование cookies

Мы используем файлы cookie в соответствии с Политикой конфиденциальности и Политикой использования cookies.

Нажимая кнопку «Принимаю», Вы даете АО «СберТех» согласие на обработку Ваших персональных данных в целях совершенствования нашего веб-сайта и Сервиса GitVerse, а также повышения удобства их использования.

Запретить использование cookies Вы можете самостоятельно в настройках Вашего браузера.