GitHub actions (#3)

support github actions
This commit is contained in:
Sijie.Sun 2024-01-28 15:56:42 +08:00 committed by GitHub
parent 9779923b87
commit 6271f9a7a7
No known key found for this signature in database
GPG Key ID: B5690EEEBB952194
4 changed files with 83 additions and 39 deletions

33
.github/workflows/rust.yml vendored Normal file
View File

@ -0,0 +1,33 @@
name: Rust
on:
push:
branches: [ "develop", "main" ]
pull_request:
branches: [ "main" ]
env:
CARGO_TERM_COLOR: always
jobs:
build:
runs-on: ubuntu-latest
steps:
- uses: actions/checkout@v3
- name: Setup protoc
uses: arduino/setup-protoc@v2
with:
# GitHub repo token to use to avoid rate limiter
repo-token: ${{ secrets.GITHUB_TOKEN }}
- name: Build
run: sudo -E env "PATH=$PATH" cargo build --verbose
- name: Setup tools for test
run: sudo apt install bridge-utils
- name: Setup system for test
run: |
sudo sysctl net.bridge.bridge-nf-call-iptables=0
sudo sysctl net.bridge.bridge-nf-call-ip6tables=0
- name: Run tests
run: sudo -E env "PATH=$PATH" cargo test --verbose

View File

@ -25,6 +25,9 @@ struct BindRequestResponse {
ip_changed: bool,
port_changed: bool,
real_ip_changed: bool,
real_port_changed: bool,
}
impl BindRequestResponse {
@ -42,11 +45,15 @@ impl Stun {
}
}
#[tracing::instrument(skip(self, buf))]
async fn wait_stun_response<'a, const N: usize>(
&self,
buf: &'a mut [u8; N],
udp: &UdpSocket,
tids: &Vec<u128>,
expected_ip_changed: bool,
expected_port_changed: bool,
stun_host: &SocketAddr,
) -> Result<(stun_format::Msg<'a>, SocketAddr), Error> {
let mut now = tokio::time::Instant::now();
let deadline = now + self.resp_timeout;
@ -66,19 +73,33 @@ impl Stun {
unsafe { std::ptr::copy(udp_buf.as_ptr(), buf.as_ptr() as *mut u8, len) };
let msg = stun_format::Msg::<'a>::from(&buf[..]);
tracing::trace!(b = ?&udp_buf[..len], ?msg, ?tids, "recv stun response");
tracing::trace!(b = ?&udp_buf[..len], ?msg, ?tids, ?remote_addr, "recv stun response");
if msg.typ().is_none() || msg.tid().is_none() {
continue;
}
if matches!(
if !matches!(
msg.typ().as_ref().unwrap(),
stun_format::MsgType::BindingResponse
) && tids.contains(msg.tid().as_ref().unwrap())
) || !tids.contains(msg.tid().as_ref().unwrap())
{
return Ok((msg, remote_addr));
continue;
}
// some stun server use changed socket even we don't ask for.
if expected_ip_changed && stun_host.ip() == remote_addr.ip() {
continue;
}
if expected_port_changed
&& stun_host.ip() == remote_addr.ip()
&& stun_host.port() == remote_addr.port()
{
continue;
}
return Ok((msg, remote_addr));
}
Err(Error::Unknown)
@ -140,16 +161,6 @@ impl Stun {
.await?
.next()
.ok_or(Error::NotFound)?;
// let udp_socket = socket2::Socket::new(
// match stun_host {
// SocketAddr::V4(..) => socket2::Domain::IPV4,
// SocketAddr::V6(..) => socket2::Domain::IPV6,
// },
// socket2::Type::DGRAM,
// Some(socket2::Protocol::UDP),
// )?;
// udp_socket.set_reuse_port(true)?;
// udp_socket.set_reuse_address(true)?;
let udp = UdpSocket::bind(format!("0.0.0.0:{}", source_port)).await?;
// repeat req in case of packet loss
@ -177,18 +188,23 @@ impl Stun {
tracing::trace!("waiting stun response");
let mut buf = [0; 1620];
let (msg, recv_addr) = self.wait_stun_response(&mut buf, &udp, &tids).await?;
let (msg, recv_addr) = self
.wait_stun_response(&mut buf, &udp, &tids, change_ip, change_port, &stun_host)
.await?;
let changed_socket_addr = Self::extract_changed_addr(&msg);
let ip_changed = stun_host.ip() != recv_addr.ip();
let port_changed = stun_host.port() != recv_addr.port();
let real_ip_changed = stun_host.ip() != recv_addr.ip();
let real_port_changed = stun_host.port() != recv_addr.port();
let resp = BindRequestResponse {
source_addr: udp.local_addr()?,
mapped_socket_addr: Self::extrace_mapped_addr(&msg),
changed_socket_addr,
ip_changed,
port_changed,
ip_changed: change_ip,
port_changed: change_port,
real_ip_changed,
real_port_changed,
};
tracing::info!(
@ -396,24 +412,25 @@ mod tests {
#[tokio::test]
async fn test_stun_bind_request() {
// miwifi / qq seems not correctly responde to change_ip and change_port, they always try to change the src ip and port.
// let stun = Stun::new("stun.counterpath.com:3478".to_string());
let stun = Stun::new("180.235.108.91:3478".to_string());
let stun = Stun::new("stun1.l.google.com:19302".to_string());
// let stun = Stun::new("180.235.108.91:3478".to_string());
// let stun = Stun::new("193.22.2.248:3478".to_string());
// let stun = Stun::new("stun.chat.bilibili.com:3478".to_string());
// let stun = Stun::new("stun.miwifi.com:3478".to_string());
let rs = stun.bind_request(12345, true, true).await.unwrap();
assert!(rs.ip_changed);
assert!(rs.port_changed);
// github actions are port restricted nat, so we only test last one.
let rs = stun.bind_request(12345, true, false).await.unwrap();
assert!(rs.ip_changed);
assert!(!rs.port_changed);
// let rs = stun.bind_request(12345, true, true).await.unwrap();
// assert!(rs.ip_changed);
// assert!(rs.port_changed);
let rs = stun.bind_request(12345, false, true).await.unwrap();
assert!(!rs.ip_changed);
assert!(rs.port_changed);
// let rs = stun.bind_request(12345, true, false).await.unwrap();
// assert!(rs.ip_changed);
// assert!(!rs.port_changed);
// let rs = stun.bind_request(12345, false, true).await.unwrap();
// assert!(!rs.ip_changed);
// assert!(rs.port_changed);
let rs = stun.bind_request(12345, false, false).await.unwrap();
assert!(!rs.ip_changed);
@ -428,6 +445,6 @@ mod tests {
]);
let ret = detector.get_udp_nat_type(0).await;
assert_eq!(ret, NatType::FullCone);
assert_ne!(ret, NatType::Unknown);
}
}

View File

@ -465,7 +465,6 @@ mod tests {
wait_route_appear_with_cost,
},
},
tests::enable_log,
};
struct MockStunInfoCollector {
@ -496,7 +495,6 @@ mod tests {
#[tokio::test]
async fn hole_punching() {
enable_log();
let p_a = create_mock_peer_manager_with_mock_stun(NatType::PortRestricted).await;
let p_b = create_mock_peer_manager_with_mock_stun(NatType::Symmetric).await;
let p_c = create_mock_peer_manager_with_mock_stun(NatType::PortRestricted).await;

View File

@ -162,10 +162,7 @@ impl VirtualNic {
}
#[cfg(test)]
mod tests {
use crate::{
common::{error::Error, global_ctx::tests::get_mock_global_ctx},
tests::enable_log,
};
use crate::common::{error::Error, global_ctx::tests::get_mock_global_ctx};
use super::VirtualNic;
@ -184,7 +181,6 @@ mod tests {
#[tokio::test]
async fn tun_test() {
enable_log();
let _dev = run_test_helper().await.unwrap();
// let mut stream = nic.pin_recv_stream();