Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

pkg/tinydtls: add IPv4 support #17765

Merged
merged 3 commits into from
Mar 26, 2022
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
8 changes: 4 additions & 4 deletions examples/dtls-echo/dtls-client.c
Original file line number Diff line number Diff line change
Expand Up @@ -128,11 +128,11 @@ static int dtls_handle_read(dtls_context_t *ctx)
session.ifindex = remote.netif;
}

memcpy(&session.addr.addr, &remote.addr.ipv6, sizeof(session.addr.addr));
memcpy(&session.addr.ipv6, &remote.addr.ipv6, sizeof(session.addr.ipv6));

if (IS_ACTIVE(ENABLE_DEBUG)) {
DEBUG("DBG-Client: Msg received from \n\t Addr Src: [");
ipv6_addr_print(&session.addr.addr);
ipv6_addr_print(&session.addr.ipv6);
DEBUG("]:%u\n", remote.port);
}

Expand Down Expand Up @@ -361,8 +361,8 @@ dtls_context_t *_init_dtls(sock_udp_t *sock, sock_udp_ep_t *local,
/* Second: We prepare the DTLS Session by means of ctx->app */
dst->addr.port = remote->port;

/* NOTE: remote.addr.ipv6 and dst->addr.addr are different structures. */
if (ipv6_addr_from_str(&dst->addr.addr, addr_str) == NULL) {
/* NOTE: remote.addr.ipv6 and dst->addr.ipv6 are different structures. */
if (ipv6_addr_from_str(&dst->addr.ipv6, addr_str) == NULL) {
puts("ERROR: init_dtls was unable to load the IPv6 addresses!");
return new_context;
}
Expand Down
2 changes: 1 addition & 1 deletion examples/dtls-echo/dtls-server.c
Original file line number Diff line number Diff line change
Expand Up @@ -123,7 +123,7 @@ static int dtls_handle_read(dtls_context_t *ctx)
session.ifindex = remote_peer->remote->netif;
}

memcpy(&session.addr.addr, &remote_peer->remote->addr.ipv6, sizeof(session.addr.addr));
memcpy(&session.addr.ipv6, &remote_peer->remote->addr.ipv6, sizeof(session.addr.ipv6));
return dtls_handle_message(ctx, &session, packet_rcvd, res);
}

Expand Down
2 changes: 1 addition & 1 deletion pkg/tinydtls/Makefile.include
Original file line number Diff line number Diff line change
Expand Up @@ -24,7 +24,7 @@ endif

# The configuration for socket overrides Sock
ifeq (,$(filter posix_sockets,$(USEMODULE)))
CFLAGS += -DWITH_RIOT_GNRC
CFLAGS += -DWITH_RIOT_SOCK
endif

# Default cipher suite when not using Kconfig
Expand Down
69 changes: 49 additions & 20 deletions pkg/tinydtls/contrib/sock_dtls.c
Original file line number Diff line number Diff line change
Expand Up @@ -14,6 +14,7 @@
*
* @author Aiman Ismail <muhammadaimanbin.ismail@haw-hamburg.de>
* @author Leandro Lanzieri <leandro.lanzieri@haw-hamburg.de>
* @author Hendrik van Essen <hendrik.ve@fu-berlin.de>
*/

