refactor: Move tinydtls connection implementation in own folder

This is a step to a more modular project setup.
This commit is contained in:
Lukas Woodtli 2024-06-28 12:54:54 +02:00 committed by Lukas Woodtli
parent 88c53d7e43
commit 104d8401d4
7 changed files with 211 additions and 294 deletions

2
.gitmodules vendored
View File

@ -1,3 +1,3 @@
[submodule "platforms/Linux/tinydtls"]
path = examples/shared/tinydtls
path = transport/tinydtls/third_party/tinydtls
url = https://github.com/eclipse/tinydtls.git

View File

@ -60,7 +60,7 @@
#include "liblwm2m.h"
#include "commandline.h"
#ifdef WITH_TINYDTLS
#include "dtlsconnection.h"
#include "tinydtls/connection.h"
#else
#include "udp/connection.h"
#endif

View File

@ -16,39 +16,35 @@
*
*******************************************************************************/
#include "tinydtls/connection.h"
#include "commandline.h"
#include <ctype.h>
#include <stdlib.h>
#include <string.h>
#include <ctype.h>
#include "dtlsconnection.h"
#include "commandline.h"
#define COAP_PORT "5683"
#define COAPS_PORT "5684"
#define URI_LENGTH 256
dtls_context_t * dtlsContext;
dtls_context_t *dtlsContext;
typedef struct _dtls_app_context_
{
lwm2m_context_t * lwm2mH;
dtls_connection_t * connList;
typedef struct _dtls_app_context_ {
lwm2m_context_t *lwm2mH;
dtls_connection_t *connList;
} dtls_app_context_t;
/********************* Security Obj Helpers **********************/
char *security_get_uri(lwm2m_context_t *lwm2mH, lwm2m_object_t *obj, int instanceId, char *uriBuffer,
size_t bufferSize) {
int size = 1;
lwm2m_data_t * dataP = lwm2m_data_new(size);
lwm2m_data_t *dataP = lwm2m_data_new(size);
dataP->id = 0; // security server uri
obj->readFunc(lwm2mH, instanceId, &size, &dataP, obj);
if (dataP != NULL &&
dataP->type == LWM2M_TYPE_STRING &&
dataP->value.asBuffer.length > 0)
{
if (bufferSize > dataP->value.asBuffer.length){
memset(uriBuffer,0,dataP->value.asBuffer.length+1);
strncpy(uriBuffer,(const char *)dataP->value.asBuffer.buffer,dataP->value.asBuffer.length);
if (dataP != NULL && dataP->type == LWM2M_TYPE_STRING && dataP->value.asBuffer.length > 0) {
if (bufferSize > dataP->value.asBuffer.length) {
memset(uriBuffer, 0, dataP->value.asBuffer.length + 1);
strncpy(uriBuffer, (const char *)dataP->value.asBuffer.buffer, dataP->value.asBuffer.length);
lwm2m_data_free(size, dataP);
return uriBuffer;
}
@ -57,15 +53,14 @@ char *security_get_uri(lwm2m_context_t *lwm2mH, lwm2m_object_t *obj, int instanc
return NULL;
}
int64_t security_get_mode(lwm2m_context_t * lwm2mH, lwm2m_object_t * obj, int instanceId){
int64_t security_get_mode(lwm2m_context_t *lwm2mH, lwm2m_object_t *obj, int instanceId) {
int64_t mode;
int size = 1;
lwm2m_data_t * dataP = lwm2m_data_new(size);
lwm2m_data_t *dataP = lwm2m_data_new(size);
dataP->id = 2; // security mode
obj->readFunc(lwm2mH, instanceId, &size, &dataP, obj);
if (0 != lwm2m_data_decode_int(dataP,&mode))
{
if (0 != lwm2m_data_decode_int(dataP, &mode)) {
lwm2m_data_free(size, dataP);
return mode;
}
@ -77,18 +72,15 @@ int64_t security_get_mode(lwm2m_context_t * lwm2mH, lwm2m_object_t * obj, int in
char *security_get_public_id(lwm2m_context_t *lwm2mH, lwm2m_object_t *obj, int instanceId, size_t *length) {
int size = 1;
lwm2m_data_t * dataP = lwm2m_data_new(size);
lwm2m_data_t *dataP = lwm2m_data_new(size);
dataP->id = 3; // public key or id
obj->readFunc(lwm2mH, instanceId, &size, &dataP, obj);
if (dataP != NULL &&
dataP->type == LWM2M_TYPE_OPAQUE)
{
char * buff;
if (dataP != NULL && dataP->type == LWM2M_TYPE_OPAQUE) {
char *buff;
buff = (char*)lwm2m_malloc(dataP->value.asBuffer.length);
if (buff != 0)
{
buff = (char *)lwm2m_malloc(dataP->value.asBuffer.length);
if (buff != 0) {
memcpy(buff, dataP->value.asBuffer.buffer, dataP->value.asBuffer.length);
*length = dataP->value.asBuffer.length;
}
@ -102,18 +94,15 @@ char *security_get_public_id(lwm2m_context_t *lwm2mH, lwm2m_object_t *obj, int i
char *security_get_secret_key(lwm2m_context_t *lwm2mH, lwm2m_object_t *obj, int instanceId, size_t *length) {
int size = 1;
lwm2m_data_t * dataP = lwm2m_data_new(size);
lwm2m_data_t *dataP = lwm2m_data_new(size);
dataP->id = 5; // secret key
obj->readFunc(lwm2mH, instanceId, &size, &dataP, obj);
if (dataP != NULL &&
dataP->type == LWM2M_TYPE_OPAQUE)
{
char * buff;
if (dataP != NULL && dataP->type == LWM2M_TYPE_OPAQUE) {
char *buff;
buff = (char*)lwm2m_malloc(dataP->value.asBuffer.length);
if (buff != 0)
{
buff = (char *)lwm2m_malloc(dataP->value.asBuffer.length);
if (buff != 0) {
memcpy(buff, dataP->value.asBuffer.buffer, dataP->value.asBuffer.length);
*length = dataP->value.asBuffer.length;
}
@ -128,10 +117,7 @@ char *security_get_secret_key(lwm2m_context_t *lwm2mH, lwm2m_object_t *obj, int
/********************* Security Obj Helpers Ends **********************/
/* Returns the number sent, or -1 for errors */
int send_data(dtls_connection_t *connP,
uint8_t * buffer,
size_t length)
{
int send_data(dtls_connection_t *connP, uint8_t *buffer, size_t length) {
int nbSent;
size_t offset;
@ -141,14 +127,11 @@ int send_data(dtls_connection_t *connP,
s[0] = 0;
if (AF_INET == connP->addr.sin6_family)
{
if (AF_INET == connP->addr.sin6_family) {
struct sockaddr_in *saddr = (struct sockaddr_in *)&connP->addr;
inet_ntop(saddr->sin_family, &saddr->sin_addr, s, INET6_ADDRSTRLEN);
port = saddr->sin_port;
}
else if (AF_INET6 == connP->addr.sin6_family)
{
} else if (AF_INET6 == connP->addr.sin6_family) {
struct sockaddr_in6 *saddr = (struct sockaddr_in6 *)&connP->addr;
inet_ntop(saddr->sin6_family, &saddr->sin6_addr, s, INET6_ADDRSTRLEN);
port = saddr->sin6_port;
@ -160,10 +143,11 @@ int send_data(dtls_connection_t *connP,
#endif
offset = 0;
while (offset != length)
{
nbSent = sendto(connP->sock, buffer + offset, length - offset, 0, (struct sockaddr *)&(connP->addr), connP->addrLen);
if (nbSent == -1) return -1;
while (offset != length) {
nbSent =
sendto(connP->sock, buffer + offset, length - offset, 0, (struct sockaddr *)&(connP->addr), connP->addrLen);
if (nbSent == -1)
return -1;
offset += nbSent;
}
connP->lastSend = lwm2m_gettime();
@ -175,61 +159,52 @@ int send_data(dtls_connection_t *connP,
/* This function is the "key store" for tinyDTLS. It is called to
* retrieve a key for the given identity within this particular
* session. */
static int get_psk_info(struct dtls_context_t *ctx,
const session_t *session,
dtls_credentials_type_t type,
const unsigned char *id, size_t id_len,
unsigned char *result, size_t result_length) {
static int get_psk_info(struct dtls_context_t *ctx, const session_t *session, dtls_credentials_type_t type,
const unsigned char *id, size_t id_len, unsigned char *result, size_t result_length) {
dtls_app_context_t *appContext = (dtls_app_context_t *)ctx->app;
// find connection
dtls_connection_t* cnx = connection_find(appContext->connList, &(session->addr.st),session->size);
if (cnx == NULL)
{
dtls_connection_t *cnx = connection_find(appContext->connList, &(session->addr.st), session->size);
if (cnx == NULL) {
printf("GET PSK session not found\n");
return dtls_alert_fatal_create(DTLS_ALERT_INTERNAL_ERROR);
}
switch (type) {
case DTLS_PSK_IDENTITY:
{
size_t idLen;
char *id2;
id2 = security_get_public_id(appContext->lwm2mH, cnx->securityObj, cnx->securityInstId, &idLen);
if (result_length < idLen)
{
printf("cannot set psk_identity -- buffer too small\n");
return dtls_alert_fatal_create(DTLS_ALERT_INTERNAL_ERROR);
}
memcpy(result, id2, idLen);
lwm2m_free(id2);
return idLen;
case DTLS_PSK_IDENTITY: {
size_t idLen;
char *id2;
id2 = security_get_public_id(appContext->lwm2mH, cnx->securityObj, cnx->securityInstId, &idLen);
if (result_length < idLen) {
printf("cannot set psk_identity -- buffer too small\n");
return dtls_alert_fatal_create(DTLS_ALERT_INTERNAL_ERROR);
}
case DTLS_PSK_KEY:
{
size_t keyLen;
char * key;
key = security_get_secret_key(appContext->lwm2mH, cnx->securityObj, cnx->securityInstId, &keyLen);
if (result_length < keyLen)
{
printf("cannot set psk -- buffer too small\n");
return dtls_alert_fatal_create(DTLS_ALERT_INTERNAL_ERROR);
}
memcpy(result, id2, idLen);
lwm2m_free(id2);
return idLen;
}
case DTLS_PSK_KEY: {
size_t keyLen;
char *key;
key = security_get_secret_key(appContext->lwm2mH, cnx->securityObj, cnx->securityInstId, &keyLen);
memcpy(result, key,keyLen);
lwm2m_free(key);
return keyLen;
if (result_length < keyLen) {
printf("cannot set psk -- buffer too small\n");
return dtls_alert_fatal_create(DTLS_ALERT_INTERNAL_ERROR);
}
case DTLS_PSK_HINT:
{
// PSK_HINT is optional and can be empty.
return 0;
}
default:
printf("unsupported request type: %d\n", type);
memcpy(result, key, keyLen);
lwm2m_free(key);
return keyLen;
}
case DTLS_PSK_HINT: {
// PSK_HINT is optional and can be empty.
return 0;
}
default:
printf("unsupported request type: %d\n", type);
}
return dtls_alert_fatal_create(DTLS_ALERT_INTERNAL_ERROR);
@ -238,21 +213,18 @@ static int get_psk_info(struct dtls_context_t *ctx,
/* The callback function must return the number of bytes
* that were sent, or a value less than zero to indicate an
* error. */
static int send_to_peer(struct dtls_context_t *ctx,
session_t *session, uint8 *data, size_t len) {
static int send_to_peer(struct dtls_context_t *ctx, session_t *session, uint8 *data, size_t len) {
dtls_app_context_t *appContext = (dtls_app_context_t *)ctx->app;
// find connection
dtls_connection_t* cnx = connection_find(appContext->connList, &(session->addr.st),session->size);
if (cnx != NULL)
{
dtls_connection_t *cnx = connection_find(appContext->connList, &(session->addr.st), session->size);
if (cnx != NULL) {
// send data to peer
// TODO: nat expiration?
int res = send_data(cnx,data,len);
if (res < 0)
{
int res = send_data(cnx, data, len);
if (res < 0) {
return -1;
}
return res;
@ -260,16 +232,14 @@ static int send_to_peer(struct dtls_context_t *ctx,
return -1;
}
static int read_from_peer(struct dtls_context_t *ctx,
session_t *session, uint8 *data, size_t len) {
static int read_from_peer(struct dtls_context_t *ctx, session_t *session, uint8 *data, size_t len) {
dtls_app_context_t *appContext = (dtls_app_context_t *)ctx->app;
// find connection
dtls_connection_t* cnx = connection_find(appContext->connList, &(session->addr.st),session->size);
if (cnx != NULL)
{
lwm2m_handle_packet(appContext->lwm2mH, (uint8_t*)data, len, (void*)cnx);
dtls_connection_t *cnx = connection_find(appContext->connList, &(session->addr.st), session->size);
if (cnx != NULL) {
lwm2m_handle_packet(appContext->lwm2mH, (uint8_t *)data, len, (void *)cnx);
return 0;
}
return -1;
@ -277,19 +247,19 @@ static int read_from_peer(struct dtls_context_t *ctx,
/************************** TinyDTLS Callbacks Ends ************************/
static dtls_handler_t cb = {
.write = send_to_peer,
.read = read_from_peer,
.event = NULL,
//#ifdef DTLS_PSK
.get_psk_info = get_psk_info,
//#endif /* DTLS_PSK */
//#ifdef DTLS_ECC
// .get_ecdsa_key = get_ecdsa_key,
// .verify_ecdsa_key = verify_ecdsa_key
//#endif /* DTLS_ECC */
.write = send_to_peer,
.read = read_from_peer,
.event = NULL,
// #ifdef DTLS_PSK
.get_psk_info = get_psk_info,
// #endif /* DTLS_PSK */
// #ifdef DTLS_ECC
// .get_ecdsa_key = get_ecdsa_key,
// .verify_ecdsa_key = verify_ecdsa_key
// #endif /* DTLS_ECC */
};
dtls_context_t * get_dtls_context(lwm2m_context_t * lwm2mH, dtls_connection_t * connList) {
dtls_context_t *get_dtls_context(lwm2m_context_t *lwm2mH, dtls_connection_t *connList) {
static dtls_app_context_t appContext;
appContext.lwm2mH = lwm2mH;
appContext.connList = connList;
@ -303,49 +273,45 @@ dtls_context_t * get_dtls_context(lwm2m_context_t * lwm2mH, dtls_connection_t *
return dtlsContext;
}
int get_port(struct sockaddr *x)
{
if (x->sa_family == AF_INET)
{
return ((struct sockaddr_in *)x)->sin_port;
} else if (x->sa_family == AF_INET6) {
return ((struct sockaddr_in6 *)x)->sin6_port;
} else {
printf("non IPV4 or IPV6 address\n");
return -1;
}
int get_port(struct sockaddr *x) {
if (x->sa_family == AF_INET) {
return ((struct sockaddr_in *)x)->sin_port;
} else if (x->sa_family == AF_INET6) {
return ((struct sockaddr_in6 *)x)->sin6_port;
} else {
printf("non IPV4 or IPV6 address\n");
return -1;
}
}
int sockaddr_cmp(struct sockaddr *x, struct sockaddr *y)
{
int sockaddr_cmp(struct sockaddr *x, struct sockaddr *y) {
int portX = get_port(x);
int portY = get_port(y);
// if the port is invalid of different
if (portX == -1 || portX != portY)
{
if (portX == -1 || portX != portY) {
return 0;
}
// IPV4?
if (x->sa_family == AF_INET)
{
if (x->sa_family == AF_INET) {
// is V4?
if (y->sa_family == AF_INET)
{
if (y->sa_family == AF_INET) {
// compare V4 with V4
return ((struct sockaddr_in *)x)->sin_addr.s_addr == ((struct sockaddr_in *)y)->sin_addr.s_addr;
// is V6 mapped V4?
} else if (IN6_IS_ADDR_V4MAPPED(&((struct sockaddr_in6 *)y)->sin6_addr)) {
struct in6_addr* addr6 = &((struct sockaddr_in6 *)y)->sin6_addr;
uint32_t y6to4 = addr6->s6_addr[15] << 24 | addr6->s6_addr[14] << 16 | addr6->s6_addr[13] << 8 | addr6->s6_addr[12];
struct in6_addr *addr6 = &((struct sockaddr_in6 *)y)->sin6_addr;
uint32_t y6to4 =
addr6->s6_addr[15] << 24 | addr6->s6_addr[14] << 16 | addr6->s6_addr[13] << 8 | addr6->s6_addr[12];
return y6to4 == ((struct sockaddr_in *)x)->sin_addr.s_addr;
} else {
return 0;
}
} else if (x->sa_family == AF_INET6 && y->sa_family == AF_INET6) {
// IPV6 with IPV6 compare
return memcmp(((struct sockaddr_in6 *)x)->sin6_addr.s6_addr, ((struct sockaddr_in6 *)y)->sin6_addr.s6_addr, 16) == 0;
return memcmp(((struct sockaddr_in6 *)x)->sin6_addr.s6_addr, ((struct sockaddr_in6 *)y)->sin6_addr.s6_addr,
16) == 0;
} else {
// unknown address type
printf("non IPV4 or IPV6 address\n");
@ -353,8 +319,7 @@ int sockaddr_cmp(struct sockaddr *x, struct sockaddr *y)
}
}
int create_socket(const char * portStr, int ai_family)
{
int create_socket(const char *portStr, int ai_family) {
int s = -1;
struct addrinfo hints;
struct addrinfo *res;
@ -365,18 +330,14 @@ int create_socket(const char * portStr, int ai_family)
hints.ai_socktype = SOCK_DGRAM;
hints.ai_flags = AI_PASSIVE;
if (0 != getaddrinfo(NULL, portStr, &hints, &res))
{
if (0 != getaddrinfo(NULL, portStr, &hints, &res)) {
return -1;
}
for(p = res ; p != NULL && s == -1 ; p = p->ai_next)
{
for (p = res; p != NULL && s == -1; p = p->ai_next) {
s = socket(p->ai_family, p->ai_socktype, p->ai_protocol);
if (s >= 0)
{
if (-1 == bind(s, p->ai_addr, p->ai_addrlen))
{
if (s >= 0) {
if (-1 == bind(s, p->ai_addr, p->ai_addrlen)) {
close(s);
s = -1;
}
@ -388,36 +349,28 @@ int create_socket(const char * portStr, int ai_family)
return s;
}
dtls_connection_t * connection_find(dtls_connection_t * connList,
const struct sockaddr_storage * addr,
size_t addrLen)
{
dtls_connection_t * connP;
dtls_connection_t *connection_find(dtls_connection_t *connList, const struct sockaddr_storage *addr, size_t addrLen) {
dtls_connection_t *connP;
connP = connList;
while (connP != NULL)
{
while (connP != NULL) {
if (sockaddr_cmp((struct sockaddr*) (&connP->addr),(struct sockaddr*) addr)) {
if (sockaddr_cmp((struct sockaddr *)(&connP->addr), (struct sockaddr *)addr)) {
return connP;
}
}
connP = connP->next;
connP = connP->next;
}
return connP;
}
dtls_connection_t * connection_new_incoming(dtls_connection_t * connList,
int sock,
const struct sockaddr * addr,
size_t addrLen)
{
dtls_connection_t * connP;
dtls_connection_t *connection_new_incoming(dtls_connection_t *connList, int sock, const struct sockaddr *addr,
size_t addrLen) {
dtls_connection_t *connP;
connP = (dtls_connection_t *)malloc(sizeof(dtls_connection_t));
if (connP != NULL)
{
if (connP != NULL) {
memset(connP, 0, sizeof(dtls_connection_t));
connP->sock = sock;
memcpy(&(connP->addr), addr, addrLen);
@ -434,65 +387,49 @@ dtls_connection_t * connection_new_incoming(dtls_connection_t * connList,
return connP;
}
dtls_connection_t * connection_create(dtls_connection_t * connList,
int sock,
lwm2m_object_t * securityObj,
int instanceId,
lwm2m_context_t * lwm2mH,
int addressFamily)
{
dtls_connection_t *connection_create(dtls_connection_t *connList, int sock, lwm2m_object_t *securityObj, int instanceId,
lwm2m_context_t *lwm2mH, int addressFamily) {
struct addrinfo hints;
struct addrinfo *servinfo = NULL;
struct addrinfo *p;
int s;
struct sockaddr *sa;
socklen_t sl;
dtls_connection_t * connP = NULL;
dtls_connection_t *connP = NULL;
char uriBuf[URI_LENGTH];
char * uri;
char * host;
char * port;
char *uri;
char *host;
char *port;
memset(&hints, 0, sizeof(hints));
hints.ai_family = addressFamily;
hints.ai_socktype = SOCK_DGRAM;
uri = security_get_uri(lwm2mH, securityObj, instanceId, uriBuf, URI_LENGTH);
if (uri == NULL) return NULL;
if (uri == NULL)
return NULL;
// parse uri in the form "coaps://[host]:[port]"
char defaultport[5];
if (0 == strncmp(uri, "coaps://", strlen("coaps://")))
{
host = uri+strlen("coaps://");
if (0 == strncmp(uri, "coaps://", strlen("coaps://"))) {
host = uri + strlen("coaps://");
strncpy(defaultport, COAPS_PORT, 5);
}
else if (0 == strncmp(uri, "coap://", strlen("coap://")))
{
host = uri+strlen("coap://");
} else if (0 == strncmp(uri, "coap://", strlen("coap://"))) {
host = uri + strlen("coap://");
strncpy(defaultport, COAP_PORT, 5);
}
else
{
} else {
return NULL;
}
port = strrchr(host, ':');
if (port == NULL)
{
if (port == NULL) {
port = defaultport;
}
else
{
} else {
// remove brackets
if (host[0] == '[')
{
if (host[0] == '[') {
host++;
if (*(port - 1) == ']')
{
if (*(port - 1) == ']') {
*(port - 1) = 0;
}
else
{
} else {
return NULL;
}
}
@ -501,61 +438,52 @@ dtls_connection_t * connection_create(dtls_connection_t * connList,
port++;
}
if (0 != getaddrinfo(host, port, &hints, &servinfo) || servinfo == NULL) return NULL;
if (0 != getaddrinfo(host, port, &hints, &servinfo) || servinfo == NULL)
return NULL;
// we test the various addresses
s = -1;
for(p = servinfo ; p != NULL && s == -1 ; p = p->ai_next)
{
for (p = servinfo; p != NULL && s == -1; p = p->ai_next) {
s = socket(p->ai_family, p->ai_socktype, p->ai_protocol);
if (s >= 0)
{
if (s >= 0) {
sa = p->ai_addr;
sl = p->ai_addrlen;
if (-1 == connect(s, p->ai_addr, p->ai_addrlen))
{
if (-1 == connect(s, p->ai_addr, p->ai_addrlen)) {
close(s);
s = -1;
}
}
}
if (s >= 0)
{
if (s >= 0) {
connP = connection_new_incoming(connList, sock, sa, sl);
close(s);
// do we need to start tinydtls?
if (connP != NULL)
{
if (connP != NULL) {
connP->securityObj = securityObj;
connP->securityInstId = instanceId;
connP->lwm2mH = lwm2mH;
if (security_get_mode(lwm2mH, connP->securityObj,connP->securityInstId)
!= LWM2M_SECURITY_MODE_NONE)
{
if (security_get_mode(lwm2mH, connP->securityObj, connP->securityInstId) != LWM2M_SECURITY_MODE_NONE) {
connP->dtlsContext = get_dtls_context(lwm2mH, connP);
}
else
{
} else {
// no dtls session
connP->dtlsSession = NULL;
}
}
}
if (NULL != servinfo) free(servinfo);
if (NULL != servinfo)
free(servinfo);
return connP;
}
void connection_free(dtls_connection_t * connList)
{
void connection_free(dtls_connection_t *connList) {
dtls_free_context(dtlsContext);
dtlsContext = NULL;
while (connList != NULL)
{
dtls_connection_t * nextP;
while (connList != NULL) {
dtls_connection_t *nextP;
nextP = connList->next;
free(connList);
@ -564,18 +492,16 @@ void connection_free(dtls_connection_t * connList)
}
}
int connection_send(dtls_connection_t *connP, uint8_t * buffer, size_t length){
int connection_send(dtls_connection_t *connP, uint8_t *buffer, size_t length) {
if (connP->dtlsSession == NULL) {
// no security
if (0 >= send_data(connP, buffer, length)) {
return -1 ;
return -1;
}
} else {
if (DTLS_NAT_TIMEOUT > 0 && (lwm2m_gettime() - connP->lastSend) > DTLS_NAT_TIMEOUT)
{
if (DTLS_NAT_TIMEOUT > 0 && (lwm2m_gettime() - connP->lastSend) > DTLS_NAT_TIMEOUT) {
// we need to rehandhake because our source IP/port probably changed for the server
if ( connection_rehandshake(connP, false) != 0 )
{
if (connection_rehandshake(connP, false) != 0) {
printf("can't send due to rehandshake error\n");
return -1;
}
@ -588,19 +514,18 @@ int connection_send(dtls_connection_t *connP, uint8_t * buffer, size_t length){
return 0;
}
int connection_handle_packet(dtls_connection_t *connP, uint8_t * buffer, size_t numBytes){
int connection_handle_packet(dtls_connection_t *connP, uint8_t *buffer, size_t numBytes) {
if (connP->dtlsSession != NULL)
{
if (connP->dtlsSession != NULL) {
// Let liblwm2m respond to the query depending on the context
int result = dtls_handle_message(connP->dtlsContext, connP->dtlsSession, buffer, numBytes);
if (result !=0) {
printf("error dtls handling message %d\n",result);
if (result != 0) {
printf("error dtls handling message %d\n", result);
}
return result;
} else {
// no security, just give the plaintext buffer to liblwm2m
lwm2m_handle_packet(connP->lwm2mH, buffer, numBytes, (void*)connP);
lwm2m_handle_packet(connP->lwm2mH, buffer, numBytes, (void *)connP);
return 0;
}
}
@ -613,49 +538,36 @@ int connection_rehandshake(dtls_connection_t *connP, bool sendCloseNotify) {
}
// reset current session
dtls_peer_t * peer = dtls_get_peer(connP->dtlsContext, connP->dtlsSession);
if (peer != NULL)
{
if (!sendCloseNotify)
{
peer->state = DTLS_STATE_CLOSED;
dtls_peer_t *peer = dtls_get_peer(connP->dtlsContext, connP->dtlsSession);
if (peer != NULL) {
if (!sendCloseNotify) {
peer->state = DTLS_STATE_CLOSED;
}
dtls_reset_peer(connP->dtlsContext, peer);
}
// start a fresh handshake
int result = dtls_connect(connP->dtlsContext, connP->dtlsSession);
if (result !=0) {
printf("error dtls reconnection %d\n",result);
if (result != 0) {
printf("error dtls reconnection %d\n", result);
}
return result;
}
uint8_t lwm2m_buffer_send(void * sessionH,
uint8_t * buffer,
size_t length,
void * userdata)
{
dtls_connection_t * connP = (dtls_connection_t*) sessionH;
uint8_t lwm2m_buffer_send(void *sessionH, uint8_t *buffer, size_t length, void *userdata) {
dtls_connection_t *connP = (dtls_connection_t *)sessionH;
if (connP == NULL)
{
if (connP == NULL) {
fprintf(stderr, "#> failed sending %zu bytes, missing connection\r\n", length);
return COAP_500_INTERNAL_SERVER_ERROR ;
return COAP_500_INTERNAL_SERVER_ERROR;
}
if (-1 == connection_send(connP, buffer, length))
{
if (-1 == connection_send(connP, buffer, length)) {
fprintf(stderr, "#> failed sending %zu bytes\r\n", length);
return COAP_500_INTERNAL_SERVER_ERROR ;
return COAP_500_INTERNAL_SERVER_ERROR;
}
return COAP_NO_ERROR;
}
bool lwm2m_session_is_equal(void * session1,
void * session2,
void * userData)
{
return (session1 == session2);
}
bool lwm2m_session_is_equal(void *session1, void *session2, void *userData) { return (session1 == session2); }

View File

@ -19,54 +19,55 @@
#ifndef DTLS_CONNECTION_H_
#define DTLS_CONNECTION_H_
#include <stdio.h>
#include <unistd.h>
#include <netinet/in.h>
#include <arpa/inet.h>
#include <netdb.h>
#include <netinet/in.h>
#include <stdbool.h>
#include <stdint.h>
#include <stdio.h>
#include <sys/socket.h>
#include <sys/stat.h>
#include <stdint.h>
#include <stdbool.h>
#include <unistd.h>
#include "tinydtls/tinydtls.h"
#include "tinydtls/dtls.h"
#include "liblwm2m.h"
#include "tinydtls/dtls.h"
#include "tinydtls/tinydtls.h"
#define LWM2M_STANDARD_PORT_STR "5683"
#define LWM2M_STANDARD_PORT 5683
#define LWM2M_DTLS_PORT_STR "5684"
#define LWM2M_DTLS_PORT 5684
#define LWM2M_STANDARD_PORT 5683
#define LWM2M_DTLS_PORT_STR "5684"
#define LWM2M_DTLS_PORT 5684
#define LWM2M_BSSERVER_PORT_STR "5685"
#define LWM2M_BSSERVER_PORT 5685
#define LWM2M_BSSERVER_PORT 5685
// after 40sec of inactivity we rehandshake
#define DTLS_NAT_TIMEOUT 40
typedef struct _dtls_connection_t
{
struct _dtls_connection_t * next;
int sock;
struct sockaddr_in6 addr;
size_t addrLen;
session_t * dtlsSession;
lwm2m_object_t * securityObj;
typedef struct _dtls_connection_t {
struct _dtls_connection_t *next;
int sock;
struct sockaddr_in6 addr;
size_t addrLen;
session_t *dtlsSession;
lwm2m_object_t *securityObj;
int securityInstId;
lwm2m_context_t * lwm2mH;
dtls_context_t * dtlsContext;
lwm2m_context_t *lwm2mH;
dtls_context_t *dtlsContext;
time_t lastSend; // last time a data was sent to the server (used for NAT timeouts)
} dtls_connection_t;
int create_socket(const char * portStr, int ai_family);
int create_socket(const char *portStr, int ai_family);
dtls_connection_t * connection_find(dtls_connection_t * connList, const struct sockaddr_storage * addr, size_t addrLen);
dtls_connection_t * connection_new_incoming(dtls_connection_t * connList, int sock, const struct sockaddr * addr, size_t addrLen);
dtls_connection_t * connection_create(dtls_connection_t * connList, int sock, lwm2m_object_t * securityObj, int instanceId, lwm2m_context_t * lwm2mH, int addressFamily);
dtls_connection_t *connection_find(dtls_connection_t *connList, const struct sockaddr_storage *addr, size_t addrLen);
dtls_connection_t *connection_new_incoming(dtls_connection_t *connList, int sock, const struct sockaddr *addr,
size_t addrLen);
dtls_connection_t *connection_create(dtls_connection_t *connList, int sock, lwm2m_object_t *securityObj, int instanceId,
lwm2m_context_t *lwm2mH, int addressFamily);
void connection_free(dtls_connection_t * connList);
void connection_free(dtls_connection_t *connList);
int connection_send(dtls_connection_t *connP, uint8_t * buffer, size_t length);
int connection_handle_packet(dtls_connection_t *connP, uint8_t * buffer, size_t length);
int connection_send(dtls_connection_t *connP, uint8_t *buffer, size_t length);
int connection_handle_packet(dtls_connection_t *connP, uint8_t *buffer, size_t length);
// rehandshake a connection, useful when your NAT timed out and your client has a new IP/PORT
int connection_rehandshake(dtls_connection_t *connP, bool sendCloseNotify);

View File

@ -1,5 +1,5 @@
# List source files
set(TINYDTLS_SOURCES_DIR ${CMAKE_CURRENT_LIST_DIR}/tinydtls)
set(TINYDTLS_SOURCES_DIR ${CMAKE_CURRENT_LIST_DIR}/third_party/tinydtls)
set(TINYDTLS_SOURCES
${TINYDTLS_SOURCES_DIR}/tinydtls.h
${TINYDTLS_SOURCES_DIR}/dtls.h

View File

@ -245,9 +245,13 @@ function(target_sources_shared target)
target_sources(${target} PRIVATE ${WAKAAMA_TOP_LEVEL_DIRECTORY}/transport/udp/connection.c)
target_include_directories(${target} PUBLIC ${WAKAAMA_TOP_LEVEL_DIRECTORY}/transport/udp/include)
elseif(TARGET_PROPERTY_CONN_IMPL MATCHES "tinydtls")
include(${WAKAAMA_EXAMPLE_SHARED_DIRECTORY}/tinydtls.cmake)
target_sources(${target} PRIVATE ${WAKAAMA_EXAMPLE_SHARED_DIRECTORY}/dtlsconnection.c)
include(${WAKAAMA_TOP_LEVEL_DIRECTORY}/transport/tinydtls/tinydtls.cmake)
target_sources(${target} PRIVATE ${WAKAAMA_TOP_LEVEL_DIRECTORY}/transport/tinydtls/connection.c)
target_compile_definitions(${target} PRIVATE WITH_TINYDTLS)
target_include_directories(
${target} PUBLIC ${WAKAAMA_TOP_LEVEL_DIRECTORY}/transport/tinydtls/include
${WAKAAMA_TOP_LEVEL_DIRECTORY}/transport/tinydtls/third_party
)
target_sources_tinydtls(${target})
elseif(TARGET_PROPERTY_CONN_IMPL MATCHES "testing")
target_include_directories(${target} PRIVATE ${WAKAAMA_TOP_LEVEL_DIRECTORY}/tests/helper/)