1use crate::error::Result;
2use bytes::Bytes;
3use std::collections::HashMap;
4
5pub struct ExtensionProtocol {
7 extensions: HashMap<u8, ExtensionInfo>,
8 #[allow(dead_code)]
9 handshake: Option<Bytes>,
10}
11
12#[derive(Debug, Clone)]
13pub struct ExtensionInfo {
14 pub id: u8,
15 pub name: String,
16 pub metadata_size: Option<usize>,
17}
18
19pub struct UtMetadata {
21 metadata: Option<Bytes>,
22 metadata_size: Option<usize>,
23}
24
25impl UtMetadata {
26 pub fn new() -> Self {
27 Self {
28 metadata: None,
29 metadata_size: None,
30 }
31 }
32
33 pub fn set_metadata(&mut self, metadata: Bytes) {
34 let len = metadata.len();
35 self.metadata = Some(metadata);
36 self.metadata_size = Some(len);
37 }
38
39 pub fn get_metadata(&self) -> Option<&Bytes> {
40 self.metadata.as_ref()
41 }
42
43 pub fn fetch(&self) -> Result<()> {
44 Ok(())
46 }
47
48 pub fn handle_request(&self, piece: usize) -> Result<Option<Bytes>> {
49 if let Some(ref metadata) = self.metadata {
50 let piece_size = 16 * 1024; let start = piece * piece_size;
52 let end = (start + piece_size).min(metadata.len());
53 if start < metadata.len() {
54 return Ok(Some(metadata.slice(start..end)));
55 }
56 }
57 Ok(None)
58 }
59}
60
61pub struct UtPex {
63 added: Vec<(String, u16)>,
64 dropped: Vec<(String, u16)>,
65}
66
67impl UtPex {
68 pub fn new() -> Self {
69 Self {
70 added: Vec::new(),
71 dropped: Vec::new(),
72 }
73 }
74
75 pub fn add_peer(&mut self, ip: String, port: u16) {
76 self.added.push((ip, port));
77 }
78
79 pub fn drop_peer(&mut self, ip: String, port: u16) {
80 self.dropped.push((ip, port));
81 }
82
83 pub fn get_added(&self) -> &[(String, u16)] {
84 &self.added
85 }
86
87 pub fn get_dropped(&self) -> &[(String, u16)] {
88 &self.dropped
89 }
90
91 pub fn reset(&mut self) {
92 self.added.clear();
93 self.dropped.clear();
94 }
95
96 pub fn encode(&self) -> Bytes {
97 let mut buf = Vec::new();
99 for (ip, port) in &self.added {
100 if let Ok(ip_bytes) = ip.parse::<std::net::Ipv4Addr>() {
101 buf.extend_from_slice(&ip_bytes.octets());
102 buf.extend_from_slice(&port.to_be_bytes());
103 }
104 }
105 Bytes::from(buf)
106 }
107
108 pub fn decode(data: &[u8]) -> Result<Vec<(String, u16)>> {
109 let mut peers = Vec::new();
110 for chunk in data.chunks_exact(6) {
111 let ip = format!("{}.{}.{}.{}", chunk[0], chunk[1], chunk[2], chunk[3]);
112 let port = u16::from_be_bytes([chunk[4], chunk[5]]);
113 peers.push((ip, port));
114 }
115 Ok(peers)
116 }
117}
118
119impl ExtensionProtocol {
120 pub fn new() -> Self {
121 Self {
122 extensions: HashMap::new(),
123 handshake: None,
124 }
125 }
126
127 pub fn register_extension(&mut self, id: u8, name: String) {
128 self.extensions.insert(id, ExtensionInfo {
129 id,
130 name,
131 metadata_size: None,
132 });
133 }
134
135 pub fn get_extension_id(&self, name: &str) -> Option<u8> {
136 self.extensions.values()
137 .find(|ext| ext.name == name)
138 .map(|ext| ext.id)
139 }
140}
141