Skip to content

Commit f126e41

Browse files
committed
Fix compilation on macos.
This also updates the testing to do more thorough testing accross platforms, as that is creating just too many issues.
1 parent 5056026 commit f126e41

5 files changed

Lines changed: 158 additions & 96 deletions

File tree

.github/workflows/build.yaml

Lines changed: 15 additions & 30 deletions
Original file line numberDiff line numberDiff line change
@@ -37,18 +37,23 @@ jobs:
3737
args: --all --check
3838

3939
build:
40-
name: Clippy & Test ${{ matrix.os }}
40+
name: Clippy & Test ${{ matrix.os }} (${{ matrix.target }})
4141
runs-on: ${{ matrix.os }}
4242
strategy:
4343
matrix:
44-
# os: [ubuntu-latest, macos-latest]
45-
os: [ubuntu-latest]
46-
rust:
47-
- 1.88.0
48-
target:
49-
- ""
50-
features:
51-
- ""
44+
include:
45+
- rust: 1.88.0
46+
os: ubuntu-latest
47+
features: ""
48+
target: "x86_64-unknown-linux-gnu"
49+
- rust: 1.88.0
50+
os: ubuntu-latest
51+
features: ""
52+
target: "x86_64-unknown-linux-musl"
53+
- rust: 1.88.0
54+
os: macos-latest
55+
features: ""
56+
target: "aarch64-apple-darwin"
5257
steps:
5358
- name: Checkout sources
5459
uses: actions/checkout@de0fac2e4500dabe0009e67214ff5f5447ce83dd
@@ -59,29 +64,9 @@ jobs:
5964
with:
6065
toolchain: ${{ matrix.rust }}
6166
override: true
62-
- name: cargo build
63-
run: cargo build ${{ matrix.features }}
64-
- name: cargo test
65-
run: cargo test
66-
env:
67-
RUST_BACKTRACE: 1
68-
69-
build-musl:
70-
name: Clippy & Test ubuntu-latest / MUSL
71-
runs-on: ubuntu-latest
72-
steps:
73-
- name: Checkout sources
74-
uses: actions/checkout@de0fac2e4500dabe0009e67214ff5f5447ce83dd
75-
with:
76-
persist-credentials: false
77-
- name: Install rust toolchain
78-
uses: actions-rs/toolchain@16499b5e05bf2e26879000db0c1d13f7e13fa3af
79-
with:
80-
toolchain: stable
81-
override: true
8267
default: true
8368
components: clippy
84-
target: x86_64-unknown-linux-musl
69+
target: ${{ matrix.target }}
8570
- name: cargo build
8671
run: cargo build ${{ matrix.features }}
8772
- name: cargo test

src/raw_socket.rs

Lines changed: 0 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -15,8 +15,6 @@ use crate::{
1515
},
1616
};
1717

18-
#[cfg(any(target_os = "macos", target_os = "freebsd"))]
19-
mod bsdlike;
2018
#[cfg(not(any(target_os = "macos", target_os = "freebsd", target_os = "linux")))]
2119
mod fallback;
2220
#[cfg(target_os = "freebsd")]

src/raw_socket/bsdlike.rs

Lines changed: 0 additions & 60 deletions
This file was deleted.

src/raw_socket/freebsd.rs

Lines changed: 57 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -1,6 +1,8 @@
1-
use crate::cerr;
1+
use libc::{in_addr, sockaddr_storage};
22

3-
use super::RawSocket;
3+
use crate::{cerr, control_message::empty_msghdr, raw_socket::sockaddr_len};
4+
5+
use super::{control_message, RawSocket};
46

57
impl RawSocket {
68
pub(crate) fn so_timestamp(&self, options: u32) -> std::io::Result<()> {
@@ -49,4 +51,57 @@ impl RawSocket {
4951
}
5052
Ok(())
5153
}
54+
55+
pub(crate) fn enable_destination_ipv4(&self) -> std::io::Result<()> {
56+
// SAFETY:
57+
//
58+
// - the socket is provided by (safe) rust, and will outlive the call
59+
// - method is guaranteed to be a valid "name" argument
60+
// - the options pointer outlives the call
61+
// - the `option_len` corresponds with the options pointer
62+
unsafe {
63+
cerr(libc::setsockopt(
64+
self.fd,
65+
libc::IPPROTO_IP,
66+
libc::IP_RECVDSTADDR,
67+
&(1 as libc::c_int) as *const _ as *const libc::c_void,
68+
std::mem::size_of::<libc::c_int>() as libc::socklen_t,
69+
))?;
70+
}
71+
Ok(())
72+
}
73+
74+
pub(crate) fn send_from_v4(&self, msg: &[u8], _addr: in_addr) -> std::io::Result<()> {
75+
// FreeBSD and similar don't support setting an IPv4 source address
76+
// on connected sockets.
77+
self.send(msg)
78+
}
79+
80+
pub(crate) fn send_from_to_v4(
81+
&self,
82+
msg: &[u8],
83+
from: in_addr,
84+
to: sockaddr_storage,
85+
) -> std::io::Result<()> {
86+
let to_len = sockaddr_len(to);
87+
88+
let control_message = control_message(libc::IPPROTO_IP, libc::IP_SENDSRCADDR, from);
89+
90+
let mut iov = libc::iovec {
91+
iov_base: msg.as_ptr() as *mut libc::c_void,
92+
iov_len: msg.len(),
93+
};
94+
95+
let mut msghdr = empty_msghdr();
96+
msghdr.msg_name = &raw const to as *mut _;
97+
msghdr.msg_namelen = to_len;
98+
msghdr.msg_iov = &raw mut iov;
99+
msghdr.msg_iovlen = 1;
100+
msghdr.msg_control = control_message.as_ptr() as *mut _;
101+
msghdr.msg_controllen = control_message.len() as _;
102+
103+
// Safety:
104+
// msghdr is valid.
105+
cerr(unsafe { libc::sendmsg(self.fd, &raw const msghdr, 0) } as _).map(|_| {})
106+
}
52107
}

