forge/socket/
tcp_server.rs1use 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}