1use core::convert::Infallible;
103use core::fmt::{self, Write};
104use core::future::Future;
105use core::num::NonZeroU16;
106use core::pin::Pin;
107use core::task::{Context, Poll};
108
109use alloc::boxed::Box;
110use alloc::collections::VecDeque;
111use alloc::string::String;
112use alloc::sync::Arc;
113use alloc::vec::Vec;
114
115use bytes::Bytes;
116use rand::prelude::*;
117use rand::rngs::SmallRng;
118use tokio::sync::Mutex;
119use tokio::task::JoinSet;
120use tokio::time::{Duration, Instant, Sleep};
121
122use crate::Buf;
123use crate::api::{
124 Broadcast, ChannelId, DecodeBody, EncodeBody, ErrorMessage, Event, Format, Id, MessageId,
125 RequestHeader, ResponseHeader,
126};
127use crate::buf::{BufPool, InvalidFrame};
128use crate::format;
129
130const MAX_CAPACITY: usize = 1048576;
131const CLOSE_NORMAL: u16 = 1000;
132const CLOSE_PROTOCOL_ERROR: u16 = 1002;
133const CLOSE_TIMEOUT: Duration = Duration::from_secs(30);
134const PING_TIMEOUT: Duration = Duration::from_secs(10);
135const DEFAULT_SEED: u64 = 0xdeadbeef;
136
137#[derive(Debug)]
139pub(crate) enum Message {
140 Text,
142 Binary(Bytes),
144 Ping(Bytes),
146 Pong(Bytes),
148 Close,
150}
151
152pub(crate) mod socket_sealed {
153 pub trait Sealed {}
154}
155
156pub(crate) trait SocketImpl
157where
158 Self: self::socket_sealed::Sealed,
159{
160 #[doc(hidden)]
161 type Message;
162
163 #[doc(hidden)]
164 type Error: fmt::Debug;
165
166 #[doc(hidden)]
167 fn poll_next(
168 self: Pin<&mut Self>,
169 ctx: &mut Context<'_>,
170 ) -> Poll<Option<Result<Message, Self::Error>>>;
171
172 #[doc(hidden)]
173 fn poll_ready(self: Pin<&mut Self>, cx: &mut Context<'_>) -> Poll<Result<(), Self::Error>>;
174
175 #[doc(hidden)]
176 fn start_send(self: Pin<&mut Self>, item: Self::Message) -> Result<(), Self::Error>;
177
178 #[doc(hidden)]
179 fn poll_flush(self: Pin<&mut Self>, cx: &mut Context<'_>) -> Poll<Result<(), Self::Error>>;
180}
181
182pub(crate) mod server_sealed {
183 pub trait Sealed {}
184}
185
186pub trait ServerImpl
192where
193 Self: self::server_sealed::Sealed,
194{
195 #[doc(hidden)]
196 type Error: fmt::Debug;
197
198 #[doc(hidden)]
199 type Message;
200
201 #[doc(hidden)]
202 #[allow(private_bounds)]
203 type Socket: SocketImpl<Message = Self::Message, Error = Self::Error>;
204
205 #[doc(hidden)]
206 fn ping(data: Bytes) -> Self::Message;
207
208 #[doc(hidden)]
209 fn pong(data: Bytes) -> Self::Message;
210
211 #[doc(hidden)]
212 fn binary(data: &[u8]) -> Self::Message;
213
214 #[doc(hidden)]
215 fn close(code: u16, reason: &str) -> Self::Message;
216}
217
218#[derive(Debug)]
219enum ErrorKind {
220 #[cfg(feature = "axum-core05")]
221 AxumCore05 {
222 error: axum_core05::Error,
223 },
224 FormatError,
225 InvalidFrame {
226 error: InvalidFrame,
227 },
228 Incoming {
229 error: format::Error,
230 },
231 Outgoing {
232 error: format::Error,
233 },
234 EncodeBroadcastHeader {
235 error: format::Error,
236 },
237 EncodeBroadcast {
238 error: format::Error,
239 },
240 EncodeConnectHeader {
241 error: format::Error,
242 },
243 ErrorMessageHeader {
244 error: format::Error,
245 },
246 ErrorMessage {
247 error: format::Error,
248 },
249 OutOfBounds {
250 offset: usize,
251 len: usize,
252 },
253 NotNegotiated,
255 ExpectedNegotiate {
257 id: u16,
258 },
259 NegotiateHeader {
261 error: format::Error,
262 },
263}
264
265#[derive(Debug)]
267pub struct Error {
268 kind: ErrorKind,
269}
270
271impl Error {
272 #[inline]
273 const fn new(kind: ErrorKind) -> Self {
274 Self { kind }
275 }
276
277 pub(crate) fn incoming(error: format::Error) -> Self {
278 Self::new(ErrorKind::Incoming { error })
279 }
280
281 pub(crate) fn outgoing(error: format::Error) -> Self {
282 Self::new(ErrorKind::Outgoing { error })
283 }
284
285 pub(crate) fn encode_broadcast_header(error: format::Error) -> Self {
286 Self::new(ErrorKind::EncodeBroadcastHeader { error })
287 }
288
289 pub(crate) fn encode_broadcast(error: format::Error) -> Self {
290 Self::new(ErrorKind::EncodeBroadcast { error })
291 }
292
293 pub(crate) fn encode_connect_header(error: format::Error) -> Self {
294 Self::new(ErrorKind::EncodeConnectHeader { error })
295 }
296
297 pub(crate) fn encode_error_message_header(error: format::Error) -> Self {
298 Self::new(ErrorKind::ErrorMessageHeader { error })
299 }
300
301 pub(crate) fn encode_error_message(error: format::Error) -> Self {
302 Self::new(ErrorKind::ErrorMessage { error })
303 }
304}
305
306impl fmt::Display for Error {
307 #[inline]
308 fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result {
309 match &self.kind {
310 #[cfg(feature = "axum-core05")]
311 ErrorKind::AxumCore05 { .. } => write!(f, "Error in axum-core"),
312 ErrorKind::FormatError => write!(f, "Error formatting error response"),
313 ErrorKind::InvalidFrame { error } => error.fmt(f),
314 ErrorKind::Incoming { .. } => {
315 write!(f, "Encoding error when decoding incoming message")
316 }
317 ErrorKind::Outgoing { .. } => {
318 write!(f, "Encoding error when encoding outgoing message")
319 }
320 ErrorKind::EncodeBroadcastHeader { .. } => {
321 write!(f, "Encoding error when encoding broadcast header")
322 }
323 ErrorKind::EncodeBroadcast { .. } => {
324 write!(f, "Encoding error when broadcasting message")
325 }
326 ErrorKind::EncodeConnectHeader { .. } => {
327 write!(f, "Encoding error when encoding connect header")
328 }
329 ErrorKind::ErrorMessageHeader { .. } => {
330 write!(f, "Encoding error when encoding error message header")
331 }
332 ErrorKind::ErrorMessage { .. } => {
333 write!(f, "Encoding error when encoding error message")
334 }
335 ErrorKind::OutOfBounds { offset, len } => {
336 write!(
337 f,
338 "Error when reading message: offset {} is out of bounds for length {}",
339 offset, len
340 )
341 }
342 ErrorKind::NotNegotiated => {
343 write!(f, "Connection closed before the format was negotiated")
344 }
345 ErrorKind::ExpectedNegotiate { id } => {
346 write!(
347 f,
348 "Expected a negotiation as the first message, but got message id {id}"
349 )
350 }
351 ErrorKind::NegotiateHeader { .. } => {
352 write!(f, "Encoding error when decoding negotiation header")
353 }
354 }
355 }
356}
357
358impl core::error::Error for Error {
359 #[inline]
360 fn source(&self) -> Option<&(dyn core::error::Error + 'static)> {
361 match &self.kind {
362 #[cfg(feature = "axum-core05")]
363 ErrorKind::AxumCore05 { error } => Some(error),
364 ErrorKind::Incoming { error } => Some(error),
365 ErrorKind::Outgoing { error } => Some(error),
366 ErrorKind::EncodeBroadcastHeader { error } => Some(error),
367 ErrorKind::EncodeBroadcast { error } => Some(error),
368 ErrorKind::EncodeConnectHeader { error } => Some(error),
369 ErrorKind::ErrorMessageHeader { error } => Some(error),
370 ErrorKind::ErrorMessage { error } => Some(error),
371 ErrorKind::NegotiateHeader { error } => Some(error),
372 _ => None,
373 }
374 }
375}
376
377#[cfg(feature = "axum-core05")]
378impl From<axum_core05::Error> for Error {
379 #[inline]
380 fn from(error: axum_core05::Error) -> Self {
381 Self::new(ErrorKind::AxumCore05 { error })
382 }
383}
384
385impl From<ErrorKind> for Error {
386 #[inline]
387 fn from(kind: ErrorKind) -> Self {
388 Self::new(kind)
389 }
390}
391
392impl From<InvalidFrame> for Error {
393 #[inline]
394 fn from(error: InvalidFrame) -> Self {
395 Self::new(ErrorKind::InvalidFrame { error })
396 }
397}
398
399type Result<T, E = Error> = core::result::Result<T, E>;
400
401pub struct Response {
403 handled: bool,
404}
405
406pub trait IntoResponse
408where
409 Self: 'static + Send,
410{
411 type Error: fmt::Display;
413
414 fn into_response(self) -> Result<Response, Self::Error>;
416}
417
418impl IntoResponse for () {
422 type Error = Infallible;
423
424 #[inline]
425 fn into_response(self) -> Result<Response, Self::Error> {
426 Ok(Response { handled: true })
427 }
428}
429
430impl IntoResponse for bool {
435 type Error = Infallible;
436
437 #[inline]
438 fn into_response(self) -> Result<Response, Self::Error> {
439 Ok(Response { handled: self })
440 }
441}
442
443impl<T, E> IntoResponse for Result<T, E>
451where
452 T: IntoResponse<Error = Infallible>,
453 E: 'static + Send + fmt::Display,
454{
455 type Error = E;
456
457 #[inline]
458 fn into_response(self) -> Result<Response, E> {
459 match self {
460 Ok(into_response) => match IntoResponse::into_response(into_response) {
461 Ok(response) => Ok(response),
462 Err(error) => match error {},
463 },
464 Err(error) => Err(error),
465 }
466 }
467}
468
469impl<T> IntoResponse for Option<T>
475where
476 T: IntoResponse,
477{
478 type Error = T::Error;
479
480 #[inline]
481 fn into_response(self) -> Result<Response, Self::Error> {
482 match self {
483 Some(value) => value.into_response(),
484 None => Ok(Response { handled: false }),
485 }
486 }
487}
488
489pub trait Handler
495where
496 Self: 'static + Send + Clone,
497{
498 type Id: Id;
500 type Response: IntoResponse;
502
503 fn open_channel<'this>(
514 &'this self,
515 channel: ChannelId,
516 ) -> impl Future<Output = ()> + Send + 'this {
517 async {
518 _ = channel;
519 }
520 }
521
522 fn close_channel<'this>(
530 &'this self,
531 channel: ChannelId,
532 ) -> impl Future<Output = ()> + Send + 'this {
533 async {
534 _ = channel;
535 }
536 }
537
538 fn handle<'this>(
540 &'this self,
541 id: Self::Id,
542 incoming: &'this mut Incoming<'_>,
543 outgoing: &'this mut Outgoing<'_>,
544 ) -> impl Future<Output = Self::Response> + Send + 'this;
545}
546
547struct Pinned<S> {
548 socket: S,
549 close_sleep: Sleep,
550 ping_sleep: Sleep,
551}
552
553impl<S> Pinned<S> {
554 #[inline]
555 fn project(self: Pin<&mut Self>) -> (Pin<&mut Sleep>, Pin<&mut Sleep>, Pin<&mut S>) {
556 unsafe {
557 let this = self.get_unchecked_mut();
558 (
559 Pin::new_unchecked(&mut this.close_sleep),
560 Pin::new_unchecked(&mut this.ping_sleep),
561 Pin::new_unchecked(&mut this.socket),
562 )
563 }
564 }
565}
566
567type HandlerOutput<H> = (Result<<H as Handler>::Response, Error>, RequestHeader, Buf);
568
569pub trait ChannelAllocator {
576 fn next(&self) -> impl Future<Output = Option<ChannelId>> + Send + '_;
584
585 fn free(&self, channel: ChannelId) -> impl Future<Output = ()> + Send + '_;
587}
588
589pub struct Connect<S, H, C = Channels>
734where
735 S: ServerImpl,
736 H: Handler,
737{
738 handler: H,
739 socket: S::Socket,
740 channels: C,
741 seed: u64,
742 max_capacity: usize,
743 formats: Option<&'static [Format]>,
746}
747
748impl<S, H> Connect<S, H, Channels>
749where
750 S: ServerImpl,
751 H: Handler,
752{
753 #[inline]
755 pub(crate) fn new(socket: S::Socket, handler: H) -> Self {
756 Self {
757 handler,
758 socket,
759 channels: Channels::default(),
760 seed: DEFAULT_SEED,
761 max_capacity: MAX_CAPACITY,
762 formats: None,
763 }
764 }
765}
766
767impl<S, H, C> Connect<S, H, C>
768where
769 S: ServerImpl,
770 H: Handler,
771{
772 #[inline]
778 pub fn seed(mut self, seed: u64) -> Self {
779 self.seed = seed;
780 self
781 }
782
783 #[inline]
785 pub fn with_channel_allocator<U>(self, channels: U) -> Connect<S, H, U>
786 where
787 U: ChannelAllocator,
788 {
789 Connect {
790 handler: self.handler,
791 socket: self.socket,
792 channels,
793 seed: self.seed,
794 max_capacity: self.max_capacity,
795 formats: self.formats,
796 }
797 }
798
799 #[inline]
801 pub fn handler(&self) -> &H {
802 &self.handler
803 }
804
805 #[inline]
817 pub fn with_formats(mut self, formats: &'static [Format]) -> Self {
818 self.formats = Some(formats);
819 self
820 }
821
822 #[inline]
824 pub fn accepts(&self, format: Format) -> bool {
825 accepts(self.formats, format)
826 }
827
828 #[inline]
838 pub fn max_capacity(mut self, max_capacity: usize) -> Self {
839 self.max_capacity = max_capacity;
840 self
841 }
842
843 #[inline]
847 pub fn with_max_capacity(self, max_capacity: usize) -> Self {
848 self.max_capacity(max_capacity)
849 }
850}
851
852impl<S, H, C> Connect<S, H, C>
853where
854 S: ServerImpl,
855 Error: From<S::Error>,
856 H: Handler,
857 C: ChannelAllocator,
858{
859 pub async fn connect(self) -> Result<Server<S, H, C>, Error> {
878 let now = Instant::now();
879
880 let mut server = Server {
881 handler: self.handler,
882 pinned: Box::pin(Pinned {
883 socket: self.socket,
884 close_sleep: tokio::time::sleep_until(now + CLOSE_TIMEOUT),
885 ping_sleep: tokio::time::sleep_until(now + PING_TIMEOUT),
886 }),
887 channels: self.channels,
888 closing: false,
889 pool: BufPool::new(self.max_capacity),
890 outbound: VecDeque::new(),
891 error: String::new(),
892 last_ping: None,
893 rng: SmallRng::seed_from_u64(self.seed),
894 out: VecDeque::new(),
895 socket_send: false,
896 socket_flush: false,
897 set: JoinSet::new(),
898 format: Format::DEFAULT,
899 formats: self.formats,
900 };
901
902 server.hello()?;
903 server.negotiate().await?;
904 Ok(server)
905 }
906}
907
908#[inline]
910fn accepts(formats: Option<&'static [Format]>, format: Format) -> bool {
911 format.is_supported() && formats.is_none_or(|f| f.contains(&format))
912}
913
914pub struct Server<S, H, C = Channels>
926where
927 S: ServerImpl,
928 H: Handler,
929{
930 handler: H,
931 pinned: Pin<Box<Pinned<S::Socket>>>,
932 channels: C,
933 closing: bool,
934 pool: BufPool,
935 outbound: VecDeque<Buf>,
936 error: String,
937 last_ping: Option<[u8; 4]>,
938 rng: SmallRng,
939 out: VecDeque<S::Message>,
940 socket_send: bool,
941 socket_flush: bool,
942 set: JoinSet<HandlerOutput<H>>,
943 format: Format,
948 formats: Option<&'static [Format]>,
951}
952
953impl<S, H, C> Server<S, H, C>
954where
955 S: ServerImpl,
956 H: Handler,
957{
958 #[inline]
960 pub fn handler(&self) -> &H {
961 &self.handler
962 }
963
964 #[inline]
970 pub fn format(&self) -> Format {
971 self.format
972 }
973
974 #[inline]
976 pub fn accepts(&self, format: Format) -> bool {
977 accepts(self.formats, format)
978 }
979}
980
981impl<S, H, C> Server<S, H, C>
982where
983 S: ServerImpl,
984 Error: From<S::Error>,
985 H: Handler,
986 C: ChannelAllocator,
987{
988 async fn negotiate(&mut self) -> Result<(), Error> {
998 let mut negotiated = false;
999 let mut failure = None::<Error>;
1002
1003 loop {
1004 let drained = self.out.is_empty() && !self.socket_flush;
1005
1006 if failure.is_some() && drained {
1007 break;
1008 }
1009
1010 if negotiated && drained && self.outbound.is_empty() {
1011 break;
1012 }
1013
1014 self.handle_send()?;
1015
1016 let result = {
1017 let inner = Select::<S::Socket, H> {
1018 pinned: self.pinned.as_mut(),
1019 wants_socket_send: !self.socket_send,
1020 wants_socket_flush: self.socket_flush,
1021 set: &mut self.set,
1022 };
1023
1024 inner.await
1025 };
1026
1027 match result {
1028 Output::Close => {
1029 return Err(Error::new(ErrorKind::NotNegotiated));
1030 }
1031 Output::Ping => {
1032 self.handle_ping()?;
1033 }
1034 Output::Recv(message) => {
1035 let Some(message) = message else {
1036 return Err(Error::new(ErrorKind::NotNegotiated));
1037 };
1038
1039 match message? {
1040 Message::Text => {
1041 self.out.push_back(S::close(
1042 CLOSE_PROTOCOL_ERROR,
1043 "Unsupported text message",
1044 ));
1045
1046 failure = Some(Error::new(ErrorKind::NotNegotiated));
1047 }
1048 Message::Binary(bytes) => match self.handle_negotiate(bytes) {
1049 Ok(()) => negotiated = true,
1050 Err(error) => failure = Some(error),
1051 },
1052 Message::Ping(payload) => {
1053 self.out.push_back(S::pong(payload));
1054 }
1055 Message::Pong(data) => {
1056 self.handle_pong(data)?;
1057 }
1058 Message::Close => {
1059 return Err(Error::new(ErrorKind::NotNegotiated));
1060 }
1061 }
1062 }
1063 Output::Send(result) => {
1064 result?;
1065 self.socket_send = true;
1066 }
1067 Output::Flushed(result) => {
1068 result?;
1069 self.socket_flush = false;
1070 }
1071 Output::Handle(..) => {
1072 }
1075 }
1076 }
1077
1078 match failure {
1079 Some(error) => Err(error),
1080 None => Ok(()),
1081 }
1082 }
1083
1084 fn handle_negotiate(&mut self, bytes: Bytes) -> Result<(), Error> {
1090 let mut at = 0;
1091
1092 let header: RequestHeader = match format::decode_envelope(&bytes, &mut at) {
1093 Ok(header) => header,
1094 Err(error) => {
1095 self.out
1096 .push_back(S::close(CLOSE_PROTOCOL_ERROR, "Invalid request header"));
1097 return Err(Error::new(ErrorKind::NegotiateHeader { error }));
1098 }
1099 };
1100
1101 if MessageId::new(header.id) != Some(MessageId::NEGOTIATE) {
1102 self.out.push_back(S::close(
1103 CLOSE_PROTOCOL_ERROR,
1104 "Expected a negotiation as the first message",
1105 ));
1106
1107 return Err(Error::new(ErrorKind::ExpectedNegotiate { id: header.id }));
1108 }
1109
1110 let Some(format) = Format::from_u8(header.format) else {
1114 self.format_error_message(format_args!(
1115 "Unknown format id {}, supported: {}",
1116 header.format,
1117 SupportedFormats(self.formats)
1118 ))?;
1119
1120 self.format = Format::DEFAULT;
1121 return self.send_error(&header);
1122 };
1123
1124 if !self.accepts(format) {
1125 self.format_error_message(format_args!(
1126 "Unsupported format `{format}`, supported: {}",
1127 SupportedFormats(self.formats)
1128 ))?;
1129
1130 tracing::debug!(?format, "Rejected format");
1131 self.format = Format::DEFAULT;
1132 return self.send_error(&header);
1133 }
1134
1135 tracing::debug!(?format, "Negotiated format");
1136 self.format = format;
1137 self.send_negotiated(&header, format)
1138 }
1139
1140 fn send_negotiated(&mut self, header: &RequestHeader, format: Format) -> Result<(), Error> {
1142 let buf = self.pool.with(|buf| {
1143 let mut writer = buf.writer();
1144
1145 let result = writer.envelope(&ResponseHeader {
1146 serial: header.serial,
1147 broadcast: 0,
1148 error: 0,
1149 format: format.to_u8(),
1150 channel: header.channel,
1151 });
1152
1153 result.map_err(Error::encode_connect_header)?;
1154 writer.flush();
1155 Ok::<_, Error>(())
1156 })?;
1157
1158 self.outbound.push_back(buf);
1159 Ok(())
1160 }
1161
1162 pub async fn run(&mut self) -> Result<(), Error> {
1166 loop {
1167 if self.closing && self.out.is_empty() && self.outbound.is_empty() {
1168 break;
1169 }
1170
1171 self.handle_send()?;
1172
1173 let result = {
1174 let inner = Select::<S::Socket, H> {
1175 pinned: self.pinned.as_mut(),
1176 wants_socket_send: !self.socket_send,
1177 wants_socket_flush: self.socket_flush,
1178 set: &mut self.set,
1179 };
1180
1181 inner.await
1182 };
1183
1184 match result {
1185 Output::Close => {
1186 if self.closing {
1190 break;
1191 }
1192
1193 self.out
1194 .push_back(S::close(CLOSE_NORMAL, "connection timed out"));
1195 self.begin_closing();
1196 }
1197 Output::Ping => {
1198 self.handle_ping()?;
1199 }
1200 Output::Recv(message) => {
1201 let Some(message) = message else {
1202 self.begin_closing();
1203 continue;
1204 };
1205
1206 match message? {
1207 Message::Text => {
1208 self.out.push_back(S::close(
1209 CLOSE_PROTOCOL_ERROR,
1210 "Unsupported text message",
1211 ));
1212 self.begin_closing();
1213 }
1214 Message::Binary(bytes) => {
1215 self.handle_message(bytes).await?;
1216 }
1217 Message::Ping(payload) => {
1218 self.out.push_back(S::pong(payload));
1219 }
1220 Message::Pong(data) => {
1221 self.handle_pong(data)?;
1222 }
1223 Message::Close => {
1224 self.begin_closing();
1225 }
1226 }
1227 }
1228 Output::Send(result) => {
1229 if let Err(err) = result {
1230 return Err(Error::from(err));
1231 };
1232
1233 self.socket_send = true;
1234 }
1235 Output::Flushed(result) => {
1236 if let Err(err) = result {
1237 return Err(Error::from(err));
1238 };
1239
1240 self.socket_flush = false;
1241 }
1242 Output::Handle(result, header, buf) => {
1243 let err = 'err: {
1244 let res = match result {
1245 Ok(res) => res,
1246 Err(error) => {
1247 self.format_error(error)?;
1248 break 'err true;
1249 }
1250 };
1251
1252 let res = match res.into_response() {
1253 Ok(res) => res,
1254 Err(error) => {
1255 self.format_error_message(error)?;
1256 break 'err true;
1257 }
1258 };
1259
1260 if !res.handled {
1261 self.format_error_message(format_args!(
1262 "No support for request {}",
1263 header.id
1264 ))?;
1265 break 'err true;
1266 }
1267
1268 self.outbound.push_back(buf);
1269 false
1270 };
1271
1272 if err {
1273 self.send_error(&header)?;
1274 }
1275 }
1276 }
1277 }
1278
1279 Ok(())
1280 }
1281
1282 pub fn broadcast<T>(&mut self, message: T) -> Result<(), Error>
1287 where
1288 T: Event,
1289 {
1290 self.broadcast_in(message, ChannelId::NONE)
1291 }
1292
1293 pub fn broadcast_in<T>(&mut self, message: T, channel: ChannelId) -> Result<(), Error>
1298 where
1299 T: Event,
1300 {
1301 tracing::debug!(id = ?<T::Broadcast as Broadcast>::ID, "Broadcast");
1302
1303 let format = self.format;
1304
1305 let buf = self.pool.with(|buf| {
1306 let mut writer = buf.writer();
1307
1308 writer
1309 .envelope(&ResponseHeader {
1310 serial: 0,
1311 broadcast: <T::Broadcast as Broadcast>::ID.get(),
1312 error: 0,
1313 format: format.to_u8(),
1314 channel,
1315 })
1316 .map_err(Error::encode_broadcast_header)?;
1317
1318 writer
1319 .body(format, &message)
1320 .map_err(Error::encode_broadcast)?;
1321 writer.flush();
1322 Ok::<_, Error>(())
1323 })?;
1324
1325 self.outbound.push_back(buf);
1326 Ok(())
1327 }
1328
1329 fn hello(&mut self) -> Result<(), Error> {
1334 tracing::debug!("Hello");
1335
1336 let mut buf = self.pool.get();
1337
1338 let result = (|| {
1339 let mut writer = buf.writer();
1340
1341 writer
1342 .envelope(&ResponseHeader {
1343 serial: 0,
1344 broadcast: MessageId::SERVER_HELLO.get(),
1345 error: 0,
1346 format: 0,
1348 channel: ChannelId::NONE,
1349 })
1350 .map_err(Error::encode_broadcast_header)?;
1351
1352 writer.flush();
1353 Ok::<_, Error>(())
1354 })();
1355
1356 if result.is_err() {
1357 self.pool.put(buf);
1358 } else {
1359 self.outbound.push_back(buf);
1360 }
1361
1362 Ok(())
1363 }
1364
1365 fn format_error_message(&mut self, error: impl fmt::Display) -> Result<(), Error> {
1366 self.error.clear();
1367
1368 if write!(self.error, "{error}").is_err() {
1369 self.error.clear();
1370 return Err(Error::new(ErrorKind::FormatError));
1371 }
1372
1373 Ok(())
1374 }
1375
1376 fn format_error(&mut self, error: impl core::error::Error) -> Result<(), Error> {
1377 self.error.clear();
1378
1379 if write!(self.error, "{error:#}").is_err() {
1380 self.error.clear();
1381 return Err(Error::new(ErrorKind::FormatError));
1382 }
1383
1384 Ok(())
1385 }
1386
1387 #[tracing::instrument(skip(self, bytes))]
1388 async fn handle_message(&mut self, bytes: Bytes) -> Result<(), Error> {
1389 let mut at = 0;
1390
1391 let header: RequestHeader = match format::decode_envelope(&bytes, &mut at) {
1392 Ok(header) => header,
1393 Err(error) => {
1394 tracing::debug!(?error, "Invalid request header");
1395 self.out
1396 .push_back(S::close(CLOSE_PROTOCOL_ERROR, "Invalid request header"));
1397 self.begin_closing();
1398 return Ok(());
1399 }
1400 };
1401
1402 let err = 'err: {
1403 let Some(id) = MessageId::new(header.id) else {
1404 self.format_error_message(format_args!("Unsupported message id {}", header.id))?;
1405 break 'err true;
1406 };
1407
1408 match id {
1409 MessageId::CONNECT => {
1410 let Some(channel) = self.channels.next().await else {
1411 self.format_error_message(format_args!(
1412 "Failed to allocate connection ID"
1413 ))?;
1414
1415 break 'err true;
1416 };
1417
1418 self.handler.open_channel(channel).await;
1419
1420 let mut buf = self.pool.get();
1421
1422 let result = (|| {
1423 let mut writer = buf.writer();
1424
1425 let result = writer.envelope(&ResponseHeader {
1426 serial: header.serial,
1427 broadcast: 0,
1428 error: 0,
1429 format: 0,
1430 channel,
1431 });
1432
1433 result.map_err(Error::encode_connect_header)?;
1434 writer.flush();
1435 Ok::<_, Error>(())
1436 })();
1437
1438 if result.is_err() {
1439 self.pool.put(buf);
1440 } else {
1441 self.outbound.push_back(buf);
1442 }
1443
1444 result?;
1445 break 'err false;
1446 }
1447 MessageId::DISCONNECT => {
1448 self.channels.free(header.channel).await;
1449 self.handler.close_channel(header.channel).await;
1450 break 'err false;
1451 }
1452 MessageId::NEGOTIATE => {
1453 let format = self.format;
1458
1459 self.format_error_message(format_args!(
1460 "Format `{format}` has already been negotiated"
1461 ))?;
1462
1463 break 'err true;
1464 }
1465 _ => {
1466 let Some(format) = Format::from_u8(header.format) else {
1467 self.format_error_message(format_args!(
1468 "Unknown format id {}",
1469 header.format
1470 ))?;
1471
1472 break 'err true;
1473 };
1474
1475 if !self.accepts(format) {
1476 self.format_error_message(format_args!(
1477 "Unsupported format `{format}`, supported: {}",
1478 SupportedFormats(self.formats)
1479 ))?;
1480
1481 break 'err true;
1482 }
1483
1484 let id = <H::Id as Id>::from_id(id);
1485 self.handle_request(bytes, at, header, id, format);
1486 return Ok(());
1487 }
1488 }
1489 };
1490
1491 if err {
1492 self.send_error(&header)?;
1493 }
1494
1495 Ok(())
1496 }
1497
1498 fn send_error(&mut self, header: &RequestHeader) -> Result<(), Error> {
1499 let format = self.format;
1504
1505 let buf = self.pool.with(|buf| {
1506 let mut writer = buf.writer();
1508
1509 let result = writer.envelope(&ResponseHeader {
1510 serial: header.serial,
1511 broadcast: 0,
1512 error: MessageId::ERROR_MESSAGE.get(),
1513 format: format.to_u8(),
1514 channel: header.channel,
1515 });
1516
1517 result.map_err(Error::encode_error_message_header)?;
1518
1519 let result = writer.body(
1520 format,
1521 &ErrorMessage {
1522 message: &self.error,
1523 },
1524 );
1525
1526 result.map_err(Error::encode_error_message)?;
1527 writer.flush();
1528 Ok::<_, Error>(())
1529 })?;
1530
1531 self.outbound.push_back(buf);
1532 Ok(())
1533 }
1534
1535 fn begin_closing(&mut self) {
1543 if self.closing {
1544 return;
1545 }
1546
1547 self.closing = true;
1548
1549 let (close_sleep, _, _) = self.pinned.as_mut().project();
1550 close_sleep.reset(Instant::now() + CLOSE_TIMEOUT);
1551 }
1552
1553 #[tracing::instrument(skip(self))]
1554 fn handle_ping(&mut self) -> Result<(), Error> {
1555 let (_, mut ping_sleep, _) = self.pinned.as_mut().project();
1556
1557 let payload = self.rng.random::<u32>();
1558 let payload = payload.to_ne_bytes();
1559
1560 self.last_ping = Some(payload);
1561
1562 tracing::debug!(data = ?&payload[..], "Sending ping");
1563
1564 self.out
1565 .push_back(S::ping(Bytes::from_owner(Vec::from(payload))));
1566
1567 let now = Instant::now();
1568 ping_sleep.as_mut().reset(now + PING_TIMEOUT);
1569 Ok(())
1570 }
1571
1572 #[tracing::instrument(skip(self, payload))]
1573 fn handle_pong(&mut self, payload: Bytes) -> Result<(), Error> {
1574 let (close_sleep, ping_sleep, _) = self.pinned.as_mut().project();
1575
1576 tracing::debug!(payload = ?&payload[..], "Pong");
1577
1578 let Some(expected) = self.last_ping else {
1579 tracing::debug!("No ping sent");
1580 return Ok(());
1581 };
1582
1583 if expected[..] != payload[..] {
1584 tracing::debug!(?expected, ?payload, "Pong doesn't match");
1585 return Ok(());
1586 }
1587
1588 let now = Instant::now();
1589
1590 close_sleep.reset(now + CLOSE_TIMEOUT);
1591 ping_sleep.reset(now + PING_TIMEOUT);
1592 self.last_ping = None;
1593 Ok(())
1594 }
1595
1596 #[tracing::instrument(skip(self))]
1597 fn handle_send(&mut self) -> Result<(), Error> {
1598 let (_, _, mut socket) = self.pinned.as_mut().project();
1599
1600 if self.socket_send
1601 && let Some(message) = self.out.pop_front()
1602 {
1603 socket.as_mut().start_send(message)?;
1604 self.socket_flush = true;
1605 self.socket_send = false;
1606 }
1607
1608 while self.socket_send
1609 && let Some(buf) = self.outbound.front_mut()
1610 {
1611 let Some(frame) = buf.read()? else {
1612 if let Some(buf) = self.outbound.pop_front() {
1613 self.pool.put(buf);
1614 }
1615
1616 continue;
1617 };
1618
1619 socket.as_mut().start_send(S::binary(frame))?;
1620
1621 self.socket_flush = true;
1622 self.socket_send = false;
1623 break;
1624 }
1625
1626 Ok(())
1627 }
1628
1629 fn handle_request(
1630 &mut self,
1631 bytes: Bytes,
1632 offset: usize,
1633 header: RequestHeader,
1634 id: H::Id,
1635 format: Format,
1636 ) {
1637 tracing::debug!(header.serial, ?id, ?format, "Got request");
1638
1639 let mut buf = self.pool.get();
1640 let handler = self.handler.clone();
1641
1642 self.set.spawn(async move {
1643 if offset > bytes.len() {
1644 let kind = ErrorKind::OutOfBounds {
1645 offset,
1646 len: bytes.len(),
1647 };
1648
1649 return (Err(Error::new(kind)), header, buf);
1650 }
1651
1652 let mut incoming = Incoming {
1653 error: None,
1654 buf: &bytes,
1655 at: offset,
1656 format,
1657 channel: header.channel,
1658 };
1659
1660 let mut outgoing = Outgoing {
1661 serial: Some(header.serial),
1662 error: None,
1663 buf: &mut buf,
1664 format,
1665 channel: header.channel,
1666 };
1667
1668 let response = handler.handle(id, &mut incoming, &mut outgoing).await;
1669
1670 if let Some(error) = incoming.error.take() {
1671 return (Err(Error::incoming(error)), header, buf);
1672 }
1673
1674 if let Some(error) = outgoing.error.take() {
1675 return (Err(Error::outgoing(error)), header, buf);
1676 }
1677
1678 (Ok(response), header, buf)
1679 });
1680 }
1681}
1682
1683enum Output<E, R> {
1684 Close,
1686 Ping,
1688 Recv(Option<Result<Message, E>>),
1690 Send(Result<(), E>),
1692 Flushed(Result<(), E>),
1694 Handle(Result<R, Error>, RequestHeader, Buf),
1696}
1697
1698struct Select<'a, S, H>
1699where
1700 H: Handler,
1701{
1702 pinned: Pin<&'a mut Pinned<S>>,
1703 wants_socket_send: bool,
1704 wants_socket_flush: bool,
1705 set: &'a mut JoinSet<HandlerOutput<H>>,
1706}
1707
1708impl<S, H> Future for Select<'_, S, H>
1709where
1710 S: SocketImpl,
1711 H: Handler,
1712{
1713 type Output = Output<S::Error, H::Response>;
1714
1715 #[inline]
1716 fn poll(self: Pin<&mut Self>, cx: &mut Context<'_>) -> Poll<Self::Output> {
1717 let close;
1718 let ping;
1719 let mut socket;
1720 let wants_socket_send;
1721 let wants_socket_flush;
1722 let set;
1723
1724 unsafe {
1726 let this = Pin::get_unchecked_mut(self);
1727 (close, ping, socket) = this.pinned.as_mut().project();
1728 wants_socket_send = this.wants_socket_send;
1729 wants_socket_flush = this.wants_socket_flush;
1730 set = &mut this.set;
1731 };
1732
1733 if close.poll(cx).is_ready() {
1734 return Poll::Ready(Output::Close);
1735 }
1736
1737 if ping.poll(cx).is_ready() {
1738 return Poll::Ready(Output::Ping);
1739 }
1740
1741 if let Poll::Ready(output) = socket.as_mut().poll_next(cx) {
1742 return Poll::Ready(Output::Recv(output));
1743 }
1744
1745 if wants_socket_send && let Poll::Ready(result) = socket.as_mut().poll_ready(cx) {
1746 return Poll::Ready(Output::Send(result));
1747 }
1748
1749 if wants_socket_flush && let Poll::Ready(result) = socket.as_mut().poll_flush(cx) {
1750 return Poll::Ready(Output::Flushed(result));
1751 }
1752
1753 if let Poll::Ready(output) = set.poll_join_next(cx)
1754 && let Some(output) = output
1755 {
1756 let output = match output {
1757 Ok(output) => output,
1758 Err(error) => {
1759 tracing::debug!(?error, "Join error in handler task");
1760 return Poll::Ready(Output::Close);
1761 }
1762 };
1763
1764 let (result, header, buf) = output;
1765 return Poll::Ready(Output::Handle(result, header, buf));
1766 }
1767
1768 Poll::Pending
1769 }
1770}
1771
1772pub struct Incoming<'de> {
1778 error: Option<format::Error>,
1779 buf: &'de [u8],
1780 at: usize,
1781 format: Format,
1782 channel: ChannelId,
1783}
1784
1785impl<'de> Incoming<'de> {
1786 pub fn channel(&self) -> ChannelId {
1793 self.channel
1794 }
1795
1796 #[inline]
1801 pub fn format(&self) -> Format {
1802 self.format
1803 }
1804
1805 #[inline]
1813 pub fn read<T>(&mut self) -> Option<T>
1814 where
1815 T: DecodeBody<'de>,
1816 {
1817 match self.format.decode(self.buf, &mut self.at) {
1818 Ok(value) => Some(value),
1819 Err(error) => {
1820 self.error = Some(error);
1821 None
1822 }
1823 }
1824 }
1825}
1826
1827pub struct Outgoing<'a> {
1833 serial: Option<u32>,
1834 error: Option<format::Error>,
1835 buf: &'a mut Buf,
1836 format: Format,
1837 channel: ChannelId,
1838}
1839
1840impl Outgoing<'_> {
1841 #[inline]
1844 pub fn format(&self) -> Format {
1845 self.format
1846 }
1847
1848 pub fn write<T>(&mut self, value: T)
1856 where
1857 T: EncodeBody,
1858 {
1859 let Some(serial) = self.serial.take() else {
1860 return;
1861 };
1862
1863 let mut writer = self.buf.writer();
1864
1865 let result = writer.envelope(&ResponseHeader {
1866 serial,
1867 broadcast: 0,
1868 error: 0,
1869 format: self.format.to_u8(),
1870 channel: self.channel,
1871 });
1872
1873 if let Err(error) = result {
1874 self.error = Some(error);
1875 return;
1876 }
1877
1878 if let Err(error) = writer.body(self.format, &value) {
1879 self.error = Some(error);
1880 }
1881
1882 writer.flush();
1883 }
1884}
1885
1886#[inline]
1891fn scramble_channel(x: u16) -> u16 {
1892 let x = x.wrapping_mul(0x9285);
1893 x ^ (x >> 8)
1894}
1895
1896#[inline]
1898#[cfg(test)]
1899fn unscramble_channel(x: u16) -> u16 {
1900 let x = x ^ (x >> 8);
1901 x.wrapping_mul(0x964d)
1902}
1903
1904#[test]
1905fn test_scramble() {
1906 assert_eq!(scramble_channel(0), 0);
1907 assert_eq!(unscramble_channel(0), 0);
1908
1909 for i in 1..=u16::MAX {
1910 let scrambled = scramble_channel(i);
1911 let unscrambled = unscramble_channel(scrambled);
1912 assert_eq!(i, unscrambled, "Failed to unscramble channel id");
1913 }
1914}
1915
1916#[derive(Default)]
1917struct ChannelsInner {
1918 last: u16,
1919 free: VecDeque<NonZeroU16>,
1920}
1921
1922#[derive(Default, Clone)]
1926pub struct Channels {
1927 inner: Arc<Mutex<ChannelsInner>>,
1928}
1929
1930impl ChannelAllocator for Channels {
1931 #[inline]
1932 async fn next(&self) -> Option<ChannelId> {
1933 let mut inner = self.inner.lock().await;
1934
1935 if let Some(id) = inner.free.pop_front() {
1936 return Some(ChannelId::from_u16(id.get()));
1937 }
1938
1939 let id = NonZeroU16::new(inner.last.wrapping_add(1))?;
1940 inner.last = id.get();
1941
1942 tracing::debug!(?id, "Allocated channel id");
1943 Some(ChannelId::from_u16(scramble_channel(id.get())))
1944 }
1945
1946 #[inline]
1947 async fn free(&self, id: ChannelId) {
1948 tracing::debug!(?id, "Freeing channel id");
1949
1950 let mut inner = self.inner.lock().await;
1951
1952 if let Some(id) = NonZeroU16::new(id.raw()) {
1953 inner.free.push_back(id);
1954 }
1955 }
1956}
1957
1958struct SupportedFormats(Option<&'static [Format]>);
1960
1961impl fmt::Display for SupportedFormats {
1962 fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result {
1963 let mut first = true;
1964
1965 for format in Format::supported() {
1966 if let Some(formats) = self.0
1967 && !formats.contains(&format)
1968 {
1969 continue;
1970 }
1971
1972 if !first {
1973 f.write_str(", ")?;
1974 }
1975
1976 write!(f, "`{format}`")?;
1977 first = false;
1978 }
1979
1980 if first {
1981 f.write_str("none")?;
1982 }
1983
1984 Ok(())
1985 }
1986}
1987
1988#[cfg(test)]
1989mod tests {
1990 use core::cell::Cell;
1991
1992 use std::thread_local;
1993
1994 use super::*;
1995
1996 const CLOSE_BUDGET: usize = 4;
2004
2005 thread_local! {
2006 static CLOSE_FRAMES: Cell<usize> = const { Cell::new(0) };
2009 }
2010
2011 #[derive(Debug)]
2012 enum TestError {}
2013
2014 impl From<TestError> for Error {
2015 #[inline]
2016 fn from(error: TestError) -> Self {
2017 match error {}
2018 }
2019 }
2020
2021 #[derive(Debug, PartialEq, Eq)]
2022 enum TestMessage {
2023 Ping(Bytes),
2024 Pong(Bytes),
2025 Binary(Vec<u8>),
2026 Close(u16),
2027 }
2028
2029 #[derive(Default)]
2033 struct TestSocket {
2034 sent: Vec<TestMessage>,
2035 }
2036
2037 impl socket_sealed::Sealed for TestSocket {}
2038
2039 impl SocketImpl for TestSocket {
2040 type Message = TestMessage;
2041 type Error = TestError;
2042
2043 fn poll_next(
2044 self: Pin<&mut Self>,
2045 _: &mut Context<'_>,
2046 ) -> Poll<Option<Result<Message, Self::Error>>> {
2047 Poll::Pending
2048 }
2049
2050 fn poll_ready(self: Pin<&mut Self>, _: &mut Context<'_>) -> Poll<Result<(), Self::Error>> {
2051 Poll::Ready(Ok(()))
2052 }
2053
2054 fn start_send(self: Pin<&mut Self>, item: Self::Message) -> Result<(), Self::Error> {
2055 unsafe { Pin::get_unchecked_mut(self).sent.push(item) };
2057 Ok(())
2058 }
2059
2060 fn poll_flush(self: Pin<&mut Self>, _: &mut Context<'_>) -> Poll<Result<(), Self::Error>> {
2061 Poll::Ready(Ok(()))
2062 }
2063 }
2064
2065 struct TestServerImpl;
2066
2067 impl server_sealed::Sealed for TestServerImpl {}
2068
2069 impl ServerImpl for TestServerImpl {
2070 type Error = TestError;
2071 type Message = TestMessage;
2072 type Socket = TestSocket;
2073
2074 fn ping(data: Bytes) -> Self::Message {
2075 TestMessage::Ping(data)
2076 }
2077
2078 fn pong(data: Bytes) -> Self::Message {
2079 TestMessage::Pong(data)
2080 }
2081
2082 fn binary(data: &[u8]) -> Self::Message {
2083 TestMessage::Binary(data.to_vec())
2084 }
2085
2086 fn close(code: u16, _: &str) -> Self::Message {
2087 let frames = CLOSE_FRAMES.with(|frames| {
2088 let count = frames.get() + 1;
2089 frames.set(count);
2090 count
2091 });
2092
2093 assert!(
2094 frames <= CLOSE_BUDGET,
2095 "`Server::run` is spinning: {frames} close frames without any progress"
2096 );
2097
2098 TestMessage::Close(code)
2099 }
2100 }
2101
2102 #[derive(Debug)]
2103 struct TestId;
2104
2105 impl Id for TestId {
2106 fn id(&self) -> MessageId {
2107 MessageId::NEGOTIATE
2108 }
2109
2110 fn from_id(_: MessageId) -> Self {
2111 Self
2112 }
2113
2114 fn __do_not_implement_id() {}
2115 }
2116
2117 #[derive(Clone)]
2118 struct TestHandler;
2119
2120 impl Handler for TestHandler {
2121 type Id = TestId;
2122 type Response = bool;
2123
2124 async fn handle(&self, _: Self::Id, _: &mut Incoming<'_>, _: &mut Outgoing<'_>) -> bool {
2125 false
2126 }
2127 }
2128
2129 fn timed_out_server(elapsed: Duration) -> Server<TestServerImpl, TestHandler, Channels> {
2131 let now = Instant::now();
2132
2133 Server {
2134 handler: TestHandler,
2135 pinned: Box::pin(Pinned {
2136 socket: TestSocket::default(),
2137 close_sleep: tokio::time::sleep_until(now - elapsed),
2138 ping_sleep: tokio::time::sleep_until(now + PING_TIMEOUT),
2139 }),
2140 channels: Channels::default(),
2141 closing: false,
2142 pool: BufPool::new(MAX_CAPACITY),
2143 outbound: VecDeque::new(),
2144 error: String::new(),
2145 last_ping: None,
2146 rng: SmallRng::seed_from_u64(DEFAULT_SEED),
2147 out: VecDeque::new(),
2148 socket_send: false,
2149 socket_flush: false,
2150 set: JoinSet::new(),
2151 format: Format::DEFAULT,
2152 formats: None,
2153 }
2154 }
2155
2156 #[tokio::test]
2163 async fn close_deadline_winds_down_once() {
2164 let mut server = timed_out_server(Duration::from_secs(1));
2165
2166 server.run().await.unwrap();
2167
2168 let (_, _, socket) = server.pinned.as_mut().project();
2169
2170 let socket = unsafe { Pin::get_unchecked_mut(socket) };
2172
2173 assert_eq!(socket.sent, [TestMessage::Close(CLOSE_NORMAL)]);
2174 assert!(server.out.is_empty());
2175 assert!(server.closing);
2176 }
2177
2178 #[tokio::test]
2181 async fn close_deadline_while_closing_gives_up() {
2182 let mut server = timed_out_server(Duration::from_secs(1));
2183
2184 server.closing = true;
2187 server.out.push_back(TestMessage::Close(CLOSE_NORMAL));
2188
2189 server.run().await.unwrap();
2190
2191 let (_, _, socket) = server.pinned.as_mut().project();
2192
2193 let socket = unsafe { Pin::get_unchecked_mut(socket) };
2195
2196 assert!(socket.sent.is_empty());
2197 assert_eq!(server.out.len(), 1);
2198 }
2199}