Skip to content

Commit 1f16209

Browse files
committed
feat(sys): improve linking behavior, separate features for vendoring DTLS
- using mbedtls or tinydtls will no longer force usage of the vendored library version of mbedtls-sys-auto/tinydtls-sys by default - remove dependency on gnutls-sys crate as it is unmaintained, we now handle linking to gnutls ourselves - mbedtls-sys-auto is only used if mbedtls should be vendored, as the crate doesn't allow for disabling vendoring independently and doesn't support mbedtls >= 3.0.0 (see fortanix/rust-mbedtls#320) - in order to use the vendored versions of DTLS crate, you now have to enable the `dtls_backend_[BACKEND]_vendored` feature of libcoap-sys (or the `dtls_[BACKEND]_vendored` feature of libcoap-rs)
1 parent 287c26c commit 1f16209

File tree

5 files changed

+60
-12
lines changed

5 files changed

+60
-12
lines changed

Cargo.toml

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -9,3 +9,4 @@ members = [
99
"libcoap",
1010
"libcoap-sys",
1111
]
12+
resolver = "2"

libcoap-sys/Cargo.toml

Lines changed: 9 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -17,6 +17,7 @@ authors = ["Hugo Hakim Damer <[email protected]>"]
1717
categories = ["external-ffi-bindings", "network-programming", "embedded"]
1818
keywords = ["coap", "libcoap"]
1919
exclude = ["src/libcoap/ext/"]
20+
resolver = "2"
2021

2122
[features]
2223
# The default features match those of libcoaps configure script, except for dtls, which is disabled here because it
@@ -34,10 +35,13 @@ default = ["server", "client", "tcp", "async", "epoll", "vendored", "static"]
3435
# different backends), we select one based on the auto-detection order specified in
3536
# https://github.com/obgm/libcoap/blob/develop/configure.ac#L494 (gnutls > openssl > mbedtls > tinydtls).
3637
dtls = []
37-
dtls_backend_openssl = ["dtls", "openssl-sys"]
38-
dtls_backend_gnutls = ["dtls", "gnutls-sys"]
39-
dtls_backend_mbedtls = ["dtls", "mbedtls-sys-auto"]
40-
dtls_backend_tinydtls = ["dtls", "tinydtls-sys"]
38+
dtls_backend_openssl = ["dtls", "dep:openssl-sys"]
39+
dtls_backend_openssl_vendored = ["dtls_backend_openssl", "openssl-sys/vendored"]
40+
dtls_backend_gnutls = ["dtls"]
41+
dtls_backend_mbedtls = ["dtls"] # can't use mbedtls-sys-auto to generate linker flags here, as the crate doesn't support mbedtls >= 3.0.0
42+
dtls_backend_mbedtls_vendored = ["dep:mbedtls-sys-auto", "dtls_backend_mbedtls"]
43+
dtls_backend_tinydtls = ["dtls", "dep:tinydtls-sys"]
44+
dtls_backend_tinydtls_vendored = ["dtls_backend_tinydtls", "tinydtls-sys/vendored"]
4145
# Enabling this feature will force libcoap-sys to be built with and statically linked to a vendored version of libcoap,
4246
# which will be built by the build-script before building libcoap-sys.
4347
# This way, it is no longer required to have libcoap installed to use this crate.
@@ -61,11 +65,10 @@ client = []
6165
epoll = []
6266

6367
[dependencies]
64-
gnutls-sys = {version = "^0.1.2", optional = true}
6568
openssl-sys = {version = "^0.9.74", optional = true}
6669
mbedtls-sys-auto = {version = "^2.26", optional = true}
6770
libc = "^0.2.126"
68-
tinydtls-sys = {version = "^0.1.2", optional = true}
71+
tinydtls-sys = {version = "^0.1.2", default-features = false, optional = true}
6972

7073
[build-dependencies]
7174
bindgen = "^0.65.1"

libcoap-sys/build.rs

Lines changed: 43 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -16,6 +16,7 @@ use std::{
1616
};
1717

1818
use bindgen::EnumVariation;
19+
use pkg_config::probe_library;
1920

2021
#[derive(Debug, PartialEq, Eq, Clone, Copy)]
2122
pub enum DtlsBackend {
@@ -124,6 +125,7 @@ fn main() {
124125
.enable("dtls", None)
125126
.with(dtls_backend.to_string().as_str(), None);
126127

128+
// If DTLS is vendored we need to tell libcoap about the vendored version
127129
match dtls_backend {
128130
DtlsBackend::TinyDtls => {
129131
// We do not ship tinydtls with our source distribution. Instead, we use tinydtls-sys.
@@ -190,9 +192,7 @@ fn main() {
190192
}
191193
},
192194
DtlsBackend::GnuTls => {
193-
// gnutls-sys doesn't provide include directory metadata, but doesn't support
194-
// vendoring the library either. Instead, it just uses the GnuTLS found via
195-
// pkg-config, which is already found by libcoap by default.
195+
// Vendoring not supported
196196
},
197197
}
198198
} else {
@@ -251,6 +251,8 @@ fn main() {
251251
);
252252
env::set_current_dir(current_dir_backup).expect("unable to switch back to source dir");
253253
}
254+
255+
// Tell cargo to link libcoap.
254256
println!(
255257
"cargo:rustc-link-lib={}{}",
256258
cfg!(feature = "static").then(|| "static=").unwrap_or(""),
@@ -263,6 +265,44 @@ fn main() {
263265
)
264266
.as_str()
265267
);
268+
269+
// For the DTLS libraries, we need to tell cargo which external libraries to link.
270+
// Note that these linker instructions have to be added *after* the linker instruction
271+
// for libcoap itself, as some linkers require dependencies to be in reverse order.
272+
if let Some(dtls_backend) = dtls_backend {
273+
match dtls_backend {
274+
DtlsBackend::TinyDtls => {
275+
// Handled by tinydtls-sys
276+
},
277+
DtlsBackend::OpenSsl => {
278+
// Handled by openssl-sys
279+
},
280+
DtlsBackend::MbedTls => {
281+
// If mbedtls is vendored, mbedtls-sys-auto already takes care of linking.
282+
if env::var_os("DEP_MBEDTLS_INCLUDE").is_none() {
283+
// We aren't using mbedtls-sys-auto if we aren't vendoring (as it doesn't support
284+
// mbedtls >= 3.0.0), so we need to tell cargo to link to mbedtls ourselves.
285+
286+
// Try to find mbedtls using pkg-config
287+
if probe_library("mbedtls").is_err() {
288+
// couldn't find using pkg-config, just try linking with default library search path
289+
println!("cargo:rustc-link-lib=mbedtls");
290+
println!("cargo:rustc-link-lib=mbedx509");
291+
println!("cargo:rustc-link-lib=mbedcrypto");
292+
}
293+
}
294+
},
295+
DtlsBackend::GnuTls => {
296+
// gnutls-sys is unmaintained, so we need to link to gnutls ourselves.
297+
298+
// try pkg-config
299+
if probe_library("gnutls").is_err() {
300+
// if that doesn't work, try using the standard library search path.
301+
println!("cargo:rustc-link-lib=gnutls")
302+
}
303+
},
304+
}
305+
}
266306

267307
bindgen_builder = bindgen_builder
268308
.header("src/wrapper.h")

libcoap-sys/src/lib.rs

Lines changed: 3 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -90,9 +90,9 @@ use libc::{epoll_event, fd_set, sockaddr, sockaddr_in, sockaddr_in6, socklen_t,
9090

9191
use crate::coap_pdu_type_t::COAP_MESSAGE_RST;
9292

93-
#[cfg(feature = "dtls_backend_gnutls")]
94-
use gnutls_sys as _;
95-
#[cfg(feature = "dtls_backend_mbedtls")]
93+
// use dtls backend libraries in cases where they set our linker flags, otherwise cargo will
94+
// optimize them out.
95+
#[cfg(feature = "dtls_backend_mbedtls_vendored")]
9696
use mbedtls_sys as _;
9797
#[cfg(feature = "dtls_backend_openssl")]
9898
use openssl_sys as _;

libcoap/Cargo.toml

Lines changed: 4 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -15,14 +15,18 @@ repository = "https://github.com/namib-project/libcoap-rs"
1515
authors = ["Hugo Hakim Damer <[email protected]>"]
1616
categories = ["api-bindings", "network-programming", "embedded"]
1717
keywords = ["coap", "libcoap"]
18+
resolver = "2"
1819

1920
[features]
2021
default = ["dtls", "tcp", "dtls_openssl"]
2122
dtls = ["libcoap-sys/dtls"]
2223
dtls_tinydtls = ["libcoap-sys/dtls_backend_tinydtls"]
24+
dtls_tinydtls_vendored = ["dtls_tinydtls", "libcoap-sys/dtls_backend_tinydtls_vendored"]
2325
dtls_openssl = ["libcoap-sys/dtls_backend_openssl"]
26+
dtls_openssl_vendored = ["dtls_openssl", "libcoap-sys/dtls_backend_openssl_vendored"]
2427
dtls_gnutls = ["libcoap-sys/dtls_backend_gnutls"]
2528
dtls_mbedtls = ["libcoap-sys/dtls_backend_mbedtls"]
29+
dtls_mbedtls_vendored = ["dtls_mbedtls", "libcoap-sys/dtls_backend_mbedtls_vendored"]
2630
tcp = []
2731
nightly = []
2832
vendored = ["libcoap-sys/vendored"]

0 commit comments

Comments
 (0)