atmos/kernel/net/
reassembly.rs1extern crate alloc;
19
20use alloc::vec::Vec;
21
22pub const MAX_SEGMENTS: usize = 16;
25
26pub const MAX_BYTES: usize = 64 * 1024;
28
29#[derive(Debug, PartialEq, Eq, Clone, Copy)]
31pub enum InsertOutcome {
32 Stored,
34 Duplicate,
36 Dropped,
38}
39
40#[derive(Debug, PartialEq, Eq, Clone, Copy)]
42pub enum ReassemblyError {
43 EmptyPayload,
45}
46
47#[derive(Debug, Default)]
49pub struct Reassembler {
50 segs: Vec<(u32, Vec<u8>)>,
52 bytes: usize,
53}
54
55impl Reassembler {
56 pub fn new() -> Self {
57 Self::default()
58 }
59
60 pub const fn new_const() -> Self {
62 Self {
63 segs: Vec::new(),
64 bytes: 0,
65 }
66 }
67
68 pub fn len(&self) -> usize {
70 self.segs.len()
71 }
72
73 pub fn is_empty(&self) -> bool {
74 self.segs.is_empty()
75 }
76
77 pub fn bytes(&self) -> usize {
79 self.bytes
80 }
81
82 pub fn insert(&mut self, seq: u32, data: &[u8]) -> Result<InsertOutcome, ReassemblyError> {
87 if data.is_empty() {
88 crate::error!("[TCP][REASM] 空ペイロードは保持できません seq={}", seq);
89 return Err(ReassemblyError::EmptyPayload);
90 }
91 if self.segs.iter().any(|(s, _)| *s == seq) {
92 return Ok(InsertOutcome::Duplicate);
93 }
94 if self.segs.len() >= MAX_SEGMENTS || self.bytes + data.len() > MAX_BYTES {
95 return Ok(InsertOutcome::Dropped);
96 }
97 let pos = self
99 .segs
100 .iter()
101 .position(|(s, _)| *s > seq)
102 .unwrap_or(self.segs.len());
103 self.segs.insert(pos, (seq, data.to_vec()));
104 self.bytes += data.len();
105 Ok(InsertOutcome::Stored)
106 }
107
108 pub fn pop_contiguous(&mut self, rcv_nxt: u32) -> (u32, Vec<u8>) {
113 let mut next = rcv_nxt;
114 let mut out: Vec<u8> = Vec::new();
115 loop {
116 let best = self
122 .segs
123 .iter()
124 .enumerate()
125 .filter_map(|(i, (s, d))| {
126 let off = next.wrapping_sub(*s);
127 (off < 0x8000_0000 && (off as usize) < d.len())
129 .then(|| (i, off as usize, d.len() - off as usize))
130 })
131 .max_by_key(|&(_, _, rest)| rest);
132 let Some((idx, off, _)) = best else {
133 break;
134 };
135 let (_, data) = self.segs.remove(idx);
136 self.bytes -= data.len();
137 let tail = data.get(off..).unwrap_or(&[]);
138 next = next.wrapping_add(tail.len() as u32);
139 out.extend_from_slice(tail);
140 }
141 self.drop_before(next);
143 (next, out)
144 }
145
146 pub fn drop_before(&mut self, rcv_nxt: u32) -> usize {
149 let before = self.segs.len();
150 let mut freed = 0usize;
151 self.segs.retain(|(s, d)| {
152 let is_past = rcv_nxt.wrapping_sub(*s) < 0x8000_0000
154 && rcv_nxt.wrapping_sub(*s) >= d.len() as u32;
155 if is_past {
156 freed += d.len();
157 }
158 !is_past
159 });
160 self.bytes -= freed;
161 before - self.segs.len()
162 }
163
164 pub fn clear(&mut self) {
166 self.segs.clear();
167 self.bytes = 0;
168 }
169}