mirror of
https://github.com/RIOT-OS/RIOT.git
synced 2024-12-29 04:50:03 +01:00
sock_dtls: add timeout to sock_dtls_send()
This commit is contained in:
parent
cc44992abe
commit
7f883f4098
@ -74,7 +74,7 @@ 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;
|
||||
|
@ -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 */
|
||||
@ -325,7 +317,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 +327,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,17 +342,25 @@ 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;
|
||||
}
|
||||
}
|
||||
}
|
||||
@ -392,7 +396,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);
|
||||
@ -448,4 +452,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;
|
||||
}
|
||||
|
||||
/** @} */
|
||||
|
@ -345,7 +345,7 @@
|
||||
* }
|
||||
*
|
||||
* 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);
|
||||
@ -423,7 +423,7 @@
|
||||
* }
|
||||
*
|
||||
* 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);
|
||||
@ -657,28 +657,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
|
||||
|
Loading…
Reference in New Issue
Block a user