Support for setting source address to socket (#40)

When receiving data, destination (own) address is stored and given to
socket when sending reply to make sure respone comes always from same
address where request was sent. This commit supports only real socket to
real socket messages, not virtual socket, or DTLS handshake messages.
pull/3240/head
Tero Heinonen 2016-10-24 11:58:53 +03:00 committed by GitHub
parent 9c88fcd984
commit 9dfc6f970c
19 changed files with 272 additions and 158 deletions

View File

@ -31,7 +31,7 @@ typedef struct internal_socket_s {
int8_t listen_socket; int8_t listen_socket;
ns_address_t dest_addr; ns_address_t dest_addr;
size_t data_len; int16_t data_len;
uint8_t *data; uint8_t *data;
bool real_socket; bool real_socket;
@ -72,7 +72,7 @@ typedef struct secure_session {
} secure_session_t; } secure_session_t;
static NS_LIST_DEFINE(secure_session_list, secure_session_t, link); static NS_LIST_DEFINE(secure_session_list, secure_session_t, link);
static int send_to_socket(int8_t socket_id, uint8_t *address_ptr, uint16_t port, const unsigned char *buf, size_t len); static int send_to_socket(int8_t socket_id, const uint8_t *address_ptr, uint16_t port, const uint8_t source_addr[static 16], const void *buf, size_t len);
static int receive_from_socket(int8_t socket_id, unsigned char *buf, size_t len); static int receive_from_socket(int8_t socket_id, unsigned char *buf, size_t len);
static void start_timer(int8_t timer_id, uint32_t int_ms, uint32_t fin_ms); static void start_timer(int8_t timer_id, uint32_t int_ms, uint32_t fin_ms);
static int timer_status(int8_t timer_id); static int timer_status(int8_t timer_id);
@ -107,7 +107,7 @@ static void secure_session_delete(secure_session_t *this)
return; return;
} }
static secure_session_t *secure_session_create(internal_socket_t *parent, uint8_t *address_ptr, uint16_t port) static secure_session_t *secure_session_create(internal_socket_t *parent, const uint8_t *address_ptr, uint16_t port)
{ {
if(!address_ptr){ if(!address_ptr){
return NULL; return NULL;
@ -173,7 +173,7 @@ static void clear_secure_sessions(internal_socket_t *this){
} }
} }
static secure_session_t *secure_session_find(internal_socket_t *parent, uint8_t *address_ptr, uint16_t port) static secure_session_t *secure_session_find(internal_socket_t *parent, const uint8_t *address_ptr, uint16_t port)
{ {
secure_session_t *this = NULL; secure_session_t *this = NULL;
ns_list_foreach(secure_session_t, cur_ptr, &secure_session_list) { ns_list_foreach(secure_session_t, cur_ptr, &secure_session_list) {
@ -227,14 +227,14 @@ static internal_socket_t *int_socket_create(uint16_t listen_port, bool use_ephem
return NULL; return NULL;
} }
socket_setsockopt(this->listen_socket, SOCKET_IPPROTO_IPV6, SOCKET_LINK_LAYER_SECURITY, &(const int8_t) { socket_setsockopt(this->listen_socket, SOCKET_IPPROTO_IPV6, SOCKET_LINK_LAYER_SECURITY, &(const int8_t) {bypassSec ? 0 : 1}, sizeof(int8_t));
bypassSec ? 0 : 1
}, sizeof(int8_t));
// XXX API for this? May want to get clever to do recommended first query = 1 hop, retries = whole PAN // XXX API for this? May want to get clever to do recommended first query = 1 hop, retries = whole PAN
socket_setsockopt(this->listen_socket, SOCKET_IPPROTO_IPV6, SOCKET_IPV6_MULTICAST_HOPS, &(const int16_t) { socket_setsockopt(this->listen_socket, SOCKET_IPPROTO_IPV6, SOCKET_IPV6_MULTICAST_HOPS, &(const int16_t) {16}, sizeof(int16_t));
16
}, sizeof(int16_t)); // Set socket option to receive packet info
socket_setsockopt(this->listen_socket, SOCKET_IPPROTO_IPV6, SOCKET_IPV6_RECVPKTINFO, &(const bool) {1}, sizeof(bool));
}else{ }else{
this->listen_socket = -1; this->listen_socket = -1;
} }
@ -290,15 +290,53 @@ static internal_socket_t *int_socket_find(uint16_t port, bool is_secure, bool is
return this; return this;
} }
static int send_to_socket(int8_t socket_id, uint8_t *address_ptr, uint16_t port, const unsigned char *buf, size_t len) static int8_t send_to_real_socket(int8_t socket_id, const ns_address_t *address, const uint8_t source_address[static 16], const void *buffer, uint16_t length)
{
ns_iovec_t msg_iov;
ns_msghdr_t msghdr;
msghdr.msg_name = (void*)address;
msghdr.msg_namelen = sizeof(ns_address_t);
msghdr.msg_iov = &msg_iov;
msghdr.msg_iovlen = 1;
msghdr.flags = 0;
if (memcmp(source_address, ns_in6addr_any, 16)) {
uint8_t ancillary_databuffer[NS_CMSG_SPACE(sizeof(ns_in6_pktinfo_t))];
ns_cmsghdr_t *cmsg;
ns_in6_pktinfo_t *pktinfo;
tr_debug("send from source address %s", trace_array(source_address, 16));
msghdr.msg_control = ancillary_databuffer;
msghdr.msg_controllen = sizeof(ancillary_databuffer);
cmsg = NS_CMSG_FIRSTHDR(&msghdr);
cmsg->cmsg_type = SOCKET_IPV6_PKTINFO;
cmsg->cmsg_level = SOCKET_IPPROTO_IPV6;
cmsg->cmsg_len = NS_CMSG_LEN(sizeof(ns_in6_pktinfo_t));
pktinfo = (ns_in6_pktinfo_t*)NS_CMSG_DATA(cmsg);
pktinfo->ipi6_ifindex = 0;
memcpy(pktinfo->ipi6_addr, source_address, 16);
} else {
msghdr.msg_control = NULL;
msghdr.msg_controllen = 0;
}
msg_iov.iov_base = (void *)buffer;
msg_iov.iov_len = length;
return socket_sendmsg(socket_id, &msghdr, 0);
}
static int send_to_socket(int8_t socket_id, const uint8_t *address_ptr, uint16_t port, const uint8_t source_addr[static 16], const void *buf, size_t len)
{ {
internal_socket_t *sock = int_socket_find_by_socket_id(socket_id); internal_socket_t *sock = int_socket_find_by_socket_id(socket_id);
if(!sock){ if(!sock){
return -1; return -1;
} }
if(!sock->real_socket){ if(!sock->real_socket){
//In this case all clients will have socket_id -1 and socket will not have a real address // Send to virtual socket cb
//so sock->dest_addr cannot be used here
int ret = sock->parent->_send_cb(sock->listen_socket, address_ptr, port, buf, len); int ret = sock->parent->_send_cb(sock->listen_socket, address_ptr, port, buf, len);
if( ret < 0 ) if( ret < 0 )
return ret; return ret;
@ -307,16 +345,18 @@ static int send_to_socket(int8_t socket_id, uint8_t *address_ptr, uint16_t port,
int opt_name = SOCKET_IPV6_PREFER_SRC_6LOWPAN_SHORT; int opt_name = SOCKET_IPV6_PREFER_SRC_6LOWPAN_SHORT;
int8_t securityLinkLayer = 1; int8_t securityLinkLayer = 1;
if( sock->bypass_link_sec ){ if (sock->bypass_link_sec) {
securityLinkLayer = 0; securityLinkLayer = 0;
} }
socket_setsockopt(sock->listen_socket, SOCKET_IPPROTO_IPV6, SOCKET_IPV6_ADDR_PREFERENCES, &opt_name, sizeof(int)); socket_setsockopt(sock->listen_socket, SOCKET_IPPROTO_IPV6, SOCKET_IPV6_ADDR_PREFERENCES, &opt_name, sizeof(int));
socket_setsockopt(sock->listen_socket, SOCKET_IPPROTO_IPV6, SOCKET_LINK_LAYER_SECURITY, &securityLinkLayer, sizeof(int8_t)); socket_setsockopt(sock->listen_socket, SOCKET_IPPROTO_IPV6, SOCKET_LINK_LAYER_SECURITY, &securityLinkLayer, sizeof(int8_t));
//For some reason socket_sendto returns 0 in success, while other socket impls return number of bytes sent!!! //For some reason socket_sendto returns 0 in success, while other socket impls return number of bytes sent!!!
//TODO: check if address_ptr is valid and use that instead if it is //TODO: check if address_ptr is valid and use that instead if it is
int ret = socket_sendto(sock->listen_socket, &sock->dest_addr, (unsigned char*)buf, len);
if( ret < 0 ) int8_t ret = send_to_real_socket(sock->listen_socket, &sock->dest_addr, source_addr, buf, len);
if (ret < 0) {
return ret; return ret;
}
return len; return len;
} }
@ -324,7 +364,7 @@ static int receive_from_socket(int8_t socket_id, unsigned char *buf, size_t len)
{ {
(void)len; (void)len;
internal_socket_t *sock = int_socket_find_by_socket_id(socket_id); internal_socket_t *sock = int_socket_find_by_socket_id(socket_id);
if( sock->data && sock->data_len > 0 ){ if (sock->data && sock->data_len > 0) {
memcpy( buf, sock->data, sock->data_len ); memcpy( buf, sock->data, sock->data_len );
int l = sock->data_len; int l = sock->data_len;
ns_dyn_mem_free(sock->data); ns_dyn_mem_free(sock->data);
@ -406,28 +446,71 @@ static int timer_status(int8_t timer_id)
return TIMER_STATE_CANCELLED; return TIMER_STATE_CANCELLED;
} }
static int read_data(socket_callback_t *sckt_data, internal_socket_t *sock, ns_address_t *src_address) static int read_data(socket_callback_t *sckt_data, internal_socket_t *sock, ns_address_t *src_address, uint8_t dst_address[static 16])
{ {
sock->data_len = 0; sock->data_len = 0;
if (sckt_data->event_type == SOCKET_DATA && sckt_data->d_len > 0) { if (sckt_data->event_type == SOCKET_DATA && sckt_data->d_len > 0) {
if( sock->data ){ uint8_t ancillary_databuffer[NS_CMSG_SPACE(sizeof(ns_in6_pktinfo_t))];
ns_iovec_t msg_iov;
ns_msghdr_t msghdr;
ns_in6_pktinfo_t *pkt = NULL;
if (sock->data) {
ns_dyn_mem_free(sock->data); ns_dyn_mem_free(sock->data);
sock->data = NULL; sock->data = NULL;
} }
sock->data = ns_dyn_mem_temporary_alloc(sckt_data->d_len); sock->data = ns_dyn_mem_temporary_alloc(sckt_data->d_len);
if( !sock->data ){ if (!sock->data) {
sock->data = NULL; sock->data = NULL;
return -1; return -1;
} }
sock->data_len = socket_read(sckt_data->socket_id, src_address, sock->data, sckt_data->d_len);
msghdr.msg_name = src_address;
msghdr.msg_namelen = sizeof(ns_address_t);
msghdr.msg_iov = &msg_iov;
msghdr.msg_iovlen = 1;
msghdr.msg_control = ancillary_databuffer;
msghdr.msg_controllen = sizeof(ancillary_databuffer);
msghdr.flags = 0;
msg_iov.iov_base = sock->data;
msg_iov.iov_len = sckt_data->d_len;
sock->data_len = socket_recvmsg(sckt_data->socket_id, &msghdr, 0);
if (sock->data_len > 0) {
ns_cmsghdr_t *cmsg = NS_CMSG_FIRSTHDR(&msghdr);
while (cmsg) {
switch (cmsg->cmsg_type) {
case SOCKET_IPV6_PKTINFO:
pkt = (ns_in6_pktinfo_t*)NS_CMSG_DATA(cmsg);
break;
default:
break;
} }
if( sock->data_len < 1){ cmsg = NS_CMSG_NXTHDR(&msghdr, cmsg);
}
if (pkt) {
memcpy(dst_address, pkt->ipi6_addr, 16);
} else {
goto return_failure;
}
} else {
goto return_failure;
}
}
return 0;
return_failure:
ns_dyn_mem_free(sock->data); ns_dyn_mem_free(sock->data);
sock->data = NULL; sock->data = NULL;
sock->data_len = 0; sock->data_len = 0;
return -1; return -1;
}
return 0;
} }
static void secure_recv_sckt_msg(void *cb_res) static void secure_recv_sckt_msg(void *cb_res)
@ -435,24 +518,25 @@ static void secure_recv_sckt_msg(void *cb_res)
socket_callback_t *sckt_data = cb_res; socket_callback_t *sckt_data = cb_res;
internal_socket_t *sock = int_socket_find_by_socket_id(sckt_data->socket_id); internal_socket_t *sock = int_socket_find_by_socket_id(sckt_data->socket_id);
ns_address_t src_address; ns_address_t src_address;
uint8_t dst_address[16];
if( sock && read_data(sckt_data, sock, &src_address) == 0 ){ if (sock && read_data(sckt_data, sock, &src_address, dst_address) == 0) {
secure_session_t *session = secure_session_find(sock, src_address.address, src_address.identifier); secure_session_t *session = secure_session_find(sock, src_address.address, src_address.identifier);
// Create session // Create session
if( !session ){ if (!session) {
memcpy( sock->dest_addr.address, src_address.address, 16 ); memcpy( sock->dest_addr.address, src_address.address, 16 );
sock->dest_addr.identifier = src_address.identifier; sock->dest_addr.identifier = src_address.identifier;
sock->dest_addr.type = src_address.type; sock->dest_addr.type = src_address.type;
session = secure_session_create(sock, src_address.address, src_address.identifier); session = secure_session_create(sock, src_address.address, src_address.identifier);
} }
if( !session ){ if (!session) {
tr_err("secure_recv_sckt_msg session creation failed - OOM"); tr_err("secure_recv_sckt_msg session creation failed - OOM");
return; return;
} }
session->last_contact_time = coap_service_get_internal_timer_ticks(); session->last_contact_time = coap_service_get_internal_timer_ticks();
// Start handshake // Start handshake
if( !session->sec_handler->_is_started ){ if (!session->sec_handler->_is_started) {
uint8_t *pw = (uint8_t *)ns_dyn_mem_alloc(64); uint8_t *pw = (uint8_t *)ns_dyn_mem_alloc(64);
uint8_t pw_len; uint8_t pw_len;
if( sock->parent->_get_password_cb && 0 == sock->parent->_get_password_cb(sock->listen_socket, src_address.address, src_address.identifier, pw, &pw_len)){ if( sock->parent->_get_password_cb && 0 == sock->parent->_get_password_cb(sock->listen_socket, src_address.address, src_address.identifier, pw, &pw_len)){
@ -464,12 +548,12 @@ static void secure_recv_sckt_msg(void *cb_res)
//TODO: error handling //TODO: error handling
} }
ns_dyn_mem_free(pw); ns_dyn_mem_free(pw);
}else{ } else {
//Continue handshake //Continue handshake
if(session->session_state == SECURE_SESSION_HANDSHAKE_ONGOING){ if (session->session_state == SECURE_SESSION_HANDSHAKE_ONGOING) {
int ret = coap_security_handler_continue_connecting(session->sec_handler); int ret = coap_security_handler_continue_connecting(session->sec_handler);
// Handshake done // Handshake done
if(ret == 0){ if (ret == 0) {
eventOS_timeout_cancel(session->timer.timer); eventOS_timeout_cancel(session->timer.timer);
session->timer.timer = NULL; session->timer.timer = NULL;
session->session_state = SECURE_SESSION_OK; session->session_state = SECURE_SESSION_OK;
@ -478,14 +562,13 @@ static void secure_recv_sckt_msg(void *cb_res)
src_address.identifier, src_address.identifier,
session->sec_handler->_keyblk.value); session->sec_handler->_keyblk.value);
} }
} } else if (ret < 0){
else if (ret < 0){
// error handling // error handling
// TODO: here we also should clear CoAP retransmission buffer and inform that CoAP request sending is failed. // TODO: here we also should clear CoAP retransmission buffer and inform that CoAP request sending is failed.
secure_session_delete(session); secure_session_delete(session);
} }
//Session valid //Session valid
}else{ } else {
unsigned char *data = ns_dyn_mem_temporary_alloc(sock->data_len); unsigned char *data = ns_dyn_mem_temporary_alloc(sock->data_len);
int len = 0; int len = 0;
len = coap_security_handler_read(session->sec_handler, data, sock->data_len); len = coap_security_handler_read(session->sec_handler, data, sock->data_len);
@ -495,9 +578,9 @@ static void secure_recv_sckt_msg(void *cb_res)
secure_session_delete(session); secure_session_delete(session);
} }
ns_dyn_mem_free(data); ns_dyn_mem_free(data);
}else{ } else {
if( sock->parent->_recv_cb ){ if (sock->parent->_recv_cb) {
sock->parent->_recv_cb(sock->listen_socket, src_address.address, src_address.identifier, data, len); sock->parent->_recv_cb(sock->listen_socket, src_address.address, src_address.identifier, dst_address, data, len);
} }
ns_dyn_mem_free(data); ns_dyn_mem_free(data);
} }
@ -511,9 +594,11 @@ static void recv_sckt_msg(void *cb_res)
socket_callback_t *sckt_data = cb_res; socket_callback_t *sckt_data = cb_res;
internal_socket_t *sock = int_socket_find_by_socket_id(sckt_data->socket_id); internal_socket_t *sock = int_socket_find_by_socket_id(sckt_data->socket_id);
ns_address_t src_address; ns_address_t src_address;
if( sock && read_data(sckt_data, sock, &src_address) == 0 ){ uint8_t dst_address[16];
if(sock->parent && sock->parent->_recv_cb){
sock->parent->_recv_cb(sock->listen_socket, src_address.address, src_address.identifier, sock->data, sock->data_len); if (sock && read_data(sckt_data, sock, &src_address, dst_address) == 0) {
if (sock->parent && sock->parent->_recv_cb) {
sock->parent->_recv_cb(sock->listen_socket, src_address.address, src_address.identifier, dst_address, sock->data, sock->data_len);
} }
ns_dyn_mem_free(sock->data); ns_dyn_mem_free(sock->data);
sock->data = NULL; sock->data = NULL;
@ -522,44 +607,44 @@ static void recv_sckt_msg(void *cb_res)
int coap_connection_handler_virtual_recv(coap_conn_handler_t *handler, uint8_t address[static 16], uint16_t port, uint8_t *data_ptr, uint16_t data_len) int coap_connection_handler_virtual_recv(coap_conn_handler_t *handler, uint8_t address[static 16], uint16_t port, uint8_t *data_ptr, uint16_t data_len)
{ {
if( !handler || !handler->socket ){ if(!handler || !handler->socket) {
return -1; return -1;
} }
internal_socket_t *sock = handler->socket; internal_socket_t *sock = handler->socket;
sock->data_len = data_len; sock->data_len = data_len;
if( sock->data ){ if (sock->data) {
ns_dyn_mem_free(sock->data); ns_dyn_mem_free(sock->data);
sock->data = NULL; sock->data = NULL;
} }
sock->data = ns_dyn_mem_temporary_alloc(data_len); sock->data = ns_dyn_mem_temporary_alloc(data_len);
if( data_len > 0 && !sock->data ){ if (data_len > 0 && !sock->data) {
return -1; return -1;
} }
if( data_ptr ){ if (data_ptr) {
memcpy(sock->data, data_ptr, data_len); memcpy(sock->data, data_ptr, data_len);
}else{ } else {
if( sock->data ){ if (sock->data) {
ns_dyn_mem_free(sock->data); ns_dyn_mem_free(sock->data);
sock->data = NULL; sock->data = NULL;
} }
} }
if( handler->socket->is_secure ){ if (handler->socket->is_secure) {
secure_session_t *session = secure_session_find(sock, address, port); secure_session_t *session = secure_session_find(sock, address, port);
if( !session ){ if (!session) {
session = secure_session_create(sock, address, port); session = secure_session_create(sock, address, port);
} }
if( !session ){ if (!session) {
tr_err("coap_connection_handler_virtual_recv session creation failed - OOM"); tr_err("coap_connection_handler_virtual_recv session creation failed - OOM");
return -1; return -1;
} }
session->last_contact_time = coap_service_get_internal_timer_ticks(); session->last_contact_time = coap_service_get_internal_timer_ticks();
if( !session->sec_handler->_is_started ){ if (!session->sec_handler->_is_started) {
uint8_t *pw = (uint8_t *)ns_dyn_mem_alloc(64); uint8_t *pw = (uint8_t *)ns_dyn_mem_alloc(64);
uint8_t pw_len; uint8_t pw_len;
if( sock->parent->_get_password_cb && 0 == sock->parent->_get_password_cb(sock->listen_socket, address, port, pw, &pw_len)){ if (sock->parent->_get_password_cb && 0 == sock->parent->_get_password_cb(sock->listen_socket, address, port, pw, &pw_len)) {
//TODO: get_password_cb should support certs and PSK also //TODO: get_password_cb should support certs and PSK also
coap_security_keys_t keys; coap_security_keys_t keys;
keys._priv = pw; keys._priv = pw;
@ -568,12 +653,12 @@ int coap_connection_handler_virtual_recv(coap_conn_handler_t *handler, uint8_t a
//TODO: error handling //TODO: error handling
ns_dyn_mem_free(pw); ns_dyn_mem_free(pw);
return 0; return 0;
}else{ } else {
ns_dyn_mem_free(pw); ns_dyn_mem_free(pw);
return -1; return -1;
} }
}else{ } else {
if(session->session_state == SECURE_SESSION_HANDSHAKE_ONGOING){ if (session->session_state == SECURE_SESSION_HANDSHAKE_ONGOING) {
int ret = coap_security_handler_continue_connecting(session->sec_handler); int ret = coap_security_handler_continue_connecting(session->sec_handler);
if(ret == 0){ if(ret == 0){
session->session_state = SECURE_SESSION_OK; session->session_state = SECURE_SESSION_OK;
@ -584,18 +669,17 @@ int coap_connection_handler_virtual_recv(coap_conn_handler_t *handler, uint8_t a
} }
return 0; return 0;
} }
else if(ret < 0) else if (ret < 0) {
{
// error handling // error handling
// TODO: here we also should clear CoAP retransmission buffer and inform that CoAP request sending is failed. // TODO: here we also should clear CoAP retransmission buffer and inform that CoAP request sending is failed.
secure_session_delete(session); secure_session_delete(session);
} }
//TODO: error handling //TODO: error handling
}else{ } else {
unsigned char *data = ns_dyn_mem_temporary_alloc(sock->data_len); unsigned char *data = ns_dyn_mem_temporary_alloc(sock->data_len);
int len = 0; int len = 0;
len = coap_security_handler_read(session->sec_handler, data, sock->data_len); len = coap_security_handler_read(session->sec_handler, data, sock->data_len);
if( len < 0 ){ if (len < 0) {
if (len != MBEDTLS_ERR_SSL_WANT_READ && len != MBEDTLS_ERR_SSL_WANT_WRITE && if (len != MBEDTLS_ERR_SSL_WANT_READ && len != MBEDTLS_ERR_SSL_WANT_WRITE &&
len != MBEDTLS_ERR_SSL_UNEXPECTED_MESSAGE) { len != MBEDTLS_ERR_SSL_UNEXPECTED_MESSAGE) {
secure_session_delete(session); secure_session_delete(session);
@ -604,7 +688,7 @@ int coap_connection_handler_virtual_recv(coap_conn_handler_t *handler, uint8_t a
return 0; return 0;
} else { } else {
if (sock->parent->_recv_cb) { if (sock->parent->_recv_cb) {
sock->parent->_recv_cb(sock->listen_socket, address, port, data, len); sock->parent->_recv_cb(sock->listen_socket, address, port, ns_in6addr_any, data, len);
} }
ns_dyn_mem_free(data); ns_dyn_mem_free(data);
data = NULL; data = NULL;
@ -612,11 +696,12 @@ int coap_connection_handler_virtual_recv(coap_conn_handler_t *handler, uint8_t a
return 0; return 0;
} }
} }
}else{ } else {
if( sock->parent->_recv_cb ){ /* unsecure*/
sock->parent->_recv_cb(sock->listen_socket, address, port, sock->data, sock->data_len); if (sock->parent->_recv_cb) {
sock->parent->_recv_cb(sock->listen_socket, address, port, ns_in6addr_any, sock->data, sock->data_len);
} }
if( sock->data ){ if (sock->data) {
ns_dyn_mem_free(sock->data); ns_dyn_mem_free(sock->data);
sock->data = NULL; sock->data = NULL;
} }
@ -630,7 +715,7 @@ coap_conn_handler_t *connection_handler_create(receive_from_socket_cb *recv_from
get_pw_cb *pw_cb, get_pw_cb *pw_cb,
security_done_cb *done_cb ) security_done_cb *done_cb )
{ {
if( recv_from_cb == NULL ){ if(recv_from_cb == NULL) {
return NULL; return NULL;
} }
@ -658,10 +743,10 @@ void connection_handler_destroy(coap_conn_handler_t *handler)
void connection_handler_close_secure_connection( coap_conn_handler_t *handler, uint8_t destination_addr_ptr[static 16], uint16_t port ) void connection_handler_close_secure_connection( coap_conn_handler_t *handler, uint8_t destination_addr_ptr[static 16], uint16_t port )
{ {
if(handler){ if (handler) {
if( handler->socket && handler->socket->is_secure){ if (handler->socket && handler->socket->is_secure) {
secure_session_t *session = secure_session_find( handler->socket, destination_addr_ptr, port); secure_session_t *session = secure_session_find( handler->socket, destination_addr_ptr, port);
if( session ){ if (session) {
coap_security_send_close_alert( session->sec_handler ); coap_security_send_close_alert( session->sec_handler );
session->session_state = SECURE_SESSION_CLOSED; session->session_state = SECURE_SESSION_CLOSED;
session->last_contact_time = coap_service_get_internal_timer_ticks(); session->last_contact_time = coap_service_get_internal_timer_ticks();
@ -672,50 +757,50 @@ void connection_handler_close_secure_connection( coap_conn_handler_t *handler, u
int coap_connection_handler_open_connection(coap_conn_handler_t *handler, uint16_t listen_port, bool use_ephemeral_port, bool is_secure, bool is_real_socket, bool bypassSec) int coap_connection_handler_open_connection(coap_conn_handler_t *handler, uint16_t listen_port, bool use_ephemeral_port, bool is_secure, bool is_real_socket, bool bypassSec)
{ {
if( !handler ){ if (!handler) {
return -1; return -1;
} }
//virtual socket must have send callback //virtual socket must have send callback
if( !is_real_socket && !handler->_send_cb ){ if (!is_real_socket && !handler->_send_cb) {
return -1; return -1;
} }
if( handler->socket ){ if (handler->socket) {
int_socket_delete(handler->socket); int_socket_delete(handler->socket);
} }
internal_socket_t *current = !use_ephemeral_port?int_socket_find(listen_port, is_secure, is_real_socket, bypassSec):NULL; internal_socket_t *current = !use_ephemeral_port?int_socket_find(listen_port, is_secure, is_real_socket, bypassSec):NULL;
if(!current){ if (!current) {
handler->socket = int_socket_create(listen_port, use_ephemeral_port, is_secure, is_real_socket, bypassSec); handler->socket = int_socket_create(listen_port, use_ephemeral_port, is_secure, is_real_socket, bypassSec);
if(!handler->socket){ if (!handler->socket) {
return -1; return -1;
} }
handler->socket->parent = ns_dyn_mem_alloc(sizeof(coap_conn_handler_t)); handler->socket->parent = ns_dyn_mem_alloc(sizeof(coap_conn_handler_t));
if(!handler->socket->parent){ if (!handler->socket->parent) {
int_socket_delete(handler->socket); int_socket_delete(handler->socket);
return -1; return -1;
} }
*handler->socket->parent = *handler; *handler->socket->parent = *handler;
}else{ } else {
current->usage_counter++; current->usage_counter++;
handler->socket = current; handler->socket = current;
} }
return 0; return 0;
} }
int coap_connection_handler_send_data(coap_conn_handler_t *handler, ns_address_t *dest_addr, uint8_t *data_ptr, uint16_t data_len, bool bypass_link_sec) int coap_connection_handler_send_data(coap_conn_handler_t *handler, const ns_address_t *dest_addr, const uint8_t src_address[static 16], uint8_t *data_ptr, uint16_t data_len, bool bypass_link_sec)
{ {
if( !handler || !handler->socket || !dest_addr){ if (!handler || !handler->socket || !dest_addr) {
return -1; return -1;
} }
if(handler->socket->is_secure){ if (handler->socket->is_secure) {
handler->socket->bypass_link_sec = bypass_link_sec; handler->socket->bypass_link_sec = bypass_link_sec;
memcpy(handler->socket->dest_addr.address, dest_addr->address, 16); memcpy(handler->socket->dest_addr.address, dest_addr->address, 16);
handler->socket->dest_addr.identifier = dest_addr->identifier; handler->socket->dest_addr.identifier = dest_addr->identifier;
handler->socket->dest_addr.type = dest_addr->type; handler->socket->dest_addr.type = dest_addr->type;
secure_session_t *session = secure_session_find(handler->socket, dest_addr->address, dest_addr->identifier); secure_session_t *session = secure_session_find(handler->socket, dest_addr->address, dest_addr->identifier);
if( !session ){ if (!session) {
session = secure_session_create(handler->socket, dest_addr->address, dest_addr->identifier); session = secure_session_create(handler->socket, dest_addr->address, dest_addr->identifier);
if( !session ){ if (!session) {
return -1; return -1;
} }
session->last_contact_time = coap_service_get_internal_timer_ticks(); session->last_contact_time = coap_service_get_internal_timer_ticks();
@ -723,12 +808,12 @@ int coap_connection_handler_send_data(coap_conn_handler_t *handler, ns_address_t
handler->socket->dest_addr.identifier = dest_addr->identifier; handler->socket->dest_addr.identifier = dest_addr->identifier;
handler->socket->dest_addr.type = dest_addr->type; handler->socket->dest_addr.type = dest_addr->type;
uint8_t *pw = (uint8_t *)ns_dyn_mem_alloc(64); uint8_t *pw = (uint8_t *)ns_dyn_mem_alloc(64);
if(!pw){ if (!pw) {
//todo: free secure session? //todo: free secure session?
return -1; return -1;
} }
uint8_t pw_len; uint8_t pw_len;
if( handler->_get_password_cb && 0 == handler->_get_password_cb(handler->socket->listen_socket, dest_addr->address, dest_addr->identifier, pw, &pw_len)){ if (handler->_get_password_cb && 0 == handler->_get_password_cb(handler->socket->listen_socket, (uint8_t*)dest_addr->address, dest_addr->identifier, pw, &pw_len)) {
//TODO: get_password_cb should support certs and PSK also //TODO: get_password_cb should support certs and PSK also
coap_security_keys_t keys; coap_security_keys_t keys;
keys._priv = pw; keys._priv = pw;
@ -736,30 +821,32 @@ int coap_connection_handler_send_data(coap_conn_handler_t *handler, ns_address_t
coap_security_handler_connect_non_blocking(session->sec_handler, false, DTLS, keys, handler->socket->timeout_min, handler->socket->timeout_max); coap_security_handler_connect_non_blocking(session->sec_handler, false, DTLS, keys, handler->socket->timeout_min, handler->socket->timeout_max);
ns_dyn_mem_free(pw); ns_dyn_mem_free(pw);
return -2; return -2;
}else{ } else {
//free secure session? //free secure session?
ns_dyn_mem_free(pw); ns_dyn_mem_free(pw);
return -1; return -1;
} }
}else if( session->session_state == SECURE_SESSION_OK ){ } else if (session->session_state == SECURE_SESSION_OK) {
if( coap_security_handler_send_message(session->sec_handler, data_ptr, data_len ) > 0 ){ if (coap_security_handler_send_message(session->sec_handler, data_ptr, data_len ) > 0 ) {
session->last_contact_time = coap_service_get_internal_timer_ticks(); session->last_contact_time = coap_service_get_internal_timer_ticks();
return 0; return 0;
} }
} }
return -1; return -1;
}else{ }else{
if( !handler->socket->real_socket && handler->_send_cb){ if (!handler->socket->real_socket && handler->_send_cb) {
return handler->_send_cb((int8_t)handler->socket->listen_socket, dest_addr->address, dest_addr->identifier, data_ptr, data_len); return handler->_send_cb((int8_t)handler->socket->listen_socket, dest_addr->address, dest_addr->identifier, data_ptr, data_len);
} }
int opt_name = SOCKET_IPV6_PREFER_SRC_6LOWPAN_SHORT; int opt_name = SOCKET_IPV6_PREFER_SRC_6LOWPAN_SHORT;
int8_t securityLinkLayer = 1; int8_t securityLinkLayer = 1;
if( bypass_link_sec ){ if (bypass_link_sec) {
securityLinkLayer = 0; securityLinkLayer = 0;
} }
socket_setsockopt(handler->socket->listen_socket, SOCKET_IPPROTO_IPV6, SOCKET_IPV6_ADDR_PREFERENCES, &opt_name, sizeof(int)); socket_setsockopt(handler->socket->listen_socket, SOCKET_IPPROTO_IPV6, SOCKET_IPV6_ADDR_PREFERENCES, &opt_name, sizeof(int));
socket_setsockopt(handler->socket->listen_socket, SOCKET_IPPROTO_IPV6, SOCKET_LINK_LAYER_SECURITY, &securityLinkLayer, sizeof(int8_t)); socket_setsockopt(handler->socket->listen_socket, SOCKET_IPPROTO_IPV6, SOCKET_LINK_LAYER_SECURITY, &securityLinkLayer, sizeof(int8_t));
return socket_sendto(handler->socket->listen_socket, dest_addr, data_ptr, data_len);
return send_to_real_socket(handler->socket->listen_socket, dest_addr, src_address, data_ptr, data_len);
} }
} }

View File

@ -177,15 +177,15 @@ coap_transaction_t *coap_message_handler_find_transaction(uint8_t *address_ptr,
return transaction_find_by_address( address_ptr, port ); return transaction_find_by_address( address_ptr, port );
} }
int16_t coap_message_handler_coap_msg_process(coap_msg_handler_t *handle, int8_t socket_id, uint8_t source_addr_ptr[static 16], uint16_t port, int16_t coap_message_handler_coap_msg_process(coap_msg_handler_t *handle, int8_t socket_id, const uint8_t source_addr_ptr[static 16], uint16_t port, const uint8_t dst_addr_ptr[static 16],
uint8_t *data_ptr, uint16_t data_len, int16_t (cb)(int8_t, sn_coap_hdr_s *, coap_transaction_t *)) uint8_t *data_ptr, uint16_t data_len, int16_t (cb)(int8_t, sn_coap_hdr_s *, coap_transaction_t *))
{ {
if( !cb || !handle ){ if (!cb || !handle) {
return -1; return -1;
} }
sn_nsdl_addr_s src_addr; sn_nsdl_addr_s src_addr;
sn_coap_hdr_s *coap_message; sn_coap_hdr_s *coap_message;
src_addr.addr_ptr = source_addr_ptr; src_addr.addr_ptr = (uint8_t *)source_addr_ptr;
src_addr.addr_len = 16; src_addr.addr_len = 16;
src_addr.type = SN_NSDL_ADDRESS_TYPE_IPV6; src_addr.type = SN_NSDL_ADDRESS_TYPE_IPV6;
src_addr.port = port; src_addr.port = port;
@ -209,6 +209,7 @@ int16_t coap_message_handler_coap_msg_process(coap_msg_handler_t *handle, int8_t
transaction_ptr->service_id = coap_service_id_find_by_socket(socket_id); transaction_ptr->service_id = coap_service_id_find_by_socket(socket_id);
transaction_ptr->msg_id = coap_message->msg_id; transaction_ptr->msg_id = coap_message->msg_id;
transaction_ptr->client_request = false;// this is server transaction transaction_ptr->client_request = false;// this is server transaction
memcpy(transaction_ptr->local_address, dst_addr_ptr, 16);
memcpy(transaction_ptr->remote_address, source_addr_ptr, 16); memcpy(transaction_ptr->remote_address, source_addr_ptr, 16);
transaction_ptr->remote_port = port; transaction_ptr->remote_port = port;
@ -219,13 +220,13 @@ int16_t coap_message_handler_coap_msg_process(coap_msg_handler_t *handle, int8_t
transaction_delete(transaction_ptr); transaction_delete(transaction_ptr);
return -1; return -1;
} }
}else{ } else {
//TODO: handle error case //TODO: handle error case
} }
/* Response received */ /* Response received */
} else { } else {
coap_transaction_t *this = NULL; coap_transaction_t *this = NULL;
if( coap_message->token_ptr ){ if (coap_message->token_ptr) {
this = transaction_find_client_by_token(coap_message->token_ptr); this = transaction_find_client_by_token(coap_message->token_ptr);
} }
if (!this) { if (!this) {
@ -235,7 +236,7 @@ int16_t coap_message_handler_coap_msg_process(coap_msg_handler_t *handle, int8_t
} }
tr_debug("Service %d, response received", this->service_id); tr_debug("Service %d, response received", this->service_id);
if (this->resp_cb) { if (this->resp_cb) {
this->resp_cb(this->service_id, source_addr_ptr, port, coap_message); this->resp_cb(this->service_id, (uint8_t *)source_addr_ptr, port, coap_message);
} }
sn_coap_parser_release_allocated_coap_msg_mem(handle->coap, coap_message); sn_coap_parser_release_allocated_coap_msg_mem(handle->coap, coap_message);
transaction_delete(this); transaction_delete(this);

View File

@ -18,6 +18,7 @@
#include "coap_security_handler.h" #include "coap_security_handler.h"
#include "randLIB.h" #include "randLIB.h"
#include "mbedtls/ssl_ciphersuites.h" #include "mbedtls/ssl_ciphersuites.h"
#include "socket_api.h"
#if defined(MBEDTLS_KEY_EXCHANGE_ECJPAKE_ENABLED) #if defined(MBEDTLS_KEY_EXCHANGE_ECJPAKE_ENABLED)
const int ECJPAKE_SUITES[] = { const int ECJPAKE_SUITES[] = {
@ -92,13 +93,13 @@ static void coap_security_handler_reset(coap_security_t *sec){
} }
coap_security_t *coap_security_create(int8_t socket_id, int8_t timer_id, uint8_t *address_ptr, uint16_t port, SecureConnectionMode mode, coap_security_t *coap_security_create(int8_t socket_id, int8_t timer_id, const uint8_t *address_ptr, uint16_t port, SecureConnectionMode mode,
send_cb *send_cb, send_cb *socket_cb,
receive_cb *receive_cb, receive_cb *receive_data_cb,
start_timer_cb *start_timer_cb, start_timer_cb *timer_start_cb,
timer_status_cb *timer_status_cb) timer_status_cb *timer_stat_cb)
{ {
if( !address_ptr || send_cb == NULL || receive_cb == NULL || start_timer_cb == NULL || timer_status_cb == NULL){ if (!address_ptr || socket_cb == NULL || receive_data_cb == NULL || timer_start_cb == NULL || timer_stat_cb == NULL) {
return NULL; return NULL;
} }
coap_security_t *this = ns_dyn_mem_alloc(sizeof(coap_security_t)); coap_security_t *this = ns_dyn_mem_alloc(sizeof(coap_security_t));
@ -106,7 +107,7 @@ coap_security_t *coap_security_create(int8_t socket_id, int8_t timer_id, uint8_t
return NULL; return NULL;
} }
memset(this, 0, sizeof(coap_security_t)); memset(this, 0, sizeof(coap_security_t));
if( -1 == coap_security_handler_init(this) ){ if (-1 == coap_security_handler_init(this)) {
ns_dyn_mem_free(this); ns_dyn_mem_free(this);
return NULL; return NULL;
} }
@ -117,10 +118,10 @@ coap_security_t *coap_security_create(int8_t socket_id, int8_t timer_id, uint8_t
this->_pw_len = 0; this->_pw_len = 0;
this->_socket_id = socket_id; this->_socket_id = socket_id;
this->_timer_id = timer_id; this->_timer_id = timer_id;
this->_send_cb = send_cb; this->_send_cb = socket_cb;
this->_receive_cb = receive_cb; this->_receive_cb = receive_data_cb;
this->_start_timer_cb = start_timer_cb; this->_start_timer_cb = timer_start_cb;
this->_timer_status_cb = timer_status_cb; this->_timer_status_cb = timer_stat_cb;
return this; return this;
} }
@ -551,7 +552,7 @@ static int get_timer(void *sec_obj)
int f_send( void *ctx, const unsigned char *buf, size_t len){ int f_send( void *ctx, const unsigned char *buf, size_t len){
coap_security_t *sec = (coap_security_t *)ctx; coap_security_t *sec = (coap_security_t *)ctx;
return sec->_send_cb(sec->_socket_id, sec->_remote_address, sec->_remote_port, buf, len); return sec->_send_cb(sec->_socket_id, sec->_remote_address, sec->_remote_port, ns_in6addr_any, buf, len);
} }
int f_recv(void *ctx, unsigned char *buf, size_t len){ int f_recv(void *ctx, unsigned char *buf, size_t len){

View File

@ -23,7 +23,6 @@
#include "coap_service_api_internal.h" #include "coap_service_api_internal.h"
#include "coap_message_handler.h" #include "coap_message_handler.h"
static int16_t coap_service_coap_msg_process(int8_t socket_id, uint8_t source_addr_ptr[static 16], uint16_t port, uint8_t *data_ptr, uint16_t data_len);
static int16_t coap_msg_process_callback(int8_t socket_id, sn_coap_hdr_s *coap_message, coap_transaction_t *transaction_ptr); static int16_t coap_msg_process_callback(int8_t socket_id, sn_coap_hdr_s *coap_message, coap_transaction_t *transaction_ptr);
typedef struct uri_registration { typedef struct uri_registration {
@ -142,7 +141,8 @@ static uint8_t coap_tx_function(uint8_t *data_ptr, uint16_t data_len, sn_nsdl_ad
dest_addr.identifier = address_ptr->port; dest_addr.identifier = address_ptr->port;
dest_addr.type = ADDRESS_IPV6; dest_addr.type = ADDRESS_IPV6;
if( -2 == coap_connection_handler_send_data(this->conn_handler, &dest_addr, data_ptr, data_len, (this->service_options & COAP_SERVICE_OPTIONS_SECURE_BYPASS) == COAP_SERVICE_OPTIONS_SECURE_BYPASS) ){ if (-2 == coap_connection_handler_send_data(this->conn_handler, &dest_addr, transaction_ptr->local_address,
data_ptr, data_len, (this->service_options & COAP_SERVICE_OPTIONS_SECURE_BYPASS) == COAP_SERVICE_OPTIONS_SECURE_BYPASS)) {
transaction_ptr->data_ptr = ns_dyn_mem_alloc(data_len); transaction_ptr->data_ptr = ns_dyn_mem_alloc(data_len);
if (!transaction_ptr->data_ptr) { if (!transaction_ptr->data_ptr) {
tr_debug("coap tx out of memory"); tr_debug("coap tx out of memory");
@ -151,7 +151,7 @@ static uint8_t coap_tx_function(uint8_t *data_ptr, uint16_t data_len, sn_nsdl_ad
} }
memcpy(transaction_ptr->data_ptr, data_ptr, data_len); memcpy(transaction_ptr->data_ptr, data_ptr, data_len);
transaction_ptr->data_len = data_len; transaction_ptr->data_len = data_len;
} else if (transaction_ptr->resp_cb == NULL ){ } else if (transaction_ptr->resp_cb == NULL ) {
transaction_delete(transaction_ptr); transaction_delete(transaction_ptr);
} }
@ -207,19 +207,18 @@ static int16_t coap_msg_process_callback(int8_t socket_id, sn_coap_hdr_s *coap_m
return -1; return -1;
} }
static int16_t coap_service_coap_msg_process(int8_t socket_id, uint8_t source_addr_ptr[static 16], uint16_t port, uint8_t *data_ptr, uint16_t data_len) static int recv_cb(int8_t socket_id, uint8_t src_address[static 16], uint16_t port, const uint8_t dst_address[static 16], unsigned char *data, int len)
{
return coap_message_handler_coap_msg_process( coap_service_handle, socket_id, source_addr_ptr, port, data_ptr, data_len, &coap_msg_process_callback);
}
static int recv_cb(int8_t socket_id, uint8_t address[static 16], uint16_t port, unsigned char *data, int len)
{ {
uint8_t *data_ptr = NULL; uint8_t *data_ptr = NULL;
uint16_t data_len = 0; uint16_t data_len = 0;
if (!data || !len) {
return -1;
}
data_ptr = own_alloc(len); data_ptr = own_alloc(len);
if (!data_ptr || len < 1) { if (!data_ptr) {
return -1; return -1;
} }
memcpy(data_ptr, data, len); memcpy(data_ptr, data, len);
@ -227,17 +226,17 @@ static int recv_cb(int8_t socket_id, uint8_t address[static 16], uint16_t port,
tr_debug("service recv socket data len %d ", data_len); tr_debug("service recv socket data len %d ", data_len);
//parse coap message what CoAP to use //parse coap message what CoAP to use
int ret = coap_service_coap_msg_process(socket_id, address, port, data_ptr, data_len); int ret = coap_message_handler_coap_msg_process(coap_service_handle, socket_id, src_address, port, dst_address, data_ptr, data_len, &coap_msg_process_callback);
own_free(data_ptr); own_free(data_ptr);
return ret; return ret;
} }
static int send_cb(int8_t socket_id, uint8_t address[static 16], uint16_t port, const unsigned char *data_ptr, int data_len) static int send_cb(int8_t socket_id, const uint8_t address[static 16], uint16_t port, const void *data_ptr, int data_len)
{ {
coap_service_t *this = service_find_by_socket(socket_id); coap_service_t *this = service_find_by_socket(socket_id);
if (this && this->virtual_socket_send_cb) { if (this && this->virtual_socket_send_cb) {
tr_debug("send to virtual socket"); tr_debug("send to virtual socket");
return this->virtual_socket_send_cb(this->service_id, address, port, data_ptr, data_len); return this->virtual_socket_send_cb(this->service_id, (uint8_t*)address, port, data_ptr, data_len);
} }
return -1; return -1;
} }
@ -259,7 +258,8 @@ static void sec_done_cb(int8_t socket_id, uint8_t address[static 16], uint16_t p
dest_addr.identifier = port; dest_addr.identifier = port;
dest_addr.type = ADDRESS_IPV6; dest_addr.type = ADDRESS_IPV6;
coap_connection_handler_send_data(this->conn_handler, &dest_addr, transaction_ptr->data_ptr, transaction_ptr->data_len, (this->service_options & COAP_SERVICE_OPTIONS_SECURE_BYPASS) == COAP_SERVICE_OPTIONS_SECURE_BYPASS); coap_connection_handler_send_data(this->conn_handler, &dest_addr, transaction_ptr->local_address,
transaction_ptr->data_ptr, transaction_ptr->data_len, (this->service_options & COAP_SERVICE_OPTIONS_SECURE_BYPASS) == COAP_SERVICE_OPTIONS_SECURE_BYPASS);
ns_dyn_mem_free(transaction_ptr->data_ptr); ns_dyn_mem_free(transaction_ptr->data_ptr);
transaction_ptr->data_ptr = NULL; transaction_ptr->data_ptr = NULL;
transaction_ptr->data_len = 0; transaction_ptr->data_len = 0;

View File

@ -32,8 +32,8 @@
struct internal_socket_s; struct internal_socket_s;
typedef int send_to_socket_cb(int8_t socket_id, uint8_t address[static 16], uint16_t port, const unsigned char *, int); typedef int send_to_socket_cb(int8_t socket_id, const uint8_t address[static 16], uint16_t port, const void *, int);
typedef int receive_from_socket_cb(int8_t socket_id, uint8_t address[static 16], uint16_t port, unsigned char *, int); typedef int receive_from_socket_cb(int8_t socket_id, uint8_t src_address[static 16], uint16_t port, const uint8_t dst_address[static 16], unsigned char *, int);
typedef int get_pw_cb(int8_t socket_id, uint8_t address[static 16], uint16_t port, uint8_t *pw_ptr, uint8_t *pw_len); typedef int get_pw_cb(int8_t socket_id, uint8_t address[static 16], uint16_t port, uint8_t *pw_ptr, uint8_t *pw_len);
typedef void security_done_cb(int8_t socket_id, uint8_t address[static 16], uint16_t port, uint8_t keyblock[static 40]); typedef void security_done_cb(int8_t socket_id, uint8_t address[static 16], uint16_t port, uint8_t keyblock[static 40]);
@ -58,7 +58,7 @@ void connection_handler_close_secure_connection( coap_conn_handler_t *handler, u
int coap_connection_handler_open_connection(coap_conn_handler_t *handler, uint16_t listen_port, bool use_ephemeral_port, bool is_secure, bool real_socket, bool bypassSec); int coap_connection_handler_open_connection(coap_conn_handler_t *handler, uint16_t listen_port, bool use_ephemeral_port, bool is_secure, bool real_socket, bool bypassSec);
//If returns -2, it means security was started and data was not send //If returns -2, it means security was started and data was not send
int coap_connection_handler_send_data(coap_conn_handler_t *handler, ns_address_t *dest_addr, uint8_t *data_ptr, uint16_t data_len, bool bypass_link_sec); int coap_connection_handler_send_data(coap_conn_handler_t *handler, const ns_address_t *dest_addr, const uint8_t src_address[static 16], uint8_t *data_ptr, uint16_t data_len, bool bypass_link_sec);
int coap_connection_handler_virtual_recv(coap_conn_handler_t *handler, uint8_t address[static 16], uint16_t port, uint8_t *data_ptr, uint16_t data_len); int coap_connection_handler_virtual_recv(coap_conn_handler_t *handler, uint8_t address[static 16], uint16_t port, uint8_t *data_ptr, uint16_t data_len);

View File

@ -49,6 +49,7 @@ typedef struct coap_msg_handler_s {
typedef struct coap_transaction { typedef struct coap_transaction {
uint8_t remote_address[16]; uint8_t remote_address[16];
uint8_t local_address[16];
uint8_t token[4]; uint8_t token[4];
uint32_t create_time; uint32_t create_time;
uint16_t remote_port; uint16_t remote_port;
@ -73,7 +74,7 @@ extern coap_transaction_t *coap_message_handler_transaction_valid(coap_transacti
extern coap_transaction_t *coap_message_handler_find_transaction(uint8_t *address_ptr, uint16_t port); extern coap_transaction_t *coap_message_handler_find_transaction(uint8_t *address_ptr, uint16_t port);
extern int16_t coap_message_handler_coap_msg_process(coap_msg_handler_t *handle, int8_t socket_id, uint8_t source_addr_ptr[static 16], uint16_t port, extern int16_t coap_message_handler_coap_msg_process(coap_msg_handler_t *handle, int8_t socket_id, const uint8_t source_addr_ptr[static 16], uint16_t port, const uint8_t dst_addr_ptr[static 16],
uint8_t *data_ptr, uint16_t data_len, int16_t (cb)(int8_t, sn_coap_hdr_s *, coap_transaction_t *)); uint8_t *data_ptr, uint16_t data_len, int16_t (cb)(int8_t, sn_coap_hdr_s *, coap_transaction_t *));
extern uint16_t coap_message_handler_request_send(coap_msg_handler_t *handle, int8_t service_id, uint8_t options, const uint8_t destination_addr[static 16], extern uint16_t coap_message_handler_request_send(coap_msg_handler_t *handle, int8_t service_id, uint8_t options, const uint8_t destination_addr[static 16],

View File

@ -38,7 +38,7 @@ typedef struct key_block {
unsigned char value[KEY_BLOCK_LEN]; unsigned char value[KEY_BLOCK_LEN];
} key_block_t; } key_block_t;
typedef int send_cb(int8_t socket_id, uint8_t *address_ptr, uint16_t port, const unsigned char *, size_t); typedef int send_cb(int8_t socket_id, const uint8_t *address_ptr, uint16_t port, const uint8_t source_addr[static 16], const void *, size_t);
typedef int receive_cb(int8_t socket_id, unsigned char *, size_t); typedef int receive_cb(int8_t socket_id, unsigned char *, size_t);
typedef void start_timer_cb(int8_t timer_id, uint32_t min, uint32_t fin); typedef void start_timer_cb(int8_t timer_id, uint32_t min, uint32_t fin);
typedef int timer_status_cb(int8_t timer_id); typedef int timer_status_cb(int8_t timer_id);
@ -99,7 +99,7 @@ typedef struct coap_security_s {
} coap_security_t; } coap_security_t;
coap_security_t *coap_security_create(int8_t socket_id, int8_t timer_id, uint8_t *address_ptr, uint16_t port, coap_security_t *coap_security_create(int8_t socket_id, int8_t timer_id, const uint8_t *address_ptr, uint16_t port,
SecureConnectionMode mode, SecureConnectionMode mode,
send_cb *send_cb, send_cb *send_cb,
receive_cb *receive_cb, receive_cb *receive_cb,

View File

@ -105,7 +105,7 @@ bool test_coap_connection_handler_open_connection()
bool test_coap_connection_handler_send_data() bool test_coap_connection_handler_send_data()
{ {
coap_security_handler_stub.counter = -1; coap_security_handler_stub.counter = -1;
if( -1 != coap_connection_handler_send_data(NULL, NULL, NULL, 0, false)) if( -1 != coap_connection_handler_send_data(NULL, NULL, ns_in6addr_any, NULL, 0, false))
return false; return false;
ns_address_t addr; ns_address_t addr;
@ -118,7 +118,7 @@ bool test_coap_connection_handler_send_data()
if( 0 != coap_connection_handler_open_connection(handler, 22,false,true,false,false) ) if( 0 != coap_connection_handler_open_connection(handler, 22,false,true,false,false) )
return false; return false;
if( -1 != coap_connection_handler_send_data(handler, &addr, NULL, 0, true)) if( -1 != coap_connection_handler_send_data(handler, &addr, ns_in6addr_any, NULL, 0, true))
return false; return false;
connection_handler_destroy(handler); connection_handler_destroy(handler);
@ -134,10 +134,10 @@ bool test_coap_connection_handler_send_data()
if( 0 != coap_connection_handler_open_connection(handler, 22,false,true,false,false) ) if( 0 != coap_connection_handler_open_connection(handler, 22,false,true,false,false) )
return false; return false;
if( -1 != coap_connection_handler_send_data(handler, &addr, NULL, 0, true)) if( -1 != coap_connection_handler_send_data(handler, &addr, ns_in6addr_any, NULL, 0, true))
return false; return false;
if( -1 != coap_connection_handler_send_data(handler, &addr, NULL, 0, true)) if( -1 != coap_connection_handler_send_data(handler, &addr, ns_in6addr_any, NULL, 0, true))
return false; return false;
connection_handler_destroy(handler); connection_handler_destroy(handler);
@ -153,7 +153,7 @@ bool test_coap_connection_handler_send_data()
return false; return false;
if( 1 != coap_connection_handler_send_data(handler, &addr, NULL, 0, true)) if( 1 != coap_connection_handler_send_data(handler, &addr, ns_in6addr_any, NULL, 0, true))
return false; return false;
connection_handler_destroy(handler); connection_handler_destroy(handler);
@ -164,7 +164,7 @@ bool test_coap_connection_handler_send_data()
return false; return false;
socket_api_stub.int8_value = 7; socket_api_stub.int8_value = 7;
if( 7 != coap_connection_handler_send_data(handler, &addr, NULL, 0, true)) if( 7 != coap_connection_handler_send_data(handler, &addr, ns_in6addr_any, NULL, 0, true))
return false; return false;
connection_handler_destroy(handler); connection_handler_destroy(handler);

View File

@ -17,7 +17,8 @@ TEST_SRC_FILES = \
../stub/nsdynmemLIB_stub.c \ ../stub/nsdynmemLIB_stub.c \
../stub/ns_list_stub.c \ ../stub/ns_list_stub.c \
../stub/randLIB_stub.c \ ../stub/randLIB_stub.c \
../stub/coap_service_api_stub.c ../stub/coap_service_api_stub.c \
../stub/socket_api_stub.c \
include ../MakefileWorker.mk include ../MakefileWorker.mk

View File

@ -8,6 +8,7 @@
#include "nsdynmemLIB_stub.h" #include "nsdynmemLIB_stub.h"
#include "sn_coap_builder_stub.h" #include "sn_coap_builder_stub.h"
#include "sn_coap_parser_stub.h" #include "sn_coap_parser_stub.h"
#include "socket_api.h"
int retCounter = 0; int retCounter = 0;
int retValue = 0; int retValue = 0;
@ -118,7 +119,7 @@ bool test_coap_message_handler_coap_msg_process()
{ {
uint8_t buf[16]; uint8_t buf[16];
memset(&buf, 1, 16); memset(&buf, 1, 16);
if( -1 != coap_message_handler_coap_msg_process(NULL, 0, buf, 22, NULL, 0, NULL)) if( -1 != coap_message_handler_coap_msg_process(NULL, 0, buf, 22, ns_in6addr_any, NULL, 0, NULL))
return false; return false;
retCounter = 1; retCounter = 1;
@ -127,13 +128,13 @@ bool test_coap_message_handler_coap_msg_process()
coap_msg_handler_t *handle = coap_message_handler_init(&own_alloc, &own_free, &coap_tx_function); coap_msg_handler_t *handle = coap_message_handler_init(&own_alloc, &own_free, &coap_tx_function);
sn_coap_protocol_stub.expectedHeader = NULL; sn_coap_protocol_stub.expectedHeader = NULL;
if( -1 != coap_message_handler_coap_msg_process(handle, 0, buf, 22, NULL, 0, process_cb)) if( -1 != coap_message_handler_coap_msg_process(handle, 0, buf, 22, ns_in6addr_any, NULL, 0, process_cb))
return false; return false;
sn_coap_protocol_stub.expectedHeader = (sn_coap_hdr_s *)malloc(sizeof(sn_coap_hdr_s)); sn_coap_protocol_stub.expectedHeader = (sn_coap_hdr_s *)malloc(sizeof(sn_coap_hdr_s));
memset(sn_coap_protocol_stub.expectedHeader, 0, sizeof(sn_coap_hdr_s)); memset(sn_coap_protocol_stub.expectedHeader, 0, sizeof(sn_coap_hdr_s));
sn_coap_protocol_stub.expectedHeader->coap_status = 66; sn_coap_protocol_stub.expectedHeader->coap_status = 66;
if( -1 != coap_message_handler_coap_msg_process(handle, 0, buf, 22, NULL, 0, process_cb)) if( -1 != coap_message_handler_coap_msg_process(handle, 0, buf, 22, ns_in6addr_any, NULL, 0, process_cb))
return false; return false;
sn_coap_protocol_stub.expectedHeader = (sn_coap_hdr_s *)malloc(sizeof(sn_coap_hdr_s)); sn_coap_protocol_stub.expectedHeader = (sn_coap_hdr_s *)malloc(sizeof(sn_coap_hdr_s));
@ -141,12 +142,12 @@ bool test_coap_message_handler_coap_msg_process()
sn_coap_protocol_stub.expectedHeader->coap_status = COAP_STATUS_OK; sn_coap_protocol_stub.expectedHeader->coap_status = COAP_STATUS_OK;
sn_coap_protocol_stub.expectedHeader->msg_code = 1; sn_coap_protocol_stub.expectedHeader->msg_code = 1;
retValue = 0; retValue = 0;
if( 0 != coap_message_handler_coap_msg_process(handle, 0, buf, 22, NULL, 0, process_cb)) if( 0 != coap_message_handler_coap_msg_process(handle, 0, buf, 22, ns_in6addr_any, NULL, 0, process_cb))
return false; return false;
nsdynmemlib_stub.returnCounter = 1; nsdynmemlib_stub.returnCounter = 1;
retValue = -1; retValue = -1;
if( -1 != coap_message_handler_coap_msg_process(handle, 0, buf, 22, NULL, 0, process_cb)) if( -1 != coap_message_handler_coap_msg_process(handle, 0, buf, 22, ns_in6addr_any, NULL, 0, process_cb))
return false; return false;
sn_coap_protocol_stub.expectedHeader = (sn_coap_hdr_s *)malloc(sizeof(sn_coap_hdr_s)); sn_coap_protocol_stub.expectedHeader = (sn_coap_hdr_s *)malloc(sizeof(sn_coap_hdr_s));
@ -154,7 +155,7 @@ bool test_coap_message_handler_coap_msg_process()
sn_coap_protocol_stub.expectedHeader->coap_status = COAP_STATUS_OK; sn_coap_protocol_stub.expectedHeader->coap_status = COAP_STATUS_OK;
sn_coap_protocol_stub.expectedHeader->msg_code = 333; sn_coap_protocol_stub.expectedHeader->msg_code = 333;
if( -1 != coap_message_handler_coap_msg_process(handle, 0, buf, 22, NULL, 0, process_cb)) if( -1 != coap_message_handler_coap_msg_process(handle, 0, buf, 22, ns_in6addr_any, NULL, 0, process_cb))
return false; return false;
sn_coap_protocol_stub.expectedHeader = (sn_coap_hdr_s *)malloc(sizeof(sn_coap_hdr_s)); sn_coap_protocol_stub.expectedHeader = (sn_coap_hdr_s *)malloc(sizeof(sn_coap_hdr_s));
@ -175,7 +176,7 @@ bool test_coap_message_handler_coap_msg_process()
sn_coap_protocol_stub.expectedHeader->msg_id = 2; sn_coap_protocol_stub.expectedHeader->msg_id = 2;
// sn_coap_protocol_stub.expectedHeader->token_ptr = (uint8_t*)malloc(4); // sn_coap_protocol_stub.expectedHeader->token_ptr = (uint8_t*)malloc(4);
// memset(sn_coap_protocol_stub.expectedHeader->token_ptr, 1, 4); // memset(sn_coap_protocol_stub.expectedHeader->token_ptr, 1, 4);
if( -1 != coap_message_handler_coap_msg_process(handle, 0, buf, 22, NULL, 0, process_cb)) if( -1 != coap_message_handler_coap_msg_process(handle, 0, buf, 22, ns_in6addr_any, NULL, 0, process_cb))
return false; return false;
// free(sn_coap_protocol_stub.expectedHeader->token_ptr); // free(sn_coap_protocol_stub.expectedHeader->token_ptr);

View File

@ -16,6 +16,7 @@ TEST_SRC_FILES = \
../stub/mbedtls_stub.c \ ../stub/mbedtls_stub.c \
../stub/randLIB_stub.c \ ../stub/randLIB_stub.c \
../stub/nsdynmemLIB_stub.c \ ../stub/nsdynmemLIB_stub.c \
../stub/socket_api_stub.c \
include ../MakefileWorker.mk include ../MakefileWorker.mk

View File

@ -330,14 +330,14 @@ bool test_conn_handler_callbacks()
if( thread_conn_handler_stub.receive_from_sock_cb ){ if( thread_conn_handler_stub.receive_from_sock_cb ){
coap_message_handler_stub.int16_value = 2; coap_message_handler_stub.int16_value = 2;
if( -1 != thread_conn_handler_stub.receive_from_sock_cb(1, buf, 12, NULL, 0)) if( -1 != thread_conn_handler_stub.receive_from_sock_cb(1, buf, 12, NULL, NULL, 0))
return false; return false;
nsdynmemlib_stub.returnCounter = 1; nsdynmemlib_stub.returnCounter = 1;
uint8_t * ptr = ns_dyn_mem_alloc(5); uint8_t * ptr = ns_dyn_mem_alloc(5);
memset(ptr, 3, 5); memset(ptr, 3, 5);
nsdynmemlib_stub.returnCounter = 1; nsdynmemlib_stub.returnCounter = 1;
if( 2 != thread_conn_handler_stub.receive_from_sock_cb(1, buf, 12, ptr, 5)) if( 2 != thread_conn_handler_stub.receive_from_sock_cb(1, buf, 12, NULL, ptr, 5))
return false; return false;
ns_dyn_mem_free(ptr); ns_dyn_mem_free(ptr);
coap_message_handler_stub.int16_value = 0; coap_message_handler_stub.int16_value = 0;

View File

@ -20,8 +20,8 @@ int coap_connection_handler_virtual_recv(coap_conn_handler_t *handler, uint8_t a
return thread_conn_handler_stub.int_value; return thread_conn_handler_stub.int_value;
} }
coap_conn_handler_t *connection_handler_create(int (*recv_cb)(int8_t socket_id, uint8_t address[static 16], uint16_t port, unsigned char *, int), coap_conn_handler_t *connection_handler_create(int (*recv_cb)(int8_t socket_id, uint8_t src_address[static 16], uint16_t port, const uint8_t dst_address[static 16], unsigned char *, int),
int (*send_cb)(int8_t socket_id, uint8_t address[static 16], uint16_t port, const unsigned char *, int), int (*send_cb)(int8_t socket_id, uint8_t const address[static 16], uint16_t port, const void *, int),
int (*pw_cb)(int8_t socket_id, uint8_t address[static 16], uint16_t port, uint8_t *pw_ptr, uint8_t *pw_len), int (*pw_cb)(int8_t socket_id, uint8_t address[static 16], uint16_t port, uint8_t *pw_ptr, uint8_t *pw_len),
void(*done_cb)(int8_t socket_id, uint8_t address[static 16], uint16_t port, uint8_t keyblock[static KEY_BLOCK_LEN]) ) void(*done_cb)(int8_t socket_id, uint8_t address[static 16], uint16_t port, uint8_t keyblock[static KEY_BLOCK_LEN]) )
{ {
@ -46,7 +46,7 @@ int coap_connection_handler_open_connection(coap_conn_handler_t *handler, uint16
return thread_conn_handler_stub.int_value; return thread_conn_handler_stub.int_value;
} }
int coap_connection_handler_send_data(coap_conn_handler_t *handler, ns_address_t *dest_addr, uint8_t *data_ptr, uint16_t data_len, bool bypass_link_sec) int coap_connection_handler_send_data(coap_conn_handler_t *handler, const ns_address_t *dest_addr, const uint8_t dst_address[static 16], uint8_t *data_ptr, uint16_t data_len, bool bypass_link_sec)
{ {
return thread_conn_handler_stub.int_value; return thread_conn_handler_stub.int_value;
} }

View File

@ -32,8 +32,8 @@ typedef struct {
bool bool_value; bool bool_value;
coap_conn_handler_t *handler_obj; coap_conn_handler_t *handler_obj;
int (*send_to_sock_cb)(int8_t socket_id, uint8_t address[static 16], uint16_t port, const unsigned char *, int); int (*send_to_sock_cb)(int8_t socket_id, uint8_t address[static 16], uint16_t port, const void *, int);
int (*receive_from_sock_cb)(int8_t socket_id, uint8_t address[static 16], uint16_t port, unsigned char *, int); int (*receive_from_sock_cb)(int8_t socket_id, uint8_t src_address[static 16], uint16_t port, const uint8_t dst_address[static 16], unsigned char *data, int len);
int (*get_passwd_cb)(int8_t socket_id, uint8_t address[static 16], uint16_t port, uint8_t *pw_ptr, uint8_t *pw_len); int (*get_passwd_cb)(int8_t socket_id, uint8_t address[static 16], uint16_t port, uint8_t *pw_ptr, uint8_t *pw_len);
void (*sec_done_cb)(int8_t socket_id, uint8_t address[static 16], uint16_t port, uint8_t keyblock[static 40]); void (*sec_done_cb)(int8_t socket_id, uint8_t address[static 16], uint16_t port, uint8_t keyblock[static 40]);

View File

@ -37,7 +37,7 @@ coap_transaction_t *coap_message_handler_find_transaction(uint8_t *address_ptr,
return coap_message_handler_stub.coap_tx_ptr; return coap_message_handler_stub.coap_tx_ptr;
} }
int16_t coap_message_handler_coap_msg_process(coap_msg_handler_t *handle, int8_t socket_id, uint8_t source_addr_ptr[static 16], uint16_t port, int16_t coap_message_handler_coap_msg_process(coap_msg_handler_t *handle, int8_t socket_id, const uint8_t source_addr_ptr[static 16], uint16_t port, const uint8_t dst_addr_ptr[static 16],
uint8_t *data_ptr, uint16_t data_len, int16_t (cb)(int8_t, sn_coap_hdr_s *, coap_transaction_t *)) uint8_t *data_ptr, uint16_t data_len, int16_t (cb)(int8_t, sn_coap_hdr_s *, coap_transaction_t *))
{ {
coap_message_handler_stub.cb = cb; coap_message_handler_stub.cb = cb;

View File

@ -12,8 +12,9 @@
thread_sec_def coap_security_handler_stub; thread_sec_def coap_security_handler_stub;
coap_security_t *coap_security_create(int8_t socket_id, int8_t timer_id, uint8_t *address_ptr, uint16_t port, SecureConnectionMode mode, coap_security_t *coap_security_create(int8_t socket_id, int8_t timer_id, const uint8_t *address_ptr, uint16_t port,
int (*send_cb)(int8_t socket_id, uint8_t *address_ptr, uint16_t port, const unsigned char *, size_t), SecureConnectionMode mode,
int (*send_cb)(int8_t socket_id, const uint8_t *address_ptr, uint16_t port, const uint8_t source_addr[static 16], const void *, size_t),
int (*receive_cb)(int8_t socket_id, unsigned char *, size_t), int (*receive_cb)(int8_t socket_id, unsigned char *, size_t),
void (*start_timer_cb)(int8_t timer_id, uint32_t min, uint32_t fin), void (*start_timer_cb)(int8_t timer_id, uint32_t min, uint32_t fin),
int (*timer_status_cb)(int8_t timer_id)) int (*timer_status_cb)(int8_t timer_id))

View File

@ -27,7 +27,7 @@ typedef struct tsh{
int counter; int counter;
int values[10]; int values[10];
int (*send_cb)(int8_t socket_id, uint8_t *address_ptr, uint16_t port, const unsigned char *, size_t); int (*send_cb)(int8_t socket_id, const uint8_t *address_ptr, uint16_t port, const void *, size_t);
int (*receive_cb)(int8_t socket_id, unsigned char *, size_t); int (*receive_cb)(int8_t socket_id, unsigned char *, size_t);
void (*start_timer_cb)(int8_t timer_id, uint32_t min, uint32_t fin); void (*start_timer_cb)(int8_t timer_id, uint32_t min, uint32_t fin);
int (*timer_status_cb)(int8_t timer_id); int (*timer_status_cb)(int8_t timer_id);

View File

@ -33,12 +33,12 @@ uint32_t randLIB_get_32bit(void)
return 0; return 0;
} }
int8_t randLIB_get_n_bytes_random(uint8_t *data_ptr, uint8_t eight_bit_boundary) void *randLIB_get_n_bytes_random(void *data_ptr, uint8_t count)
{ {
if(data_ptr && eight_bit_boundary > 0){ if(data_ptr && count > 0){
data_ptr[0] = counter++%255; *((int*)data_ptr) = counter++%255;
} }
return 0; return data_ptr;
} }
uint16_t randLIB_get_random_in_range(uint16_t min, uint16_t max) uint16_t randLIB_get_random_in_range(uint16_t min, uint16_t max)

View File

@ -5,6 +5,7 @@
#include "socket_api_stub.h" #include "socket_api_stub.h"
socket_api_stub_data_t socket_api_stub; socket_api_stub_data_t socket_api_stub;
const uint8_t ns_in6addr_any[16] = {0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0};
int8_t socket_raw_open(void (*passed_fptr)(void *)) int8_t socket_raw_open(void (*passed_fptr)(void *))
{ {
@ -116,3 +117,22 @@ int8_t socket_getsockopt(int8_t socket, uint8_t level, uint8_t opt_name, void *o
return socket_api_stub.int8_value; return socket_api_stub.int8_value;
} }
int8_t socket_sendmsg(int8_t socket, const ns_msghdr_t *msg, int flags)
{
if( socket_api_stub.counter >= 0){
return socket_api_stub.values[socket_api_stub.counter--];
}
return socket_api_stub.int8_value;
}
int16_t socket_recvmsg(int8_t socket, ns_msghdr_t *msg, int flags)
{
return -1;
}
ns_cmsghdr_t *NS_CMSG_NXTHDR(const ns_msghdr_t *msgh, const ns_cmsghdr_t *cmsg)
{
return NULL;
}