Skip to main content

forge/socket/
tcp_server.rs

1use core::{
2    ffi::c_void,
3    net::{SocketAddr, SocketAddrV4, SocketAddrV6},
4};
5use log::error;
6use sys::socket::*;
7
8use super::tcp_stream::TcpStream;
9
10pub struct TcpServer {
11    socket: Socket,
12}
13
14impl TcpServer {
15    pub fn bind(addr: SocketAddr) -> Option<Self> {
16        match addr {
17            SocketAddr::V4(v4) => Self::bind_v4(v4),
18            SocketAddr::V6(v6) => Self::bind_v6(v6),
19        }
20    }
21
22    pub fn accept(&self) -> Option<TcpStream> {
23        let mut peer_addr = SockAddrIn {
24            sin_len: 0,
25            sin_family: 0,
26            sin_port: 0,
27            sin_addr: [0; 4],
28            sin_zero: [0; 8],
29        };
30        let mut addrlen = size_of::<SockAddrIn>();
31
32        let socket =
33            unsafe { forge_socket_accept(&self.socket, &mut peer_addr, &mut addrlen) };
34        if socket.fd == -1 {
35            error!("Failed to accept connection");
36            return None;
37        }
38
39        Some(TcpStream::from_socket(socket))
40    }
41
42    pub fn close(&mut self) {
43        unsafe { forge_socket_destroy(&mut self.socket) }
44    }
45
46    fn bind_v4(addr: SocketAddrV4) -> Option<Self> {
47        let mut socket = unsafe {
48            forge_socket_create(super::consts::AF_INET, super::consts::SOCK_STREAM, 0)
49        };
50        if socket.fd == -1 {
51            error!("Failed to create socket");
52            return None;
53        }
54
55        let reuse: i32 = 1;
56        unsafe {
57            forge_socket_setSockOpt(
58                &socket,
59                super::consts::SOL_SOCKET,
60                super::consts::SO_REUSEADDR,
61                &reuse as *const i32 as *const c_void,
62                size_of::<i32>() as u32,
63            )
64        };
65
66        let in_addr = SockAddrIn {
67            sin_len: 0,
68            sin_family: super::consts::AF_INET as u8,
69            sin_port: addr.port().to_be(),
70            sin_addr: addr.ip().octets(),
71            sin_zero: [0; 8],
72        };
73
74        if unsafe { forge_socket_bind(&socket, &in_addr, size_of::<SockAddrIn>()) } == -1 {
75            unsafe { forge_socket_destroy(&mut socket) };
76            error!("Failed to bind to address");
77            return None;
78        }
79
80        if unsafe { forge_socket_listen(&socket, 128) } == -1 {
81            unsafe { forge_socket_destroy(&mut socket) };
82            error!("Failed to listen on socket");
83            return None;
84        }
85
86        Some(Self { socket })
87    }
88
89    fn bind_v6(_addr: SocketAddrV6) -> Option<Self> {
90        error!("IPv6 not currently supported");
91        None
92    }
93}
94
95impl Drop for TcpServer {
96    fn drop(&mut self) {
97        unsafe { forge_socket_destroy(&mut self.socket) }
98    }
99}