Skip to content

Commit 53382d6

Browse files
author
Arto Kinnunen
authored
Merge pull request ARMmbed#116 from ARMmbed/IOTTHD-1608
Update message prevalidation API
2 parents 46f86d4 + 15889cb commit 53382d6

16 files changed

+182
-91
lines changed

coap-service/coap_service_api.h

Lines changed: 11 additions & 10 deletions
Original file line numberDiff line numberDiff line change
@@ -125,19 +125,20 @@ typedef int coap_service_security_done_cb(int8_t service_id, uint8_t address[sta
125125
*
126126
* Message prevalidation callback function type used in method coap_service_msg_prevalidate_callback_set.
127127
*
128-
* \param interface_id Application interface ID.
129-
* \param source_address Sender address.
130-
* \param source_port Sender port.
131-
* \param local_address Local address.
132-
* \param local_port Local port.
133-
* \param request_uri CoAP URI, NUL terminated.
128+
* \param local_interface_id Local interface ID, message arrived to this interface.
129+
* \param local_address Local address, message arrived to this address.
130+
* \param local_port Local port, message arrived to this port.
131+
* \param recv_interface_id Interface ID where message was received.
132+
* \param source_address Sender address.
133+
* \param source_port Sender port.
134+
* \param coap_uri CoAP URI, NUL terminated.
134135
*
135136
* \return <0 in case of errors,
136137
* 0 if message is valid to process further,
137138
* >0 if message should be dropped.
138139
*/
139140

140-
typedef int coap_service_msg_prevalidate_cb(int8_t interface_id, uint8_t source_address[static 16], uint16_t source_port, uint8_t local_address[static 16], uint16_t local_port, char *request_uri);
141+
typedef int coap_service_msg_prevalidate_cb(int8_t local_interface_id, uint8_t local_address[static 16], uint16_t local_port, int8_t recv_interface_id, uint8_t source_address[static 16], uint16_t source_port, char *coap_uri);
141142

142143
/**
143144
* \brief Initialise server instance.
@@ -400,13 +401,13 @@ extern int8_t coap_service_blockwise_size_set(int8_t service_id, uint16_t size);
400401
*
401402
* CoAP service will call this function to allow application prevalidate incoming CoAP message before passing it to application.
402403
*
403-
* \param service_id Id number of the current service.
404-
* \param msg_prevalidate_cb Callback to be called to validate incoming message before pprocessing it.
404+
* \param listen_port Socket port where to set callback.
405+
* \param msg_prevalidate_cb Callback to be called to validate incoming message before processing it. Use NULL to clear callback usage.
405406
*
406407
* \return -1 For failure
407408
* 0 For success
408409
*/
409-
extern int8_t coap_service_msg_prevalidate_callback_set(int8_t service_id, coap_service_msg_prevalidate_cb *msg_prevalidate_cb);
410+
extern int8_t coap_service_msg_prevalidate_callback_set(uint16_t listen_port, coap_service_msg_prevalidate_cb *msg_prevalidate_cb);
410411

411412
#ifdef __cplusplus
412413
}

source/coap_connection_handler.c

Lines changed: 17 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -45,6 +45,7 @@ typedef struct internal_socket_s {
4545

4646
int16_t data_len;
4747
uint8_t *data;
48+
int8_t recv_if_id; // interface ID where data is coming from
4849

4950
int8_t socket; //positive value = socket id, negative value virtual socket id
5051
bool real_socket;
@@ -549,6 +550,7 @@ static int timer_status(int8_t timer_id)
549550
static int read_data(socket_callback_t *sckt_data, internal_socket_t *sock, ns_address_t *src_address, uint8_t dst_address[static 16])
550551
{
551552
sock->data_len = 0;
553+
sock->recv_if_id = -1;
552554
if (sckt_data->event_type == SOCKET_DATA && sckt_data->d_len > 0) {
553555
uint8_t ancillary_databuffer[NS_CMSG_SPACE(sizeof(ns_in6_pktinfo_t))];
554556
ns_iovec_t msg_iov;
@@ -593,6 +595,7 @@ static int read_data(socket_callback_t *sckt_data, internal_socket_t *sock, ns_a
593595
}
594596
if (pkt) {
595597
memcpy(dst_address, pkt->ipi6_addr, 16);
598+
sock->recv_if_id = pkt->ipi6_ifindex;
596599
} else {
597600
goto return_failure;
598601
}
@@ -694,7 +697,7 @@ static void secure_recv_sckt_msg(void *cb_res)
694697
ns_dyn_mem_free(data);
695698
} else {
696699
if (sock->parent->_recv_cb) {
697-
sock->parent->_recv_cb(sock->socket, src_address.address, src_address.identifier, dst_address, data, len);
700+
sock->parent->_recv_cb(sock->socket, sock->recv_if_id, src_address.address, src_address.identifier, dst_address, data, len);
698701
}
699702
ns_dyn_mem_free(data);
700703
}
@@ -713,7 +716,7 @@ static void recv_sckt_msg(void *cb_res)
713716

714717
if (sock && read_data(sckt_data, sock, &src_address, dst_address) == 0) {
715718
if (sock->parent && sock->parent->_recv_cb) {
716-
sock->parent->_recv_cb(sock->socket, src_address.address, src_address.identifier, dst_address, sock->data, sock->data_len);
719+
sock->parent->_recv_cb(sock->socket, sock->recv_if_id, src_address.address, src_address.identifier, dst_address, sock->data, sock->data_len);
717720
}
718721
ns_dyn_mem_free(sock->data);
719722
sock->data = NULL;
@@ -802,7 +805,7 @@ int coap_connection_handler_virtual_recv(coap_conn_handler_t *handler, uint8_t a
802805
return 0;
803806
} else {
804807
if (sock->parent->_recv_cb) {
805-
sock->parent->_recv_cb(sock->socket, address, port, ns_in6addr_any, data, len);
808+
sock->parent->_recv_cb(sock->socket, sock->recv_if_id, address, port, ns_in6addr_any, data, len);
806809
}
807810
ns_dyn_mem_free(data);
808811
data = NULL;
@@ -813,7 +816,7 @@ int coap_connection_handler_virtual_recv(coap_conn_handler_t *handler, uint8_t a
813816
} else {
814817
/* unsecure*/
815818
if (sock->parent->_recv_cb) {
816-
sock->parent->_recv_cb(sock->socket, address, port, ns_in6addr_any, sock->data, sock->data_len);
819+
sock->parent->_recv_cb(sock->socket, sock->recv_if_id, address, port, ns_in6addr_any, sock->data, sock->data_len);
817820
}
818821
if (sock->data) {
819822
ns_dyn_mem_free(sock->data);
@@ -1034,6 +1037,16 @@ int coap_connection_handler_msg_prevalidate_callback_set(coap_conn_handler_t *ha
10341037
return 0;
10351038
}
10361039

1040+
coap_conn_handler_t *coap_connection_handler_find_by_socket_port(uint16_t listen_port)
1041+
{
1042+
ns_list_foreach(internal_socket_t, cur_ptr, &socket_list) {
1043+
if (cur_ptr->listen_port == listen_port) {
1044+
return cur_ptr->parent;
1045+
}
1046+
}
1047+
return NULL;
1048+
}
1049+
10371050
cch_func_cb *coap_connection_handler_msg_prevalidate_callback_get(coap_conn_handler_t *handler, uint16_t *listen_socket_port)
10381051
{
10391052
if (!handler || !listen_socket_port) {

source/coap_message_handler.c

Lines changed: 3 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -293,8 +293,8 @@ coap_transaction_t *coap_message_handler_find_transaction(uint8_t *address_ptr,
293293
return transaction_find_by_address(address_ptr, port);
294294
}
295295

296-
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],
297-
uint8_t *data_ptr, uint16_t data_len, int16_t (msg_process_callback)(int8_t, sn_coap_hdr_s *, coap_transaction_t *, const uint8_t *))
296+
int16_t coap_message_handler_coap_msg_process(coap_msg_handler_t *handle, int8_t socket_id, int8_t recv_if_id, const uint8_t source_addr_ptr[static 16], uint16_t port, const uint8_t dst_addr_ptr[static 16],
297+
uint8_t *data_ptr, uint16_t data_len, coap_msg_process_cb *msg_process_callback)
298298
{
299299
sn_nsdl_addr_s src_addr;
300300
sn_coap_hdr_s *coap_message;
@@ -345,7 +345,7 @@ int16_t coap_message_handler_coap_msg_process(coap_msg_handler_t *handle, int8_t
345345
memcpy(transaction_ptr->token, coap_message->token_ptr, coap_message->token_len);
346346
transaction_ptr->token_len = coap_message->token_len;
347347
}
348-
if (msg_process_callback(socket_id, coap_message, transaction_ptr, dst_addr_ptr) < 0) {
348+
if (msg_process_callback(socket_id, recv_if_id, coap_message, transaction_ptr, dst_addr_ptr) < 0) {
349349
// negative return value = message ignored -> delete transaction
350350
transaction_delete(transaction_ptr);
351351
}

source/coap_service_api.c

Lines changed: 48 additions & 33 deletions
Original file line numberDiff line numberDiff line change
@@ -36,7 +36,7 @@
3636
#include "coap_message_handler.h"
3737
#include "mbed-coap/sn_coap_protocol.h"
3838

39-
static int16_t coap_msg_process_callback(int8_t socket_id, sn_coap_hdr_s *coap_message, coap_transaction_t *transaction_ptr, const uint8_t * local_addr);
39+
static int16_t coap_msg_process_callback(int8_t socket_id, int8_t recv_if_id, sn_coap_hdr_s *coap_message, coap_transaction_t *transaction_ptr, const uint8_t *local_addr);
4040

4141
typedef struct uri_registration {
4242
char *uri_ptr;
@@ -70,6 +70,13 @@ static uint32_t coap_ticks = 1;
7070

7171
#define COAP_TICK_TIMER 0xf1
7272

73+
#define TRACE_DEEP
74+
#ifdef TRACE_DEEP
75+
#define tr_deep tr_debug
76+
#else
77+
#define tr_deep(...)
78+
#endif
79+
7380
static uri_registration_t *uri_registration_find(coap_service_t *this, const void *uri_ptr, uint16_t uri_len)
7481
{
7582
ns_list_foreach(uri_registration_t, cur_ptr, &this->uri_list) {
@@ -165,7 +172,7 @@ static uint8_t coap_tx_function(uint8_t *data_ptr, uint16_t data_len, sn_nsdl_ad
165172
return 0;
166173
}
167174

168-
tr_debug("Service %d, CoAP TX Function - mid: %d", transaction_ptr->service_id, common_read_16_bit(data_ptr + 2));
175+
tr_debug("Service %d, CoAP TX - mid: %d", transaction_ptr->service_id, common_read_16_bit(data_ptr + 2));
169176

170177
this = service_find(transaction_ptr->service_id);
171178
if (!this) {
@@ -211,17 +218,44 @@ static void service_event_handler(arm_event_s *event)
211218
eventOS_event_timer_request((uint8_t)COAP_TICK_TIMER, ARM_LIB_SYSTEM_TIMER_EVENT, tasklet_id, 1000);
212219
}
213220

214-
static int16_t coap_msg_process_callback(int8_t socket_id, sn_coap_hdr_s *coap_message, coap_transaction_t *transaction_ptr, const uint8_t * local_addr)
221+
static int16_t coap_msg_process_callback(int8_t socket_id, int8_t recv_if_id, sn_coap_hdr_s *coap_message, coap_transaction_t *transaction_ptr, const uint8_t *local_addr)
215222
{
216223
coap_service_t *this;
224+
coap_service_msg_prevalidate_cb *msg_prevalidate_callback;
225+
uint16_t listen_socket_port;
226+
217227
if (!coap_message || !transaction_ptr) {
218228
return -1;
219229
}
220230

221-
// Message is request, find correct handle
231+
// Message is request, find correct handle based on URI
222232
this = service_find_by_uri(socket_id, coap_message->uri_path_ptr, coap_message->uri_path_len);
223233
if (!this) {
224-
tr_debug("not registered uri %.*s", coap_message->uri_path_len, coap_message->uri_path_ptr);
234+
tr_deep("URI %.*s not registered", coap_message->uri_path_len, coap_message->uri_path_ptr);
235+
// URI is not available, find any service that holds the same shared socket so that we can get msg_prevalidate_callback to validate addresses
236+
this = service_find_by_socket(socket_id);
237+
if (!this) {
238+
return -1;
239+
}
240+
}
241+
242+
msg_prevalidate_callback = (coap_service_msg_prevalidate_cb *)coap_connection_handler_msg_prevalidate_callback_get(this->conn_handler, &listen_socket_port);
243+
if (msg_prevalidate_callback) {
244+
// message prevalidation activated for the port
245+
char request_uri[coap_message->uri_path_len + 1];
246+
memcpy(request_uri, coap_message->uri_path_ptr, coap_message->uri_path_len);
247+
request_uri[coap_message->uri_path_len] = 0;
248+
249+
int msg_prevalidate_status = msg_prevalidate_callback(this->interface_id, (uint8_t *)local_addr, listen_socket_port, recv_if_id, transaction_ptr->remote_address, transaction_ptr->remote_port, request_uri);
250+
if (msg_prevalidate_status >= 1) {
251+
tr_deep("Drop CoAP msg %s from %s to %s", request_uri, trace_ipv6(transaction_ptr->remote_address), trace_ipv6(local_addr));
252+
return -1;
253+
}
254+
}
255+
256+
uri_registration_t *uri_reg_ptr = uri_registration_find(this, coap_message->uri_path_ptr, coap_message->uri_path_len);
257+
if (!uri_reg_ptr) {
258+
/* URI is not available, stop further processing */
225259
if (coap_message->msg_type == COAP_MSG_TYPE_CONFIRMABLE) {
226260
coap_message_handler_response_send(coap_service_handle, transaction_ptr->service_id, COAP_SERVICE_OPTIONS_NONE, coap_message,
227261
COAP_MSG_CODE_RESPONSE_NOT_FOUND, COAP_CT_NONE, NULL, 0);
@@ -230,40 +264,22 @@ static int16_t coap_msg_process_callback(int8_t socket_id, sn_coap_hdr_s *coap_m
230264
return -1;
231265
}
232266

233-
uri_registration_t *uri_reg_ptr = uri_registration_find(this, coap_message->uri_path_ptr, coap_message->uri_path_len);
234-
if (uri_reg_ptr && uri_reg_ptr->request_recv_cb) {
235-
tr_debug("Service %d, call request recv cb uri %.*s", this->service_id, coap_message->uri_path_len, coap_message->uri_path_ptr);
236-
267+
if (uri_reg_ptr->request_recv_cb) {
237268
if ((this->service_options & COAP_SERVICE_OPTIONS_SECURE_BYPASS) == COAP_SERVICE_OPTIONS_SECURE_BYPASS) { //TODO Add secure bypass option
238269
// Service has secure bypass active TODO this is not defined in interface
239270
// this check can be removed I think
240271
transaction_ptr->options = COAP_REQUEST_OPTIONS_SECURE_BYPASS;
241272
}
242-
coap_service_msg_prevalidate_cb *msg_prevalidate_callback;
243-
uint16_t listen_socket_port;
244273

245274
transaction_ptr->service_id = this->service_id;
246-
247-
msg_prevalidate_callback = (coap_service_msg_prevalidate_cb*)coap_connection_handler_msg_prevalidate_callback_get(this->conn_handler, &listen_socket_port);
248-
if (msg_prevalidate_callback) {
249-
// message prevalidation activated for the port
250-
char request_uri[coap_message->uri_path_len + 1];
251-
memcpy(request_uri, coap_message->uri_path_ptr, coap_message->uri_path_len);
252-
request_uri[coap_message->uri_path_len] = 0;
253-
254-
int msg_prevalidate_status = msg_prevalidate_callback(this->interface_id, transaction_ptr->remote_address, transaction_ptr->remote_port, (uint8_t*)local_addr, listen_socket_port, request_uri);
255-
if (msg_prevalidate_status == 1) {
256-
tr_warn("Drop msg %s", request_uri);
257-
return -1;
258-
}
259-
}
260-
275+
tr_debug("Service %d, recv msg: %.*s", this->service_id, coap_message->uri_path_len, coap_message->uri_path_ptr);
261276
return uri_reg_ptr->request_recv_cb(this->service_id, transaction_ptr->remote_address, transaction_ptr->remote_port, coap_message);
262277
}
278+
263279
return -1;
264280
}
265281

266-
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)
282+
static int recv_cb(int8_t socket_id, int8_t recv_if_id, uint8_t src_address[static 16], uint16_t port, const uint8_t dst_address[static 16], unsigned char *data, int len)
267283
{
268284
uint8_t *data_ptr = NULL;
269285
uint16_t data_len = 0;
@@ -279,10 +295,9 @@ static int recv_cb(int8_t socket_id, uint8_t src_address[static 16], uint16_t po
279295
}
280296
memcpy(data_ptr, data, len);
281297
data_len = len;
282-
tr_debug("Service recv %d bytes", data_len);
283298

284299
//parse coap message what CoAP to use
285-
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);
300+
int ret = coap_message_handler_coap_msg_process(coap_service_handle, socket_id, recv_if_id, src_address, port, dst_address, data_ptr, data_len, &coap_msg_process_callback);
286301
own_free(data_ptr);
287302
return ret;
288303
}
@@ -645,11 +660,11 @@ int8_t coap_service_blockwise_size_set(int8_t service_id, uint16_t size)
645660
return sn_coap_protocol_set_block_size(coap_service_handle->coap, size);
646661
}
647662

648-
int8_t coap_service_msg_prevalidate_callback_set(int8_t service_id, coap_service_msg_prevalidate_cb *msg_prevalidate_cb)
663+
int8_t coap_service_msg_prevalidate_callback_set(uint16_t listen_socket, coap_service_msg_prevalidate_cb *msg_prevalidate_cb)
649664
{
650-
coap_service_t *this = service_find(service_id);
651-
if (this) {
652-
return (int8_t)coap_connection_handler_msg_prevalidate_callback_set(this->conn_handler, (cch_func_cb*)msg_prevalidate_cb);
665+
coap_conn_handler_t *conn_handler = coap_connection_handler_find_by_socket_port(listen_socket);
666+
if (conn_handler) {
667+
return (int8_t)coap_connection_handler_msg_prevalidate_callback_set(conn_handler, (cch_func_cb *)msg_prevalidate_cb);
653668
}
654669
return -1;
655670
}

source/include/coap_connection_handler.h

Lines changed: 3 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -35,7 +35,7 @@
3535
struct internal_socket_s;
3636

3737
typedef int send_to_socket_cb(int8_t socket_id, const uint8_t address[static 16], uint16_t port, const void *, int);
38-
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);
38+
typedef int receive_from_socket_cb(int8_t socket_id, int8_t recv_if_id, uint8_t src_address[static 16], uint16_t port, const uint8_t dst_address[static 16], unsigned char *, int);
3939
typedef int get_pw_cb(int8_t socket_id, uint8_t address[static 16], uint16_t port, coap_security_keys_t *security_ptr);
4040
typedef void security_done_cb(int8_t socket_id, uint8_t address[static 16], uint16_t port, uint8_t keyblock[static 40]);
4141
typedef void cch_func_cb(void);
@@ -82,6 +82,8 @@ int8_t coap_connection_handler_handshake_limits_set(uint8_t handshakes_limit, ui
8282

8383
void coap_connection_handler_exec(uint32_t time);
8484

85+
coap_conn_handler_t *coap_connection_handler_find_by_socket_port(uint16_t listen_port);
86+
8587
int coap_connection_handler_msg_prevalidate_callback_set(coap_conn_handler_t *handler, cch_func_cb *function_callback);
8688

8789
cch_func_cb *coap_connection_handler_msg_prevalidate_callback_get(coap_conn_handler_t *handler, uint16_t *listen_socket_port);

source/include/coap_message_handler.h

Lines changed: 16 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -49,9 +49,7 @@ typedef int coap_message_handler_response_recv(int8_t service_id, uint8_t source
4949
typedef struct coap_msg_handler_s {
5050
void *(*sn_coap_service_malloc)(uint16_t);
5151
void (*sn_coap_service_free)(void *);
52-
5352
uint8_t (*sn_coap_tx_callback)(uint8_t *, uint16_t, sn_nsdl_addr_s *, void *);
54-
5553
struct coap_s *coap;
5654
} coap_msg_handler_t;
5755

@@ -74,6 +72,20 @@ typedef struct coap_transaction {
7472
ns_list_link_t link;
7573
} coap_transaction_t;
7674

75+
/**
76+
* \brief Service message processing callback.
77+
*
78+
* Function that processes CoAP service message
79+
*
80+
* \param socket_id Socket that receives the message.
81+
* \param recv_if_id Interface where message is received.
82+
* \param coap_message Actual CoAP message.
83+
* \param transaction_ptr Message transaction.
84+
* \param local_addr Address where message is received.
85+
*
86+
* \return 0 for success / -1 for failure
87+
*/
88+
typedef int16_t coap_msg_process_cb(int8_t socket_id, int8_t recv_if_id, sn_coap_hdr_s *coap_message, coap_transaction_t *transaction_ptr, const uint8_t *local_addr);
7789

7890
extern coap_msg_handler_t *coap_message_handler_init(void *(*used_malloc_func_ptr)(uint16_t), void (*used_free_func_ptr)(void *),
7991
uint8_t (*used_tx_callback_ptr)(uint8_t *, uint16_t, sn_nsdl_addr_s *, void *));
@@ -84,8 +96,8 @@ extern coap_transaction_t *coap_message_handler_transaction_valid(coap_transacti
8496

8597
extern coap_transaction_t *coap_message_handler_find_transaction(uint8_t *address_ptr, uint16_t port);
8698

87-
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],
88-
uint8_t *data_ptr, uint16_t data_len, int16_t (msg_process_callback)(int8_t, sn_coap_hdr_s *, coap_transaction_t *, const uint8_t *));
99+
extern int16_t coap_message_handler_coap_msg_process(coap_msg_handler_t *handle, int8_t socket_id, int8_t recv_if_id, const uint8_t source_addr_ptr[static 16], uint16_t port,
100+
const uint8_t dst_addr_ptr[static 16], uint8_t *data_ptr, uint16_t data_len, coap_msg_process_cb *msg_process_callback);
89101

90102
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],
91103
uint16_t destination_port, sn_coap_msg_type_e msg_type, sn_coap_msg_code_e msg_code, const char *uri, sn_coap_content_format_e cont_type,

test/coap-service/unittest/coap_connection_handler/coap_connection_handlertest.cpp

Lines changed: 5 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -76,3 +76,8 @@ TEST(coap_connection_handler, test_coap_connection_handler_msg_prevalidate_cb_re
7676
CHECK(test_coap_connection_handler_msg_prevalidate_cb_read_and_set());
7777
}
7878

79+
TEST(coap_connection_handler, test_coap_connection_handler_find_by_socket_port)
80+
{
81+
CHECK(test_coap_connection_handler_find_by_socket_port());
82+
}
83+

0 commit comments

Comments
 (0)