Skip to content

Commit 30e3dbf

Browse files
committed
publisher script for testers
1 parent f8b14b8 commit 30e3dbf

File tree

10 files changed

+146
-21
lines changed

10 files changed

+146
-21
lines changed

.github/workflows/publish.yml

Lines changed: 45 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,45 @@
1+
name: Publish binary
2+
3+
on:
4+
workflow_dispatch:
5+
6+
env:
7+
CARGO_TERM_COLOR: always
8+
9+
jobs:
10+
build_n_publish:
11+
strategy:
12+
fail-fast: false
13+
matrix:
14+
os: [ubuntu-latest, macos-latest, windows-latest]
15+
16+
runs-on: ${{ matrix.os }}
17+
18+
steps:
19+
- uses: actions/checkout@v4
20+
- uses: dtolnay/rust-toolchain@stable
21+
- name: Build
22+
if: ${{ !cancelled() }}
23+
run: cargo build --release --verbose --examples --all-features
24+
- name: Prepare for publish
25+
if: ${{ !cancelled() }}
26+
shell: bash
27+
run: |
28+
mkdir -p mypubdir4
29+
if [[ "${{ matrix.os }}" == "windows-latest" ]]; then
30+
powershell -Command "(Get-Item target/release/examples/wintun.dll).LastWriteTime = Get-Date"
31+
powershell Compress-Archive -Path target/release/examples/tun.exe, README.md, target/release/examples/wintun.dll -DestinationPath mypubdir4/ipstack-${{ matrix.os }}.zip
32+
else
33+
zip -j mypubdir4/ipstack-${{ matrix.os }}.zip target/release/examples/tun README.md
34+
fi
35+
- name: Publish
36+
if: ${{ !cancelled() }}
37+
uses: softprops/action-gh-release@v1
38+
env:
39+
GITHUB_TOKEN: ${{ secrets.GITHUB_TOKEN }}
40+
with:
41+
files: mypubdir4/*
42+
43+
- name: Abort on error
44+
if: ${{ failure() }}
45+
run: echo "Some of jobs failed" && false

Cargo.toml

Lines changed: 4 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -26,7 +26,7 @@ tokio = { version = "1.45", default-features = false, features = [
2626

2727
[dev-dependencies]
2828
clap = { version = "4.5", features = ["derive"] }
29-
criterion = { version = "0.6" } # Benchmarks
29+
criterion = { version = "0.7" } # Benchmarks
3030
dotenvy = "0.15"
3131
env_logger = "0.11"
3232
tokio = { version = "1.45", default-features = false, features = [
@@ -38,6 +38,9 @@ udp-stream = { version = "0.0", default-features = false }
3838
[target.'cfg(target_os = "windows")'.dev-dependencies]
3939
wintun = { version = "0.5", default-features = false }
4040

41+
[build-dependencies]
42+
serde_json = "1"
43+
4144
[profile.release]
4245
opt-level = 's' # Optimize for size (with loop vectorization enabled).
4346
lto = true # Enable Link Time Optimization

build.rs

Lines changed: 77 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,77 @@
1+
fn main() -> Result<(), Box<dyn std::error::Error>> {
2+
let target_os = std::env::var("CARGO_CFG_TARGET_OS").unwrap_or_else(|_| "unknown".to_string());
3+
4+
if target_os == "windows" {
5+
let out_dir = std::path::PathBuf::from(std::env::var("OUT_DIR")?);
6+
let profile = std::env::var("PROFILE").unwrap_or_else(|_| "debug".to_string());
7+
8+
let Ok(cargo_target_dir) = extract_matching_parent_dir(&out_dir, &profile) else {
9+
println!("cargo:warning=Could not find target directory");
10+
return Ok(());
11+
};
12+
// The wintun crate's root directory
13+
let crate_dir = get_crate_dir("wintun")?;
14+
15+
// The path to the DLL file, relative to the crate root, depending on the target architecture
16+
let dll_path = get_wintun_bin_relative_path()?;
17+
let src_path = crate_dir.join(dll_path);
18+
19+
let dst_path = cargo_target_dir.join("examples/wintun.dll");
20+
21+
// Copy to the target directory
22+
std::fs::copy(src_path, &dst_path)?;
23+
24+
// Set the modified time to the current time, or the publishing process will fail.
25+
let file = std::fs::OpenOptions::new().write(true).open(&dst_path)?;
26+
file.set_modified(std::time::SystemTime::now())?;
27+
}
28+
Ok(())
29+
}
30+
31+
fn extract_matching_parent_dir<P: AsRef<std::path::Path>>(path: P, match_name: &str) -> std::io::Result<std::path::PathBuf> {
32+
let target_dir = std::path::Path::new(path.as_ref())
33+
.ancestors()
34+
.find(|p| p.file_name().map(|n| *n == *match_name).unwrap_or(false))
35+
.ok_or(std::io::Error::new(
36+
std::io::ErrorKind::NotFound,
37+
format!("No parent directory matching '{match_name}'"),
38+
))?;
39+
Ok(target_dir.to_path_buf())
40+
}
41+
42+
fn get_wintun_bin_relative_path() -> Result<std::path::PathBuf, Box<dyn std::error::Error>> {
43+
let target_arch = std::env::var("CARGO_CFG_TARGET_ARCH")?;
44+
45+
let dll_path = match target_arch.as_str() {
46+
"x86" => "wintun/bin/x86/wintun.dll",
47+
"x86_64" => "wintun/bin/amd64/wintun.dll",
48+
"arm" => "wintun/bin/arm/wintun.dll",
49+
"aarch64" => "wintun/bin/arm64/wintun.dll",
50+
_ => return Err("Unsupported architecture".into()),
51+
};
52+
53+
Ok(dll_path.into())
54+
}
55+
56+
fn get_crate_dir(crate_name: &str) -> Result<std::path::PathBuf, Box<dyn std::error::Error>> {
57+
let output = std::process::Command::new("cargo")
58+
.arg("metadata")
59+
.arg("--format-version=1")
60+
.output()?;
61+
62+
let metadata = serde_json::from_slice::<serde_json::Value>(&output.stdout)?;
63+
let packages = metadata["packages"].as_array().ok_or("packages")?;
64+
65+
let mut crate_dir = None;
66+
67+
for package in packages {
68+
let name = package["name"].as_str().ok_or("name")?;
69+
if name == crate_name {
70+
let path = package["manifest_path"].as_str().ok_or("manifest_path")?;
71+
let path = std::path::PathBuf::from(path);
72+
crate_dir = Some(path.parent().ok_or("parent")?.to_path_buf());
73+
break;
74+
}
75+
}
76+
Ok(crate_dir.ok_or("crate_dir")?)
77+
}

examples/tun.rs

Lines changed: 7 additions & 7 deletions
Original file line numberDiff line numberDiff line change
@@ -111,7 +111,7 @@ async fn main() -> Result<(), Box<dyn std::error::Error>> {
111111
let mut s = match TcpStream::connect(server_addr).await {
112112
Ok(s) => s,
113113
Err(e) => {
114-
log::info!("connect TCP server failed \"{}\"", e);
114+
log::info!("connect TCP server failed \"{e}\"");
115115
continue;
116116
}
117117
};
@@ -120,13 +120,13 @@ async fn main() -> Result<(), Box<dyn std::error::Error>> {
120120
log::info!("#{number1} TCP connecting, session count {c}");
121121
tokio::spawn(async move {
122122
if let Err(err) = tokio::io::copy_bidirectional(&mut tcp, &mut s).await {
123-
log::info!("#{number1} TCP error: {}", err);
123+
log::info!("#{number1} TCP error: {err}");
124124
}
125125
if let Err(e) = s.shutdown().await {
126-
log::info!("#{number1} TCP upstream shutdown error: {}", e);
126+
log::info!("#{number1} TCP upstream shutdown error: {e}");
127127
}
128128
if let Err(e) = tcp.shutdown().await {
129-
log::info!("#{number1} TCP stack stream shutdown error: {}", e);
129+
log::info!("#{number1} TCP stack stream shutdown error: {e}");
130130
}
131131
let c = count.fetch_sub(1, std::sync::atomic::Ordering::Relaxed) - 1;
132132
log::info!("#{number1} TCP closed, session count {c}");
@@ -136,7 +136,7 @@ async fn main() -> Result<(), Box<dyn std::error::Error>> {
136136
let mut s = match UdpStream::connect(server_addr).await {
137137
Ok(s) => s,
138138
Err(e) => {
139-
log::info!("connect UDP server failed \"{}\"", e);
139+
log::info!("connect UDP server failed \"{e}\"");
140140
continue;
141141
}
142142
};
@@ -145,11 +145,11 @@ async fn main() -> Result<(), Box<dyn std::error::Error>> {
145145
log::info!("#{number2} UDP connecting, session count {c}");
146146
tokio::spawn(async move {
147147
if let Err(err) = tokio::io::copy_bidirectional(&mut udp, &mut s).await {
148-
log::info!("#{number2} UDP error: {}", err);
148+
log::info!("#{number2} UDP error: {err}");
149149
}
150150
s.shutdown();
151151
if let Err(e) = udp.shutdown().await {
152-
log::info!("#{number2} UDP stack stream shutdown error: {}", e);
152+
log::info!("#{number2} UDP stack stream shutdown error: {e}");
153153
}
154154
let c = count.fetch_sub(1, std::sync::atomic::Ordering::Relaxed) - 1;
155155
log::info!("#{number2} UDP closed, session count {c}");

examples/tun_wintun.rs

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -57,7 +57,7 @@ async fn main() -> Result<(), Box<dyn std::error::Error>> {
5757
let mut s = match TcpStream::connect(server_addr).await {
5858
Ok(s) => s,
5959
Err(e) => {
60-
println!("connect TCP server failed \"{}\"", e);
60+
println!("connect TCP server failed \"{e}\"");
6161
continue;
6262
}
6363
};
@@ -73,7 +73,7 @@ async fn main() -> Result<(), Box<dyn std::error::Error>> {
7373
let mut s = match UdpStream::connect(server_addr).await {
7474
Ok(s) => s,
7575
Err(e) => {
76-
println!("connect UDP server failed \"{}\"", e);
76+
println!("connect UDP server failed \"{e}\"");
7777
continue;
7878
}
7979
};

src/lib.rs

Lines changed: 5 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -119,9 +119,9 @@ fn run<Device: AsyncRead + AsyncWrite + Unpin + Send + 'static>(
119119
if let Err(e) = process_device_read(&buffer[offset..n], sessions.clone(), u, &config, &accept_sender).await {
120120
let io_err: std::io::Error = e.into();
121121
if io_err.kind() == std::io::ErrorKind::ConnectionRefused {
122-
log::trace!("Received junk data: {}", io_err);
122+
log::trace!("Received junk data: {io_err}");
123123
} else {
124-
log::warn!("process_device_read error: {}", io_err);
124+
log::warn!("process_device_read error: {io_err}");
125125
}
126126
}
127127
}
@@ -164,7 +164,7 @@ async fn process_device_read(
164164
match sessions.lock().await.entry(network_tuple) {
165165
std::collections::hash_map::Entry::Occupied(entry) => {
166166
let len = packet.payload.as_ref().map(|p| p.len()).unwrap_or(0);
167-
log::trace!("packet sent to stream: {} len {}", network_tuple, len);
167+
log::trace!("packet sent to stream: {network_tuple} len {len}");
168168
entry.get().send(packet).map_err(std::io::Error::other)?;
169169
}
170170
std::collections::hash_map::Entry::Vacant(entry) => {
@@ -173,12 +173,12 @@ async fn process_device_read(
173173
tokio::spawn(async move {
174174
rx.await.ok();
175175
sessions_clone.lock().await.remove(&network_tuple);
176-
log::debug!("session destroyed: {}", network_tuple);
176+
log::debug!("session destroyed: {network_tuple}");
177177
});
178178
let packet_sender = ip_stack_stream.stream_sender()?;
179179
accept_sender.send(ip_stack_stream)?;
180180
entry.insert(packet_sender);
181-
log::debug!("session created: {}", network_tuple);
181+
log::debug!("session created: {network_tuple}");
182182
}
183183
}
184184
Ok(())

src/stream/seqnum.rs

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -37,7 +37,7 @@ impl TryFrom<usize> for SeqNum {
3737
if value > u32::MAX as usize {
3838
return Err(std::io::Error::new(
3939
std::io::ErrorKind::InvalidInput,
40-
format!("value 0x{:X} is too large to convert to SeqNum", value),
40+
format!("value 0x{value:X} is too large to convert to SeqNum"),
4141
));
4242
}
4343
Ok(Self(value as u32))

src/stream/tcb.rs

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -429,7 +429,7 @@ mod tests {
429429
for i in 0..MAX_RETRANSMIT_COUNT {
430430
// Simulate a timeout for the first packet
431431
let timeout = tcb.inflight_packets.values().next().unwrap().retransmit_timeout + std::time::Duration::from_millis(100);
432-
println!("timeout: {:?}", timeout);
432+
println!("timeout: {timeout:?}");
433433
std::thread::sleep(timeout);
434434

435435
let packets = tcb.collect_timed_out_inflight_packets();

src/stream/tcp.rs

Lines changed: 3 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -105,10 +105,10 @@ impl IpStackTcpStream {
105105
if !tcp.syn {
106106
if !tcp.rst {
107107
if let Err(err) = write_packet_to_device(&up_packet_sender, tuple, &tcb, ACK | RST, None, None) {
108-
log::warn!("Error sending RST/ACK packet: {:?}", err);
108+
log::warn!("Error sending RST/ACK packet: {err}");
109109
}
110110
}
111-
let info = format!("Invalid TCP packet: {} {}", tuple, tcp_header_fmt(&tcp));
111+
let info = format!("Invalid TCP packet: {tuple} {}", tcp_header_fmt(&tcp));
112112
return Err(IpStackError::IoError(std::io::Error::new(ConnectionRefused, info)));
113113
}
114114

@@ -538,7 +538,7 @@ async fn tcp_main_logic_loop(
538538

539539
let (state, seq, ack) = { (tcb.get_state(), tcb.get_seq(), tcb.get_ack()) };
540540
let (info, len) = (tcp_header_fmt(tcp_header), payload.len());
541-
let l_info = format!("local {{ seq: {}, ack: {} }}", seq, ack);
541+
let l_info = format!("local {{ seq: {seq}, ack: {ack} }}");
542542
log::trace!("{network_tuple} {state:?}: {l_info} {info}, {pkt_type:?}, len = {len}");
543543
if pkt_type == PacketType::Invalid {
544544
continue;

src/stream/unknown.rs

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -46,7 +46,7 @@ impl IpStackUnknownTransport {
4646
let packet = self.create_rev_packet(&mut payload)?;
4747
self.packet_sender
4848
.send(packet)
49-
.map_err(|e| std::io::Error::other(format!("send error: {}", e)))?;
49+
.map_err(|e| std::io::Error::other(format!("send error: {e}")))?;
5050
if payload.is_empty() {
5151
return Ok(());
5252
}

0 commit comments

Comments
 (0)