Skip to content

Commit

Permalink
Merge pull request #103 from hubertmis/pr/udp-client-from-std-socket
Browse files Browse the repository at this point in the history
New CoAPClient creator method using a standard socket
  • Loading branch information
Covertness authored Sep 4, 2024
2 parents cffad3c + e64c209 commit 783a7b5
Show file tree
Hide file tree
Showing 2 changed files with 42 additions and 7 deletions.
3 changes: 2 additions & 1 deletion Cargo.toml
Original file line number Diff line number Diff line change
Expand Up @@ -38,5 +38,6 @@ dtls = ["dep:webrtc-dtls", "dep:webrtc-util", "dep:rustls", "dep:rustls-pemfile"

[dev-dependencies]
quickcheck = "0.8.2"

socket2 = "0.5"
tokio-test = "0.4.4"

46 changes: 40 additions & 6 deletions src/client.rs
Original file line number Diff line number Diff line change
Expand Up @@ -391,13 +391,8 @@ impl UdpCoAPClient {
bind_addr: A,
peer_addr: B,
) -> IoResult<Self> {
let peer_addr = lookup_host(peer_addr).await?.next().ok_or(Error::new(
ErrorKind::InvalidInput,
"could not get socket address",
))?;
let socket = UdpSocket::bind(bind_addr).await?;
let transport = UdpTransport { socket, peer_addr };
return Ok(UdpCoAPClient::from_transport(transport));
Self::new_with_tokio_socket(socket, peer_addr).await
}

pub async fn new_udp<A: ToSocketAddrs>(addr: A) -> IoResult<Self> {
Expand All @@ -410,6 +405,45 @@ impl UdpCoAPClient {
SocketAddr::V6(_) => Self::new_with_specific_source(":::0", sock_addr).await?,
})
}

/// Create a client with a `std::net` socket
///
/// Using a standard socket is useful to get advanced features from socket2 crate
///
/// # Examples
///
/// ```
/// # tokio_test::block_on(async {
/// use socket2::{Socket, Domain, Type};
/// use coap::UdpCoAPClient;
///
/// let socket = Socket::new(Domain::IPV6, Type::DGRAM, None).expect("Standard socket creation failed");
/// socket.set_multicast_hops_v6(16).expect("Setting multicast hops failed");
/// let client = UdpCoAPClient::new_with_std_socket(socket.into(), "[::1]:5683").await.expect("Client creation failed");
/// # })
/// ```
pub async fn new_with_std_socket<A: ToSocketAddrs>(
socket: std::net::UdpSocket,
peer_addr: A,
) -> IoResult<Self> {
socket.set_nonblocking(true)?;
let socket = UdpSocket::from_std(socket)?;
Self::new_with_tokio_socket(socket, peer_addr).await
}

async fn new_with_tokio_socket<A: ToSocketAddrs>(
socket: UdpSocket,
peer_addr: A,
) -> IoResult<Self> {
let peer_addr = lookup_host(peer_addr).await?.next().ok_or(Error::new(
ErrorKind::InvalidInput,
"could not get socket address",
))?;

let transport = UdpTransport { socket, peer_addr };
Ok(UdpCoAPClient::from_transport(transport))
}

/// Send a request to all CoAP devices.
/// - IPv4 AllCoAP multicast address is '224.0.1.187'
/// - IPv6 AllCoAp multicast addresses are 'ff0?::fd'
Expand Down

0 comments on commit 783a7b5

Please sign in to comment.