diff --git a/.github/workflows/docker.yml b/.github/workflows/docker.yml index 0da9db4..88408e4 100644 --- a/.github/workflows/docker.yml +++ b/.github/workflows/docker.yml @@ -1,27 +1,8 @@ name: Docker Build and Publish - on: push: - branches: [ "main" ] - paths: - - 'src/**' - - 'Cargo.toml' - - 'Cargo.lock' - - 'assets/services' - - 'Dockerfile' - - 'build.rs' - - '.github/workflows/docker.yml' - tags: [ "v*.*.*" ] - pull_request: - branches: [ "main" ] - paths: - - 'src/**' - - 'Cargo.toml' - - 'Cargo.lock' - - 'assets/services' - - 'Dockerfile' - - 'build.rs' - - '.github/workflows/docker.yml' + tags: + - "v[0-9]+.[0-9]+.[0-9]+" workflow_dispatch: env: diff --git a/.github/workflows/publish.yml b/.github/workflows/publish.yml new file mode 100644 index 0000000..b37dbc0 --- /dev/null +++ b/.github/workflows/publish.yml @@ -0,0 +1,23 @@ +name: Publish to crates.io + +on: + push: + tags: + - "v[0-9]+.[0-9]+.[0-9]+" + workflow_dispatch: + +jobs: + publish: + runs-on: ubuntu-latest + + steps: + - name: Checkout repository + uses: actions/checkout@v4 + + - name: Set up Rust + uses: dtolnay/rust-toolchain@stable + + - name: Publish to crates.io + env: + CARGO_REGISTRY_TOKEN: ${{ secrets.CRATES_IO_TOKEN }} + run: cargo publish diff --git a/.github/workflows/release.yml b/.github/workflows/release.yml index 1121897..f8cdecf 100644 --- a/.github/workflows/release.yml +++ b/.github/workflows/release.yml @@ -86,9 +86,7 @@ jobs: - name: Install cross if: matrix.cargo == 'cross' - uses: taiki-e/cache-cargo-install-action@v2 - with: - tool: cross@0.2.5 + run: cargo install cross@0.2.5 - name: Build release binary shell: bash diff --git a/Cargo.lock b/Cargo.lock index 1eb54e3..0578686 100644 --- a/Cargo.lock +++ b/Cargo.lock @@ -140,6 +140,12 @@ version = "1.4.0" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "ace50bade8e6234aa140d9a2f552bbee1db4d353f69b8217bc503490fc1a9f26" +[[package]] +name = "base64" +version = "0.22.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "72b3254f16251a8381aa12e40e3c4d2f0199f8c6508fbecb9d91f575e0fbb8c6" + [[package]] name = "bitflags" version = "1.3.2" @@ -815,6 +821,15 @@ version = "0.1.1" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "00b0228411908ca8685dba7fc2cdd70ec9990a6e753e89b6ac91a84c40fbaf4b" +[[package]] +name = "form_urlencoded" +version = "1.2.2" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "cb4cb245038516f5f85277875cdaa4f7d2c9a0fa0468de06ed190163b1581fcf" +dependencies = [ + "percent-encoding", +] + [[package]] name = "generic-array" version = "0.14.7" @@ -938,12 +953,119 @@ dependencies = [ "cc", ] +[[package]] +name = "icu_collections" +version = "2.0.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "200072f5d0e3614556f94a9930d5dc3e0662a652823904c3a75dc3b0af7fee47" +dependencies = [ + "displaydoc", + "potential_utf", + "yoke", + "zerofrom", + "zerovec", +] + +[[package]] +name = "icu_locale_core" +version = "2.0.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "0cde2700ccaed3872079a65fb1a78f6c0a36c91570f28755dda67bc8f7d9f00a" +dependencies = [ + "displaydoc", + "litemap", + "tinystr", + "writeable", + "zerovec", +] + +[[package]] +name = "icu_normalizer" +version = "2.0.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "436880e8e18df4d7bbc06d58432329d6458cc84531f7ac5f024e93deadb37979" +dependencies = [ + "displaydoc", + "icu_collections", + "icu_normalizer_data", + "icu_properties", + "icu_provider", + "smallvec", + "zerovec", +] + +[[package]] +name = "icu_normalizer_data" +version = "2.0.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "00210d6893afc98edb752b664b8890f0ef174c8adbb8d0be9710fa66fbbf72d3" + +[[package]] +name = "icu_properties" +version = "2.0.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "016c619c1eeb94efb86809b015c58f479963de65bdb6253345c1a1276f22e32b" +dependencies = [ + "displaydoc", + "icu_collections", + "icu_locale_core", + "icu_properties_data", + "icu_provider", + "potential_utf", + "zerotrie", + "zerovec", +] + +[[package]] +name = "icu_properties_data" +version = "2.0.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "298459143998310acd25ffe6810ed544932242d3f07083eee1084d83a71bd632" + +[[package]] +name = "icu_provider" +version = "2.0.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "03c80da27b5f4187909049ee2d72f276f0d9f99a42c306bd0131ecfe04d8e5af" +dependencies = [ + "displaydoc", + "icu_locale_core", + "stable_deref_trait", + "tinystr", + "writeable", + "yoke", + "zerofrom", + "zerotrie", + "zerovec", +] + [[package]] name = "ident_case" version = "1.0.1" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "b9e0384b61958566e926dc50660321d12159025e767c18e043daf26b70104c39" +[[package]] +name = "idna" +version = "1.1.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "3b0875f23caa03898994f6ddc501886a45c7d3d62d04d2d90788d47be1b1e4de" +dependencies = [ + "idna_adapter", + "smallvec", + "utf8_iter", +] + +[[package]] +name = "idna_adapter" +version = "1.2.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "3acae9609540aa318d1bc588455225fb2085b9ed0c4f6bd0d9d5bcd86f1a0344" +dependencies = [ + "icu_normalizer", + "icu_properties", +] + [[package]] name = "image" version = "0.25.6" @@ -1127,6 +1249,12 @@ version = "0.9.4" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "cd945864f07fe9f5371a27ad7b52a172b4b499999f1d97574c9fa68373937e12" +[[package]] +name = "litemap" +version = "0.8.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "241eaef5fd12c88705a01fc1066c48c4b36e0dd4377dcdc7ec3942cea7a69956" + [[package]] name = "litrs" version = "0.4.1" @@ -1534,6 +1662,15 @@ dependencies = [ "miniz_oxide", ] +[[package]] +name = "potential_utf" +version = "0.1.3" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "84df19adbe5b5a0782edcab45899906947ab039ccf4573713735ee7de1e6b08a" +dependencies = [ + "zerovec", +] + [[package]] name = "powerfmt" version = "0.2.0" @@ -1702,6 +1839,41 @@ dependencies = [ "windows-sys 0.59.0", ] +[[package]] +name = "rustls" +version = "0.23.32" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "cd3c25631629d034ce7cd9940adc9d45762d46de2b0f57193c4443b92c6d4d40" +dependencies = [ + "log", + "once_cell", + "ring", + "rustls-pki-types", + "rustls-webpki", + "subtle", + "zeroize", +] + +[[package]] +name = "rustls-pki-types" +version = "1.12.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "229a4a4c221013e7e1f1a043678c5cc39fe5171437c88fb47151a21e6f5b5c79" +dependencies = [ + "zeroize", +] + +[[package]] +name = "rustls-webpki" +version = "0.103.7" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "e10b3f4191e8a80e6b43eebabfac91e5dcecebb27a71f04e820c47ec41d314bf" +dependencies = [ + "ring", + "rustls-pki-types", + "untrusted", +] + [[package]] name = "rustnet-monitor" version = "0.12.0" @@ -1731,7 +1903,7 @@ dependencies = [ "ring", "simple-logging", "simplelog", - "vmlinux", + "ureq", "winapi", "zip", ] @@ -1939,6 +2111,12 @@ dependencies = [ "windows-sys 0.59.0", ] +[[package]] +name = "stable_deref_trait" +version = "1.2.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "a8f112729512f8e442d81f95a8a7ddf2b7c6b8a1a6f509a95864142b30cab2d3" + [[package]] name = "static_assertions" version = "1.1.0" @@ -1990,6 +2168,17 @@ dependencies = [ "unicode-ident", ] +[[package]] +name = "synstructure" +version = "0.13.2" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "728a70f3dbaf5bab7f0c4b1ac8d7ae5ea60a4b5549c8a5914361c99147a709d2" +dependencies = [ + "proc-macro2", + "quote", + "syn", +] + [[package]] name = "tempfile" version = "3.22.0" @@ -2000,7 +2189,7 @@ dependencies = [ "getrandom 0.3.3", "once_cell", "rustix 1.0.7", - "windows-sys 0.60.2", + "windows-sys 0.61.1", ] [[package]] @@ -2096,6 +2285,16 @@ dependencies = [ "time-core", ] +[[package]] +name = "tinystr" +version = "0.8.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "5d4f6d1145dcb577acf783d4e601bc1d76a13337bb54e6233add580b07344c8b" +dependencies = [ + "displaydoc", + "zerovec", +] + [[package]] name = "tracing" version = "0.1.41" @@ -2181,6 +2380,38 @@ version = "0.9.0" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "8ecb6da28b8a351d773b68d5825ac39017e680750f980f3a1a85cd8dd28a47c1" +[[package]] +name = "ureq" +version = "2.12.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "02d1a66277ed75f640d608235660df48c8e3c19f3b4edb6a263315626cc3c01d" +dependencies = [ + "base64", + "log", + "once_cell", + "rustls", + "rustls-pki-types", + "url", + "webpki-roots 0.26.11", +] + +[[package]] +name = "url" +version = "2.5.4" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "32f8b686cadd1473f4bd0117a5d28d36b1ade384ea9b5069a1c40aefed7fda60" +dependencies = [ + "form_urlencoded", + "idna", + "percent-encoding", +] + +[[package]] +name = "utf8_iter" +version = "1.0.4" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "b6c140620e7ffbb22c2dee59cafe6084a59b5ffc27a8859a5f0d494b5d52b6be" + [[package]] name = "utf8parse" version = "0.2.2" @@ -2199,11 +2430,6 @@ version = "0.9.5" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "0b928f33d975fc6ad9f86c8f283853ad26bdd5b10b7f1542aa2fa15e2289105a" -[[package]] -name = "vmlinux" -version = "0.0.0" -source = "git+https://github.com/libbpf/vmlinux.h.git?rev=83a228cf37fc65f2d14e4896a04922b5ee531a94#83a228cf37fc65f2d14e4896a04922b5ee531a94" - [[package]] name = "vsprintf" version = "2.0.0" @@ -2296,6 +2522,24 @@ dependencies = [ "unicode-ident", ] +[[package]] +name = "webpki-roots" +version = "0.26.11" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "521bc38abb08001b01866da9f51eb7c5d647a19260e00054a8c7fd5f9e57f7a9" +dependencies = [ + "webpki-roots 1.0.2", +] + +[[package]] +name = "webpki-roots" +version = "1.0.2" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "7e8983c3ab33d6fb807cfcdad2491c4ea8cbc8ed839181c7dfd9c67c83e261b2" +dependencies = [ + "rustls-pki-types", +] + [[package]] name = "weezl" version = "0.1.8" @@ -2669,6 +2913,12 @@ version = "0.46.0" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "f17a85883d4e6d00e8a97c586de764dabcc06133f7f1d55dce5cdc070ad7fe59" +[[package]] +name = "writeable" +version = "0.6.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "ea2f10b9bb0928dfb1b42b65e1f9e36f7f54dbdf08457afefb38afcdec4fa2bb" + [[package]] name = "x11rb" version = "0.13.1" @@ -2695,6 +2945,51 @@ dependencies = [ "lzma-sys", ] +[[package]] +name = "yoke" +version = "0.8.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "5f41bb01b8226ef4bfd589436a297c53d118f65921786300e427be8d487695cc" +dependencies = [ + "serde", + "stable_deref_trait", + "yoke-derive", + "zerofrom", +] + +[[package]] +name = "yoke-derive" +version = "0.8.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "38da3c9736e16c5d3c8c597a9aaa5d1fa565d0532ae05e27c24aa62fb32c0ab6" +dependencies = [ + "proc-macro2", + "quote", + "syn", + "synstructure", +] + +[[package]] +name = "zerofrom" +version = "0.1.6" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "50cc42e0333e05660c3587f3bf9d0478688e15d870fab3346451ce7f8c9fbea5" +dependencies = [ + "zerofrom-derive", +] + +[[package]] +name = "zerofrom-derive" +version = "0.1.6" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "d71e5d6e06ab090c67b5e44993ec16b72dcbaabc526db883a360057678b48502" +dependencies = [ + "proc-macro2", + "quote", + "syn", + "synstructure", +] + [[package]] name = "zeroize" version = "1.8.1" @@ -2715,6 +3010,39 @@ dependencies = [ "syn", ] +[[package]] +name = "zerotrie" +version = "0.2.2" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "36f0bbd478583f79edad978b407914f61b2972f5af6fa089686016be8f9af595" +dependencies = [ + "displaydoc", + "yoke", + "zerofrom", +] + +[[package]] +name = "zerovec" +version = "0.11.4" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "e7aa2bd55086f1ab526693ecbe444205da57e25f4489879da80635a46d90e73b" +dependencies = [ + "yoke", + "zerofrom", + "zerovec-derive", +] + +[[package]] +name = "zerovec-derive" +version = "0.11.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "5b96237efa0c878c64bd89c436f661be4e46b2f3eff1ebb976f7ef2321d2f58f" +dependencies = [ + "proc-macro2", + "quote", + "syn", +] + [[package]] name = "zip" version = "2.4.2" diff --git a/Cargo.toml b/Cargo.toml index be271b2..9e3b8fb 100644 --- a/Cargo.toml +++ b/Cargo.toml @@ -62,7 +62,7 @@ zip = "2.1" [target.'cfg(target_os = "linux")'.build-dependencies] libbpf-cargo = "0.25" -vmlinux = { version = "0.0", git = "https://github.com/libbpf/vmlinux.h.git", rev = "83a228cf37fc65f2d14e4896a04922b5ee531a94" } +ureq = { version = "2.10", default-features = false, features = ["tls"] } [features] default = [] diff --git a/build.rs b/build.rs index b38d9d6..b3b5e1d 100644 --- a/build.rs +++ b/build.rs @@ -148,6 +148,73 @@ fn download_windows_npcap_sdk() -> Result<()> { Ok(()) } +#[cfg(all(target_os = "linux", feature = "ebpf"))] +fn download_vmlinux_header(arch: &str) -> Result { + use std::fs; + use std::io::{Read, Write}; + + // Cache directory in OUT_DIR + let out_dir = PathBuf::from(env::var("OUT_DIR")?); + let cache_dir = out_dir.join("vmlinux_headers").join(arch); + let vmlinux_file = cache_dir.join("vmlinux.h"); + + // Return cached version if it exists + if vmlinux_file.exists() { + println!("cargo:warning=Using cached vmlinux.h for {}", arch); + return Ok(cache_dir); + } + + // Download from libbpf/vmlinux.h repository + // Note: vmlinux.h is a symlink, so we first download it to get the target filename + let symlink_url = format!( + "https://raw.githubusercontent.com/libbpf/vmlinux.h/main/include/{}/vmlinux.h", + arch + ); + + println!("cargo:warning=Downloading vmlinux.h for {} from {}", arch, symlink_url); + + // Create cache directory + fs::create_dir_all(&cache_dir)?; + + // Download the symlink to get the actual filename + let response = ureq::get(&symlink_url) + .call() + .map_err(|e| anyhow::anyhow!("Failed to download vmlinux.h symlink: {}", e))?; + + let mut symlink_content = String::new(); + response.into_reader() + .read_to_string(&mut symlink_content) + .map_err(|e| anyhow::anyhow!("Failed to read symlink: {}", e))?; + + // The symlink content is just the target filename, e.g. "vmlinux_6.14.h" + let target_filename = symlink_content.trim(); + + // Download the actual vmlinux header file + let actual_url = format!( + "https://raw.githubusercontent.com/libbpf/vmlinux.h/main/include/{}/{}", + arch, target_filename + ); + + println!("cargo:warning=Following symlink to {}", target_filename); + + let response = ureq::get(&actual_url) + .call() + .map_err(|e| anyhow::anyhow!("Failed to download {}: {}", target_filename, e))?; + + let mut content = Vec::new(); + response.into_reader() + .read_to_end(&mut content) + .map_err(|e| anyhow::anyhow!("Failed to read response: {}", e))?; + + // Write to cache + let mut file = fs::File::create(&vmlinux_file)?; + file.write_all(&content)?; + + println!("cargo:warning=Downloaded and cached vmlinux.h for {}", arch); + + Ok(cache_dir) +} + #[cfg(all(target_os = "linux", feature = "ebpf"))] fn compile_ebpf_programs() { use libbpf_cargo::SkeletonBuilder; @@ -165,19 +232,23 @@ fn compile_ebpf_programs() { let arch = env::var("CARGO_CFG_TARGET_ARCH") .expect("CARGO_CFG_TARGET_ARCH must be set in build script"); - // Map Rust arch names to eBPF target arch defines - let target_arch_define = match arch.as_str() { - "x86_64" => "-D__TARGET_ARCH_x86", - "aarch64" => "-D__TARGET_ARCH_arm64", - "arm" => "-D__TARGET_ARCH_arm", - _ => "-D__TARGET_ARCH_x86", // fallback + // Map Rust arch names to eBPF target arch defines and vmlinux.h arch names + let (target_arch_define, vmlinux_arch) = match arch.as_str() { + "x86_64" => ("-D__TARGET_ARCH_x86", "x86"), + "aarch64" => ("-D__TARGET_ARCH_arm64", "aarch64"), + "arm" => ("-D__TARGET_ARCH_arm", "arm"), + _ => ("-D__TARGET_ARCH_x86", "x86"), // fallback }; + // Download architecture-specific vmlinux.h if not cached + let vmlinux_include_path = download_vmlinux_header(vmlinux_arch) + .expect("Failed to download vmlinux.h"); + SkeletonBuilder::new() .source(src) .clang_args([ OsStr::new("-I"), - vmlinux::include_path_root().join(&arch).as_os_str(), + vmlinux_include_path.as_os_str(), OsStr::new(target_arch_define), ]) .build_and_generate(&out)