Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
12 changes: 6 additions & 6 deletions .github/workflows/ci.yml
Original file line number Diff line number Diff line change
Expand Up @@ -24,23 +24,23 @@ jobs:
- uses: actions/checkout@v3
with:
submodules: true
- uses: dtolnay/rust-toolchain@master
- uses: dtolnay/rust-toolchain@stable
with:
components: rust-src
toolchain: nightly
toolchain: stable
- if: matrix.dtls_backend == 'gnutls'
uses: awalsh128/cache-apt-pkgs-action@latest
with:
packages: libgnutls28-dev libgnutls30
version: 1.0
- if: matrix.crate == 'libcoap-rs' && matrix.dtls_backend != 'gnutls'
run: cargo test -p ${{ matrix.crate }} --no-default-features --features dtls,tcp,vendored --features dtls_${{ matrix.dtls_backend }} --features dtls_${{ matrix.dtls_backend }}_vendored --no-fail-fast -- -Z unstable-options --report-time --ensure-time
run: cargo test -p ${{ matrix.crate }} --no-default-features --features dtls,tcp,vendored --features dtls_${{ matrix.dtls_backend }} --features dtls_${{ matrix.dtls_backend }}_vendored --no-fail-fast
- if: matrix.crate == 'libcoap-rs' && matrix.dtls_backend == 'gnutls'
run: cargo test -p ${{ matrix.crate }} --no-default-features --features dtls,tcp,vendored --features dtls_${{ matrix.dtls_backend }} --no-fail-fast -- -Z unstable-options --report-time --ensure-time
run: cargo test -p ${{ matrix.crate }} --no-default-features --features dtls,tcp,vendored --features dtls_${{ matrix.dtls_backend }} --no-fail-fast
- if: matrix.crate == 'libcoap-sys' && matrix.dtls_backend != 'gnutls'
run: cargo test -p ${{ matrix.crate }} --features dtls,dtls_backend_${{ matrix.dtls_backend }},dtls_backend_${{ matrix.dtls_backend }}_vendored --no-fail-fast -- -Z unstable-options --report-time --ensure-time
run: cargo test -p ${{ matrix.crate }} --features dtls,dtls_backend_${{ matrix.dtls_backend }},dtls_backend_${{ matrix.dtls_backend }}_vendored --no-fail-fast
- if: matrix.crate == 'libcoap-sys' && matrix.dtls_backend == 'gnutls'
run: cargo test -p ${{ matrix.crate }} --features dtls,dtls_backend_${{ matrix.dtls_backend }} --no-fail-fast -- -Z unstable-options --report-time --ensure-time
run: cargo test -p ${{ matrix.crate }} --features dtls,dtls_backend_${{ matrix.dtls_backend }} --no-fail-fast

lint:
runs-on: ubuntu-latest
Expand Down
6 changes: 6 additions & 0 deletions .idea/dtsSettings.xml

Some generated files are not rendered by default. Learn more about how customized files appear on GitHub.

5 changes: 1 addition & 4 deletions .idea/runConfigurations/Test.xml

Some generated files are not rendered by default. Learn more about how customized files appear on GitHub.

