Add musl support
Đánh giá
- Độ khó
- 3/5
- Thời gian dự kiến
- 1-2 ngày
- Mức phù hợp với người mới
- 48/100
- Loại issue
- Tính năng
- Độ rõ ràng
- Khá rõ ràng
- Mức độ hoạt động
- Ít trao đổi
- Công nghệ
- docker, linux, rust
- Lĩnh vực
- build-system, operating-systems
Hướng nghiên cứu
Bắt đầu với ktls/src/ffi.rs tại trình khởi tạo cmsghdr quanh dòng 255 và trình khởi tạo msghdr quanh dòng 275, sau đó tái hiện lỗi bằng x86_64-unknown-linux-musl cargo build của Dockerfile. Cập nhật khả năng tương thích với musl cho các cấu trúc FFI này và xác minh rằng target ktls-smoke build thành công cho target musl.
Do mô hình lập chỉ mục viết ra từ nội dung của issue.
Mô tả
I would like to compile my rust application to a statically linked binary so that I can use it inside a FROM scratch docker image. However, it seems like this crate is incompatible with musl.
To reproduce this, I have create a somewhat lengthy dockerfile that attempts to run a simple application that smoke-tests ktls. You can find it here:
Dockerfile
FROM rust:1-bookworm AS base
WORKDIR /workspace
RUN apt-get update \
&& apt-get install -y --no-install-recommends pkg-config musl-tools \
&& rm -rf /var/lib/apt/lists/*
RUN rustup target add x86_64-unknown-linux-musl
FROM base AS deps
COPY Cargo.lock Cargo.lock
COPY ktls/Cargo.toml ktls/Cargo.toml
COPY ktls-sys/Cargo.toml ktls-sys/Cargo.toml
RUN cat > Cargo.toml << 'TOML'
[workspace]
members = ["ktls", "ktls-sys", "app"]
resolver = "2"
[workspace.package]
edition = "2021"
rust-version = "1.75.0"
authors = ["Amos Wenger <[email protected]>"]
license = "MIT OR Apache-2.0"
readme = "README.md"
repository = "https://github.com/rustls/ktls"
TOML
RUN mkdir -p app/src && cat > app/Cargo.toml << 'TOML'
[package]
name = "ktls-smoke"
version = "0.1.0"
edition = "2021"
[dependencies]
ktls = { path = "../ktls", default-features = false, features = ["ring", "tls12"] }
tokio = { version = "1", features = ["full"] }
tokio-rustls = { version = "0.26", default-features = false, features = ["ring", "tls12"] }
rustls = { version = "0.23", default-features = false, features = ["ring", "tls12"] }
rcgen = "0.13"
TOML
RUN mkdir -p ktls/src ktls-sys/src && \
touch ktls/src/lib.rs ktls-sys/src/lib.rs && \
printf 'fn main() {}\n' > app/src/main.rs
RUN cargo build --release -p ktls-smoke
RUN cargo build --release --target x86_64-unknown-linux-musl -p ktls-smoke
# LLM-generated ktls smoke test file for a minimal repro:
RUN cat > app/src/main.rs << 'RUST'
//! Minimal end-to-end kTLS smoke test:
//! - generates a self-signed certificate
//! - starts a TLS server with kernel TLS offload enabled (kTLS)
//! - connects a plain TLS client
//! - exchanges a round-trip payload and verifies it
use std::sync::Arc;
use ktls::CorkStream;
use rcgen::generate_simple_self_signed;
use rustls::{ClientConfig, RootCertStore, ServerConfig};
use tokio::{
io::{AsyncReadExt, AsyncWriteExt},
net::{TcpListener, TcpStream},
};
use tokio_rustls::TlsConnector;
const PING: &[u8] = b"ping from ktls client";
const PONG: &[u8] = b"pong from ktls server";
#[tokio::main]
async fn main() {
rustls::crypto::ring::default_provider()
.install_default()
.expect("failed to install ring crypto provider");
let cert = generate_simple_self_signed(vec!["localhost".to_string()])
.expect("cert generation failed");
let mut server_cfg = ServerConfig::builder()
.with_no_client_auth()
.with_single_cert(
vec![cert.cert.der().clone()],
rustls::pki_types::PrivatePkcs8KeyDer::from(cert.key_pair.serialize_der()).into(),
)
.expect("server config error");
server_cfg.enable_secret_extraction = true;
let acceptor = tokio_rustls::TlsAcceptor::from(Arc::new(server_cfg));
let ln = TcpListener::bind("127.0.0.1:0").await.expect("bind failed");
let addr = ln.local_addr().unwrap();
let server = tokio::spawn(async move {
let (tcp, _) = ln.accept().await.expect("accept failed");
// CorkStream must wrap the TCP socket before the TLS handshake so
// that ktls can drain the rustls internal buffer at the record boundary.
let tls = acceptor
.accept(CorkStream::new(tcp))
.await
.expect("TLS handshake failed");
let mut stream = ktls::config_ktls_server(tls)
.await
.expect("kTLS offload setup failed — is the tls kernel module loaded?");
let mut buf = vec![0u8; PING.len()];
stream.read_exact(&mut buf).await.expect("server read failed");
assert_eq!(buf, PING, "server received unexpected payload");
stream.write_all(PONG).await.expect("server write failed");
stream.flush().await.expect("server flush failed");
stream.shutdown().await.expect("server shutdown failed");
});
let mut root_store = RootCertStore::empty();
root_store.add(cert.cert.der().clone()).unwrap();
let client_cfg = ClientConfig::builder()
.with_root_certificates(root_store)
.with_no_client_auth();
let connector = TlsConnector::from(Arc::new(client_cfg));
let tcp = TcpStream::connect(addr).await.expect("connect failed");
let mut tls = connector
.connect("localhost".try_into().unwrap(), tcp)
.await
.expect("client TLS handshake failed");
tls.write_all(PING).await.expect("client write failed");
tls.flush().await.expect("client flush failed");
let mut buf = vec![0u8; PONG.len()];
tls.read_exact(&mut buf).await.expect("client read failed");
assert_eq!(buf, PONG, "client received unexpected payload");
server.await.unwrap();
eprintln!("ktls smoke test passed");
}
RUST
FROM deps AS build-gnu
COPY ktls/src/ ktls/src/
COPY ktls-sys/src/ ktls-sys/src/
# mark all files as dirty
RUN find ktls ktls-sys app -name '*.rs' | xargs touch
RUN cargo build --release -p ktls-smoke
FROM deps AS build-musl
COPY ktls/src/ ktls/src/
COPY ktls-sys/src/ ktls-sys/src/
# mark all files as dirty
RUN find ktls ktls-sys app -name '*.rs' | xargs touch
RUN cargo build --release --target x86_64-unknown-linux-musl -p ktls-smoke
FROM scratch
COPY --from=build-musl /workspace/target/x86_64-unknown-linux-musl/release/ktls-smoke /ktls-smoke
ENTRYPOINT ["/ktls-smoke"]
When I build it, I see this error:
$ docker build --progress=plain -t ktls-repro .
#0 building with "default" instance using docker driver
#1 [internal] load build definition from Dockerfile
#1 transferring dockerfile: 5.67kB done
#1 DONE 0.0s
#2 resolve image config for docker-image://docker.io/docker/dockerfile:1
#2 DONE 2.8s
#3 docker-image://docker.io/docker/dockerfile:1@sha256:2780b5c3bab67f1f76c781860de469442999ed1a0d7992a5efdf2cffc0e3d769
#3 CACHED
#4 [internal] load metadata for docker.io/library/rust:1-bookworm
#4 DONE 1.3s
#5 [internal] load .dockerignore
#5 transferring context: 2B done
#5 DONE 0.0s
#6 [base 1/4] FROM docker.io/library/rust:1-bookworm@sha256:adab7941580c74513aa3347f2d2a1f975498280743d29ec62978ba12e3540d3a
#6 DONE 0.0s
#7 [internal] load build context
#7 transferring context: 11.27kB done
#7 DONE 0.0s
#8 [deps 4/9] RUN cat > Cargo.toml << 'TOML'
#8 CACHED
#9 [deps 6/9] RUN mkdir -p ktls/src ktls-sys/src && touch ktls/src/lib.rs ktls-sys/src/lib.rs && printf 'fn main() {}\n' > app/src/main.rs
#9 CACHED
#10 [deps 7/9] RUN cargo build --release -p ktls-smoke
#10 CACHED
#11 [base 4/4] RUN rustup target add x86_64-unknown-linux-musl
#11 CACHED
#12 [deps 8/9] RUN cargo build --release --target x86_64-unknown-linux-musl -p ktls-smoke
#12 CACHED
#13 [deps 1/9] COPY Cargo.lock Cargo.lock
#13 CACHED
#14 [base 2/4] WORKDIR /workspace
#14 CACHED
#15 [base 3/4] RUN apt-get update && apt-get install -y --no-install-recommends pkg-config musl-tools && rm -rf /var/lib/apt/lists/*
#15 CACHED
#16 [deps 3/9] COPY ktls-sys/Cargo.toml ktls-sys/Cargo.toml
#16 CACHED
#17 [deps 2/9] COPY ktls/Cargo.toml ktls/Cargo.toml
#17 CACHED
#18 [deps 5/9] RUN mkdir -p app/src && cat > app/Cargo.toml << 'TOML'
#18 CACHED
#19 [deps 9/9] RUN cat > app/src/main.rs << 'RUST'
#19 CACHED
#20 [build-musl 1/4] COPY ktls/src/ ktls/src/
#20 DONE 0.0s
#21 [build-musl 2/4] COPY ktls-sys/src/ ktls-sys/src/
#21 DONE 0.0s
#22 [build-musl 3/4] RUN find ktls ktls-sys app -name '*.rs' | xargs touch
#22 DONE 0.2s
#23 [build-musl 4/4] RUN cargo build --release --target x86_64-unknown-linux-musl -p ktls-smoke
#23 0.245 Compiling ktls v6.0.2 (/workspace/ktls)
#23 0.369 error[E0063]: missing field `__pad1` in initializer of `cmsghdr`
#23 0.369 --> ktls/src/ffi.rs:255:18
#23 0.369 |
#23 0.369 255 | hdr: libc::cmsghdr {
#23 0.369 | ^^^^^^^^^^^^^ missing `__pad1`
#23 0.369
#23 0.370 error: cannot construct `msghdr` with struct literal syntax due to private fields
#23 0.370 --> ktls/src/ffi.rs:275:15
#23 0.370 |
#23 0.370 275 | let msg = libc::msghdr {
#23 0.370 | ^^^^^^^^^^^^
#23 0.370 |
#23 0.370 = note: ...and other private fields `__pad1` and `__pad2` that were not provided
#23 0.370
#23 0.434 For more information about this error, try `rustc --explain E0063`.
#23 0.437 error: could not compile `ktls` (lib) due to 2 previous errors
#23 ERROR: process "/bin/sh -c cargo build --release --target x86_64-unknown-linux-musl -p ktls-smoke" did not complete successfully: exit code: 101
------
> [build-musl 4/4] RUN cargo build --release --target x86_64-unknown-linux-musl -p ktls-smoke:
0.370 error: cannot construct `msghdr` with struct literal syntax due to private fields
0.370 --> ktls/src/ffi.rs:275:15
0.370 |
0.370 275 | let msg = libc::msghdr {
0.370 | ^^^^^^^^^^^^
0.370 |
0.370 = note: ...and other private fields `__pad1` and `__pad2` that were not provided
0.370
0.434 For more information about this error, try `rustc --explain E0063`.
0.437 error: could not compile `ktls` (lib) due to 2 previous errors
------
Dockerfile:173
--------------------
171 | RUN find ktls ktls-sys app -name '*.rs' | xargs touch
172 |
173 | >>> RUN cargo build --release --target x86_64-unknown-linux-musl -p ktls-smoke
174 |
175 | FROM scratch
--------------------
ERROR: failed to build: failed to solve: process "/bin/sh -c cargo build --release --target x86_64-unknown-linux-musl -p ktls-smoke" did not complete successfully: exit code: 101
From what I can tell, this means that the ktls crate does not compile against the libc structs because they have hidden fields.
- Ngôn ngữ chính
- Rust
- Star
- 100
- Fork
- 19
- Chỉ số merge pull request
- Không có pull request nào được merge trong 30 ngày
Chuẩn bị môi trường
Dự án này không cung cấp dev container, Dockerfile hay hướng dẫn đóng góp, nên bạn cần tự thiết lập môi trường: hãy bắt đầu từ README và xem hướng dẫn đóng góp lần đầu của chúng tôi để biết các bước chung.
Bắt đầu từ đâu
- Đọc hết issue, rồi đọc hướng dẫn đóng góp của dự án.
- Bình luận trên issue rằng bạn sẽ nhận — tránh hai người làm cùng một việc.
- Fork repository và làm thay đổi trên một nhánh.
- Mở pull request có tham chiếu số hiệu của issue.
Issue khác của rustls/ktls
-
Độ khó 2/5 1-3 giờ Mức phù hợp với người mới 68/100
-
Độ khó 3/5 1-2 ngày Mức phù hợp với người mới 52/100
-
Support new rustls `KernelConnection` API, and thence TLS1.3 KeyUpdatesCó thể đã có người làm @cxw620 đã nhận 436 ngày trước. Đang mở
Độ khó 4/5 3-5 ngày Mức phù hợp với người mới 42/100
-
Độ khó 4/5 3-5 ngày Mức phù hợp với người mới 35/100
-
Độ khó 5/5 Hơn một tuần Mức phù hợp với người mới 25/100
Issue tương tự
-
Độ khó 2/5 1-3 giờ Mức phù hợp với người mới 70/100
Maintainer thường phản hồi trong vòng 1 ngày
-
Độ khó 2/5 1-3 giờ Mức phù hợp với người mới 70/100
libnativeapi/nativeapi#21 ·
-
Độ khó 2/5 1-3 giờ Mức phù hợp với người mới 78/100
Maintainer thường phản hồi trong vòng 1 ngày
-
Độ khó 2/5 1-3 giờ Mức phù hợp với người mới 68/100
longbridge/nsh#804 ·
Maintainer thường phản hồi trong vòng 1 ngày
-
Độ khó 2/5 1-3 giờ Mức phù hợp với người mới 62/100
Maintainer thường phản hồi trong vòng 1 ngày