s2n_quic_platform/message/cmsg/
encode.rs1use crate::features;
5use s2n_quic_core::inet::{ExplicitCongestionNotification, SocketAddress};
6
7#[derive(Clone, Copy, Debug)]
8pub struct Error;
9
10pub trait Encoder {
11 fn encode_cmsg<T: Copy>(
16 &mut self,
17 level: libc::c_int,
18 ty: libc::c_int,
19 value: T,
20 ) -> Result<usize, Error>;
21
22 #[inline]
24 fn encode_ecn(
25 &mut self,
26 ecn: ExplicitCongestionNotification,
27 remote_address: &SocketAddress,
28 ) -> Result<usize, Error> {
29 if ecn == ExplicitCongestionNotification::NotEct {
31 return Ok(0);
32 }
33
34 match remote_address.unmap() {
36 SocketAddress::IpV4(_) => {
37 if let (Some(level), Some(ty)) = (features::tos_v4::LEVEL, features::tos_v4::TYPE) {
38 return self.encode_cmsg(level, ty, ecn as u8 as features::tos_v4::Cmsg);
39 }
40 }
41 SocketAddress::IpV6(_) => {
42 if let (Some(level), Some(ty)) = (features::tos_v6::LEVEL, features::tos_v6::TYPE) {
43 return self.encode_cmsg(level, ty, ecn as u8 as features::tos_v6::Cmsg);
44 }
45 }
46 }
47
48 Ok(0)
49 }
50
51 #[inline]
53 fn encode_gso(&mut self, segment_size: u16) -> Result<usize, Error> {
54 if let (Some(level), Some(ty)) = (features::gso::LEVEL, features::gso::TYPE) {
55 let segment_size = segment_size as features::gso::Cmsg;
56 self.encode_cmsg(level, ty, segment_size)
57 } else {
58 panic!("platform does not support GSO");
59 }
60 }
61
62 #[inline]
63 fn encode_local_address(&mut self, address: &SocketAddress) -> Result<usize, Error> {
64 use s2n_quic_core::inet::Unspecified;
65
66 match address {
67 SocketAddress::IpV4(addr) => {
68 use features::pktinfo_v4 as pktinfo;
69 if let (Some(level), Some(ty)) = (pktinfo::LEVEL, pktinfo::TYPE) {
70 let ip = addr.ip();
71
72 if ip.is_unspecified() {
73 return Ok(0);
74 }
75
76 let value = pktinfo::encode(ip, None);
77 return self.encode_cmsg(level, ty, value);
78 }
79 }
80 SocketAddress::IpV6(addr) => {
81 use features::pktinfo_v6 as pktinfo;
82 if let (Some(level), Some(ty)) = (pktinfo::LEVEL, pktinfo::TYPE) {
83 let ip = addr.ip();
84
85 if ip.is_unspecified() {
86 return Ok(0);
87 }
88
89 let value = pktinfo::encode(ip, None);
90 return self.encode_cmsg(level, ty, value);
91 }
92 }
93 }
94
95 Ok(0)
96 }
97}