1use alloc::vec::Vec;
16use core::net::{IpAddr, SocketAddr};
17
18use stun_proto::agent::{StunAgent, Transmit};
19use stun_proto::types::data::Data;
20use stun_proto::Instant;
21
22use stun_proto::types::TransportType;
23
24use turn_types::channel::ChannelData;
25use turn_types::stun::message::Message;
26
27use tracing::{trace, warn};
28
29use crate::api::{
30 DataRangeOrOwned, DelayedMessageOrChannelSend, Socket5Tuple, TcpAllocateError, TcpConnectError,
31 TransmitBuild, TurnClientApi, TurnConfig, TurnPeerData,
32};
33use crate::protocol::{TurnClientProtocol, TurnProtocolChannelRecv};
34
35pub use crate::api::{
36 BindChannelError, CreatePermissionError, DeleteError, SendError, TurnEvent, TurnPollRet,
37 TurnRecvRet,
38};
39
40#[derive(Debug)]
42pub struct TurnClientUdp {
43 protocol: TurnClientProtocol,
44}
45
46impl TurnClientUdp {
47 #[tracing::instrument(
70 name = "turn_client_allocate"
71 skip(config),
72 fields(allocation_transport = %config.allocation_transport(),)
73 )]
74 pub fn allocate(local_addr: SocketAddr, remote_addr: SocketAddr, config: TurnConfig) -> Self {
75 let stun_agent = StunAgent::builder(TransportType::Udp, local_addr)
76 .remote_addr(remote_addr)
77 .build();
78 if config.allocation_transport() != TransportType::Udp {
79 panic!("Attempt made to create a UDP TURN client without a UDP allocation");
80 }
81
82 Self {
83 protocol: TurnClientProtocol::new(stun_agent, config),
84 }
85 }
86}
87
88impl TurnClientApi for TurnClientUdp {
89 fn transport(&self) -> TransportType {
90 self.protocol.transport()
91 }
92
93 fn local_addr(&self) -> SocketAddr {
94 self.protocol.local_addr()
95 }
96
97 fn remote_addr(&self) -> SocketAddr {
98 self.protocol.remote_addr()
99 }
100
101 fn poll(&mut self, now: Instant) -> TurnPollRet {
102 self.protocol.poll(now)
103 }
104
105 fn relayed_addresses(&self) -> impl Iterator<Item = (TransportType, SocketAddr)> + '_ {
106 self.protocol.relayed_addresses()
107 }
108
109 fn permissions(
110 &self,
111 transport: TransportType,
112 relayed: SocketAddr,
113 ) -> impl Iterator<Item = IpAddr> + '_ {
114 self.protocol.permissions(transport, relayed)
115 }
116
117 fn poll_transmit(&mut self, now: Instant) -> Option<Transmit<Data<'static>>> {
118 self.protocol.poll_transmit(now)
119 }
120
121 fn poll_event(&mut self) -> Option<TurnEvent> {
122 self.protocol.poll_event()
123 }
124
125 fn delete(&mut self, now: Instant) -> Result<(), DeleteError> {
126 self.protocol.delete(now)
127 }
128
129 fn create_permission(
130 &mut self,
131 transport: TransportType,
132 peer_addr: IpAddr,
133 now: Instant,
134 ) -> Result<(), CreatePermissionError> {
135 self.protocol.create_permission(transport, peer_addr, now)
136 }
137
138 fn have_permission(&self, transport: TransportType, to: IpAddr) -> bool {
139 self.protocol.have_permission(transport, to)
140 }
141
142 fn bind_channel(
143 &mut self,
144 transport: TransportType,
145 peer_addr: SocketAddr,
146 now: Instant,
147 ) -> Result<(), BindChannelError> {
148 self.protocol.bind_channel(transport, peer_addr, now)
149 }
150
151 fn tcp_connect(&mut self, peer_addr: SocketAddr, now: Instant) -> Result<(), TcpConnectError> {
152 self.protocol.tcp_connect(peer_addr, now)
153 }
154
155 fn allocated_tcp_socket(
156 &mut self,
157 id: u32,
158 five_tuple: Socket5Tuple,
159 peer_addr: SocketAddr,
160 local_addr: Option<SocketAddr>,
161 now: Instant,
162 ) -> Result<(), TcpAllocateError> {
163 self.protocol
164 .allocated_tcp_socket(id, five_tuple, peer_addr, local_addr, now)
165 }
166
167 fn tcp_closed(&mut self, local_addr: SocketAddr, remote_addr: SocketAddr, now: Instant) {
168 self.protocol.tcp_closed(local_addr, remote_addr, now)
169 }
170
171 fn send_to<T: AsRef<[u8]> + core::fmt::Debug>(
172 &mut self,
173 transport: TransportType,
174 to: SocketAddr,
175 data: T,
176 now: Instant,
177 ) -> Result<Option<TransmitBuild<DelayedMessageOrChannelSend<T>>>, SendError> {
178 self.protocol.send_to(transport, to, data, now).map(Some)
179 }
180
181 fn recv<T: AsRef<[u8]> + core::fmt::Debug>(
182 &mut self,
183 transmit: Transmit<T>,
184 now: Instant,
185 ) -> TurnRecvRet<T> {
186 if transmit.to != self.local_addr()
188 || self.transport() != transmit.transport
189 || transmit.from != self.remote_addr()
190 {
191 trace!(
192 "received data not directed at us ({:?}) but for {:?}!",
193 self.local_addr(),
194 transmit.to
195 );
196 return TurnRecvRet::Ignored(transmit);
197 }
198
199 let data = transmit.data.as_ref();
200 let Ok(msg) = Message::from_bytes(data) else {
201 let Ok(channel) = ChannelData::parse(data) else {
202 return TurnRecvRet::Ignored(transmit);
203 };
204 let ret = self.protocol.handle_channel(channel, now);
205 match ret {
206 TurnProtocolChannelRecv::Ignored => return TurnRecvRet::Ignored(transmit),
207 TurnProtocolChannelRecv::PeerData {
208 range,
209 transport,
210 peer,
211 } => {
212 return TurnRecvRet::PeerData(TurnPeerData {
213 data: DataRangeOrOwned::Range {
214 data: transmit.data,
215 range,
216 },
217 transport,
218 peer,
219 })
220 }
221 }
222 };
223
224 let msg_transmit = Transmit::new(msg, transmit.transport, transmit.from, transmit.to);
225 TurnRecvRet::from_protocol_recv(self.protocol.handle_message(msg_transmit, now), transmit)
226 }
227
228 fn poll_recv(&mut self, _now: Instant) -> Option<TurnPeerData<Vec<u8>>> {
229 None
230 }
231
232 fn protocol_error(&mut self) {
233 self.protocol.protocol_error()
234 }
235}