1*bb4ee6a4SAndroid Build Coastguard Worker // Documentation for code maintainers:
2*bb4ee6a4SAndroid Build Coastguard Worker //
3*bb4ee6a4SAndroid Build Coastguard Worker // Closure pointers as *c_void
4*bb4ee6a4SAndroid Build Coastguard Worker // -----------------
5*bb4ee6a4SAndroid Build Coastguard Worker // This file interfaces with Slirp's callbacks extensively. As part of that, it passes Rust closures
6*bb4ee6a4SAndroid Build Coastguard Worker // to callbacks as opaque data, and those closures are executed during a call into Slirp; in other
7*bb4ee6a4SAndroid Build Coastguard Worker // words, the sequence of events looks like this:
8*bb4ee6a4SAndroid Build Coastguard Worker // 1. Rust creates a closure C.
9*bb4ee6a4SAndroid Build Coastguard Worker // 2. Rust calls Slirp and gives it callback CB (a Rust func.), and opaque data that contains C.
10*bb4ee6a4SAndroid Build Coastguard Worker // 3. (0...n times) CB runs and unpacks C from the opaque data. a. CB calls C.
11*bb4ee6a4SAndroid Build Coastguard Worker // 4. The call from #2 completes.
12*bb4ee6a4SAndroid Build Coastguard Worker // Closures are represented as trait objects, and trait object references are wide/fat pointers
13*bb4ee6a4SAndroid Build Coastguard Worker // (2x machine pointer size) that contain pointers to the closure's struct & its vtable. Since wide
14*bb4ee6a4SAndroid Build Coastguard Worker // pointers are obviously too large to fit into a *mut c_void (this is the opaque data), we cannot
15*bb4ee6a4SAndroid Build Coastguard Worker // pass them directly. Luckily, wide pointers themselves are simple sized data structures, so we can
16*bb4ee6a4SAndroid Build Coastguard Worker // pass a reference to the wide pointer as a *mut c_void; in other words, the way to pass a closure
17*bb4ee6a4SAndroid Build Coastguard Worker // is to cast &mut &mut some_closure into a *mut c_void. We can then unpack this easily and call
18*bb4ee6a4SAndroid Build Coastguard Worker // the closure.
19*bb4ee6a4SAndroid Build Coastguard Worker //
20*bb4ee6a4SAndroid Build Coastguard Worker // Why is CallbackHandler involved in the outbound (guest -> host) packet path?
21*bb4ee6a4SAndroid Build Coastguard Worker // ----------------------------------------------------------------------------
22*bb4ee6a4SAndroid Build Coastguard Worker // In short, ownership. Since the CallbackHandler is responsible for writing to the guest, it must
23*bb4ee6a4SAndroid Build Coastguard Worker // own the connection/stream that is attached to the guest. Because CallbackHandler owns the
24*bb4ee6a4SAndroid Build Coastguard Worker // connection, it would be significantly complicated to have any other entity read from the
25*bb4ee6a4SAndroid Build Coastguard Worker // connection.
26*bb4ee6a4SAndroid Build Coastguard Worker //
27*bb4ee6a4SAndroid Build Coastguard Worker // Safety assumptions
28*bb4ee6a4SAndroid Build Coastguard Worker // ------------------
29*bb4ee6a4SAndroid Build Coastguard Worker // Most statements explaining the safety of unsafe code depend on libslirp behaving in a safe
30*bb4ee6a4SAndroid Build Coastguard Worker // & expected manner. Given that libslirp is has experienced CVEs related to safety problems,
31*bb4ee6a4SAndroid Build Coastguard Worker // these statements should be taken with a grain of salt. Consumers of this library are STRONGLY
32*bb4ee6a4SAndroid Build Coastguard Worker // RECOMMENDED to run this code in a separate process with strong sandboxing.
33*bb4ee6a4SAndroid Build Coastguard Worker
34*bb4ee6a4SAndroid Build Coastguard Worker // Some bindings of the libslirp API are used, but we want to keep them for completeness
35*bb4ee6a4SAndroid Build Coastguard Worker #![allow(dead_code)]
36*bb4ee6a4SAndroid Build Coastguard Worker
37*bb4ee6a4SAndroid Build Coastguard Worker use std::ffi::CStr;
38*bb4ee6a4SAndroid Build Coastguard Worker use std::ffi::CString;
39*bb4ee6a4SAndroid Build Coastguard Worker use std::fmt;
40*bb4ee6a4SAndroid Build Coastguard Worker use std::io;
41*bb4ee6a4SAndroid Build Coastguard Worker use std::net::Ipv4Addr;
42*bb4ee6a4SAndroid Build Coastguard Worker use std::net::Ipv6Addr;
43*bb4ee6a4SAndroid Build Coastguard Worker use std::ops;
44*bb4ee6a4SAndroid Build Coastguard Worker use std::os::raw::c_char;
45*bb4ee6a4SAndroid Build Coastguard Worker use std::os::raw::c_int;
46*bb4ee6a4SAndroid Build Coastguard Worker use std::os::raw::c_void;
47*bb4ee6a4SAndroid Build Coastguard Worker use std::slice;
48*bb4ee6a4SAndroid Build Coastguard Worker use std::str;
49*bb4ee6a4SAndroid Build Coastguard Worker
50*bb4ee6a4SAndroid Build Coastguard Worker use base::error;
51*bb4ee6a4SAndroid Build Coastguard Worker use base::RawDescriptor;
52*bb4ee6a4SAndroid Build Coastguard Worker use libslirp_sys::*;
53*bb4ee6a4SAndroid Build Coastguard Worker
54*bb4ee6a4SAndroid Build Coastguard Worker use crate::slirp::SlirpError;
55*bb4ee6a4SAndroid Build Coastguard Worker use crate::Error;
56*bb4ee6a4SAndroid Build Coastguard Worker use crate::Result;
57*bb4ee6a4SAndroid Build Coastguard Worker
58*bb4ee6a4SAndroid Build Coastguard Worker /// An instance of libslirp is represented by a Context, which provides methods that consumers use
59*bb4ee6a4SAndroid Build Coastguard Worker /// to interact with Slirp. The Context is also where consumers register their CallbackHandler,
60*bb4ee6a4SAndroid Build Coastguard Worker /// which provides required functions to libslirp, and allows libslirp to communicate back to the
61*bb4ee6a4SAndroid Build Coastguard Worker /// consumer. The Context is intended to be used from an event loop which handles polling for IO
62*bb4ee6a4SAndroid Build Coastguard Worker /// from the guest and host (see `Context.pollfds_fill`, `Context.pollfds_poll`, and
63*bb4ee6a4SAndroid Build Coastguard Worker /// `Context.handle_guest_input`).
64*bb4ee6a4SAndroid Build Coastguard Worker ///
65*bb4ee6a4SAndroid Build Coastguard Worker /// Example data flow for an outbound packet:
66*bb4ee6a4SAndroid Build Coastguard Worker /// 1. Context `ctx` created with CallbackHandler `h`. An event loop (henceforth the slirp loop) is
67*bb4ee6a4SAndroid Build Coastguard Worker /// started, which polls for packets from the guest, and from the outside world (sockets).
68*bb4ee6a4SAndroid Build Coastguard Worker /// 2. Guest emits an ethernet frame. The consumer makes this frame available through their
69*bb4ee6a4SAndroid Build Coastguard Worker /// implementation of `h.read_from_guest`.
70*bb4ee6a4SAndroid Build Coastguard Worker /// 3. The slirp loop is notified there is a packet from the guest, and invokes
71*bb4ee6a4SAndroid Build Coastguard Worker /// `ctx.handle_guest_input`. `ctx.handle_guest_input` reads all currently available packets
72*bb4ee6a4SAndroid Build Coastguard Worker /// using `h.read_from_guest` & returns back to the slirp loop.
73*bb4ee6a4SAndroid Build Coastguard Worker ///
74*bb4ee6a4SAndroid Build Coastguard Worker /// Example data flow for an inbound packet:
75*bb4ee6a4SAndroid Build Coastguard Worker /// 1. Same as above.
76*bb4ee6a4SAndroid Build Coastguard Worker /// 2. An ethernet frame arrives to the host, and gets demuxed by the host kernel into one of the
77*bb4ee6a4SAndroid Build Coastguard Worker /// host sockets opened by libslirp.
78*bb4ee6a4SAndroid Build Coastguard Worker /// 3. The slirp loop receives a notification that data has arrived on one of the libslirp sockets,
79*bb4ee6a4SAndroid Build Coastguard Worker /// and invokes `ctx.pollfds_poll` to notify libslirp. a. libslirp calls into `h.send_packet` to
80*bb4ee6a4SAndroid Build Coastguard Worker /// deliver the packet to the consumer.
81*bb4ee6a4SAndroid Build Coastguard Worker pub struct Context<H> {
82*bb4ee6a4SAndroid Build Coastguard Worker slirp: *mut Slirp,
83*bb4ee6a4SAndroid Build Coastguard Worker callbacks: SlirpCb,
84*bb4ee6a4SAndroid Build Coastguard Worker callback_handler: H,
85*bb4ee6a4SAndroid Build Coastguard Worker }
86*bb4ee6a4SAndroid Build Coastguard Worker
87*bb4ee6a4SAndroid Build Coastguard Worker impl<H> Drop for Context<H> {
drop(&mut self)88*bb4ee6a4SAndroid Build Coastguard Worker fn drop(&mut self) {
89*bb4ee6a4SAndroid Build Coastguard Worker if !self.slirp.is_null() {
90*bb4ee6a4SAndroid Build Coastguard Worker // SAFETY:
91*bb4ee6a4SAndroid Build Coastguard Worker // Safe because self.context is guaranteed to be valid or null upon construction.
92*bb4ee6a4SAndroid Build Coastguard Worker unsafe {
93*bb4ee6a4SAndroid Build Coastguard Worker slirp_cleanup(self.slirp);
94*bb4ee6a4SAndroid Build Coastguard Worker }
95*bb4ee6a4SAndroid Build Coastguard Worker }
96*bb4ee6a4SAndroid Build Coastguard Worker }
97*bb4ee6a4SAndroid Build Coastguard Worker }
98*bb4ee6a4SAndroid Build Coastguard Worker
99*bb4ee6a4SAndroid Build Coastguard Worker /// `CallbackHandler` is the safe Rust interface for the Slirp callbacks. Consumers of Slirp MUST
100*bb4ee6a4SAndroid Build Coastguard Worker /// implement this interface to handle the required callbacks from Slirp.
101*bb4ee6a4SAndroid Build Coastguard Worker ///
102*bb4ee6a4SAndroid Build Coastguard Worker /// ## Notes about timers
103*bb4ee6a4SAndroid Build Coastguard Worker /// To send NDP router advertisements on IPv6, libslirp uses a timer. If IPv6 support is not
104*bb4ee6a4SAndroid Build Coastguard Worker /// needed, the timer callbacks can be left unimplemented.
105*bb4ee6a4SAndroid Build Coastguard Worker ///
106*bb4ee6a4SAndroid Build Coastguard Worker /// Example data flow for timer creation/modification (`timer_new`/`timer_mod`/`timer_free`):
107*bb4ee6a4SAndroid Build Coastguard Worker /// 1. libslirp calls into `timer_new` to request a new timer. `timer_new` creates some entity to
108*bb4ee6a4SAndroid Build Coastguard Worker /// represent the timer and boxes it. A pointer to that boxed entity is returned to libslirp, and
109*bb4ee6a4SAndroid Build Coastguard Worker /// is how libslirp will refer to the timer in the future.
110*bb4ee6a4SAndroid Build Coastguard Worker /// 2. The timer's expire time can be changed when timer_mod is called by libslirp. A pointer to the
111*bb4ee6a4SAndroid Build Coastguard Worker /// boxed timer is passed in by libslirp.
112*bb4ee6a4SAndroid Build Coastguard Worker /// 3. The implementor of `CallbackHandler` is responsible for ensuring that the timer's callback as
113*bb4ee6a4SAndroid Build Coastguard Worker /// provided in `timer_new` is invoked at/after the `expire_time`.
114*bb4ee6a4SAndroid Build Coastguard Worker /// 4. libslirp will free timers using `timer_free` when `slirp_cleanup` runs.
115*bb4ee6a4SAndroid Build Coastguard Worker ///
116*bb4ee6a4SAndroid Build Coastguard Worker /// libslirp never does anything with the timer pointer beyond passing it to/from the the functions
117*bb4ee6a4SAndroid Build Coastguard Worker /// in `CallbackHandler`.
118*bb4ee6a4SAndroid Build Coastguard Worker pub trait CallbackHandler {
119*bb4ee6a4SAndroid Build Coastguard Worker type Timer;
120*bb4ee6a4SAndroid Build Coastguard Worker
121*bb4ee6a4SAndroid Build Coastguard Worker /// Returns a timestamp in nanoseconds relative to the moment that this instance of libslirp
122*bb4ee6a4SAndroid Build Coastguard Worker /// started running.
clock_get_ns(&mut self) -> i64123*bb4ee6a4SAndroid Build Coastguard Worker fn clock_get_ns(&mut self) -> i64;
124*bb4ee6a4SAndroid Build Coastguard Worker
send_packet(&mut self, buf: &[u8]) -> io::Result<usize>125*bb4ee6a4SAndroid Build Coastguard Worker fn send_packet(&mut self, buf: &[u8]) -> io::Result<usize>;
126*bb4ee6a4SAndroid Build Coastguard Worker
127*bb4ee6a4SAndroid Build Coastguard Worker /// Gets an iterator of timers (as raw descriptors) so they can be awaited with a suitable
128*bb4ee6a4SAndroid Build Coastguard Worker /// polling function as part of libslirp's main consumer loop.
get_timers<'a>(&'a self) -> Box<dyn Iterator<Item = &RawDescriptor> + 'a>129*bb4ee6a4SAndroid Build Coastguard Worker fn get_timers<'a>(&'a self) -> Box<dyn Iterator<Item = &RawDescriptor> + 'a>;
130*bb4ee6a4SAndroid Build Coastguard Worker
131*bb4ee6a4SAndroid Build Coastguard Worker /// Runs the handler function for a specific timer.
execute_timer(&mut self, timer: RawDescriptor)132*bb4ee6a4SAndroid Build Coastguard Worker fn execute_timer(&mut self, timer: RawDescriptor);
133*bb4ee6a4SAndroid Build Coastguard Worker
134*bb4ee6a4SAndroid Build Coastguard Worker // Normally in crosvm we refer to FDs as descriptors, because FDs are platform specific;
135*bb4ee6a4SAndroid Build Coastguard Worker // however, this interface is very close to the libslirp FFI, and libslirp follows the Linux
136*bb4ee6a4SAndroid Build Coastguard Worker // philosophy of everything is an FD. Since even Windows refers to FDs in WSAPoll, keeping FD
137*bb4ee6a4SAndroid Build Coastguard Worker // as a concept here helps keep terminology consistent between crosvm code interfacing with
138*bb4ee6a4SAndroid Build Coastguard Worker // libslirp, and libslirp itself.
register_poll_fd(&mut self, fd: i32)139*bb4ee6a4SAndroid Build Coastguard Worker fn register_poll_fd(&mut self, fd: i32);
unregister_poll_fd(&mut self, fd: i32)140*bb4ee6a4SAndroid Build Coastguard Worker fn unregister_poll_fd(&mut self, fd: i32);
141*bb4ee6a4SAndroid Build Coastguard Worker
guest_error(&mut self, msg: &str)142*bb4ee6a4SAndroid Build Coastguard Worker fn guest_error(&mut self, msg: &str);
143*bb4ee6a4SAndroid Build Coastguard Worker
notify(&mut self)144*bb4ee6a4SAndroid Build Coastguard Worker fn notify(&mut self);
145*bb4ee6a4SAndroid Build Coastguard Worker
timer_new(&mut self, callback: Box<dyn FnMut()>) -> Box<Self::Timer>146*bb4ee6a4SAndroid Build Coastguard Worker fn timer_new(&mut self, callback: Box<dyn FnMut()>) -> Box<Self::Timer>;
147*bb4ee6a4SAndroid Build Coastguard Worker
148*bb4ee6a4SAndroid Build Coastguard Worker /// Sets a timer to expire in expire_time_ms - (clock_get_ns() (as ms).
timer_mod(&mut self, timer: &mut Self::Timer, expire_time: i64)149*bb4ee6a4SAndroid Build Coastguard Worker fn timer_mod(&mut self, timer: &mut Self::Timer, expire_time: i64);
150*bb4ee6a4SAndroid Build Coastguard Worker
timer_free(&mut self, timer: Box<Self::Timer>)151*bb4ee6a4SAndroid Build Coastguard Worker fn timer_free(&mut self, timer: Box<Self::Timer>);
152*bb4ee6a4SAndroid Build Coastguard Worker
begin_read_from_guest(&mut self) -> io::Result<()>153*bb4ee6a4SAndroid Build Coastguard Worker fn begin_read_from_guest(&mut self) -> io::Result<()>;
154*bb4ee6a4SAndroid Build Coastguard Worker
end_read_from_guest(&mut self) -> io::Result<&[u8]>155*bb4ee6a4SAndroid Build Coastguard Worker fn end_read_from_guest(&mut self) -> io::Result<&[u8]>;
156*bb4ee6a4SAndroid Build Coastguard Worker }
157*bb4ee6a4SAndroid Build Coastguard Worker
write_handler_callback(buf: *const c_void, len: usize, opaque: *mut c_void) -> isize158*bb4ee6a4SAndroid Build Coastguard Worker extern "C" fn write_handler_callback(buf: *const c_void, len: usize, opaque: *mut c_void) -> isize {
159*bb4ee6a4SAndroid Build Coastguard Worker // SAFETY:
160*bb4ee6a4SAndroid Build Coastguard Worker // Safe because we pass in opaque as exactly this type.
161*bb4ee6a4SAndroid Build Coastguard Worker let closure = unsafe { &mut *(opaque as *mut &mut dyn FnMut(&[u8]) -> isize) };
162*bb4ee6a4SAndroid Build Coastguard Worker
163*bb4ee6a4SAndroid Build Coastguard Worker // SAFETY:
164*bb4ee6a4SAndroid Build Coastguard Worker // Safe because libslirp provides us with a valid buffer & that buffer's length.
165*bb4ee6a4SAndroid Build Coastguard Worker let slice = unsafe { slice::from_raw_parts(buf as *const u8, len) };
166*bb4ee6a4SAndroid Build Coastguard Worker
167*bb4ee6a4SAndroid Build Coastguard Worker closure(slice)
168*bb4ee6a4SAndroid Build Coastguard Worker }
169*bb4ee6a4SAndroid Build Coastguard Worker
read_handler_callback(buf: *mut c_void, len: usize, opaque: *mut c_void) -> isize170*bb4ee6a4SAndroid Build Coastguard Worker extern "C" fn read_handler_callback(buf: *mut c_void, len: usize, opaque: *mut c_void) -> isize {
171*bb4ee6a4SAndroid Build Coastguard Worker // SAFETY:
172*bb4ee6a4SAndroid Build Coastguard Worker // Safe because we pass in opaque as exactly this type.
173*bb4ee6a4SAndroid Build Coastguard Worker let closure = unsafe { &mut *(opaque as *mut &mut dyn FnMut(&mut [u8]) -> isize) };
174*bb4ee6a4SAndroid Build Coastguard Worker
175*bb4ee6a4SAndroid Build Coastguard Worker // SAFETY:
176*bb4ee6a4SAndroid Build Coastguard Worker // Safe because libslirp provides us with a valid buffer & that buffer's length.
177*bb4ee6a4SAndroid Build Coastguard Worker let slice = unsafe { slice::from_raw_parts_mut(buf as *mut u8, len) };
178*bb4ee6a4SAndroid Build Coastguard Worker
179*bb4ee6a4SAndroid Build Coastguard Worker closure(slice)
180*bb4ee6a4SAndroid Build Coastguard Worker }
181*bb4ee6a4SAndroid Build Coastguard Worker
182*bb4ee6a4SAndroid Build Coastguard Worker /// Represents poll events in libslirp's format (e.g. `struct pollfd.[r]events`).
183*bb4ee6a4SAndroid Build Coastguard Worker #[derive(Copy, PartialEq, Eq, Clone, PartialOrd, Ord)]
184*bb4ee6a4SAndroid Build Coastguard Worker pub struct PollEvents(usize);
185*bb4ee6a4SAndroid Build Coastguard Worker
186*bb4ee6a4SAndroid Build Coastguard Worker impl PollEvents {
empty() -> Self187*bb4ee6a4SAndroid Build Coastguard Worker pub fn empty() -> Self {
188*bb4ee6a4SAndroid Build Coastguard Worker PollEvents(0)
189*bb4ee6a4SAndroid Build Coastguard Worker }
poll_in() -> Self190*bb4ee6a4SAndroid Build Coastguard Worker pub fn poll_in() -> Self {
191*bb4ee6a4SAndroid Build Coastguard Worker PollEvents(SLIRP_POLL_IN as usize)
192*bb4ee6a4SAndroid Build Coastguard Worker }
poll_out() -> Self193*bb4ee6a4SAndroid Build Coastguard Worker pub fn poll_out() -> Self {
194*bb4ee6a4SAndroid Build Coastguard Worker PollEvents(SLIRP_POLL_OUT as usize)
195*bb4ee6a4SAndroid Build Coastguard Worker }
poll_pri() -> Self196*bb4ee6a4SAndroid Build Coastguard Worker pub fn poll_pri() -> Self {
197*bb4ee6a4SAndroid Build Coastguard Worker PollEvents(SLIRP_POLL_PRI as usize)
198*bb4ee6a4SAndroid Build Coastguard Worker }
poll_err() -> Self199*bb4ee6a4SAndroid Build Coastguard Worker pub fn poll_err() -> Self {
200*bb4ee6a4SAndroid Build Coastguard Worker PollEvents(SLIRP_POLL_ERR as usize)
201*bb4ee6a4SAndroid Build Coastguard Worker }
poll_hup() -> Self202*bb4ee6a4SAndroid Build Coastguard Worker pub fn poll_hup() -> Self {
203*bb4ee6a4SAndroid Build Coastguard Worker PollEvents(SLIRP_POLL_HUP as usize)
204*bb4ee6a4SAndroid Build Coastguard Worker }
contains<T: Into<Self>>(&self, other: T) -> bool205*bb4ee6a4SAndroid Build Coastguard Worker pub fn contains<T: Into<Self>>(&self, other: T) -> bool {
206*bb4ee6a4SAndroid Build Coastguard Worker let other = other.into();
207*bb4ee6a4SAndroid Build Coastguard Worker (*self & other) == other
208*bb4ee6a4SAndroid Build Coastguard Worker }
is_empty(&self) -> bool209*bb4ee6a4SAndroid Build Coastguard Worker pub fn is_empty(&self) -> bool {
210*bb4ee6a4SAndroid Build Coastguard Worker self.0 == 0
211*bb4ee6a4SAndroid Build Coastguard Worker }
has_in(&self) -> bool212*bb4ee6a4SAndroid Build Coastguard Worker pub fn has_in(&self) -> bool {
213*bb4ee6a4SAndroid Build Coastguard Worker self.contains(PollEvents::poll_in())
214*bb4ee6a4SAndroid Build Coastguard Worker }
has_out(&self) -> bool215*bb4ee6a4SAndroid Build Coastguard Worker pub fn has_out(&self) -> bool {
216*bb4ee6a4SAndroid Build Coastguard Worker self.contains(PollEvents::poll_out())
217*bb4ee6a4SAndroid Build Coastguard Worker }
has_pri(&self) -> bool218*bb4ee6a4SAndroid Build Coastguard Worker pub fn has_pri(&self) -> bool {
219*bb4ee6a4SAndroid Build Coastguard Worker self.contains(PollEvents::poll_pri())
220*bb4ee6a4SAndroid Build Coastguard Worker }
has_err(&self) -> bool221*bb4ee6a4SAndroid Build Coastguard Worker pub fn has_err(&self) -> bool {
222*bb4ee6a4SAndroid Build Coastguard Worker self.contains(PollEvents::poll_err())
223*bb4ee6a4SAndroid Build Coastguard Worker }
has_hup(&self) -> bool224*bb4ee6a4SAndroid Build Coastguard Worker pub fn has_hup(&self) -> bool {
225*bb4ee6a4SAndroid Build Coastguard Worker self.contains(PollEvents::poll_hup())
226*bb4ee6a4SAndroid Build Coastguard Worker }
227*bb4ee6a4SAndroid Build Coastguard Worker }
228*bb4ee6a4SAndroid Build Coastguard Worker
229*bb4ee6a4SAndroid Build Coastguard Worker impl<T: Into<PollEvents>> ops::BitAnd<T> for PollEvents {
230*bb4ee6a4SAndroid Build Coastguard Worker type Output = PollEvents;
231*bb4ee6a4SAndroid Build Coastguard Worker
bitand(self, other: T) -> PollEvents232*bb4ee6a4SAndroid Build Coastguard Worker fn bitand(self, other: T) -> PollEvents {
233*bb4ee6a4SAndroid Build Coastguard Worker PollEvents(self.0 & other.into().0)
234*bb4ee6a4SAndroid Build Coastguard Worker }
235*bb4ee6a4SAndroid Build Coastguard Worker }
236*bb4ee6a4SAndroid Build Coastguard Worker
237*bb4ee6a4SAndroid Build Coastguard Worker impl<T: Into<PollEvents>> ops::BitOr<T> for PollEvents {
238*bb4ee6a4SAndroid Build Coastguard Worker type Output = PollEvents;
239*bb4ee6a4SAndroid Build Coastguard Worker
bitor(self, other: T) -> PollEvents240*bb4ee6a4SAndroid Build Coastguard Worker fn bitor(self, other: T) -> PollEvents {
241*bb4ee6a4SAndroid Build Coastguard Worker PollEvents(self.0 | other.into().0)
242*bb4ee6a4SAndroid Build Coastguard Worker }
243*bb4ee6a4SAndroid Build Coastguard Worker }
244*bb4ee6a4SAndroid Build Coastguard Worker
245*bb4ee6a4SAndroid Build Coastguard Worker impl<T: Into<PollEvents>> ops::BitOrAssign<T> for PollEvents {
bitor_assign(&mut self, other: T)246*bb4ee6a4SAndroid Build Coastguard Worker fn bitor_assign(&mut self, other: T) {
247*bb4ee6a4SAndroid Build Coastguard Worker self.0 |= other.into().0;
248*bb4ee6a4SAndroid Build Coastguard Worker }
249*bb4ee6a4SAndroid Build Coastguard Worker }
250*bb4ee6a4SAndroid Build Coastguard Worker
251*bb4ee6a4SAndroid Build Coastguard Worker impl fmt::Debug for PollEvents {
fmt(&self, fmt: &mut fmt::Formatter) -> fmt::Result252*bb4ee6a4SAndroid Build Coastguard Worker fn fmt(&self, fmt: &mut fmt::Formatter) -> fmt::Result {
253*bb4ee6a4SAndroid Build Coastguard Worker let mut one = false;
254*bb4ee6a4SAndroid Build Coastguard Worker let flags = [
255*bb4ee6a4SAndroid Build Coastguard Worker (PollEvents(SLIRP_POLL_IN as usize), "IN"),
256*bb4ee6a4SAndroid Build Coastguard Worker (PollEvents(SLIRP_POLL_OUT as usize), "OUT"),
257*bb4ee6a4SAndroid Build Coastguard Worker (PollEvents(SLIRP_POLL_PRI as usize), "PRI"),
258*bb4ee6a4SAndroid Build Coastguard Worker (PollEvents(SLIRP_POLL_ERR as usize), "ERR"),
259*bb4ee6a4SAndroid Build Coastguard Worker (PollEvents(SLIRP_POLL_HUP as usize), "HUP"),
260*bb4ee6a4SAndroid Build Coastguard Worker ];
261*bb4ee6a4SAndroid Build Coastguard Worker
262*bb4ee6a4SAndroid Build Coastguard Worker for &(flag, msg) in &flags {
263*bb4ee6a4SAndroid Build Coastguard Worker if self.contains(flag) {
264*bb4ee6a4SAndroid Build Coastguard Worker if one {
265*bb4ee6a4SAndroid Build Coastguard Worker write!(fmt, " | ")?
266*bb4ee6a4SAndroid Build Coastguard Worker }
267*bb4ee6a4SAndroid Build Coastguard Worker write!(fmt, "{}", msg)?;
268*bb4ee6a4SAndroid Build Coastguard Worker
269*bb4ee6a4SAndroid Build Coastguard Worker one = true
270*bb4ee6a4SAndroid Build Coastguard Worker }
271*bb4ee6a4SAndroid Build Coastguard Worker }
272*bb4ee6a4SAndroid Build Coastguard Worker
273*bb4ee6a4SAndroid Build Coastguard Worker if !one {
274*bb4ee6a4SAndroid Build Coastguard Worker fmt.write_str("(empty)")?;
275*bb4ee6a4SAndroid Build Coastguard Worker }
276*bb4ee6a4SAndroid Build Coastguard Worker
277*bb4ee6a4SAndroid Build Coastguard Worker Ok(())
278*bb4ee6a4SAndroid Build Coastguard Worker }
279*bb4ee6a4SAndroid Build Coastguard Worker }
280*bb4ee6a4SAndroid Build Coastguard Worker
add_poll_handler_callback(fd: c_int, events: c_int, opaque: *mut c_void) -> c_int281*bb4ee6a4SAndroid Build Coastguard Worker extern "C" fn add_poll_handler_callback(fd: c_int, events: c_int, opaque: *mut c_void) -> c_int {
282*bb4ee6a4SAndroid Build Coastguard Worker // SAFETY:
283*bb4ee6a4SAndroid Build Coastguard Worker // Safe because we pass in opaque as exactly this type.
284*bb4ee6a4SAndroid Build Coastguard Worker let closure = unsafe { &mut *(opaque as *mut &mut dyn FnMut(i32, PollEvents) -> i32) };
285*bb4ee6a4SAndroid Build Coastguard Worker
286*bb4ee6a4SAndroid Build Coastguard Worker closure(fd, PollEvents(events as usize))
287*bb4ee6a4SAndroid Build Coastguard Worker }
288*bb4ee6a4SAndroid Build Coastguard Worker
get_revents_handler_callback(idx: c_int, opaque: *mut c_void) -> c_int289*bb4ee6a4SAndroid Build Coastguard Worker extern "C" fn get_revents_handler_callback(idx: c_int, opaque: *mut c_void) -> c_int {
290*bb4ee6a4SAndroid Build Coastguard Worker // SAFETY:
291*bb4ee6a4SAndroid Build Coastguard Worker // Safe because we pass in opaque as exactly this type.
292*bb4ee6a4SAndroid Build Coastguard Worker let closure = unsafe { &mut *(opaque as *mut &mut dyn FnMut(i32) -> PollEvents) };
293*bb4ee6a4SAndroid Build Coastguard Worker
294*bb4ee6a4SAndroid Build Coastguard Worker closure(idx).0 as c_int
295*bb4ee6a4SAndroid Build Coastguard Worker }
296*bb4ee6a4SAndroid Build Coastguard Worker
297*bb4ee6a4SAndroid Build Coastguard Worker /// Inbound packets from libslirp are delivered to this handler, which passes them on to the
298*bb4ee6a4SAndroid Build Coastguard Worker /// Context's CallbackHandler for forwarding to the guest.
send_packet_handler<H: CallbackHandler>( buf: *const c_void, len: usize, opaque: *mut c_void, ) -> isize299*bb4ee6a4SAndroid Build Coastguard Worker extern "C" fn send_packet_handler<H: CallbackHandler>(
300*bb4ee6a4SAndroid Build Coastguard Worker buf: *const c_void,
301*bb4ee6a4SAndroid Build Coastguard Worker len: usize,
302*bb4ee6a4SAndroid Build Coastguard Worker opaque: *mut c_void,
303*bb4ee6a4SAndroid Build Coastguard Worker ) -> isize {
304*bb4ee6a4SAndroid Build Coastguard Worker // SAFETY:
305*bb4ee6a4SAndroid Build Coastguard Worker // Safe because libslirp gives us a valid buffer & that buffer's length.
306*bb4ee6a4SAndroid Build Coastguard Worker let slice = unsafe { slice::from_raw_parts(buf as *const u8, len) };
307*bb4ee6a4SAndroid Build Coastguard Worker
308*bb4ee6a4SAndroid Build Coastguard Worker // SAFETY:
309*bb4ee6a4SAndroid Build Coastguard Worker // Safe because we pass in opaque as exactly this type when constructing the Slirp object.
310*bb4ee6a4SAndroid Build Coastguard Worker let res = unsafe {
311*bb4ee6a4SAndroid Build Coastguard Worker (*(opaque as *mut Context<H>))
312*bb4ee6a4SAndroid Build Coastguard Worker .callback_handler
313*bb4ee6a4SAndroid Build Coastguard Worker .send_packet(slice)
314*bb4ee6a4SAndroid Build Coastguard Worker };
315*bb4ee6a4SAndroid Build Coastguard Worker
316*bb4ee6a4SAndroid Build Coastguard Worker match res {
317*bb4ee6a4SAndroid Build Coastguard Worker Ok(res) => res as isize,
318*bb4ee6a4SAndroid Build Coastguard Worker Err(e) => {
319*bb4ee6a4SAndroid Build Coastguard Worker error!("send_packet error: {}", e);
320*bb4ee6a4SAndroid Build Coastguard Worker -1
321*bb4ee6a4SAndroid Build Coastguard Worker }
322*bb4ee6a4SAndroid Build Coastguard Worker }
323*bb4ee6a4SAndroid Build Coastguard Worker }
324*bb4ee6a4SAndroid Build Coastguard Worker
guest_error_handler<H: CallbackHandler>(msg: *const c_char, opaque: *mut c_void)325*bb4ee6a4SAndroid Build Coastguard Worker extern "C" fn guest_error_handler<H: CallbackHandler>(msg: *const c_char, opaque: *mut c_void) {
326*bb4ee6a4SAndroid Build Coastguard Worker // SAFETY:
327*bb4ee6a4SAndroid Build Coastguard Worker // Safe because libslirp gives us a valid C string representing the error message.
328*bb4ee6a4SAndroid Build Coastguard Worker let msg = str::from_utf8(unsafe { CStr::from_ptr(msg) }.to_bytes()).unwrap_or("");
329*bb4ee6a4SAndroid Build Coastguard Worker
330*bb4ee6a4SAndroid Build Coastguard Worker // SAFETY:
331*bb4ee6a4SAndroid Build Coastguard Worker // Safe because we pass in opaque as exactly this type when constructing the Slirp object.
332*bb4ee6a4SAndroid Build Coastguard Worker unsafe {
333*bb4ee6a4SAndroid Build Coastguard Worker (*(opaque as *mut Context<H>))
334*bb4ee6a4SAndroid Build Coastguard Worker .callback_handler
335*bb4ee6a4SAndroid Build Coastguard Worker .guest_error(msg)
336*bb4ee6a4SAndroid Build Coastguard Worker }
337*bb4ee6a4SAndroid Build Coastguard Worker }
338*bb4ee6a4SAndroid Build Coastguard Worker
clock_get_ns_handler<H: CallbackHandler>(opaque: *mut c_void) -> i64339*bb4ee6a4SAndroid Build Coastguard Worker extern "C" fn clock_get_ns_handler<H: CallbackHandler>(opaque: *mut c_void) -> i64 {
340*bb4ee6a4SAndroid Build Coastguard Worker // SAFETY:
341*bb4ee6a4SAndroid Build Coastguard Worker // Safe because we pass in opaque as exactly this type when constructing the Slirp object.
342*bb4ee6a4SAndroid Build Coastguard Worker unsafe {
343*bb4ee6a4SAndroid Build Coastguard Worker (*(opaque as *mut Context<H>))
344*bb4ee6a4SAndroid Build Coastguard Worker .callback_handler
345*bb4ee6a4SAndroid Build Coastguard Worker .clock_get_ns()
346*bb4ee6a4SAndroid Build Coastguard Worker }
347*bb4ee6a4SAndroid Build Coastguard Worker }
348*bb4ee6a4SAndroid Build Coastguard Worker
timer_new_handler<H: CallbackHandler>( cb: SlirpTimerCb, cb_opaque: *mut c_void, opaque: *mut c_void, ) -> *mut c_void349*bb4ee6a4SAndroid Build Coastguard Worker extern "C" fn timer_new_handler<H: CallbackHandler>(
350*bb4ee6a4SAndroid Build Coastguard Worker cb: SlirpTimerCb,
351*bb4ee6a4SAndroid Build Coastguard Worker cb_opaque: *mut c_void,
352*bb4ee6a4SAndroid Build Coastguard Worker opaque: *mut c_void,
353*bb4ee6a4SAndroid Build Coastguard Worker ) -> *mut c_void {
354*bb4ee6a4SAndroid Build Coastguard Worker let callback = Box::new(move || {
355*bb4ee6a4SAndroid Build Coastguard Worker if let Some(cb) = cb {
356*bb4ee6a4SAndroid Build Coastguard Worker // SAFETY:
357*bb4ee6a4SAndroid Build Coastguard Worker // Safe because libslirp gives us a valid callback function to call.
358*bb4ee6a4SAndroid Build Coastguard Worker unsafe {
359*bb4ee6a4SAndroid Build Coastguard Worker cb(cb_opaque);
360*bb4ee6a4SAndroid Build Coastguard Worker }
361*bb4ee6a4SAndroid Build Coastguard Worker }
362*bb4ee6a4SAndroid Build Coastguard Worker });
363*bb4ee6a4SAndroid Build Coastguard Worker
364*bb4ee6a4SAndroid Build Coastguard Worker // SAFETY:
365*bb4ee6a4SAndroid Build Coastguard Worker // Safe because we pass in opaque as exactly this type when constructing the Slirp object.
366*bb4ee6a4SAndroid Build Coastguard Worker let timer = unsafe {
367*bb4ee6a4SAndroid Build Coastguard Worker (*(opaque as *mut Context<H>))
368*bb4ee6a4SAndroid Build Coastguard Worker .callback_handler
369*bb4ee6a4SAndroid Build Coastguard Worker .timer_new(callback)
370*bb4ee6a4SAndroid Build Coastguard Worker };
371*bb4ee6a4SAndroid Build Coastguard Worker
372*bb4ee6a4SAndroid Build Coastguard Worker Box::into_raw(timer) as *mut c_void
373*bb4ee6a4SAndroid Build Coastguard Worker }
374*bb4ee6a4SAndroid Build Coastguard Worker
timer_free_handler<H: CallbackHandler>(timer: *mut c_void, opaque: *mut c_void)375*bb4ee6a4SAndroid Build Coastguard Worker extern "C" fn timer_free_handler<H: CallbackHandler>(timer: *mut c_void, opaque: *mut c_void) {
376*bb4ee6a4SAndroid Build Coastguard Worker // SAFETY:
377*bb4ee6a4SAndroid Build Coastguard Worker // Safe because we pass in opaque as exactly this type when constructing the Slirp object.
378*bb4ee6a4SAndroid Build Coastguard Worker // Also, timer was created by us as exactly the type we unpack into.
379*bb4ee6a4SAndroid Build Coastguard Worker unsafe {
380*bb4ee6a4SAndroid Build Coastguard Worker let timer = Box::from_raw(timer as *mut H::Timer);
381*bb4ee6a4SAndroid Build Coastguard Worker (*(opaque as *mut Context<H>))
382*bb4ee6a4SAndroid Build Coastguard Worker .callback_handler
383*bb4ee6a4SAndroid Build Coastguard Worker .timer_free(timer);
384*bb4ee6a4SAndroid Build Coastguard Worker }
385*bb4ee6a4SAndroid Build Coastguard Worker }
386*bb4ee6a4SAndroid Build Coastguard Worker
timer_mod_handler<H: CallbackHandler>( timer: *mut c_void, expire_time: i64, opaque: *mut c_void, )387*bb4ee6a4SAndroid Build Coastguard Worker extern "C" fn timer_mod_handler<H: CallbackHandler>(
388*bb4ee6a4SAndroid Build Coastguard Worker timer: *mut c_void,
389*bb4ee6a4SAndroid Build Coastguard Worker expire_time: i64,
390*bb4ee6a4SAndroid Build Coastguard Worker opaque: *mut c_void,
391*bb4ee6a4SAndroid Build Coastguard Worker ) {
392*bb4ee6a4SAndroid Build Coastguard Worker // SAFETY:
393*bb4ee6a4SAndroid Build Coastguard Worker // Safe because:
394*bb4ee6a4SAndroid Build Coastguard Worker // 1. We pass in opaque as exactly this type when constructing the Slirp object.
395*bb4ee6a4SAndroid Build Coastguard Worker // 2. timer was created by us as exactly the type we unpack into
396*bb4ee6a4SAndroid Build Coastguard Worker // 3. libslirp is responsible for freeing timer, so forgetting about it is safe.
397*bb4ee6a4SAndroid Build Coastguard Worker unsafe {
398*bb4ee6a4SAndroid Build Coastguard Worker let mut timer = Box::from_raw(timer as *mut H::Timer);
399*bb4ee6a4SAndroid Build Coastguard Worker (*(opaque as *mut Context<H>))
400*bb4ee6a4SAndroid Build Coastguard Worker .callback_handler
401*bb4ee6a4SAndroid Build Coastguard Worker .timer_mod(&mut timer, expire_time);
402*bb4ee6a4SAndroid Build Coastguard Worker Box::into_raw(timer);
403*bb4ee6a4SAndroid Build Coastguard Worker }
404*bb4ee6a4SAndroid Build Coastguard Worker }
405*bb4ee6a4SAndroid Build Coastguard Worker
register_poll_fd_handler<H: CallbackHandler>(fd: c_int, opaque: *mut c_void)406*bb4ee6a4SAndroid Build Coastguard Worker extern "C" fn register_poll_fd_handler<H: CallbackHandler>(fd: c_int, opaque: *mut c_void) {
407*bb4ee6a4SAndroid Build Coastguard Worker // SAFETY:
408*bb4ee6a4SAndroid Build Coastguard Worker // Safe because we pass in opaque as exactly this type when constructing the Slirp object.
409*bb4ee6a4SAndroid Build Coastguard Worker unsafe {
410*bb4ee6a4SAndroid Build Coastguard Worker (*(opaque as *mut Context<H>))
411*bb4ee6a4SAndroid Build Coastguard Worker .callback_handler
412*bb4ee6a4SAndroid Build Coastguard Worker .register_poll_fd(fd)
413*bb4ee6a4SAndroid Build Coastguard Worker }
414*bb4ee6a4SAndroid Build Coastguard Worker }
415*bb4ee6a4SAndroid Build Coastguard Worker
unregister_poll_fd_handler<H: CallbackHandler>(fd: c_int, opaque: *mut c_void)416*bb4ee6a4SAndroid Build Coastguard Worker extern "C" fn unregister_poll_fd_handler<H: CallbackHandler>(fd: c_int, opaque: *mut c_void) {
417*bb4ee6a4SAndroid Build Coastguard Worker // SAFETY:
418*bb4ee6a4SAndroid Build Coastguard Worker // Safe because we pass in opaque as exactly this type when constructing the Slirp object.
419*bb4ee6a4SAndroid Build Coastguard Worker unsafe {
420*bb4ee6a4SAndroid Build Coastguard Worker (*(opaque as *mut Context<H>))
421*bb4ee6a4SAndroid Build Coastguard Worker .callback_handler
422*bb4ee6a4SAndroid Build Coastguard Worker .unregister_poll_fd(fd)
423*bb4ee6a4SAndroid Build Coastguard Worker }
424*bb4ee6a4SAndroid Build Coastguard Worker }
425*bb4ee6a4SAndroid Build Coastguard Worker
notify_handler<H: CallbackHandler>(opaque: *mut c_void)426*bb4ee6a4SAndroid Build Coastguard Worker extern "C" fn notify_handler<H: CallbackHandler>(opaque: *mut c_void) {
427*bb4ee6a4SAndroid Build Coastguard Worker // SAFETY:
428*bb4ee6a4SAndroid Build Coastguard Worker // Safe because we pass in opaque as exactly this type when constructing the Slirp object.
429*bb4ee6a4SAndroid Build Coastguard Worker unsafe { (*(opaque as *mut Context<H>)).callback_handler.notify() }
430*bb4ee6a4SAndroid Build Coastguard Worker }
431*bb4ee6a4SAndroid Build Coastguard Worker
432*bb4ee6a4SAndroid Build Coastguard Worker impl<H: CallbackHandler> Context<H> {
433*bb4ee6a4SAndroid Build Coastguard Worker /// Create a new instance of the libslirp context.
434*bb4ee6a4SAndroid Build Coastguard Worker ///
435*bb4ee6a4SAndroid Build Coastguard Worker /// The parameters which are prefixed by "host" refer to the system on which libslirp runs;
436*bb4ee6a4SAndroid Build Coastguard Worker /// for example, host_v4_address is the IP address of the host system that the guest will be
437*bb4ee6a4SAndroid Build Coastguard Worker /// able to connect to.
438*bb4ee6a4SAndroid Build Coastguard Worker ///
439*bb4ee6a4SAndroid Build Coastguard Worker /// `host_v[4|6]_address` maps to the host's local loopback interface.
440*bb4ee6a4SAndroid Build Coastguard Worker /// `dns_server_` options configure the DNS server provided on the virtual network by libslirp.
new( disable_access_to_host: bool, ipv4_enabled: bool, virtual_network_v4_address: Ipv4Addr, virtual_network_v4_mask: Ipv4Addr, host_v4_address: Ipv4Addr, ipv6_enabled: bool, virtual_network_v6_address: Ipv6Addr, virtual_network_v6_prefix_len: u8, host_v6_address: Ipv6Addr, host_hostname: Option<String>, dhcp_start_addr: Ipv4Addr, dns_server_v4_addr: Ipv4Addr, dns_server_v6_addr: Ipv6Addr, virtual_network_dns_search_domains: Vec<String>, dns_server_domain_name: Option<String>, callback_handler: H, ) -> Result<Box<Context<H>>>441*bb4ee6a4SAndroid Build Coastguard Worker pub fn new(
442*bb4ee6a4SAndroid Build Coastguard Worker disable_access_to_host: bool,
443*bb4ee6a4SAndroid Build Coastguard Worker ipv4_enabled: bool,
444*bb4ee6a4SAndroid Build Coastguard Worker virtual_network_v4_address: Ipv4Addr,
445*bb4ee6a4SAndroid Build Coastguard Worker virtual_network_v4_mask: Ipv4Addr,
446*bb4ee6a4SAndroid Build Coastguard Worker host_v4_address: Ipv4Addr,
447*bb4ee6a4SAndroid Build Coastguard Worker ipv6_enabled: bool,
448*bb4ee6a4SAndroid Build Coastguard Worker virtual_network_v6_address: Ipv6Addr,
449*bb4ee6a4SAndroid Build Coastguard Worker virtual_network_v6_prefix_len: u8,
450*bb4ee6a4SAndroid Build Coastguard Worker host_v6_address: Ipv6Addr,
451*bb4ee6a4SAndroid Build Coastguard Worker host_hostname: Option<String>,
452*bb4ee6a4SAndroid Build Coastguard Worker dhcp_start_addr: Ipv4Addr,
453*bb4ee6a4SAndroid Build Coastguard Worker dns_server_v4_addr: Ipv4Addr,
454*bb4ee6a4SAndroid Build Coastguard Worker dns_server_v6_addr: Ipv6Addr,
455*bb4ee6a4SAndroid Build Coastguard Worker virtual_network_dns_search_domains: Vec<String>,
456*bb4ee6a4SAndroid Build Coastguard Worker dns_server_domain_name: Option<String>,
457*bb4ee6a4SAndroid Build Coastguard Worker callback_handler: H,
458*bb4ee6a4SAndroid Build Coastguard Worker ) -> Result<Box<Context<H>>> {
459*bb4ee6a4SAndroid Build Coastguard Worker let mut ret = Box::new(Context {
460*bb4ee6a4SAndroid Build Coastguard Worker slirp: std::ptr::null_mut(),
461*bb4ee6a4SAndroid Build Coastguard Worker callbacks: SlirpCb {
462*bb4ee6a4SAndroid Build Coastguard Worker send_packet: Some(send_packet_handler::<H>),
463*bb4ee6a4SAndroid Build Coastguard Worker guest_error: Some(guest_error_handler::<H>),
464*bb4ee6a4SAndroid Build Coastguard Worker clock_get_ns: Some(clock_get_ns_handler::<H>),
465*bb4ee6a4SAndroid Build Coastguard Worker timer_new: Some(timer_new_handler::<H>),
466*bb4ee6a4SAndroid Build Coastguard Worker timer_free: Some(timer_free_handler::<H>),
467*bb4ee6a4SAndroid Build Coastguard Worker timer_mod: Some(timer_mod_handler::<H>),
468*bb4ee6a4SAndroid Build Coastguard Worker register_poll_fd: Some(register_poll_fd_handler::<H>),
469*bb4ee6a4SAndroid Build Coastguard Worker unregister_poll_fd: Some(unregister_poll_fd_handler::<H>),
470*bb4ee6a4SAndroid Build Coastguard Worker notify: Some(notify_handler::<H>),
471*bb4ee6a4SAndroid Build Coastguard Worker },
472*bb4ee6a4SAndroid Build Coastguard Worker callback_handler,
473*bb4ee6a4SAndroid Build Coastguard Worker });
474*bb4ee6a4SAndroid Build Coastguard Worker
475*bb4ee6a4SAndroid Build Coastguard Worker let cstr_dns_search: Vec<_> = virtual_network_dns_search_domains
476*bb4ee6a4SAndroid Build Coastguard Worker .iter()
477*bb4ee6a4SAndroid Build Coastguard Worker .map(|arg| CString::new(arg.clone().into_bytes()).unwrap())
478*bb4ee6a4SAndroid Build Coastguard Worker .collect();
479*bb4ee6a4SAndroid Build Coastguard Worker let mut p_dns_search: Vec<_> = cstr_dns_search.iter().map(|arg| arg.as_ptr()).collect();
480*bb4ee6a4SAndroid Build Coastguard Worker p_dns_search.push(std::ptr::null());
481*bb4ee6a4SAndroid Build Coastguard Worker
482*bb4ee6a4SAndroid Build Coastguard Worker let host_hostname = host_hostname.and_then(|s| CString::new(s).ok());
483*bb4ee6a4SAndroid Build Coastguard Worker let dns_server_domain_name = dns_server_domain_name.and_then(|s| CString::new(s).ok());
484*bb4ee6a4SAndroid Build Coastguard Worker let rust_context_ptr = &*ret as *const _ as *mut _;
485*bb4ee6a4SAndroid Build Coastguard Worker
486*bb4ee6a4SAndroid Build Coastguard Worker let as_ptr = |p: &Option<CString>| p.as_ref().map_or(std::ptr::null(), |s| s.as_ptr());
487*bb4ee6a4SAndroid Build Coastguard Worker
488*bb4ee6a4SAndroid Build Coastguard Worker let slirp_config = SlirpConfig {
489*bb4ee6a4SAndroid Build Coastguard Worker version: 1,
490*bb4ee6a4SAndroid Build Coastguard Worker restricted: 0,
491*bb4ee6a4SAndroid Build Coastguard Worker disable_dhcp: false,
492*bb4ee6a4SAndroid Build Coastguard Worker in_enabled: ipv4_enabled,
493*bb4ee6a4SAndroid Build Coastguard Worker vnetwork: virtual_network_v4_address.into(),
494*bb4ee6a4SAndroid Build Coastguard Worker vnetmask: virtual_network_v4_mask.into(),
495*bb4ee6a4SAndroid Build Coastguard Worker vhost: host_v4_address.into(),
496*bb4ee6a4SAndroid Build Coastguard Worker in6_enabled: ipv6_enabled,
497*bb4ee6a4SAndroid Build Coastguard Worker vprefix_addr6: virtual_network_v6_address.into(),
498*bb4ee6a4SAndroid Build Coastguard Worker vprefix_len: virtual_network_v6_prefix_len,
499*bb4ee6a4SAndroid Build Coastguard Worker vhost6: host_v6_address.into(),
500*bb4ee6a4SAndroid Build Coastguard Worker vhostname: as_ptr(&host_hostname),
501*bb4ee6a4SAndroid Build Coastguard Worker tftp_server_name: std::ptr::null(),
502*bb4ee6a4SAndroid Build Coastguard Worker tftp_path: std::ptr::null(),
503*bb4ee6a4SAndroid Build Coastguard Worker bootfile: std::ptr::null(),
504*bb4ee6a4SAndroid Build Coastguard Worker vdhcp_start: dhcp_start_addr.into(),
505*bb4ee6a4SAndroid Build Coastguard Worker vnameserver: dns_server_v4_addr.into(),
506*bb4ee6a4SAndroid Build Coastguard Worker vnameserver6: dns_server_v6_addr.into(),
507*bb4ee6a4SAndroid Build Coastguard Worker vdnssearch: p_dns_search.as_ptr() as *mut *const _,
508*bb4ee6a4SAndroid Build Coastguard Worker vdomainname: as_ptr(&dns_server_domain_name),
509*bb4ee6a4SAndroid Build Coastguard Worker if_mtu: 0,
510*bb4ee6a4SAndroid Build Coastguard Worker if_mru: 0,
511*bb4ee6a4SAndroid Build Coastguard Worker disable_host_loopback: disable_access_to_host,
512*bb4ee6a4SAndroid Build Coastguard Worker enable_emu: false,
513*bb4ee6a4SAndroid Build Coastguard Worker outbound_addr: std::ptr::null(),
514*bb4ee6a4SAndroid Build Coastguard Worker outbound_addr6: std::ptr::null(),
515*bb4ee6a4SAndroid Build Coastguard Worker disable_dns: false,
516*bb4ee6a4SAndroid Build Coastguard Worker };
517*bb4ee6a4SAndroid Build Coastguard Worker
518*bb4ee6a4SAndroid Build Coastguard Worker // SAFETY:
519*bb4ee6a4SAndroid Build Coastguard Worker // Safe because we pass valid pointers (or null as appropriate) as parameters and we check
520*bb4ee6a4SAndroid Build Coastguard Worker // that the return value is valid.
521*bb4ee6a4SAndroid Build Coastguard Worker let slirp = unsafe {
522*bb4ee6a4SAndroid Build Coastguard Worker slirp_new(
523*bb4ee6a4SAndroid Build Coastguard Worker &slirp_config,
524*bb4ee6a4SAndroid Build Coastguard Worker &ret.callbacks,
525*bb4ee6a4SAndroid Build Coastguard Worker // This value is passed to callbacks as opaque data, which allows those callbacks
526*bb4ee6a4SAndroid Build Coastguard Worker // to get access to the Context struct. It allows them to invoke the appropriate
527*bb4ee6a4SAndroid Build Coastguard Worker // methods on the CallbackHandler to notify it about new packets, get data about
528*bb4ee6a4SAndroid Build Coastguard Worker // sockets that are ready for reading, etc.
529*bb4ee6a4SAndroid Build Coastguard Worker rust_context_ptr,
530*bb4ee6a4SAndroid Build Coastguard Worker )
531*bb4ee6a4SAndroid Build Coastguard Worker };
532*bb4ee6a4SAndroid Build Coastguard Worker assert!(!slirp.is_null());
533*bb4ee6a4SAndroid Build Coastguard Worker match ret.callback_handler.begin_read_from_guest() {
534*bb4ee6a4SAndroid Build Coastguard Worker Err(e) if e.kind() == std::io::ErrorKind::BrokenPipe => {
535*bb4ee6a4SAndroid Build Coastguard Worker return Err(Error::Slirp(SlirpError::BrokenPipe(e)));
536*bb4ee6a4SAndroid Build Coastguard Worker }
537*bb4ee6a4SAndroid Build Coastguard Worker Err(e) => {
538*bb4ee6a4SAndroid Build Coastguard Worker return Err(Error::Slirp(SlirpError::OverlappedError(e)));
539*bb4ee6a4SAndroid Build Coastguard Worker }
540*bb4ee6a4SAndroid Build Coastguard Worker _ => {}
541*bb4ee6a4SAndroid Build Coastguard Worker }
542*bb4ee6a4SAndroid Build Coastguard Worker ret.slirp = slirp;
543*bb4ee6a4SAndroid Build Coastguard Worker Ok(ret)
544*bb4ee6a4SAndroid Build Coastguard Worker }
545*bb4ee6a4SAndroid Build Coastguard Worker
546*bb4ee6a4SAndroid Build Coastguard Worker /// Reads from the guest & injects into Slirp. This method reads until an error is encountered
547*bb4ee6a4SAndroid Build Coastguard Worker /// or io::ErrorKind::WouldBlock is returned by the callback_handler's read_from_guest.
handle_guest_input(&mut self) -> Result<()>548*bb4ee6a4SAndroid Build Coastguard Worker pub fn handle_guest_input(&mut self) -> Result<()> {
549*bb4ee6a4SAndroid Build Coastguard Worker loop {
550*bb4ee6a4SAndroid Build Coastguard Worker match self.callback_handler.end_read_from_guest() {
551*bb4ee6a4SAndroid Build Coastguard Worker Ok(ethernet_frame) => {
552*bb4ee6a4SAndroid Build Coastguard Worker // SAFETY:
553*bb4ee6a4SAndroid Build Coastguard Worker // Safe because the buffer (ethernet_frame) is valid & libslirp is provided
554*bb4ee6a4SAndroid Build Coastguard Worker // with the data's underlying length.
555*bb4ee6a4SAndroid Build Coastguard Worker unsafe {
556*bb4ee6a4SAndroid Build Coastguard Worker slirp_input(
557*bb4ee6a4SAndroid Build Coastguard Worker self.slirp,
558*bb4ee6a4SAndroid Build Coastguard Worker ethernet_frame.as_ptr(),
559*bb4ee6a4SAndroid Build Coastguard Worker ethernet_frame.len() as i32,
560*bb4ee6a4SAndroid Build Coastguard Worker );
561*bb4ee6a4SAndroid Build Coastguard Worker }
562*bb4ee6a4SAndroid Build Coastguard Worker }
563*bb4ee6a4SAndroid Build Coastguard Worker Err(e) if e.kind() == std::io::ErrorKind::InvalidData => {
564*bb4ee6a4SAndroid Build Coastguard Worker error!("error reading packet from guest: {}", e);
565*bb4ee6a4SAndroid Build Coastguard Worker }
566*bb4ee6a4SAndroid Build Coastguard Worker Err(e) if e.kind() == std::io::ErrorKind::WouldBlock => {
567*bb4ee6a4SAndroid Build Coastguard Worker // No packets are available. Yield back to the Slirp loop.
568*bb4ee6a4SAndroid Build Coastguard Worker break;
569*bb4ee6a4SAndroid Build Coastguard Worker }
570*bb4ee6a4SAndroid Build Coastguard Worker Err(e) if e.kind() == std::io::ErrorKind::BrokenPipe => {
571*bb4ee6a4SAndroid Build Coastguard Worker return Err(Error::Slirp(SlirpError::BrokenPipe(e)));
572*bb4ee6a4SAndroid Build Coastguard Worker }
573*bb4ee6a4SAndroid Build Coastguard Worker Err(_) => {
574*bb4ee6a4SAndroid Build Coastguard Worker match self.callback_handler.begin_read_from_guest() {
575*bb4ee6a4SAndroid Build Coastguard Worker Err(e) if e.kind() == std::io::ErrorKind::BrokenPipe => {
576*bb4ee6a4SAndroid Build Coastguard Worker return Err(Error::Slirp(SlirpError::BrokenPipe(e)));
577*bb4ee6a4SAndroid Build Coastguard Worker }
578*bb4ee6a4SAndroid Build Coastguard Worker Err(e) => {
579*bb4ee6a4SAndroid Build Coastguard Worker return Err(Error::Slirp(SlirpError::OverlappedError(e)));
580*bb4ee6a4SAndroid Build Coastguard Worker }
581*bb4ee6a4SAndroid Build Coastguard Worker _ => {}
582*bb4ee6a4SAndroid Build Coastguard Worker }
583*bb4ee6a4SAndroid Build Coastguard Worker break;
584*bb4ee6a4SAndroid Build Coastguard Worker }
585*bb4ee6a4SAndroid Build Coastguard Worker }
586*bb4ee6a4SAndroid Build Coastguard Worker match self.callback_handler.begin_read_from_guest() {
587*bb4ee6a4SAndroid Build Coastguard Worker Err(e) if e.kind() == std::io::ErrorKind::BrokenPipe => {
588*bb4ee6a4SAndroid Build Coastguard Worker return Err(Error::Slirp(SlirpError::BrokenPipe(e)));
589*bb4ee6a4SAndroid Build Coastguard Worker }
590*bb4ee6a4SAndroid Build Coastguard Worker Err(e) => {
591*bb4ee6a4SAndroid Build Coastguard Worker return Err(Error::Slirp(SlirpError::OverlappedError(e)));
592*bb4ee6a4SAndroid Build Coastguard Worker }
593*bb4ee6a4SAndroid Build Coastguard Worker _ => {}
594*bb4ee6a4SAndroid Build Coastguard Worker }
595*bb4ee6a4SAndroid Build Coastguard Worker }
596*bb4ee6a4SAndroid Build Coastguard Worker Ok(())
597*bb4ee6a4SAndroid Build Coastguard Worker }
598*bb4ee6a4SAndroid Build Coastguard Worker
connection_info(&mut self) -> &str599*bb4ee6a4SAndroid Build Coastguard Worker pub fn connection_info(&mut self) -> &str {
600*bb4ee6a4SAndroid Build Coastguard Worker str::from_utf8(
601*bb4ee6a4SAndroid Build Coastguard Worker // TODO(b/315998194): Add safety comment
602*bb4ee6a4SAndroid Build Coastguard Worker #[allow(clippy::undocumented_unsafe_blocks)]
603*bb4ee6a4SAndroid Build Coastguard Worker unsafe { CStr::from_ptr(slirp_connection_info(self.slirp)) }.to_bytes(),
604*bb4ee6a4SAndroid Build Coastguard Worker )
605*bb4ee6a4SAndroid Build Coastguard Worker .unwrap_or("")
606*bb4ee6a4SAndroid Build Coastguard Worker }
607*bb4ee6a4SAndroid Build Coastguard Worker
608*bb4ee6a4SAndroid Build Coastguard Worker /// Requests libslirp provide the set of sockets & events that should be polled for. These
609*bb4ee6a4SAndroid Build Coastguard Worker /// sockets are provided to you by 0..n calls to `add_poll_cb`. `add_poll_cb` must return an
610*bb4ee6a4SAndroid Build Coastguard Worker /// integer (henceforth the socket reference) which libslirp can use to later request the
611*bb4ee6a4SAndroid Build Coastguard Worker /// revents that came from polling on that socket.
612*bb4ee6a4SAndroid Build Coastguard Worker ///
613*bb4ee6a4SAndroid Build Coastguard Worker /// The `timeout` value expresses how long (in ms) the consumer intends to wait (at most) when
614*bb4ee6a4SAndroid Build Coastguard Worker /// it invokes the polling function. libslirp will overwrite this with the time that the
615*bb4ee6a4SAndroid Build Coastguard Worker /// consumer should wait.
pollfds_fill<F>(&mut self, timeout: &mut u32, mut add_poll_cb: F) where F: FnMut(i32, PollEvents) -> i32,616*bb4ee6a4SAndroid Build Coastguard Worker pub fn pollfds_fill<F>(&mut self, timeout: &mut u32, mut add_poll_cb: F)
617*bb4ee6a4SAndroid Build Coastguard Worker where
618*bb4ee6a4SAndroid Build Coastguard Worker F: FnMut(i32, PollEvents) -> i32,
619*bb4ee6a4SAndroid Build Coastguard Worker {
620*bb4ee6a4SAndroid Build Coastguard Worker let cb = &mut (&mut add_poll_cb as &mut dyn FnMut(i32, PollEvents) -> i32);
621*bb4ee6a4SAndroid Build Coastguard Worker // SAFETY:
622*bb4ee6a4SAndroid Build Coastguard Worker // Safe because cb is only used while slirp_pollfds_fill is running, and self.slirp is
623*bb4ee6a4SAndroid Build Coastguard Worker // guaranteed to be valid.
624*bb4ee6a4SAndroid Build Coastguard Worker unsafe {
625*bb4ee6a4SAndroid Build Coastguard Worker slirp_pollfds_fill(
626*bb4ee6a4SAndroid Build Coastguard Worker self.slirp,
627*bb4ee6a4SAndroid Build Coastguard Worker timeout,
628*bb4ee6a4SAndroid Build Coastguard Worker Some(add_poll_handler_callback),
629*bb4ee6a4SAndroid Build Coastguard Worker cb as *mut _ as *mut c_void,
630*bb4ee6a4SAndroid Build Coastguard Worker );
631*bb4ee6a4SAndroid Build Coastguard Worker }
632*bb4ee6a4SAndroid Build Coastguard Worker }
633*bb4ee6a4SAndroid Build Coastguard Worker
634*bb4ee6a4SAndroid Build Coastguard Worker /// Informs libslirp that polling has returned with some events on sockets that libslirp said
635*bb4ee6a4SAndroid Build Coastguard Worker /// should be polled for when you called `pollfds_fill`. You provide the results of polling by
636*bb4ee6a4SAndroid Build Coastguard Worker /// supplying `get_revents_cb`, which returns the `PollEvents` for each provided socket
637*bb4ee6a4SAndroid Build Coastguard Worker /// reference. libslirp will call that function 0..n times to gather results from the polling
638*bb4ee6a4SAndroid Build Coastguard Worker /// operation.
pollfds_poll<F>(&mut self, error: bool, mut get_revents_cb: F) where F: FnMut(i32) -> PollEvents,639*bb4ee6a4SAndroid Build Coastguard Worker pub fn pollfds_poll<F>(&mut self, error: bool, mut get_revents_cb: F)
640*bb4ee6a4SAndroid Build Coastguard Worker where
641*bb4ee6a4SAndroid Build Coastguard Worker F: FnMut(i32) -> PollEvents,
642*bb4ee6a4SAndroid Build Coastguard Worker {
643*bb4ee6a4SAndroid Build Coastguard Worker let cb = &mut (&mut get_revents_cb as &mut dyn FnMut(i32) -> PollEvents);
644*bb4ee6a4SAndroid Build Coastguard Worker
645*bb4ee6a4SAndroid Build Coastguard Worker // SAFETY:
646*bb4ee6a4SAndroid Build Coastguard Worker // Safe because cb is only used while slirp_pollfds_poll is running, and self.slirp is
647*bb4ee6a4SAndroid Build Coastguard Worker // guaranteed to be valid.
648*bb4ee6a4SAndroid Build Coastguard Worker unsafe {
649*bb4ee6a4SAndroid Build Coastguard Worker slirp_pollfds_poll(
650*bb4ee6a4SAndroid Build Coastguard Worker self.slirp,
651*bb4ee6a4SAndroid Build Coastguard Worker error as i32,
652*bb4ee6a4SAndroid Build Coastguard Worker Some(get_revents_handler_callback),
653*bb4ee6a4SAndroid Build Coastguard Worker cb as *mut _ as *mut c_void,
654*bb4ee6a4SAndroid Build Coastguard Worker );
655*bb4ee6a4SAndroid Build Coastguard Worker }
656*bb4ee6a4SAndroid Build Coastguard Worker }
657*bb4ee6a4SAndroid Build Coastguard Worker
state_save<F>(&mut self, mut write_cb: F) where F: FnMut(&[u8]) -> isize,658*bb4ee6a4SAndroid Build Coastguard Worker pub fn state_save<F>(&mut self, mut write_cb: F)
659*bb4ee6a4SAndroid Build Coastguard Worker where
660*bb4ee6a4SAndroid Build Coastguard Worker F: FnMut(&[u8]) -> isize,
661*bb4ee6a4SAndroid Build Coastguard Worker {
662*bb4ee6a4SAndroid Build Coastguard Worker let cb = &mut (&mut write_cb as &mut dyn FnMut(&[u8]) -> isize);
663*bb4ee6a4SAndroid Build Coastguard Worker // SAFETY:
664*bb4ee6a4SAndroid Build Coastguard Worker // Safe because cb is only used while state_save is running, and self.slirp is
665*bb4ee6a4SAndroid Build Coastguard Worker // guaranteed to be valid.
666*bb4ee6a4SAndroid Build Coastguard Worker unsafe {
667*bb4ee6a4SAndroid Build Coastguard Worker slirp_state_save(
668*bb4ee6a4SAndroid Build Coastguard Worker self.slirp,
669*bb4ee6a4SAndroid Build Coastguard Worker Some(write_handler_callback),
670*bb4ee6a4SAndroid Build Coastguard Worker cb as *mut _ as *mut c_void,
671*bb4ee6a4SAndroid Build Coastguard Worker );
672*bb4ee6a4SAndroid Build Coastguard Worker }
673*bb4ee6a4SAndroid Build Coastguard Worker }
674*bb4ee6a4SAndroid Build Coastguard Worker
state_load<F>(&mut self, version_id: i32, mut read_cb: F) -> i32 where F: FnMut(&mut [u8]) -> isize,675*bb4ee6a4SAndroid Build Coastguard Worker pub fn state_load<F>(&mut self, version_id: i32, mut read_cb: F) -> i32
676*bb4ee6a4SAndroid Build Coastguard Worker where
677*bb4ee6a4SAndroid Build Coastguard Worker F: FnMut(&mut [u8]) -> isize,
678*bb4ee6a4SAndroid Build Coastguard Worker {
679*bb4ee6a4SAndroid Build Coastguard Worker let cb = &mut (&mut read_cb as &mut dyn FnMut(&mut [u8]) -> isize);
680*bb4ee6a4SAndroid Build Coastguard Worker // SAFETY:
681*bb4ee6a4SAndroid Build Coastguard Worker // Safe because cb is only used while state_load is running, and self.slirp is
682*bb4ee6a4SAndroid Build Coastguard Worker // guaranteed to be valid. While this function may fail, interpretation of the error code
683*bb4ee6a4SAndroid Build Coastguard Worker // is the responsibility of the caller.
684*bb4ee6a4SAndroid Build Coastguard Worker //
685*bb4ee6a4SAndroid Build Coastguard Worker // TODO(nkgold): if state_load becomes used by crosvm, interpretation of the error code
686*bb4ee6a4SAndroid Build Coastguard Worker // should occur here.
687*bb4ee6a4SAndroid Build Coastguard Worker unsafe {
688*bb4ee6a4SAndroid Build Coastguard Worker slirp_state_load(
689*bb4ee6a4SAndroid Build Coastguard Worker self.slirp,
690*bb4ee6a4SAndroid Build Coastguard Worker version_id,
691*bb4ee6a4SAndroid Build Coastguard Worker Some(read_handler_callback),
692*bb4ee6a4SAndroid Build Coastguard Worker cb as *mut _ as *mut c_void,
693*bb4ee6a4SAndroid Build Coastguard Worker )
694*bb4ee6a4SAndroid Build Coastguard Worker }
695*bb4ee6a4SAndroid Build Coastguard Worker }
696*bb4ee6a4SAndroid Build Coastguard Worker
get_timers<'a>(&'a self) -> Box<dyn Iterator<Item = &RawDescriptor> + 'a>697*bb4ee6a4SAndroid Build Coastguard Worker pub fn get_timers<'a>(&'a self) -> Box<dyn Iterator<Item = &RawDescriptor> + 'a> {
698*bb4ee6a4SAndroid Build Coastguard Worker self.callback_handler.get_timers()
699*bb4ee6a4SAndroid Build Coastguard Worker }
700*bb4ee6a4SAndroid Build Coastguard Worker
execute_timer(&mut self, timer: RawDescriptor)701*bb4ee6a4SAndroid Build Coastguard Worker pub fn execute_timer(&mut self, timer: RawDescriptor) {
702*bb4ee6a4SAndroid Build Coastguard Worker self.callback_handler.execute_timer(timer)
703*bb4ee6a4SAndroid Build Coastguard Worker }
704*bb4ee6a4SAndroid Build Coastguard Worker }
705