1 change: 1 addition & 0 deletions libcoap-sys/build.rs
Original file line number Diff line number Diff line change
Expand Up @@ -94,6 +94,7 @@ fn get_builder_espidf() -> bindgen::Builder {
let esp_arch = env::var("CARGO_CFG_TARGET_ARCH").expect("CARGO_CFG_TARGET_ARCH is not set");

// Determine compiler path
// SAFETY: Always safe to call in a single-threaded environment (see docs of env::set_var).
unsafe { env::set_var("PATH", embuild_env) };
let cmake_info = embuild::cmake::Query::new(
&Path::new(&esp_idf_buildroot).join("build"),
Expand Down
63 changes: 49 additions & 14 deletions libcoap-sys/src/lib.rs
Original file line number Diff line number Diff line change
Expand Up @@ -86,16 +86,22 @@
#![allow(deref_nullptr)]
#![allow(non_snake_case)]

use libc::{fd_set, sockaddr, sockaddr_in, sockaddr_in6, socklen_t, time_t, sa_family_t};
#[cfg(not(target_os = "espidf"))]
use libc::{epoll_event};
use std::ffi::c_void;

// use dtls backend libraries in cases where they set our linker flags, otherwise cargo will
#[allow(unused_imports)]
use libc::{fd_set, memcmp, sa_family_t, sockaddr, sockaddr_in, sockaddr_in6, socklen_t, time_t};
#[allow(unused_imports)]
#[cfg(not(target_os = "espidf"))]
use libc::epoll_event;
// use dtls backend libraries in cases where they set our linker flags, otherwise cargo will
// optimize them out.
#[allow(unused_imports)]
#[cfg(feature = "dtls_backend_mbedtls_vendored")]
use mbedtls_sys as _;
#[allow(unused_imports)]
#[cfg(feature = "dtls_backend_openssl")]
use openssl_sys as _;
#[allow(unused_imports)]
#[cfg(feature = "dtls_backend_tinydtls")]
use tinydtls_sys as _;

Expand All @@ -106,13 +112,45 @@ include!(concat!(env!("OUT_DIR"), "/bindings.rs"));

#[inline]
#[cfg(inlined_coap_send_rst)]
pub unsafe fn coap_send_rst(
session: *mut coap_session_t,
request: *const coap_pdu_t,
) -> coap_mid_t {
pub unsafe fn coap_send_rst(session: *mut coap_session_t, request: *const coap_pdu_t) -> coap_mid_t {
coap_send_message_type(session, request, crate::coap_pdu_type_t::COAP_MESSAGE_RST)
}

/// Compares instances of coap_str_const_t and/or coap_string_t.
///
/// This macro is a reimplementation of the macro defined in coap_str.h, see
/// <https://libcoap.net/doc/reference/develop/group__string.html#ga7f43c10b486dc6d45c37fcaf987d711b>.
#[macro_export]
macro_rules! coap_string_equal {
( $string1:expr, $string2:expr ) => {{
use libcoap_sys::coap_string_equal_internal;
let s1 = $string1;
let s2 = $string2;
coap_string_equal_internal((*s1).s, (*s1).length, (*s2).s, (*s2).length)
}};
}

/// Internal only function for CoAP string comparisons.
///
/// *DO NOT USE THIS FUNCTION DIRECTLY.* It is only public because it is used by the
/// [coap_string_equal] macro, which is the function you probably wanted to call instead.
///
/// # Safety
///
/// This function should not be called directly, use [coap_string_equal] instead.
pub unsafe fn coap_string_equal_internal(
str1_ptr: *const u8,
str1_len: usize,
str2_ptr: *const u8,
str2_len: usize,
) -> bool {
str1_len == str2_len
&& (str1_len == 0
|| !str1_ptr.is_null()
&& !str2_ptr.is_null()
&& memcmp(str1_ptr as *const c_void, str2_ptr as *const c_void, str1_len) == 0)
}

#[cfg(all(test, not(target_os = "espidf")))]
mod tests {
use std::{
Expand All @@ -122,16 +160,17 @@ mod tests {
sync::{Arc, Barrier},
};

use libc::{in6_addr, in_addr, sa_family_t, size_t, AF_INET, AF_INET6};
use libc::{AF_INET, AF_INET6, in6_addr, in_addr, sa_family_t, size_t};

use super::*;
use crate::{
coap_pdu_code_t::{COAP_REQUEST_CODE_GET, COAP_RESPONSE_CODE_CONTENT},
coap_proto_t::COAP_PROTO_UDP,
coap_request_t::COAP_REQUEST_GET,
coap_response_t::COAP_RESPONSE_OK,
};

use super::*;

const COAP_TEST_RESOURCE_URI: &str = "test";
const COAP_TEST_RESOURCE_RESPONSE: &str = "Hello World!";

Expand Down Expand Up @@ -286,8 +325,6 @@ mod tests {
// This also seems to free all resources.
unsafe {
coap_free_context(context);
std::mem::drop(context);
std::mem::drop(test_resource);
}
}

Expand Down Expand Up @@ -371,8 +408,6 @@ mod tests {
// This also seems to free all resources.
unsafe {
coap_free_context(context);
std::mem::drop(context);
std::mem::drop(client_session)
}
server_thread_handle.join().expect("Error waiting for server thread");
}
Expand Down
8 changes: 4 additions & 4 deletions libcoap/Cargo.toml
Original file line number Diff line number Diff line change
Expand Up @@ -18,7 +18,7 @@ keywords = ["coap", "libcoap"]
resolver = "2"

[features]
default = ["dtls", "tcp", "dtls_openssl"]
default = ["dtls", "tcp", "dtls_openssl", "vendored"]
dtls = ["libcoap-sys/dtls"]
dtls_tinydtls = ["libcoap-sys/dtls_backend_tinydtls"]
dtls_tinydtls_vendored = ["dtls_tinydtls", "libcoap-sys/dtls_backend_tinydtls_vendored"]
Expand All @@ -34,11 +34,11 @@ vendored = ["libcoap-sys/vendored"]
[dependencies]
libcoap-sys = { version = "^0.2.2", path = "../libcoap-sys", default-features = false, features = ["client", "server"] }
libc = { version = "^0.2.95" }
num-derive = { version = "^0.3.3" }
num-derive = { version = "^0.3.3" }
num-traits = { version = "^0.2.14" }
url = { version = "^2.2" }
url = { version = "^2.2", optional = true }
rand = { version = "^0.8.4" }
thiserror = "^1.0"

[package.metadata.docs.rs]
features = ["dtls", "dtls_openssl", "vendored"]
features = ["dtls", "dtls_openssl", "vendored", "url"]
7 changes: 4 additions & 3 deletions libcoap/src/crypto.rs
Original file line number Diff line number Diff line change
Expand Up @@ -19,8 +19,8 @@ use libcoap_sys::{
coap_bin_const_t, coap_context_t, coap_dtls_cpsk_info_t, coap_dtls_spsk_info_t, coap_session_t, coap_str_const_t,
};

use crate::session::CoapServerSession;
use crate::{context::CoapContext, session::CoapClientSession};
use crate::session::CoapServerSession;

/// Representation of cryptographic information used by a server.
#[derive(Debug, Clone, PartialEq, Eq)]
Expand Down Expand Up @@ -132,6 +132,7 @@ pub trait CoapServerCryptoProvider: Debug {

// TODO DTLS PKI/RPK

// DTLS Identity Hint callback is unsupported on mbedtls
#[cfg(feature = "dtls")]
pub(crate) unsafe extern "C" fn dtls_ih_callback(
hint: *mut coap_str_const_t,
Expand All @@ -142,7 +143,7 @@ pub(crate) unsafe extern "C" fn dtls_ih_callback(
let provided_identity = std::slice::from_raw_parts((*hint).s, (*hint).length);
session
.provide_raw_key_for_hint(provided_identity)
.map(|v| v as *const coap_dtls_cpsk_info_t)
.map(|v| v)
.unwrap_or(std::ptr::null())
}

Expand Down Expand Up @@ -170,7 +171,7 @@ pub(crate) unsafe extern "C" fn dtls_server_sni_callback(
if let Ok(sni_value) = sni_value {
context
.provide_raw_hint_for_sni(sni_value)
.map(|v| (v as *const coap_dtls_spsk_info_t))
.map(|v| (v))
.unwrap_or(std::ptr::null())
} else {
std::ptr::null()
Expand Down
25 changes: 13 additions & 12 deletions libcoap/src/error.rs
Original file line number Diff line number Diff line change
Expand Up @@ -9,6 +9,7 @@

//! Error types

use std::ffi::NulError;
use std::string::FromUtf8Error;

use thiserror::Error;
Expand Down Expand Up @@ -82,16 +83,25 @@ pub enum OptionValueError {
/// A string value could not be converted to UTF-8.
#[error("CoAP option has invalid value: invalid string")]
StringConversion(#[from] FromUtf8Error),
/// URI encoded in message could not be parsed.
#[error("CoAP option has invalid value: invalid URI")]
UriParsing(#[from] UriParsingError),
/// Option has an illegal value.
#[error("CoAP option has invalid value")]
IllegalValue,
}

#[derive(Error, Debug, Copy, Clone, Eq, PartialEq)]
#[derive(Error, Debug, Clone, Eq, PartialEq)]
pub enum UriParsingError {
/// Unknown error inside of libcoap
#[error("CoAP option creation error: unknown error in call to libcoap")]
Unknown,
/// URI does not have a valid scheme for libcoap (coap, coaps, coap+tcp, coaps+tcp, http, https).
#[error("URL does not have scheme valid for libcoap")]
NotACoapScheme,
#[error("URI scheme {} is not a valid CoAP scheme known to libcoap", .0)]
NotACoapScheme(String),
/// Provided URI contains a null byte.
#[error("Provided URI contains a null byte")]
ContainsNullByte(#[from] NulError),
}

#[derive(Error, Debug, Clone, Eq, PartialEq)]
Expand All @@ -109,9 +119,6 @@ pub enum MessageConversionError {
/// Provided URI has invalid scheme.
#[error("CoAP message conversion error: provided uri does not have scheme valid for CoAP")]
NotACoapUri(UriParsingError),
/// URI is invalid (most likely a Proxy URI cannot be parsed as a valid URL).
#[error("CoAP message conversion error: invalid uri (malformed proxy URL?)")]
InvalidUri(url::ParseError),
/// Invalid message code.
#[error("CoAP message conversion error: invalid message code")]
InvalidMessageCode(#[from] MessageCodeError),
Expand Down Expand Up @@ -143,12 +150,6 @@ impl From<UriParsingError> for MessageConversionError {
}
}

impl From<url::ParseError> for MessageConversionError {
fn from(v: url::ParseError) -> Self {
MessageConversionError::InvalidUri(v)
}
}

#[derive(Error, Debug, Copy, Clone, Eq, PartialEq)]
pub enum MessageCodeError {
/// Provided message code for request was not a request code.
Expand Down
17 changes: 7 additions & 10 deletions libcoap/src/lib.rs
Original file line number Diff line number Diff line change
Expand Up @@ -3,7 +3,7 @@
* lib.rs - Main library entry point for safe libcoap bindings.
* This file is part of the libcoap-rs crate, see the README and LICENSE files for
* more information and terms of use.
* Copyright © 2021-2023 The NAMIB Project Developers, all rights reserved.
* Copyright © 2021-2024 The NAMIB Project Developers, all rights reserved.
* See the README as well as the LICENSE file for more information.
*/

Expand Down Expand Up @@ -56,8 +56,6 @@
//! types::{CoapUriScheme, CoapUri}
//! };
//!
//! use url::Url;
//!
//! let server_address : SocketAddr = "[::1]:5683".parse().unwrap();
//!
//! // Create a new context.
Expand All @@ -68,11 +66,10 @@
//! .expect("Failed to create client-side session");
//!
//! // Create a new CoAP URI to request from.
//! let uri = CoapUri::try_from_url(Url::parse("coap://[::1]:5683/hello_world").unwrap()).unwrap();
//! let uri = "coap://[::1]:5683/hello_world".parse().unwrap();
//!
//! // Create a new request of type get with the specified URI.
//! let mut request = CoapRequest::new(CoapMessageType::Con, CoapRequestCode::Get).unwrap();
//! request.set_uri(Some(uri)).unwrap();
//! let mut request = CoapRequest::new(CoapMessageType::Con, CoapRequestCode::Get, uri).unwrap();
//!
//! // Send the request and wait for a response.
//! let req_handle = session.send_request(request).expect("Unable to send request");
Expand Down Expand Up @@ -178,6 +175,10 @@
//! Note that enabling multiple backends is not possible and doing so will result in a single
//! backend being chosen based on the priority order (gnutls > openssl > mbedtls > tinydtls).

pub use context::CoapContext;
pub use event::CoapEventHandler;
pub use resource::{CoapRequestHandler, CoapResource};

mod context;
#[cfg(feature = "dtls")]
pub mod crypto;
Expand All @@ -190,7 +191,3 @@ mod resource;
pub mod session;
pub mod transport;
pub mod types;

pub use context::CoapContext;
pub use event::CoapEventHandler;
pub use resource::{CoapRequestHandler, CoapResource};
Loading