#include <assert.h>
Expand Down Expand Up @@ -89,10 +90,8 @@ typedef struct ecdsa_key_assignment {
static ecdsa_key_assignment_t _ecdsa_keys[CONFIG_DTLS_CREDENTIALS_MAX];
#endif

static int _read(struct dtls_context_t *ctx, session_t *session, uint8_t *buf,
size_t len)
static int _read(struct dtls_context_t *ctx, session_t *session, uint8_t *buf, size_t len)
{
(void)session;
sock_dtls_t *sock = dtls_get_app_data(ctx);

DEBUG("sock_dtls: decrypted message arrived\n");
Expand All @@ -109,14 +108,12 @@ static int _read(struct dtls_context_t *ctx, session_t *session, uint8_t *buf,
return len;
}

static int _write(struct dtls_context_t *ctx, session_t *session, uint8_t *buf,
size_t len)
static int _write(struct dtls_context_t *ctx, session_t *session, uint8_t *buf, size_t len)
{
sock_dtls_t *sock = (sock_dtls_t *)dtls_get_app_data(ctx);
sock_udp_ep_t remote;

_session_to_ep(session, &remote);
remote.family = AF_INET6;

ssize_t res = sock_udp_send(sock->udp_sock, buf, len, &remote);

Expand All @@ -129,9 +126,6 @@ static int _write(struct dtls_context_t *ctx, session_t *session, uint8_t *buf,
static int _event(struct dtls_context_t *ctx, session_t *session,
dtls_alert_level_t level, unsigned short code)
{
(void)level;
(void)session;

sock_dtls_t *sock = dtls_get_app_data(ctx);
msg_t msg = { .type = code, .content.ptr = session };

Expand Down Expand Up @@ -310,7 +304,6 @@ static int _get_psk_info(struct dtls_context_t *ctx, const session_t *session,
static int _get_ecdsa_key(struct dtls_context_t *ctx, const session_t *session,
const dtls_ecdsa_key_t **result)
{
(void)session;
int ret = CREDMAN_ERROR;
sock_dtls_t *sock = (sock_dtls_t *)dtls_get_app_data(ctx);
sock_udp_ep_t ep;
Expand Down Expand Up @@ -535,15 +528,20 @@ int sock_dtls_session_init(sock_dtls_t *sock, const sock_udp_ep_t *ep,
if (!sock->udp_sock || (sock_udp_get_local(sock->udp_sock, &local) < 0)) {
return -EADDRNOTAVAIL;
}

if (ep->port == 0) {
return -EINVAL;
}

switch (ep->family) {
#ifdef SOCK_HAS_IPV4
case AF_INET:
#if IS_ACTIVE(SOCK_HAS_IPV6)
break;
#endif
#ifdef SOCK_HAS_IPV6
case AF_INET6:
#endif
break;
#endif
default:
return -EINVAL;
}
Expand Down Expand Up @@ -818,24 +816,55 @@ void sock_dtls_init(void)
static void _ep_to_session(const sock_udp_ep_t *ep, session_t *session)
{
dtls_session_init(session);
session->addr.family = ep->family;
session->addr.port = ep->port;

if (ipv6_addr_is_link_local((ipv6_addr_t *)ep->addr.ipv6)) {
/* set ifindex for link-local addresses */
session->ifindex = ep->netif;
}
else {
switch (ep->family) {
#ifdef SOCK_HAS_IPV4
case AF_INET:
session->ifindex = SOCK_ADDR_ANY_NETIF;
memcpy(&session->addr.ipv4, &ep->addr.ipv4, sizeof(session->addr.ipv4));
break;
#endif
#ifdef SOCK_HAS_IPV6
case AF_INET6:
if (ipv6_addr_is_link_local((ipv6_addr_t *)ep->addr.ipv6)) {
/* set ifindex for link-local addresses */
session->ifindex = ep->netif;
}
else {
session->ifindex = SOCK_ADDR_ANY_NETIF;
}
memcpy(&session->addr.ipv6, &ep->addr.ipv6, sizeof(session->addr.ipv6));
break;
#endif
default:
assert(0);
return;
}
memcpy(&session->addr.addr, &ep->addr.ipv6, sizeof(session->addr.addr));
}

static void _session_to_ep(const session_t *session, sock_udp_ep_t *ep)
{
ep->port = session->addr.port;
ep->netif = session->ifindex;
ep->family = AF_INET6;
memcpy(&ep->addr.ipv6, &session->addr.addr, sizeof(ep->addr.ipv6));
ep->family = session->addr.family;

switch (session->addr.family) {
#ifdef SOCK_HAS_IPV4
case AF_INET:
memcpy(&ep->addr.ipv4, &session->addr.ipv4, sizeof(ep->addr.ipv4));
break;
#endif
#ifdef SOCK_HAS_IPV6
case AF_INET6:
memcpy(&ep->addr.ipv6, &session->addr.ipv6, sizeof(ep->addr.ipv6));
break;
#endif
default:
/* addr_family is actually ok to be 0 when coming from _copy_buffer */
return;
}
}

static inline uint32_t _update_timeout(uint32_t start, uint32_t timeout)
Expand Down
Original file line number Diff line number Diff line change
@@ -0,0 +1,61 @@
From 86dea8ab253df87aa09bc477b26ed1331ce149c6 Mon Sep 17 00:00:00 2001
From: HendrikVE <hendrik1995@msn.com>
Date: Fri, 25 Mar 2022 13:45:39 +0100
Subject: [PATCH 3/4] session: Rename condition WITH_RIOT_GNRC to
WITH_RIOT_SOCK

Using tinydtls on RIOT OS is not limited to GNRC as network stack.
It is also working with e.g. lwIP, see: https://github.com/RIOT-OS/RIOT/pull/17552
Therefore the name WITH_RIOT_GNRC is misleading.
---
session.c | 2 +-
session.h | 6 +++---
2 files changed, 4 insertions(+), 4 deletions(-)

diff --git a/session.c b/session.c
index 020ab5b..7615188 100644
--- a/session.c
+++ b/session.c
@@ -31,7 +31,7 @@
&& (A)->port == (B)->port \
&& uip_ipaddr_cmp(&((A)->addr),&((B)->addr)) \
&& (A)->ifindex == (B)->ifindex)
-#elif defined(WITH_RIOT_GNRC)
+#elif defined(WITH_RIOT_SOCK)
#define _dtls_address_equals_impl(A,B) \
((A)->size == (B)->size \
&& (A)->addr.port == (B)->addr.port \
diff --git a/session.h b/session.h
index 2ab600a..9d7041a 100644
--- a/session.h
+++ b/session.h
@@ -31,7 +31,7 @@ typedef struct {
int ifindex;
} session_t;
/* TODO: Add support for RIOT over sockets */
-#elif defined(WITH_RIOT_GNRC)
+#elif defined(WITH_RIOT_SOCK)
#include "net/ipv6/addr.h"
typedef struct {
unsigned char size;
@@ -41,7 +41,7 @@ typedef struct {
} addr;
int ifindex;
} session_t;
-#else /* ! WITH_CONTIKI && ! WITH_RIOT_GNRC */
+#else /* ! WITH_CONTIKI && ! WITH_RIOT_SOCK */

#include <sys/socket.h>
#include <netinet/in.h>
@@ -57,7 +57,7 @@ typedef struct {
} addr;
int ifindex;
} session_t;
-#endif /* ! WITH_CONTIKI && ! WITH_RIOT_GNRC */
+#endif /* ! WITH_CONTIKI && ! WITH_RIOT_SOCK */

/**
* Resets the given session_t object @p sess to its default
--
2.25.1

Original file line number Diff line number Diff line change
@@ -0,0 +1,94 @@
From 5e044288ff5f15a71aa89c8c17fab4ba0d40a86d Mon Sep 17 00:00:00 2001
From: HendrikVE <hendrik1995@msn.com>
Date: Fri, 25 Mar 2022 14:04:02 +0100
Subject: [PATCH 4/4] session: Add support for IPv4 on RIOT OS

---
session.c | 38 +++++++++++++++++++++++++++++++++-----
session.h | 11 ++++++++++-
2 files changed, 43 insertions(+), 6 deletions(-)

diff --git a/session.c b/session.c
index 7615188..bdd845a 100644
--- a/session.c
+++ b/session.c
@@ -32,11 +32,23 @@
&& uip_ipaddr_cmp(&((A)->addr),&((B)->addr)) \
&& (A)->ifindex == (B)->ifindex)
#elif defined(WITH_RIOT_SOCK)
-#define _dtls_address_equals_impl(A,B) \
- ((A)->size == (B)->size \
- && (A)->addr.port == (B)->addr.port \
- && ipv6_addr_equal(&((A)->addr.addr),&((B)->addr.addr)) \
- && (A)->ifindex == (B)->ifindex)
+#include "net/af.h"
+#ifdef SOCK_HAS_IPV4
+#define _dtls_ipv4_address_equals_impl(A,B) \
+ ((A)->size == (B)->size \
+ && (A)->addr.port == (B)->addr.port \
+ && (A)->ifindex == (B)->ifindex) \
+ && (A)->addr.family == (B)->addr.family \
+ && ipv4_addr_equal(&((A)->addr.ipv4),&((B)->addr.ipv4))
+#endif
+#ifdef SOCK_HAS_IPV6
+#define _dtls_ipv6_address_equals_impl(A,B) \
+ ((A)->size == (B)->size \
+ && (A)->addr.port == (B)->addr.port \
+ && (A)->ifindex == (B)->ifindex) \
+ && (A)->addr.family == (B)->addr.family \
+ && ipv6_addr_equal(&((A)->addr.ipv6),&((B)->addr.ipv6))
+#endif
#else /* WITH_CONTIKI */

static inline int
@@ -120,5 +132,21 @@ dtls_session_addr(session_t *sess, socklen_t *addrlen) {
int
dtls_session_equals(const session_t *a, const session_t *b) {
assert(a); assert(b);
+#ifdef RIOT_VERSION
+ switch (a->addr.family) {
+#ifdef SOCK_HAS_IPV4
+ case AF_INET:
+ return _dtls_ipv4_address_equals_impl(a, b);
+#endif
+#ifdef SOCK_HAS_IPV6
+ case AF_INET6:
+ return _dtls_ipv6_address_equals_impl(a, b);
+#endif
+ default:
+ assert(0);
+ return false;
+ }
+#else
return _dtls_address_equals_impl(a, b);
+#endif /* RIOT_VERSION */
}
diff --git a/session.h b/session.h
index 9d7041a..6ae5a82 100644
--- a/session.h
+++ b/session.h
@@ -32,11 +32,20 @@ typedef struct {
} session_t;
/* TODO: Add support for RIOT over sockets */
#elif defined(WITH_RIOT_SOCK)
+#include "net/ipv4/addr.h"
#include "net/ipv6/addr.h"
typedef struct {
unsigned char size;
struct {
- ipv6_addr_t addr;
+ int family;
+ union {
+#ifdef SOCK_HAS_IPV4
+ ipv4_addr_t ipv4;
+#endif
+#ifdef SOCK_HAS_IPV6
+ ipv6_addr_t ipv6;
+#endif
+ };
unsigned short port;
} addr;
int ifindex;
--
2.25.1