Skip to main content

libinject/
socket.rs

1use navigator::{
2    pipe_event::PipeEvent,
3    socket::{HalfDuplexExchange, RecvBuffer},
4};
5use std::os::raw::{c_ulong, c_void};
6
7use crate::{
8    drcore::{self, log},
9    pipe,
10};
11
12#[derive(Debug)]
13pub struct Socket {
14    pub id: usize,
15    pub data: SocketData,
16}
17
18#[derive(Debug)]
19pub enum SocketData {
20    Sync(RecvBuffer),
21    ServerManaged,
22}
23
24impl Socket {
25    pub unsafe fn push_exchange(&self, exchange: HalfDuplexExchange) {
26        match &self.data {
27            SocketData::Sync(recv_buf) => {
28                let mut guard = recv_buf
29                    .slot
30                    .lock()
31                    .expect("Recv queue mutex should not be poisoned");
32
33                *guard = Some(exchange);
34            }
35            SocketData::ServerManaged => {
36                pipe::send(&PipeEvent::Server(exchange));
37                log("[push exchange] pushed exchange as PipeEvent::Server");
38            }
39        }
40    }
41}
42
43// Helper function to write to the recv buffer.
44pub fn write_recv_buffer(to_write: &Vec<u8>, buf_size: usize, buf_ptr: *mut c_void, log_msg: &str) {
45    assert!(to_write.len() <= buf_size);
46    // Write the response payload to the recv buffer.
47    match drcore::safe_write(buf_ptr, to_write.clone()) {
48        Ok(()) => log(log_msg),
49        Err(write_err) => {
50            panic!("[recv] Failed writing payload: {:?}", write_err);
51        }
52    };
53}
54
55/// `Send`-safe version of the WSABUF data structure.
56#[repr(C)]
57#[derive(Debug, Clone)]
58pub struct WSABuf {
59    pub len: c_ulong,
60    /// This is a pointer to a byte (`*mut u8` or `*const u8`), but it is stored as a usize so
61    /// that the struct is `Send`.
62    pub buf: usize,
63}
64
65impl From<WSABufRaw> for WSABuf {
66    fn from(value: WSABufRaw) -> Self {
67        WSABuf {
68            len: value.len,
69            buf: value.buf as usize,
70        }
71    }
72}
73
74/// WSABUF data structure.
75/// See https://learn.microsoft.com/en-us/windows/win32/api/ws2def/ns-ws2def-wsabuf
76#[repr(C)]
77#[derive(Debug)]
78pub struct WSABufRaw {
79    pub len: c_ulong,
80    pub buf: *mut u8,
81}
82
83impl From<WSABuf> for WSABufRaw {
84    fn from(value: WSABuf) -> Self {
85        WSABufRaw {
86            len: value.len,
87            buf: value.buf as *mut u8,
88        }
89    }
90}
91
92/// DWORD is unsigned long on Windows, which is u32 for both 32bit and 64bit builds.
93type DWORD = u32;
94
95#[repr(C)]
96#[derive(Debug, Clone)]
97pub struct WSAOverlapped {
98    pub internal: DWORD,
99    pub internal_high: DWORD,
100    pub offset: DWORD,
101    pub offset_high: DWORD,
102    /// This is a pointer to an opaque struct (`*mut c_void`), but it is stored as a usize so
103    /// that the struct is `Send`.
104    pub h_event: usize,
105}
106
107#[repr(C)]
108#[derive(Debug)]
109pub struct WSAOverlappedRaw {
110    pub internal: DWORD,
111    pub internal_high: DWORD,
112    pub offset: DWORD,
113    pub offset_high: DWORD,
114    pub h_event: *mut c_void,
115}
116
117#[derive(Debug, Clone)]
118pub struct OverlappedData {
119    socket: usize,
120    buffers: Vec<WSABuf>,
121    lp_number_of_bytes_recvd: usize,
122    lp_flags: usize,
123    lp_overlapped: usize,
124}
125
126#[derive(Debug)]
127pub struct OverlappedDataRaw {
128    socket: usize,
129    buffers: Vec<WSABufRaw>,
130    lp_number_of_bytes_recvd: *mut u32,
131    lp_flags: *mut u32,
132    lp_overlapped: *mut WSAOverlappedRaw,
133}
134
135impl OverlappedData {
136    pub unsafe fn from_ptrs(
137        sock_id: usize,
138        buffers_ptr: *mut WSABufRaw,
139        buffer_count: usize,
140        bytes_recvd_ptr: *mut u32,
141        flags_ptr: *mut u32,
142        overlapped_ptr: *mut WSAOverlappedRaw,
143    ) -> OverlappedData {
144        unsafe {
145            let mut buffers = Vec::new();
146            for i in 0..buffer_count {
147                buffers.push(buffers_ptr.add(i).read().into());
148            }
149            OverlappedData {
150                socket: sock_id,
151                buffers,
152                lp_number_of_bytes_recvd: bytes_recvd_ptr as usize,
153                lp_flags: flags_ptr as usize,
154                lp_overlapped: overlapped_ptr as usize,
155            }
156        }
157    }
158
159    /// Cast all `Send`-safe usize pointers back to raw pointers.
160    pub fn into_raw(self) -> OverlappedDataRaw {
161        let buffers: Vec<_> = self
162            .buffers
163            .into_iter()
164            .map(|wsabuf| wsabuf.into())
165            .collect();
166        OverlappedDataRaw {
167            socket: self.socket,
168            buffers,
169            lp_number_of_bytes_recvd: self.lp_number_of_bytes_recvd as *mut u32,
170            lp_flags: self.lp_flags as *mut u32,
171            lp_overlapped: self.lp_overlapped as *mut WSAOverlappedRaw,
172        }
173    }
174
175    pub unsafe fn to_string(&self) -> String {
176        unsafe {
177            let raw = self.clone().into_raw();
178            if raw.lp_number_of_bytes_recvd.is_null() {
179                format!("OverlappedData:\nlp_number_of_bytes_recvd: null")
180            } else {
181                format!(
182                    "OverlappedData:\nlp_number_of_bytes_recvd: {}",
183                    raw.lp_number_of_bytes_recvd.read()
184                )
185            }
186        }
187    }
188}