mirror of
https://github.com/RIOT-OS/RIOT.git
synced 2024-12-29 04:50:03 +01:00
Merge pull request #14043 from pokgak/pr/sock_dtls/send_api_change
sock_dtls: add timeout to sock_dtls_send and add sock_dtls_session_init
This commit is contained in:
commit
e011e3ed38
@ -74,10 +74,11 @@ static int client_send(char *addr_str, char *data, size_t datalen)
|
||||
sock_udp_t udp_sock;
|
||||
sock_dtls_t dtls_sock;
|
||||
sock_dtls_session_t session;
|
||||
sock_udp_ep_t remote;
|
||||
sock_udp_ep_t remote = SOCK_IPV6_EP_ANY;
|
||||
sock_udp_ep_t local = SOCK_IPV6_EP_ANY;
|
||||
local.port = 12345;
|
||||
remote.port = DTLS_DEFAULT_PORT;
|
||||
uint8_t buf[DTLS_HANDSHAKE_BUFSIZE];
|
||||
|
||||
/* get interface */
|
||||
char* iface = ipv6_addr_split_iface(addr_str);
|
||||
@ -122,26 +123,32 @@ static int client_send(char *addr_str, char *data, size_t datalen)
|
||||
return -1;
|
||||
}
|
||||
|
||||
res = sock_dtls_session_create(&dtls_sock, &remote, &session);
|
||||
if (res < 0) {
|
||||
res = sock_dtls_session_init(&dtls_sock, &remote, &session);
|
||||
if (res <= 0) {
|
||||
return res;
|
||||
}
|
||||
|
||||
res = sock_dtls_recv(&dtls_sock, &session, buf, sizeof(buf),
|
||||
SOCK_NO_TIMEOUT);
|
||||
if (res != -SOCK_DTLS_HANDSHAKE) {
|
||||
printf("Error creating session: %d\n", (int)res);
|
||||
sock_dtls_close(&dtls_sock);
|
||||
sock_udp_close(&udp_sock);
|
||||
return -1;
|
||||
}
|
||||
printf("Connection to server successful\n");
|
||||
|
||||
if (sock_dtls_send(&dtls_sock, &session, data, datalen) < 0) {
|
||||
if (sock_dtls_send(&dtls_sock, &session, data, datalen, 0) < 0) {
|
||||
puts("Error sending data");
|
||||
}
|
||||
else {
|
||||
printf("Sent DTLS message\n");
|
||||
|
||||
uint8_t rcv[512];
|
||||
if (sock_dtls_recv(&dtls_sock, &session, rcv, sizeof(rcv), SOCK_NO_TIMEOUT) < 0) {
|
||||
printf("Error receiving DTLS message\n");
|
||||
}
|
||||
else {
|
||||
printf("Received DTLS message\n");
|
||||
if ((res = sock_dtls_recv(&dtls_sock, &session, rcv, sizeof(rcv),
|
||||
SOCK_NO_TIMEOUT)) >= 0) {
|
||||
printf("Received %d bytes: \"%.*s\"\n", (int)res, (int)res,
|
||||
(char *)rcv);
|
||||
}
|
||||
}
|
||||
|
||||
|
@ -108,22 +108,22 @@ void *dtls_server_wrapper(void *arg)
|
||||
}
|
||||
|
||||
while (active) {
|
||||
if ((msg_try_receive(&msg) == 1) && (msg.type == DTLS_STOP_SERVER_MSG)) {
|
||||
if ((msg_try_receive(&msg) == 1) &&
|
||||
(msg.type == DTLS_STOP_SERVER_MSG)){
|
||||
active = false;
|
||||
}
|
||||
else {
|
||||
res = sock_dtls_recv(&sock, &session, rcv, sizeof(rcv),
|
||||
10 * US_PER_SEC);
|
||||
if (res < 0) {
|
||||
if (res != -ETIMEDOUT) {
|
||||
printf("Error receiving UDP over DTLS %d", (int)res);
|
||||
if (res >= 0) {
|
||||
printf("Received %d bytes -- (echo)\n", (int)res);
|
||||
res = sock_dtls_send(&sock, &session, rcv, (size_t)res, 0);
|
||||
if (res < 0) {
|
||||
printf("Error resending DTLS message: %d", (int)res);
|
||||
}
|
||||
continue;
|
||||
}
|
||||
printf("Received %d bytes -- (echo!)\n", (int)res);
|
||||
res = sock_dtls_send(&sock, &session, rcv, (size_t)res);
|
||||
if (res < 0) {
|
||||
printf("Error resending DTLS message: %d", (int)res);
|
||||
else if (res == -SOCK_DTLS_HANDSHAKE) {
|
||||
printf("New client connected\n");
|
||||
}
|
||||
}
|
||||
}
|
||||
|
@ -24,15 +24,6 @@
|
||||
#include "debug.h"
|
||||
#include "dtls_debug.h"
|
||||
|
||||
#define DTLS_HANDSHAKE_BUFSIZE (256) /**< Size buffer used in handshake
|
||||
to hold credentials */
|
||||
/* ECC handshake takes more time */
|
||||
#ifdef CONFIG_DTLS_ECC
|
||||
#define DTLS_HANDSHAKE_TIMEOUT (30 * US_PER_SEC)
|
||||
#else
|
||||
#define DTLS_HANDSHAKE_TIMEOUT (1 * US_PER_SEC)
|
||||
#endif /* CONFIG_DTLS_ECC */
|
||||
|
||||
#ifdef CONFIG_DTLS_PSK
|
||||
static int _get_psk_info(struct dtls_context_t *ctx, const session_t *session,
|
||||
dtls_credentials_type_t type,
|
||||
@ -61,6 +52,7 @@ static int _event(struct dtls_context_t *ctx, session_t *session,
|
||||
|
||||
static void _session_to_ep(const session_t *session, sock_udp_ep_t *ep);
|
||||
static void _ep_to_session(const sock_udp_ep_t *ep, session_t *session);
|
||||
static uint32_t _update_timeout(uint32_t start, uint32_t timeout);
|
||||
|
||||
static dtls_handler_t _dtls_handler = {
|
||||
.event = _event,
|
||||
@ -112,7 +104,7 @@ static int _event(struct dtls_context_t *ctx, session_t *session,
|
||||
sock_dtls_t *sock = dtls_get_app_data(ctx);
|
||||
msg_t msg = { .type = code };
|
||||
#ifdef ENABLE_DEBUG
|
||||
switch(code) {
|
||||
switch (code) {
|
||||
case DTLS_EVENT_CONNECT:
|
||||
DEBUG("sock_dtls: event connect\n");
|
||||
break;
|
||||
@ -155,7 +147,7 @@ static int _get_psk_info(struct dtls_context_t *ctx, const session_t *session,
|
||||
|
||||
const void *c = NULL;
|
||||
size_t c_len = 0;
|
||||
switch(type) {
|
||||
switch (type) {
|
||||
case DTLS_PSK_HINT:
|
||||
DEBUG("sock_dtls: psk hint request\n");
|
||||
/* Ignored. See https://tools.ietf.org/html/rfc4279#section-5.2 */
|
||||
@ -267,27 +259,39 @@ int sock_dtls_create(sock_dtls_t *sock, sock_udp_t *udp_sock,
|
||||
return 0;
|
||||
}
|
||||
|
||||
int sock_dtls_session_create(sock_dtls_t *sock, const sock_udp_ep_t *ep,
|
||||
sock_dtls_session_t *remote)
|
||||
int sock_dtls_session_init(sock_dtls_t *sock, const sock_udp_ep_t *ep,
|
||||
sock_dtls_session_t *remote)
|
||||
{
|
||||
uint8_t rcv_buffer[DTLS_HANDSHAKE_BUFSIZE];
|
||||
msg_t msg;
|
||||
ssize_t res;
|
||||
|
||||
assert(sock);
|
||||
assert(ep);
|
||||
assert(remote);
|
||||
|
||||
sock_udp_ep_t local;
|
||||
if (!sock->udp_sock || (sock_udp_get_local(sock->udp_sock, &local) < 0)) {
|
||||
return -EADDRNOTAVAIL;
|
||||
}
|
||||
if (ep->port == 0) {
|
||||
return -EINVAL;
|
||||
}
|
||||
switch (ep->family) {
|
||||
case AF_INET:
|
||||
#if IS_ACTIVE(SOCK_HAS_IPV6)
|
||||
case AF_INET6:
|
||||
#endif
|
||||
break;
|
||||
default:
|
||||
return -EINVAL;
|
||||
}
|
||||
|
||||
/* prepare a the remote party to connect to */
|
||||
memcpy(&remote->ep, ep, sizeof(sock_udp_ep_t));
|
||||
memcpy(&remote->dtls_session.addr, &ep->addr.ipv6, sizeof(ipv6_addr_t));
|
||||
_ep_to_session(ep, &remote->dtls_session);
|
||||
|
||||
/* start a handshake */
|
||||
DEBUG("sock_dtls: starting handshake\n");
|
||||
res = dtls_connect(sock->dtls_ctx, &remote->dtls_session);
|
||||
/* start the handshake */
|
||||
int res = dtls_connect(sock->dtls_ctx, &remote->dtls_session);
|
||||
if (res < 0) {
|
||||
DEBUG("sock_dtls: error establishing a session: %d\n", (int)res);
|
||||
DEBUG("sock_dtls: error establishing a session: %d\n", res);
|
||||
return -ENOMEM;
|
||||
}
|
||||
else if (res == 0) {
|
||||
@ -295,28 +299,8 @@ int sock_dtls_session_create(sock_dtls_t *sock, const sock_udp_ep_t *ep,
|
||||
return 0;
|
||||
}
|
||||
|
||||
/* receive all handshake messages or timeout if timer expires */
|
||||
while (!mbox_try_get(&sock->mbox, &msg) ||
|
||||
msg.type != DTLS_EVENT_CONNECTED) {
|
||||
res = sock_udp_recv(sock->udp_sock, rcv_buffer, sizeof(rcv_buffer),
|
||||
DTLS_HANDSHAKE_TIMEOUT, &remote->ep);
|
||||
if (res <= 0) {
|
||||
DEBUG("sock_dtls: error receiving handshake messages: %d\n", (int)res);
|
||||
/* deletes peer created in dtls_connect() */
|
||||
dtls_peer_t *peer = dtls_get_peer(sock->dtls_ctx,
|
||||
&remote->dtls_session);
|
||||
dtls_reset_peer(sock->dtls_ctx, peer);
|
||||
return -ETIMEDOUT;
|
||||
}
|
||||
|
||||
res = dtls_handle_message(sock->dtls_ctx, &remote->dtls_session,
|
||||
rcv_buffer, res);
|
||||
/* stop handshake if received fatal level alert */
|
||||
if (res == -1) {
|
||||
return res;
|
||||
}
|
||||
}
|
||||
return 0;
|
||||
/* New handshake initiated */
|
||||
return 1;
|
||||
}
|
||||
|
||||
void sock_dtls_session_destroy(sock_dtls_t *sock, sock_dtls_session_t *remote)
|
||||
@ -325,7 +309,7 @@ void sock_dtls_session_destroy(sock_dtls_t *sock, sock_dtls_session_t *remote)
|
||||
}
|
||||
|
||||
ssize_t sock_dtls_send(sock_dtls_t *sock, sock_dtls_session_t *remote,
|
||||
const void *data, size_t len)
|
||||
const void *data, size_t len, uint32_t timeout)
|
||||
{
|
||||
assert(sock);
|
||||
assert(remote);
|
||||
@ -335,6 +319,10 @@ ssize_t sock_dtls_send(sock_dtls_t *sock, sock_dtls_session_t *remote,
|
||||
if (!dtls_get_peer(sock->dtls_ctx, &remote->dtls_session)) {
|
||||
int res;
|
||||
|
||||
if (timeout == 0) {
|
||||
return -ENOTCONN;
|
||||
}
|
||||
|
||||
/* no session with remote, creating new session.
|
||||
* This will also create new peer for this session */
|
||||
res = dtls_connect(sock->dtls_ctx, &remote->dtls_session);
|
||||
@ -346,22 +334,31 @@ ssize_t sock_dtls_send(sock_dtls_t *sock, sock_dtls_session_t *remote,
|
||||
/* handshake initiated, wait until connected or timed out */
|
||||
|
||||
msg_t msg;
|
||||
bool is_timed_out = false;
|
||||
do {
|
||||
res = xtimer_msg_receive_timeout(&msg, 3 * DTLS_HANDSHAKE_TIMEOUT);
|
||||
uint32_t start = xtimer_now_usec();
|
||||
res = xtimer_msg_receive_timeout(&msg, timeout);
|
||||
|
||||
if (timeout != SOCK_NO_TIMEOUT) {
|
||||
timeout = _update_timeout(start, timeout);
|
||||
is_timed_out = (res < 0) || (timeout == 0);
|
||||
}
|
||||
}
|
||||
while ((res != -1) && (msg.type != DTLS_EVENT_CONNECTED));
|
||||
if (res == -1) {
|
||||
while (!is_timed_out && (msg.type != DTLS_EVENT_CONNECTED));
|
||||
if (is_timed_out && (msg.type != DTLS_EVENT_CONNECTED)) {
|
||||
DEBUG("sock_dtls: handshake process timed out\n");
|
||||
|
||||
/* deletes peer created in dtls_connect() before */
|
||||
dtls_peer_t *peer = dtls_get_peer(sock->dtls_ctx, &remote->dtls_session);
|
||||
dtls_peer_t *peer = dtls_get_peer(sock->dtls_ctx,
|
||||
&remote->dtls_session);
|
||||
dtls_reset_peer(sock->dtls_ctx, peer);
|
||||
return -EHOSTUNREACH;
|
||||
return -ETIMEDOUT;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
return dtls_write(sock->dtls_ctx, &remote->dtls_session, (uint8_t *)data, len);
|
||||
return dtls_write(sock->dtls_ctx, &remote->dtls_session,
|
||||
(uint8_t *)data, len);
|
||||
}
|
||||
|
||||
static ssize_t _copy_buffer(sock_dtls_t *sock, void *data, size_t max_len)
|
||||
@ -392,7 +389,7 @@ ssize_t sock_dtls_recv(sock_dtls_t *sock, sock_dtls_session_t *remote,
|
||||
}
|
||||
|
||||
/* loop breaks when timeout or application data read */
|
||||
while(1) {
|
||||
while (1) {
|
||||
uint32_t start_recv = xtimer_now_usec();
|
||||
ssize_t res = sock_udp_recv(sock->udp_sock, data, max_len, timeout,
|
||||
&remote->ep);
|
||||
@ -406,13 +403,17 @@ ssize_t sock_dtls_recv(sock_dtls_t *sock, sock_dtls_session_t *remote,
|
||||
(uint8_t *)data, res);
|
||||
|
||||
if ((timeout != SOCK_NO_TIMEOUT) && (timeout != 0)) {
|
||||
uint32_t time_passed = (xtimer_now_usec() - start_recv);
|
||||
timeout = (time_passed > timeout) ? 0: timeout - time_passed;
|
||||
timeout = _update_timeout(start_recv, timeout);
|
||||
}
|
||||
|
||||
msg_t msg;
|
||||
if (sock->buf != NULL) {
|
||||
return _copy_buffer(sock, data, max_len);
|
||||
}
|
||||
else if (mbox_try_get(&sock->mbox, &msg) &&
|
||||
msg.type == DTLS_EVENT_CONNECTED) {
|
||||
return -SOCK_DTLS_HANDSHAKE;
|
||||
}
|
||||
else if (timeout == 0) {
|
||||
DEBUG("sock_dtls: timed out while decrypting message\n");
|
||||
return -ETIMEDOUT;
|
||||
@ -448,4 +449,10 @@ static void _session_to_ep(const session_t *session, sock_udp_ep_t *ep)
|
||||
memcpy(&ep->addr.ipv6, &session->addr, sizeof(ipv6_addr_t));
|
||||
}
|
||||
|
||||
static inline uint32_t _update_timeout(uint32_t start, uint32_t timeout)
|
||||
{
|
||||
uint32_t diff = (xtimer_now_usec() - start);
|
||||
return (diff > timeout) ? 0: timeout - diff;
|
||||
}
|
||||
|
||||
/** @} */
|
||||
|
@ -29,12 +29,15 @@
|
||||
* 2. Add the credential using @ref credman_add()
|
||||
* - Server operation
|
||||
* 1. Create UDP sock @ref sock_udp_create()
|
||||
* 2. Create DTLS sock @ref sock_dtls_create() using role @ref SOCK_DTLS_SERVER
|
||||
* 2. Create DTLS sock @ref sock_dtls_create() using role
|
||||
* @ref SOCK_DTLS_SERVER
|
||||
* 3. Start listening with @ref sock_dtls_recv()
|
||||
* - Client operation
|
||||
* 1. Create UDP sock @ref sock_udp_create()
|
||||
* 2. Create DTLS sock @ref sock_dtls_create() using role @ref SOCK_DTLS_CLIENT
|
||||
* 3. Create session to server @ref sock_dtls_session_create()
|
||||
* 2. Create DTLS sock @ref sock_dtls_create() using role
|
||||
* @ref SOCK_DTLS_CLIENT
|
||||
* 3. Start handshake session to server @ref sock_dtls_session_init()
|
||||
* 4. Handle incoming handshake packets with @ref sock_dtls_recv()
|
||||
* 4. Send packet to server @ref sock_dtls_send()
|
||||
*
|
||||
* ## Makefile Includes
|
||||
@ -109,7 +112,7 @@
|
||||
* .y = server_ecdsa_pub_key_y,
|
||||
* },
|
||||
* .client_keys = other_pubkeys,
|
||||
* .client_keys_size = sizeof(other_pubkeys) / sizeof(other_pubkeys[0]),
|
||||
* .client_keys_size = ARRAY_SIZE(other_pubkeys),
|
||||
* },
|
||||
* },
|
||||
* };
|
||||
@ -298,7 +301,7 @@
|
||||
* #define SOCK_DTLS_CLIENT_TAG (20)
|
||||
*
|
||||
* #ifndef SERVER_ADDR
|
||||
* #define SERVER_ADDR "fe80::aa:bb:cc:dd" // replace this with the server address
|
||||
* #define SERVER_ADDR "fe80::aa:bb:cc:dd" // replace with the server address
|
||||
* #endif
|
||||
*
|
||||
* int main(void)
|
||||
@ -312,7 +315,7 @@
|
||||
* sock_udp_ep_t local = SOCK_IPV6_EP_ANY;
|
||||
* local.port = 12345;
|
||||
*
|
||||
* sock_udp_ep_t remote;
|
||||
* sock_udp_ep_t remote = SOCK_IPV6_EP_ANY;
|
||||
* remote.port = DTLS_DEFAULT_PORT;
|
||||
* remote.netif = gnrc_netif_iter(NULL)->pid; // only if gnrc_netif_highlander() returns true
|
||||
*
|
||||
@ -337,7 +340,8 @@
|
||||
* return -1;
|
||||
* }
|
||||
*
|
||||
* if (sock_dtls_session_create(&dtls_sock, &remote, &session) < 0) {
|
||||
* if (sock_dtls_session_create(&dtls_sock, &remote, &session,
|
||||
* SOCK_NO_TIMEOUT) < 0) {
|
||||
* puts("Error creating session");
|
||||
* sock_dtls_close(&dtls_sock);
|
||||
* sock_udp_close(&udp_sock);
|
||||
@ -345,10 +349,11 @@
|
||||
* }
|
||||
*
|
||||
* const char data[] = "HELLO";
|
||||
* int res = sock_dtls_send(&dtls_sock, &session, data, sizeof(data));
|
||||
* int res = sock_dtls_send(&dtls_sock, &session, data, sizeof(data), 0);
|
||||
* if (res >= 0) {
|
||||
* printf("Sent %d bytes\n", res);
|
||||
* res = sock_dtls_recv(&dtls_sock, &session, rcv, sizeof(rcv), SOCK_NO_TIMEOUT);
|
||||
* res = sock_dtls_recv(&dtls_sock, &session, rcv, sizeof(rcv),
|
||||
* SOCK_NO_TIMEOUT);
|
||||
* if (res > 0) {
|
||||
* printf("Received %d bytes\n", res);
|
||||
* }
|
||||
@ -378,7 +383,7 @@
|
||||
* listening port, which is DTLS_DEFAULT_PORT (20220).
|
||||
*
|
||||
* ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ {.c}
|
||||
* sock_udp_ep_t remote;
|
||||
* sock_udp_ep_t remote = SOCK_IPV6_EP_ANY;
|
||||
* remote.port = DTLS_DEFAULT_PORT;
|
||||
* remote.netif = gnrc_netif_iter(NULL)->pid; // only if gnrc_netif_highlander() returns true
|
||||
*
|
||||
@ -390,10 +395,18 @@
|
||||
*
|
||||
* After the UDP sock is created, we can proceed with creating the DTLS sock.
|
||||
* Before sending the packet, we must first create a session with the remote
|
||||
* endpoint using @ref sock_dtls_session_create(). If the handshake is
|
||||
* successful and the session is created, we send packets to it using
|
||||
* @ref sock_dtls_send(). If the packet is successfully sent, we listen for
|
||||
* the response with @ref sock_dtls_recv().
|
||||
* endpoint using @ref sock_dtls_session_create(). We can set the timeout to `0`
|
||||
* if we want the function returns immediately after starting the handshake.
|
||||
* In that case, we will need to call @ref sock_dtls_recv() to receive and
|
||||
* process all the handshake packets. If the handshake is successful and the
|
||||
* session is created, we send packets to it using @ref sock_dtls_send().
|
||||
* As we already know the session exists, we can set the timeout to `0` and
|
||||
* listen to the reply with @ref sock_dtls_recv().
|
||||
*
|
||||
* Alternatively, set the timeout to of @ref sock_dtls_send() to the duration we
|
||||
* want to wait for the handshake process. We can also set the timeout to
|
||||
* @ref SOCK_NO_TIMEOUT to block indefinitely until handshake is complete.
|
||||
* After handshake completes, the packet will be sent.
|
||||
*
|
||||
* @ref sock_dtls_create() and @ref sock_dtls_close() only manages the DTLS
|
||||
* layer. That means we still have to clean up the created UDP sock from before
|
||||
@ -415,7 +428,8 @@
|
||||
* return -1;
|
||||
* }
|
||||
*
|
||||
* if (sock_dtls_session_create(&dtls_sock, &remote, &session) < 0) {
|
||||
* if (sock_dtls_session_create(&dtls_sock, &remote, &session,
|
||||
* SOCK_NO_TIMEOUT) < 0) {
|
||||
* puts("Error creating session");
|
||||
* sock_dtls_close(&dtls_sock);
|
||||
* sock_udp_close(&udp_sock);
|
||||
@ -423,10 +437,11 @@
|
||||
* }
|
||||
*
|
||||
* const char data[] = "HELLO";
|
||||
* int res = sock_dtls_send(&dtls_sock, &session, data, sizeof(data));
|
||||
* int res = sock_dtls_send(&dtls_sock, &session, data, sizeof(data), 0);
|
||||
* if (res >= 0) {
|
||||
* printf("Sent %d bytes: %*.s\n", res, res, data);
|
||||
* res = sock_dtls_recv(&dtls_sock, &session, rcv, sizeof(rcv), SOCK_NO_TIMEOUT);
|
||||
* res = sock_dtls_recv(&dtls_sock, &session, rcv, sizeof(rcv),
|
||||
* SOCK_NO_TIMEOUT);
|
||||
* if (res > 0) {
|
||||
* printf("Received %d bytes: %*.s\n", res, res, rcv);
|
||||
* }
|
||||
@ -476,6 +491,14 @@
|
||||
extern "C" {
|
||||
#endif
|
||||
|
||||
#ifndef DTLS_HANDSHAKE_BUFSIZE
|
||||
#define DTLS_HANDSHAKE_BUFSIZE (256) /**< Size buffer used in handshake to
|
||||
hold credentials */
|
||||
#endif
|
||||
|
||||
#define SOCK_DTLS_HANDSHAKE (EXDEV) /**< Return value for a successful
|
||||
handshake */
|
||||
|
||||
/**
|
||||
* @brief DTLS version number
|
||||
* @anchor sock_dtls_prot_version
|
||||
@ -547,25 +570,24 @@ int sock_dtls_create(sock_dtls_t *sock, sock_udp_t *udp_sock,
|
||||
credman_tag_t tag, unsigned version, unsigned role);
|
||||
|
||||
/**
|
||||
* @brief Creates a new DTLS session
|
||||
* @brief Initialize session handshake.
|
||||
*
|
||||
* Initializes handshake process with a DTLS server at @p ep.
|
||||
* Sends a ClientHello message to initialize the handshake. Call
|
||||
* @ref sock_dtls_recv() to finish the handshake.
|
||||
*
|
||||
* @param[in] sock DLTS sock to use
|
||||
* @param[in] ep Remote endpoint of the session
|
||||
* @param[out] remote The created session, cannot be NULL
|
||||
* @param[in] sock DTLS sock to use
|
||||
* @param[in] ep Remote endpoint to start a handshake with
|
||||
* @param[out] remote Resulting session
|
||||
*
|
||||
* @return 0 on success
|
||||
* @return -EAGAIN, if DTLS_HANDSHAKE_TIMEOUT is `0` and no data is available.
|
||||
* @return -EADDRNOTAVAIL, if the local endpoint of @p sock is not set.
|
||||
* @return -EINVAL, if @p remote is invalid or @p sock is not properly
|
||||
* initialized (or closed while sock_udp_recv() blocks).
|
||||
* @return -ENOBUFS, if buffer space is not large enough to store received
|
||||
* credentials.
|
||||
* @return -ETIMEDOUT, if timed out when trying to create session.
|
||||
* @return 1, if new handshake is started
|
||||
* @return 0, if there is an existing session
|
||||
* @return -ENOMEM, not enough memory to allocate for new peer
|
||||
* @return -EADDRNOTAVAIL, if the local endpoint of @p sock is not set.
|
||||
* @return -EINVAL, if @p remote is invalid or @p sock is not properly
|
||||
* initialized (or closed while sock_udp_recv() blocks).
|
||||
*/
|
||||
int sock_dtls_session_create(sock_dtls_t *sock, const sock_udp_ep_t *ep,
|
||||
sock_dtls_session_t *remote);
|
||||
int sock_dtls_session_init(sock_dtls_t *sock, const sock_udp_ep_t *ep,
|
||||
sock_dtls_session_t *remote);
|
||||
|
||||
/**
|
||||
* @brief Destroys an existing DTLS session
|
||||
@ -578,7 +600,7 @@ int sock_dtls_session_create(sock_dtls_t *sock, const sock_udp_ep_t *ep,
|
||||
void sock_dtls_session_destroy(sock_dtls_t *sock, sock_dtls_session_t *remote);
|
||||
|
||||
/**
|
||||
* @brief Decrypts and reads a message from a remote peer.
|
||||
* @brief Receive handshake messages and application data from remote peer.
|
||||
*
|
||||
* @param[in] sock DTLS sock to use.
|
||||
* @param[out] remote Remote DTLS session of the received data.
|
||||
@ -593,7 +615,8 @@ void sock_dtls_session_destroy(sock_dtls_t *sock, sock_dtls_session_t *remote);
|
||||
*
|
||||
* @note Function may block if data is not available and @p timeout != 0
|
||||
*
|
||||
* @return The number of bytes received on success
|
||||
* @return The number of bytes received on success
|
||||
* @return -SOCK_DTLS_HANDSHAKE when new handshake is completed
|
||||
* @return -EADDRNOTAVAIL, if the local endpoint of @p sock is not set.
|
||||
* @return -EAGAIN, if @p timeout is `0` and no data is available.
|
||||
* @return -EINVAL, if @p remote is invalid or @p sock is not properly
|
||||
@ -657,28 +680,32 @@ ssize_t sock_dtls_recv_buf(sock_dtls_t *sock, sock_dtls_session_t *remote,
|
||||
* if no session exist between client and server.
|
||||
* @param[in] data Pointer where the data to be send are stored
|
||||
* @param[in] len Length of @p data to be send
|
||||
* @param[in] timeout Handshake timeout in microseconds.
|
||||
* If `timeout > 0`, will start a new handshake if no
|
||||
* session exists yet. The function will block until
|
||||
* handshake completed or timed out.
|
||||
* May be SOCK_NO_TIMEOUT to block indefinitely until
|
||||
* handshake complete.
|
||||
*
|
||||
* @note Function may block until a session is created if there is no
|
||||
* existing session with @p remote.
|
||||
*
|
||||
* @note Initiating a session through this function will require
|
||||
* @ref sock_dtls_recv() called from another thread to receive the handshake
|
||||
* messages.
|
||||
* @note When blocking, we will need an extra thread to call
|
||||
* @ref sock_dtls_recv() function to handle the incoming handshake
|
||||
* messages.
|
||||
*
|
||||
* @return The number of bytes sent on success
|
||||
* @return -ENOTCONN, if `timeout == 0` and no existing session exists with
|
||||
* @p remote
|
||||
* @return -EADDRINUSE, if sock_dtls_t::udp_sock has no local end-point.
|
||||
* @return -EAFNOSUPPORT, if `remote->ep != NULL` and
|
||||
* sock_dtls_session_t::ep::family of @p remote is != AF_UNSPEC and
|
||||
* not supported.
|
||||
* @return -EHOSTUNREACH, if sock_dtls_session_t::ep of @p remote is not
|
||||
* reachable.
|
||||
* @return -EINVAL, if sock_udp_ep_t::addr of @p remote->ep is an
|
||||
* invalid address.
|
||||
* @return -EINVAL, if sock_udp_ep_t::port of @p remote->ep is 0.
|
||||
* @return -ENOMEM, if no memory was available to send @p data.
|
||||
* @return -ETIMEDOUT, `0 < timeout < SOCK_NO_TIMEOUT` and timed out.
|
||||
*/
|
||||
ssize_t sock_dtls_send(sock_dtls_t *sock, sock_dtls_session_t *remote,
|
||||
const void *data, size_t len);
|
||||
const void *data, size_t len, uint32_t timeout);
|
||||
|
||||
/**
|
||||
* @brief Closes a DTLS sock
|
||||
@ -694,6 +721,49 @@ ssize_t sock_dtls_send(sock_dtls_t *sock, sock_dtls_session_t *remote,
|
||||
*/
|
||||
void sock_dtls_close(sock_dtls_t *sock);
|
||||
|
||||
/**
|
||||
* @brief Creates a new DTLS session
|
||||
*
|
||||
* Initiates a handshake with a DTLS server at @p ep and wait until it
|
||||
* completes or timed out.
|
||||
*
|
||||
* @deprecated Will not be available after the 2020.10 release.
|
||||
* Please use @ref sock_dtls_session_init() and
|
||||
* @ref sock_dtls_recv() instead.
|
||||
*
|
||||
* @param[in] sock DLTS sock to use
|
||||
* @param[in] ep Remote endpoint of the session
|
||||
* @param[out] remote The created session, cannot be NULL
|
||||
* @param[in] timeout Timeout to wait for handshake to finish.
|
||||
* Returns immediately if 0.
|
||||
* May be SOCK_NO_TIMEOUT to wait indefinitely until
|
||||
* handshake complete.
|
||||
*
|
||||
* @return 0 on success
|
||||
* @return -ENOMEM, if no memory to allocate for new peer
|
||||
* @return -EADDRNOTAVAIL, if the local endpoint of @p sock is not set.
|
||||
* @return -EINVAL, if @p remote is invalid or @p sock is not properly
|
||||
* initialized (or closed while sock_udp_recv() blocks).
|
||||
*/
|
||||
static inline int sock_dtls_session_create(sock_dtls_t *sock,
|
||||
const sock_udp_ep_t *ep,
|
||||
sock_dtls_session_t *remote,
|
||||
unsigned timeout)
|
||||
{
|
||||
int res;
|
||||
uint8_t buf[DTLS_HANDSHAKE_BUFSIZE];
|
||||
|
||||
assert(sock);
|
||||
assert(remote);
|
||||
|
||||
res = sock_dtls_session_init(sock, ep, remote);
|
||||
if (res <= 0) {
|
||||
return res;
|
||||
}
|
||||
|
||||
return sock_dtls_recv(sock, remote, buf, sizeof(buf), timeout);
|
||||
}
|
||||
|
||||
#include "sock_dtls_types.h"
|
||||
|
||||
#ifdef __cplusplus
|
||||
|
Loading…
Reference in New Issue
Block a user