atm0s_media_server_transport_webrtc/transport/net/
ssltcp.rs

1use std::net::SocketAddr;
2
3use async_std::net::TcpStream;
4use futures::{AsyncReadExt, AsyncWriteExt};
5
6// Should this have a session id? The response doesn't have a
7// certificate, so the hello should have a session id ?
8const K_SSL_CLIENT_HELLO: [u8; 72] = [
9    0x80, 0x46, // msg len
10    0x01, // CLIENT_HELLO
11    0x03, 0x01, // SSL 3.1
12    0x00, 0x2d, // ciphersuite len
13    0x00, 0x00, // session id len
14    0x00, 0x10, // challenge len
15    0x01, 0x00, 0x80, 0x03, 0x00, 0x80, 0x07, 0x00, 0xc0, // ciphersuites
16    0x06, 0x00, 0x40, 0x02, 0x00, 0x80, 0x04, 0x00, 0x80, //
17    0x00, 0x00, 0x04, 0x00, 0xfe, 0xff, 0x00, 0x00, 0x0a, //
18    0x00, 0xfe, 0xfe, 0x00, 0x00, 0x09, 0x00, 0x00, 0x64, //
19    0x00, 0x00, 0x62, 0x00, 0x00, 0x03, 0x00, 0x00, 0x06, //
20    0x1f, 0x17, 0x0c, 0xa6, 0x2f, 0x00, 0x78, 0xfc, // challenge
21    0x46, 0x55, 0x2e, 0xb1, 0x83, 0x39, 0xf1, 0xea, //
22];
23
24// This is a TLSv1 SERVER_HELLO message.
25const K_SSL_SERVER_HELLO: [u8; 79] = [
26    0x16, // handshake message
27    0x03, 0x01, // SSL 3.1
28    0x00, 0x4a, // message len
29    0x02, // SERVER_HELLO
30    0x00, 0x00, 0x46, // handshake len
31    0x03, 0x01, // SSL 3.1
32    0x42, 0x85, 0x45, 0xa7, 0x27, 0xa9, 0x5d, 0xa0, // server random
33    0xb3, 0xc5, 0xe7, 0x53, 0xda, 0x48, 0x2b, 0x3f, //
34    0xc6, 0x5a, 0xca, 0x89, 0xc1, 0x58, 0x52, 0xa1, //
35    0x78, 0x3c, 0x5b, 0x17, 0x46, 0x00, 0x85, 0x3f, //
36    0x20, // session id len
37    0x0e, 0xd3, 0x06, 0x72, 0x5b, 0x5b, 0x1b, 0x5f, // session id
38    0x15, 0xac, 0x13, 0xf9, 0x88, 0x53, 0x9d, 0x9b, //
39    0xe8, 0x3d, 0x7b, 0x0c, 0x30, 0x32, 0x6e, 0x38, //
40    0x4d, 0xa2, 0x75, 0x57, 0x41, 0x6c, 0x34, 0x5c, //
41    0x00, 0x04, // RSA/RC4-128/MD5
42    0x00, // null compression
43];
44
45struct SsltcpStream {
46    stream: TcpStream,
47    addr: SocketAddr,
48    local: SocketAddr,
49    handshake: bool,
50    buf: Vec<u8>,
51    buf_offset: usize,
52    buf_len: usize,
53    send_buf: Vec<u8>,
54}
55
56impl SsltcpStream {
57    pub async fn read(&mut self, buf: &mut [u8]) -> std::io::Result<usize> {
58        loop {
59            if self.buf_offset < self.buf_len {
60                if self.buf_offset + 2 > self.buf_len {
61                    return Err(std::io::Error::new(std::io::ErrorKind::InvalidData, "Invalid data"));
62                }
63
64                //get frame size form first 2 bytes from buf + offset
65                let n = u16::from_be_bytes([self.buf[self.buf_offset], self.buf[self.buf_offset + 1]]) as usize;
66                if self.buf_offset + n + 2 > self.buf_len {
67                    return Err(std::io::Error::new(std::io::ErrorKind::InvalidData, "Invalid data"));
68                }
69
70                log::debug!("    => frame {}", n);
71
72                self.buf_offset += 2;
73                buf[0..n].copy_from_slice(&self.buf[self.buf_offset..self.buf_offset + n]);
74                self.buf_offset += n;
75                return Ok(n);
76            }
77
78            let n = self.stream.read(&mut self.buf).await?;
79            if n == 0 {
80                return Ok(0);
81            }
82
83            if !self.handshake {
84                if self.buf[0..n].eq(&K_SSL_CLIENT_HELLO) {
85                    self.stream.write(&K_SSL_SERVER_HELLO).await?;
86                    self.handshake = true;
87                } else {
88                    return Err(std::io::Error::new(std::io::ErrorKind::InvalidData, "Invalid data"));
89                }
90            } else {
91                self.buf_len = n;
92                self.buf_offset = 0;
93                log::debug!("received {}", n);
94                continue;
95            }
96        }
97    }
98
99    pub async fn write(&mut self, buf: &[u8]) -> std::io::Result<usize> {
100        if !self.handshake {
101            return Err(std::io::Error::new(std::io::ErrorKind::NotConnected, "Waiting for handshake"));
102        }
103        self.send_buf[0..2].copy_from_slice(&(buf.len() as u16).to_be_bytes());
104        self.send_buf[2..2 + buf.len()].copy_from_slice(buf);
105        self.stream.write(&self.send_buf[0..2 + buf.len()]).await
106    }
107}
108
109pub struct WebrtcSsltcpListener {
110    async_listener: async_std::net::TcpListener,
111    local_addr: SocketAddr,
112    socket: Option<SsltcpStream>,
113}
114
115impl WebrtcSsltcpListener {
116    pub async fn new(port: u16) -> Result<Self, std::io::Error> {
117        let addr: SocketAddr = format!("0.0.0.0:{}", port).parse().expect("Should parse ip address");
118        let async_socket = async_std::net::TcpListener::bind(addr).await?;
119
120        Ok(Self {
121            local_addr: async_socket.local_addr().expect("Should has local port"),
122            async_listener: async_socket,
123            socket: None,
124        })
125    }
126
127    pub fn proto(&self) -> str0m::net::Protocol {
128        str0m::net::Protocol::SslTcp
129    }
130
131    pub fn local_addr(&self) -> SocketAddr {
132        self.local_addr
133    }
134
135    pub async fn recv(&mut self, buf: &mut [u8]) -> std::io::Result<(usize, std::net::SocketAddr, std::net::SocketAddr, str0m::net::Protocol)> {
136        loop {
137            if let Some(stream) = self.socket.as_mut() {
138                let n = stream.read(buf).await?;
139                if n == 0 {
140                    self.socket = None;
141                    continue;
142                }
143                return Ok((n, stream.addr.clone(), stream.local.clone(), str0m::net::Protocol::SslTcp));
144            } else {
145                let (stream, addr) = self.async_listener.accept().await?;
146                self.local_addr = stream.local_addr().expect("Should has local port");
147                log::info!("[SslTcp] New connection from {} => {}", addr, self.local_addr);
148                self.socket = Some(SsltcpStream {
149                    local: stream.local_addr().expect("Should has local port"),
150                    stream,
151                    addr,
152                    handshake: false,
153                    buf: vec![0; 1 << 16],
154                    buf_offset: 0,
155                    buf_len: 0,
156                    send_buf: vec![0; 1500],
157                });
158            }
159        }
160    }
161
162    pub async fn send_to(&mut self, buf: &[u8], _addr: std::net::SocketAddr) -> std::io::Result<usize> {
163        if let Some(socket) = &mut self.socket {
164            socket.write(buf).await
165        } else {
166            Err(std::io::Error::new(std::io::ErrorKind::NotConnected, "Not connected"))
167        }
168    }
169}