Add musl support

Đang mở
#69 2 bình luận 0 reaction 0 người được giao Xem trên GitHub

@KnorpelSenf đang làm issue này rồi.

Từ ngày 4/5/2026.

  • #70 của @KnorpelSenf — đang mở

Đá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

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

  1. Đọc hết issue, rồi đọc hướng dẫn đóng góp của dự án.
  2. 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.
  3. Fork repository và làm thay đổi trên một nhánh.
  4. Mở pull request có tham chiếu số hiệu của issue.

Issue khác của rustls/ktls

Tất cả issue của rustls/ktls

Issue tương tự

Thêm issue về Rust

Nhận issue mới trong hộp thư của bạn

Bản tóm tắt ngắn những issue GitHub phù hợp với người mới.