src/raw_socket/macos.rs

Lines changed: 86 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -1,6 +1,8 @@
1-
use crate::cerr;
1+
use libc::{in_addr, sockaddr_storage};
22

3-
use super::RawSocket;
3+
use crate::{cerr, control_message::empty_msghdr, raw_socket::sockaddr_len};
4+
5+
use super::{control_message, RawSocket};
46

57
impl RawSocket {
68
pub(crate) fn so_timestamp(&self, options: u32) -> std::io::Result<()> {
@@ -32,4 +34,86 @@ impl RawSocket {
3234

3335
Ok(())
3436
}
37+
38+
pub(crate) fn enable_destination_ipv4(&self) -> std::io::Result<()> {
39+
// SAFETY:
40+
//
41+
// - the socket is provided by (safe) rust, and will outlive the call
42+
// - method is guaranteed to be a valid "name" argument
43+
// - the options pointer outlives the call
44+
// - the `option_len` corresponds with the options pointer
45+
unsafe {
46+
cerr(libc::setsockopt(
47+
self.fd,
48+
libc::IPPROTO_IP,
49+
libc::IP_RECVDSTADDR,
50+
&(1 as libc::c_int) as *const _ as *const libc::c_void,
51+
std::mem::size_of::<libc::c_int>() as libc::socklen_t,
52+
))?;
53+
}
54+
Ok(())
55+
}
56+
57+
pub(crate) fn send_from_v4(&self, msg: &[u8], addr: in_addr) -> std::io::Result<()> {
58+
let control_message = control_message(
59+
libc::IPPROTO_IP,
60+
libc::IP_PKTINFO,
61+
libc::in_pktinfo {
62+
ipi_ifindex: 0,
63+
ipi_spec_dst: addr,
64+
ipi_addr: libc::in_addr { s_addr: 0 },
65+
},
66+
);
67+
68+
let mut iov = libc::iovec {
69+
iov_base: msg.as_ptr() as *mut libc::c_void,
70+
iov_len: msg.len(),
71+
};
72+
73+
let mut msghdr = empty_msghdr();
74+
msghdr.msg_iov = &raw mut iov;
75+
msghdr.msg_iovlen = 1;
76+
msghdr.msg_control = control_message.as_ptr() as *mut _;
77+
msghdr.msg_controllen = control_message.len() as _;
78+
79+
// Safety:
80+
// msghdr is valid.
81+
cerr(unsafe { libc::sendmsg(self.fd, &raw const msghdr, 0) } as _).map(|_| {})
82+
}
83+
84+
pub(crate) fn send_from_to_v4(
85+
&self,
86+
msg: &[u8],
87+
from: in_addr,
88+
to: sockaddr_storage,
89+
) -> std::io::Result<()> {
90+
let to_len = sockaddr_len(to);
91+
92+
let control_message = control_message(
93+
libc::IPPROTO_IP,
94+
libc::IP_PKTINFO,
95+
libc::in_pktinfo {
96+
ipi_ifindex: 0,
97+
ipi_spec_dst: from,
98+
ipi_addr: libc::in_addr { s_addr: 0 },
99+
},
100+
);
101+
102+
let mut iov = libc::iovec {
103+
iov_base: msg.as_ptr() as *mut libc::c_void,
104+
iov_len: msg.len(),
105+
};
106+
107+
let mut msghdr = empty_msghdr();
108+
msghdr.msg_name = &raw const to as *mut _;
109+
msghdr.msg_namelen = to_len;
110+
msghdr.msg_iov = &raw mut iov;
111+
msghdr.msg_iovlen = 1;
112+
msghdr.msg_control = control_message.as_ptr() as *mut _;
113+
msghdr.msg_controllen = control_message.len() as _;
114+
115+
// Safety:
116+
// msghdr is valid.
117+
cerr(unsafe { libc::sendmsg(self.fd, &raw const msghdr, 0) } as _).map(|_| {})
118+
}
35119
}

0 commit comments

Comments
 (0)