turn_server/service/routing.rs
1use std::{net::SocketAddr, sync::Arc};
2
3use bytes::BytesMut;
4
5use super::{
6 Service, ServiceHandler,
7 session::{Identifier, Session, SessionManager},
8};
9
10use crate::codec::{
11 DecodeResult, Decoder,
12 channel_data::ChannelData,
13 crypto::Password,
14 message::{
15 Message, MessageEncoder,
16 attributes::{error::ErrorType, *},
17 methods::*,
18 },
19};
20
21struct Request<'a, 'b, T, M>
22where
23 T: ServiceHandler,
24{
25 id: &'a Identifier,
26 encode_buffer: &'b mut BytesMut,
27 state: &'a State<T>,
28 payload: &'a M,
29}
30
31impl<'a, 'b, T> Request<'a, 'b, T, Message<'a>>
32where
33 T: ServiceHandler,
34{
35 // Verify the IP address specified by the client in the request, such as the
36 // peer address used when creating permissions and binding channels. Currently,
37 // only peer addresses that are local addresses of the TURN server are allowed;
38 // arbitrary addresses are not permitted.
39 //
40 // Allowing arbitrary addresses would pose security risks, such as enabling
41 // the TURN server to forward data to any target.
42 #[inline(always)]
43 fn verify_ip(&self, address: &SocketAddr) -> bool {
44 self.state
45 .interfaces
46 .iter()
47 .any(|item| item.ip() == address.ip())
48 }
49
50 // The key for the HMAC depends on whether long-term or short-term
51 // credentials are in use. For long-term credentials, the key is 16
52 // bytes:
53 //
54 // key = MD5(username ":" realm ":" SASLprep(password))
55 //
56 // That is, the 16-byte key is formed by taking the MD5 hash of the
57 // result of concatenating the following five fields: (1) the username,
58 // with any quotes and trailing nulls removed, as taken from the
59 // USERNAME attribute (in which case SASLprep has already been applied);
60 // (2) a single colon; (3) the realm, with any quotes and trailing nulls
61 // removed; (4) a single colon; and (5) the password, with any trailing
62 // nulls removed and after processing using SASLprep. For example, if
63 // the username was 'user', the realm was 'realm', and the password was
64 // 'pass', then the 16-byte HMAC key would be the result of performing
65 // an MD5 hash on the string 'user:realm:pass', the resulting hash being
66 // 0x8493fbc53ba582fb4c044c456bdc40eb.
67 //
68 // For short-term credentials:
69 //
70 // key = SASLprep(password)
71 //
72 // where MD5 is defined in RFC 1321 [RFC1321] and SASLprep() is defined
73 // in RFC 4013 [RFC4013].
74 //
75 // The structure of the key when used with long-term credentials
76 // facilitates deployment in systems that also utilize SIP. Typically,
77 // SIP systems utilizing SIP's digest authentication mechanism do not
78 // actually store the password in the database. Rather, they store a
79 // value called H(A1), which is equal to the key defined above.
80 //
81 // Based on the rules above, the hash used to construct MESSAGE-
82 // INTEGRITY includes the length field from the STUN message header.
83 // Prior to performing the hash, the MESSAGE-INTEGRITY attribute MUST be
84 // inserted into the message (with dummy content). The length MUST then
85 // be set to point to the length of the message up to, and including,
86 // the MESSAGE-INTEGRITY attribute itself, but excluding any attributes
87 // after it. Once the computation is performed, the value of the
88 // MESSAGE-INTEGRITY attribute can be filled in, and the value of the
89 // length in the STUN header can be set to its correct value -- the
90 // length of the entire message. Similarly, when validating the
91 // MESSAGE-INTEGRITY, the length field should be adjusted to point to
92 // the end of the MESSAGE-INTEGRITY attribute prior to calculating the
93 // HMAC. Such adjustment is necessary when attributes, such as
94 // FINGERPRINT, appear after MESSAGE-INTEGRITY.
95 #[inline(always)]
96 async fn verify(&self) -> Option<(&str, Password)> {
97 let username = self.payload.get::<UserName>()?;
98 let algorithm = self
99 .payload
100 .get::<PasswordAlgorithm>()
101 .unwrap_or(PasswordAlgorithm::Md5);
102
103 let password = self
104 .state
105 .manager
106 .get_password(self.id, username, algorithm)
107 .await?;
108
109 if self.payload.verify(&password).is_err() {
110 return None;
111 }
112
113 Some((username, password))
114 }
115}
116
117/// The target of the response.
118#[derive(Debug, Clone, Copy, Default)]
119pub struct Target {
120 pub endpoint: Option<SocketAddr>,
121 pub relay: Option<SocketAddr>,
122}
123
124/// The response.
125#[derive(Debug)]
126pub struct Response<'a> {
127 /// if the method is None, the response is a channel data response
128 pub method: Option<Method>,
129 /// the bytes of the response
130 pub bytes: &'a [u8],
131 /// the target of the response
132 pub target: Target,
133}
134
135pub(crate) struct State<T>
136where
137 T: ServiceHandler,
138{
139 pub realm: String,
140 pub software: String,
141 pub manager: Arc<SessionManager<T>>,
142 pub endpoint: SocketAddr,
143 pub interface: SocketAddr,
144 pub interfaces: Arc<Vec<SocketAddr>>,
145 pub handler: T,
146}
147
148pub struct Router<T>
149where
150 T: ServiceHandler,
151{
152 current_id: Identifier,
153 state: State<T>,
154 decoder: Decoder,
155 bytes: BytesMut,
156}
157
158impl<T> Router<T>
159where
160 T: ServiceHandler + Clone,
161{
162 pub fn new(service: &Service<T>, endpoint: SocketAddr, interface: SocketAddr) -> Self {
163 Self {
164 bytes: BytesMut::with_capacity(4096),
165 decoder: Decoder::default(),
166 current_id: Identifier {
167 source: "0.0.0.0:0".parse().unwrap(),
168 interface,
169 },
170 state: State {
171 interfaces: service.interfaces.clone(),
172 software: service.software.clone(),
173 handler: service.handler.clone(),
174 manager: service.manager.clone(),
175 realm: service.realm.clone(),
176 interface,
177 endpoint,
178 },
179 }
180 }
181
182 pub async fn route<'a, 'b: 'a>(
183 &'b mut self,
184 bytes: &'b [u8],
185 address: SocketAddr,
186 ) -> Result<Option<Response<'a>>, crate::codec::Error> {
187 {
188 self.current_id.source = address;
189 }
190
191 Ok(match self.decoder.decode(bytes)? {
192 DecodeResult::ChannelData(channel) => channel_data(
193 bytes,
194 Request {
195 id: &self.current_id,
196 state: &self.state,
197 encode_buffer: &mut self.bytes,
198 payload: &channel,
199 },
200 ),
201 DecodeResult::Message(message) => {
202 let req = Request {
203 id: &self.current_id,
204 state: &self.state,
205 encode_buffer: &mut self.bytes,
206 payload: &message,
207 };
208
209 match req.payload.method() {
210 BINDING_REQUEST => binding(req),
211 ALLOCATE_REQUEST => allocate(req).await,
212 CREATE_PERMISSION_REQUEST => create_permission(req).await,
213 CHANNEL_BIND_REQUEST => channel_bind(req).await,
214 REFRESH_REQUEST => refresh(req).await,
215 SEND_INDICATION => indication(req),
216 _ => None,
217 }
218 }
219 })
220 }
221}
222
223fn reject<'a, T>(req: Request<'_, 'a, T, Message<'_>>, error: ErrorType) -> Option<Response<'a>>
224where
225 T: ServiceHandler,
226{
227 let method = req.payload.method().error()?;
228
229 {
230 let mut message = MessageEncoder::extend(method, req.payload, req.encode_buffer);
231 message.append::<ErrorCode>(ErrorCode::from(error));
232
233 if error == ErrorType::Unauthorized {
234 message.append::<Realm>(&req.state.realm);
235 message.append::<Nonce>(
236 req.state
237 .manager
238 .get_session_or_default(req.id)
239 .get_ref()?
240 .nonce(),
241 );
242
243 message.append::<PasswordAlgorithms>(vec![
244 PasswordAlgorithm::Md5,
245 PasswordAlgorithm::Sha256,
246 ]);
247 }
248
249 message.flush(None).ok()?;
250 }
251
252 Some(Response {
253 target: Target::default(),
254 bytes: req.encode_buffer,
255 method: Some(method),
256 })
257}
258
259/// [rfc8489](https://tools.ietf.org/html/rfc8489)
260///
261/// In the Binding request/response transaction, a Binding request is
262/// sent from a STUN client to a STUN server. When the Binding request
263/// arrives at the STUN server, it may have passed through one or more
264/// NATs between the STUN client and the STUN server (in Figure 1, there
265/// are two such NATs). As the Binding request message passes through a
266/// NAT, the NAT will modify the source transport address (that is, the
267/// source IP address and the source port) of the packet. As a result,
268/// the source transport address of the request received by the server
269/// will be the public IP address and port created by the NAT closest to
270/// the server. This is called a "reflexive transport address". The
271/// STUN server copies that source transport address into an XOR-MAPPED-
272/// ADDRESS attribute in the STUN Binding response and sends the Binding
273/// response back to the STUN client. As this packet passes back through
274/// a NAT, the NAT will modify the destination transport address in the
275/// IP header, but the transport address in the XOR-MAPPED-ADDRESS
276/// attribute within the body of the STUN response will remain untouched.
277/// In this way, the client can learn its reflexive transport address
278/// allocated by the outermost NAT with respect to the STUN server.
279fn binding<'a, T>(req: Request<'_, 'a, T, Message<'_>>) -> Option<Response<'a>>
280where
281 T: ServiceHandler,
282{
283 {
284 let mut message = MessageEncoder::extend(BINDING_RESPONSE, req.payload, req.encode_buffer);
285 message.append::<XorMappedAddress>(req.id.source);
286 message.append::<MappedAddress>(req.id.source);
287 message.append::<ResponseOrigin>(req.state.interface);
288 message.append::<Software>(&req.state.software);
289 message.flush(None).ok()?;
290 }
291
292 Some(Response {
293 method: Some(BINDING_RESPONSE),
294 target: Target::default(),
295 bytes: req.encode_buffer,
296 })
297}
298
299/// [rfc8489](https://tools.ietf.org/html/rfc8489)
300///
301/// In all cases, the server SHOULD only allocate ports from the range
302/// 49152 - 65535 (the Dynamic and/or Private Port range [PORT-NUMBERS]),
303/// unless the TURN server application knows, through some means not
304/// specified here, that other applications running on the same host as
305/// the TURN server application will not be impacted by allocating ports
306/// outside this range. This condition can often be satisfied by running
307/// the TURN server application on a dedicated machine and/or by
308/// arranging that any other applications on the machine allocate ports
309/// before the TURN server application starts. In any case, the TURN
310/// server SHOULD NOT allocate ports in the range 0 - 1023 (the Well-
311/// Known Port range) to discourage clients from using TURN to run
312/// standard contexts.
313async fn allocate<'a, T>(req: Request<'_, 'a, T, Message<'_>>) -> Option<Response<'a>>
314where
315 T: ServiceHandler,
316{
317 if req.payload.get::<ReqeestedTransport>().is_none() {
318 return reject(req, ErrorType::ServerError);
319 }
320
321 let Some((username, password)) = req.verify().await else {
322 return reject(req, ErrorType::Unauthorized);
323 };
324
325 let lifetime = req.payload.get::<Lifetime>();
326
327 let Some(port) = req.state.manager.allocate(req.id, lifetime) else {
328 return reject(req, ErrorType::AllocationQuotaReached);
329 };
330
331 req.state.handler.on_allocated(req.id, username, port);
332
333 {
334 let mut message = MessageEncoder::extend(ALLOCATE_RESPONSE, req.payload, req.encode_buffer);
335 message.append::<XorRelayedAddress>(SocketAddr::new(req.state.interface.ip(), port));
336 message.append::<XorMappedAddress>(req.id.source);
337 message.append::<Lifetime>(lifetime.unwrap_or(600));
338 message.append::<Software>(&req.state.software);
339 message.flush(Some(&password)).ok()?;
340 }
341
342 Some(Response {
343 target: Target::default(),
344 method: Some(ALLOCATE_RESPONSE),
345 bytes: req.encode_buffer,
346 })
347}
348
349/// The server MAY impose restrictions on the IP address and port values
350/// allowed in the XOR-PEER-ADDRESS attribute; if a value is not allowed,
351/// the server rejects the request with a 403 (Forbidden) error.
352///
353/// If the request is valid, but the server is unable to fulfill the
354/// request due to some capacity limit or similar, the server replies
355/// with a 508 (Insufficient Capacity) error.
356///
357/// Otherwise, the server replies with a ChannelBind success response.
358/// There are no required attributes in a successful ChannelBind
359/// response.
360///
361/// If the server can satisfy the request, then the server creates or
362/// refreshes the channel binding using the channel number in the
363/// CHANNEL-NUMBER attribute and the transport address in the XOR-PEER-
364/// ADDRESS attribute. The server also installs or refreshes a
365/// permission for the IP address in the XOR-PEER-ADDRESS attribute as
366/// described in Section 9.
367///
368/// NOTE: A server need not do anything special to implement
369/// idempotency of ChannelBind requests over UDP using the
370/// "stateless stack approach". Retransmitted ChannelBind requests
371/// will simply refresh the channel binding and the corresponding
372/// permission. Furthermore, the client must wait 5 minutes before
373/// binding a previously bound channel number or peer address to a
374/// different channel, eliminating the possibility that the
375/// transaction would initially fail but succeed on a
376/// retransmission.
377async fn channel_bind<'a, T>(req: Request<'_, 'a, T, Message<'_>>) -> Option<Response<'a>>
378where
379 T: ServiceHandler,
380{
381 let Some(peer) = req.payload.get::<XorPeerAddress>() else {
382 return reject(req, ErrorType::BadRequest);
383 };
384
385 if !req.verify_ip(&peer) {
386 return reject(req, ErrorType::PeerAddressFamilyMismatch);
387 }
388
389 let Some(number) = req.payload.get::<ChannelNumber>() else {
390 return reject(req, ErrorType::BadRequest);
391 };
392
393 if !(0x4000..=0x7FFF).contains(&number) {
394 return reject(req, ErrorType::BadRequest);
395 }
396
397 let Some((username, password)) = req.verify().await else {
398 return reject(req, ErrorType::Unauthorized);
399 };
400
401 if !req
402 .state
403 .manager
404 .bind_channel(req.id, &req.state.endpoint, peer.port(), number)
405 {
406 return reject(req, ErrorType::Forbidden);
407 }
408
409 req.state.handler.on_channel_bind(req.id, username, number);
410
411 {
412 MessageEncoder::extend(CHANNEL_BIND_RESPONSE, req.payload, req.encode_buffer)
413 .flush(Some(&password))
414 .ok()?;
415 }
416
417 Some(Response {
418 target: Target::default(),
419 method: Some(CHANNEL_BIND_RESPONSE),
420 bytes: req.encode_buffer,
421 })
422}
423
424/// [rfc8489](https://tools.ietf.org/html/rfc8489)
425///
426/// When the server receives the CreatePermission request, it processes
427/// as per [Section 5](https://tools.ietf.org/html/rfc8656#section-5)
428/// plus the specific rules mentioned here.
429///
430/// The message is checked for validity. The CreatePermission request
431/// MUST contain at least one XOR-PEER-ADDRESS attribute and MAY contain
432/// multiple such attributes. If no such attribute exists, or if any of
433/// these attributes are invalid, then a 400 (Bad Request) error is
434/// returned. If the request is valid, but the server is unable to
435/// satisfy the request due to some capacity limit or similar, then a 508
436/// (Insufficient Capacity) error is returned.
437///
438/// If an XOR-PEER-ADDRESS attribute contains an address of an address
439/// family that is not the same as that of a relayed transport address
440/// for the allocation, the server MUST generate an error response with
441/// the 443 (Peer Address Family Mismatch) response code.
442///
443/// The server MAY impose restrictions on the IP address allowed in the
444/// XOR-PEER-ADDRESS attribute; if a value is not allowed, the server
445/// rejects the request with a 403 (Forbidden) error.
446///
447/// If the message is valid and the server is capable of carrying out the
448/// request, then the server installs or refreshes a permission for the
449/// IP address contained in each XOR-PEER-ADDRESS attribute as described
450/// in [Section 9](https://tools.ietf.org/html/rfc8656#section-9).
451/// The port portion of each attribute is ignored and may be any arbitrary
452/// value.
453///
454/// The server then responds with a CreatePermission success response.
455/// There are no mandatory attributes in the success response.
456///
457/// NOTE: A server need not do anything special to implement idempotency of
458/// CreatePermission requests over UDP using the "stateless stack approach".
459/// Retransmitted CreatePermission requests will simply refresh the
460/// permissions.
461async fn create_permission<'a, T>(req: Request<'_, 'a, T, Message<'_>>) -> Option<Response<'a>>
462where
463 T: ServiceHandler,
464{
465 let Some((username, password)) = req.verify().await else {
466 return reject(req, ErrorType::Unauthorized);
467 };
468
469 let mut ports = Vec::with_capacity(15);
470 for it in req.payload.get_all::<XorPeerAddress>() {
471 if !req.verify_ip(&it) {
472 return reject(req, ErrorType::PeerAddressFamilyMismatch);
473 }
474
475 ports.push(it.port());
476 }
477
478 if !req
479 .state
480 .manager
481 .create_permission(req.id, &req.state.endpoint, &ports)
482 {
483 return reject(req, ErrorType::Forbidden);
484 }
485
486 req.state
487 .handler
488 .on_create_permission(req.id, username, &ports);
489
490 {
491 MessageEncoder::extend(CREATE_PERMISSION_RESPONSE, req.payload, req.encode_buffer)
492 .flush(Some(&password))
493 .ok()?;
494 }
495
496 Some(Response {
497 method: Some(CREATE_PERMISSION_RESPONSE),
498 target: Target::default(),
499 bytes: req.encode_buffer,
500 })
501}
502
503/// When the server receives a Send indication, it processes as per
504/// [Section 5](https://tools.ietf.org/html/rfc8656#section-5) plus
505/// the specific rules mentioned here.
506///
507/// The message is first checked for validity. The Send indication MUST
508/// contain both an XOR-PEER-ADDRESS attribute and a DATA attribute. If
509/// one of these attributes is missing or invalid, then the message is
510/// discarded. Note that the DATA attribute is allowed to contain zero
511/// bytes of data.
512///
513/// The Send indication may also contain the DONT-FRAGMENT attribute. If
514/// the server is unable to set the DF bit on outgoing UDP datagrams when
515/// this attribute is present, then the server acts as if the DONT-
516/// FRAGMENT attribute is an unknown comprehension-required attribute
517/// (and thus the Send indication is discarded).
518///
519/// The server also checks that there is a permission installed for the
520/// IP address contained in the XOR-PEER-ADDRESS attribute. If no such
521/// permission exists, the message is discarded. Note that a Send
522/// indication never causes the server to refresh the permission.
523///
524/// The server MAY impose restrictions on the IP address and port values
525/// allowed in the XOR-PEER-ADDRESS attribute; if a value is not allowed,
526/// the server silently discards the Send indication.
527///
528/// If everything is OK, then the server forms a UDP datagram as follows:
529///
530/// * the source transport address is the relayed transport address of the
531/// allocation, where the allocation is determined by the 5-tuple on which the
532/// Send indication arrived;
533///
534/// * the destination transport address is taken from the XOR-PEER-ADDRESS
535/// attribute;
536///
537/// * the data following the UDP header is the contents of the value field of
538/// the DATA attribute.
539///
540/// The handling of the DONT-FRAGMENT attribute (if present), is
541/// described in Sections [14](https://tools.ietf.org/html/rfc8656#section-14)
542/// and [15](https://tools.ietf.org/html/rfc8656#section-15).
543///
544/// The resulting UDP datagram is then sent to the peer.
545#[rustfmt::skip]
546fn indication<'a, T>(req: Request<'_, 'a, T, Message<'_>>) -> Option<Response<'a>>
547where
548 T: ServiceHandler,
549{
550 let peer = req.payload.get::<XorPeerAddress>()?;
551 let data = req.payload.get::<Data>()?;
552
553 if let Some(Session::Authenticated { allocate_port, .. }) =
554 req.state.manager.get_session(req.id).get_ref() && let Some(local_port) = *allocate_port
555 {
556 let relay = req.state.manager.get_relay_address(req.id, peer.port())?;
557
558 {
559 let mut message = MessageEncoder::extend(DATA_INDICATION, req.payload, req.encode_buffer);
560 message.append::<XorPeerAddress>(SocketAddr::new(req.state.interface.ip(), local_port));
561 message.append::<Data>(data);
562 message.flush(None).ok()?;
563 }
564
565 return Some(Response {
566 method: Some(DATA_INDICATION),
567 bytes: req.encode_buffer,
568 target: Target {
569 relay: Some(relay.source),
570 endpoint: if req.state.endpoint != relay.endpoint {
571 Some(relay.endpoint)
572 } else {
573 None
574 },
575 },
576 });
577 }
578
579 None
580}
581
582/// If the server receives a Refresh Request with a REQUESTED-ADDRESS-
583/// FAMILY attribute and the attribute value does not match the address
584/// family of the allocation, the server MUST reply with a 443 (Peer
585/// Address Family Mismatch) Refresh error response.
586///
587/// The server computes a value called the "desired lifetime" as follows:
588/// if the request contains a LIFETIME attribute and the attribute value
589/// is zero, then the "desired lifetime" is zero. Otherwise, if the
590/// request contains a LIFETIME attribute, then the server computes the
591/// minimum of the client's requested lifetime and the server's maximum
592/// allowed lifetime. If this computed value is greater than the default
593/// lifetime, then the "desired lifetime" is the computed value.
594/// Otherwise, the "desired lifetime" is the default lifetime.
595///
596/// Subsequent processing depends on the "desired lifetime" value:
597///
598/// * If the "desired lifetime" is zero, then the request succeeds and the
599/// allocation is deleted.
600///
601/// * If the "desired lifetime" is non-zero, then the request succeeds and the
602/// allocation's time-to-expiry is set to the "desired lifetime".
603///
604/// If the request succeeds, then the server sends a success response
605/// containing:
606///
607/// * A LIFETIME attribute containing the current value of the time-to-expiry
608/// timer.
609///
610/// NOTE: A server need not do anything special to implement
611/// idempotency of Refresh requests over UDP using the "stateless
612/// stack approach". Retransmitted Refresh requests with a non-
613/// zero "desired lifetime" will simply refresh the allocation. A
614/// retransmitted Refresh request with a zero "desired lifetime"
615/// will cause a 437 (Allocation Mismatch) response if the
616/// allocation has already been deleted, but the client will treat
617/// this as equivalent to a success response (see below).
618async fn refresh<'a, T>(req: Request<'_, 'a, T, Message<'_>>) -> Option<Response<'a>>
619where
620 T: ServiceHandler,
621{
622 let Some((username, password)) = req.verify().await else {
623 return reject(req, ErrorType::Unauthorized);
624 };
625
626 let lifetime = req.payload.get::<Lifetime>().unwrap_or(600);
627 if !req.state.manager.refresh(req.id, lifetime) {
628 return reject(req, ErrorType::AllocationMismatch);
629 }
630
631 req.state.handler.on_refresh(req.id, username, lifetime);
632
633 {
634 let mut message = MessageEncoder::extend(REFRESH_RESPONSE, req.payload, req.encode_buffer);
635 message.append::<Lifetime>(lifetime);
636 message.flush(Some(&password)).ok()?;
637 }
638
639 Some(Response {
640 target: Target::default(),
641 method: Some(REFRESH_RESPONSE),
642 bytes: req.encode_buffer,
643 })
644}
645
646/// If the ChannelData message is received on a channel that is not bound
647/// to any peer, then the message is silently discarded.
648///
649/// On the client, it is RECOMMENDED that the client discard the
650/// ChannelData message if the client believes there is no active
651/// permission towards the peer. On the server, the receipt of a
652/// ChannelData message MUST NOT refresh either the channel binding or
653/// the permission towards the peer.
654///
655/// On the server, if no errors are detected, the server relays the
656/// application data to the peer by forming a UDP datagram as follows:
657///
658/// * the source transport address is the relayed transport address of the
659/// allocation, where the allocation is determined by the 5-tuple on which the
660/// ChannelData message arrived;
661///
662/// * the destination transport address is the transport address to which the
663/// channel is bound;
664///
665/// * the data following the UDP header is the contents of the data field of the
666/// ChannelData message.
667///
668/// The resulting UDP datagram is then sent to the peer. Note that if
669/// the Length field in the ChannelData message is 0, then there will be
670/// no data in the UDP datagram, but the UDP datagram is still formed and
671/// sent [(Section 4.1 of [RFC6263])](https://tools.ietf.org/html/rfc6263#section-4.1).
672fn channel_data<'a, T>(
673 bytes: &'a [u8],
674 req: Request<'_, 'a, T, ChannelData<'_>>,
675) -> Option<Response<'a>>
676where
677 T: ServiceHandler,
678{
679 let relay = req
680 .state
681 .manager
682 .get_channel_relay_address(req.id, req.payload.number())?;
683
684 Some(Response {
685 bytes,
686 target: Target {
687 relay: Some(relay.source),
688 endpoint: if req.state.endpoint != relay.endpoint {
689 Some(relay.endpoint)
690 } else {
691 None
692 },
693 },
694 method: None,
695 })
696}