Skip to content

Commit 2ecb464

Browse files
author
Adam
authored
Split WgDataIo into WgReadIo and WgWriteIo to avoid Drop (#53)
* Split WgDataIo into WgReadIo and WgWriteIo to avoid Drop * Make WgRead/WriteIo fields private
1 parent d253efc commit 2ecb464

File tree

3 files changed

+56
-39
lines changed

3 files changed

+56
-39
lines changed

Cargo.lock

Lines changed: 2 additions & 2 deletions
Some generated files are not rendered by default. Learn more about customizing how changed files appear on GitHub.

src/bsd/mod.rs

Lines changed: 5 additions & 14 deletions
Original file line numberDiff line numberDiff line change
@@ -21,7 +21,7 @@ use self::{
2121
nvlist::NvList,
2222
sockaddr::{pack_sockaddr, unpack_sockaddr},
2323
timespec::{pack_timespec, unpack_timespec},
24-
wgio::WgDataIo,
24+
wgio::{WgReadIo, WgWriteIo},
2525
};
2626
use crate::{
2727
host::{Host, Peer},
@@ -253,7 +253,7 @@ impl<'a> Key {
253253
}
254254

255255
pub fn get_host(if_name: &str) -> Result<Host, IoError> {
256-
let mut wg_data = WgDataIo::new(if_name);
256+
let mut wg_data = WgReadIo::new(if_name);
257257
wg_data.read_data()?;
258258

259259
let mut nvlist = NvList::new();
@@ -266,40 +266,31 @@ pub fn get_host(if_name: &str) -> Result<Host, IoError> {
266266
}
267267

268268
pub fn set_host(if_name: &str, host: &Host) -> Result<(), IoError> {
269-
let mut wg_data = WgDataIo::new(if_name);
270-
271269
let nvlist = host.as_nvlist();
272270
// FIXME: use proper error, here and above
273271
let mut buf = nvlist.pack().map_err(|_| IoError::MemAlloc)?;
274272

275-
wg_data.wgd_data = buf.as_mut_ptr();
276-
wg_data.wgd_size = buf.len();
273+
let mut wg_data = WgWriteIo::new(if_name, &mut buf);
277274
wg_data.write_data()
278275
}
279276

280277
pub fn set_peer(if_name: &str, peer: &Peer) -> Result<(), IoError> {
281-
let mut wg_data = WgDataIo::new(if_name);
282-
283278
let mut nvlist = NvList::new();
284279
nvlist.append_nvlist_array(NV_PEERS, vec![peer.as_nvlist()]);
285280
// FIXME: use proper error, here and above
286281
let mut buf = nvlist.pack().map_err(|_| IoError::MemAlloc)?;
287282

288-
wg_data.wgd_data = buf.as_mut_ptr();
289-
wg_data.wgd_size = buf.len();
283+
let mut wg_data = WgWriteIo::new(if_name, &mut buf);
290284
wg_data.write_data()
291285
}
292286

293287
pub fn delete_peer(if_name: &str, public_key: &Key) -> Result<(), IoError> {
294-
let mut wg_data = WgDataIo::new(if_name);
295-
296288
let mut nvlist = NvList::new();
297289
nvlist.append_nvlist_array(NV_PEERS, vec![public_key.as_nvlist_for_removal()]);
298290
// FIXME: use proper error, here and above
299291
let mut buf = nvlist.pack().map_err(|_| IoError::MemAlloc)?;
300292

301-
wg_data.wgd_data = buf.as_mut_ptr();
302-
wg_data.wgd_size = buf.len();
293+
let mut wg_data = WgWriteIo::new(if_name, &mut buf);
303294
wg_data.write_data()
304295
}
305296

src/bsd/wgio.rs

Lines changed: 49 additions & 23 deletions
Original file line numberDiff line numberDiff line change
@@ -10,21 +10,21 @@ use nix::{ioctl_readwrite, sys::socket::AddressFamily};
1010

1111
use super::{create_socket, IoError};
1212

13-
// FIXME: `WgDataIo` has to be declared as public
14-
ioctl_readwrite!(write_wireguard_data, b'i', 210, WgDataIo);
15-
ioctl_readwrite!(read_wireguard_data, b'i', 211, WgDataIo);
13+
// FIXME: `WgReadIo` and `WgWriteIo` have to be declared public.
14+
ioctl_readwrite!(write_wireguard_data, b'i', 210, WgWriteIo);
15+
ioctl_readwrite!(read_wireguard_data, b'i', 211, WgReadIo);
1616

1717
/// Represent `struct wg_data_io` defined in
1818
/// https://github.com/freebsd/freebsd-src/blob/main/sys/dev/wg/if_wg.h
1919
#[repr(C)]
20-
pub struct WgDataIo {
21-
pub(super) wgd_name: [u8; IF_NAMESIZE],
22-
pub(super) wgd_data: *mut u8, // *void
23-
pub(super) wgd_size: usize,
20+
pub struct WgReadIo {
21+
wgd_name: [u8; IF_NAMESIZE],
22+
wgd_data: *mut u8, // *void
23+
wgd_size: usize,
2424
}
2525

26-
impl WgDataIo {
27-
/// Create `WgDataIo` without data buffer.
26+
impl WgReadIo {
27+
/// Create `WgReadIo` without data buffer.
2828
#[must_use]
2929
pub fn new(if_name: &str) -> Self {
3030
let mut wgd_name = [0u8; IF_NAMESIZE];
@@ -63,41 +63,67 @@ impl WgDataIo {
6363
unsafe {
6464
// First do ioctl with empty `wg_data` to obtain buffer size.
6565
if let Err(err) = read_wireguard_data(socket.as_raw_fd(), self) {
66-
error!("WgDataIo first read error {err}");
66+
error!("WgReadIo first read error {err}");
6767
return Err(IoError::ReadIo(err));
6868
}
6969
// Allocate buffer.
7070
self.alloc_data()?;
7171
// Second call to ioctl with allocated buffer.
7272
if let Err(err) = read_wireguard_data(socket.as_raw_fd(), self) {
73-
error!("WgDataIo second read error {err}");
73+
error!("WgReadIo second read error {err}");
7474
return Err(IoError::ReadIo(err));
7575
}
7676
}
7777

7878
Ok(())
7979
}
80+
}
81+
82+
impl Drop for WgReadIo {
83+
fn drop(&mut self) {
84+
if self.wgd_size != 0 {
85+
let layout = Layout::array::<u8>(self.wgd_size).expect("Bad layout");
86+
unsafe {
87+
dealloc(self.wgd_data, layout);
88+
}
89+
}
90+
}
91+
}
92+
93+
/// Same data layout as `WgReadIo`, but avoid `Drop`.
94+
#[repr(C)]
95+
pub struct WgWriteIo {
96+
wgd_name: [u8; IF_NAMESIZE],
97+
wgd_data: *mut u8, // *void
98+
wgd_size: usize,
99+
}
100+
101+
impl WgWriteIo {
102+
/// Create `WgWriteIo` from slice.
103+
#[must_use]
104+
pub fn new(if_name: &str, buf: &mut [u8]) -> Self {
105+
let mut wgd_name = [0u8; IF_NAMESIZE];
106+
if_name
107+
.bytes()
108+
.take(IF_NAMESIZE - 1)
109+
.enumerate()
110+
.for_each(|(i, b)| wgd_name[i] = b);
111+
Self {
112+
wgd_name,
113+
wgd_data: buf.as_mut_ptr(),
114+
wgd_size: buf.len(),
115+
}
116+
}
80117

81118
pub(super) fn write_data(&mut self) -> Result<(), IoError> {
82119
let socket = create_socket(AddressFamily::Unix).map_err(IoError::WriteIo)?;
83120
unsafe {
84121
if let Err(err) = write_wireguard_data(socket.as_raw_fd(), self) {
85-
error!("WgDataIo write error {err}");
122+
error!("WgWriteIo write error {err}");
86123
return Err(IoError::WriteIo(err));
87124
}
88125
}
89126

90127
Ok(())
91128
}
92129
}
93-
94-
impl Drop for WgDataIo {
95-
fn drop(&mut self) {
96-
if self.wgd_size != 0 {
97-
let layout = Layout::array::<u8>(self.wgd_size).expect("Bad layout");
98-
unsafe {
99-
dealloc(self.wgd_data, layout);
100-
}
101-
}
102-
}
103-
}

0 commit comments

Comments
 (0)