Skip to content

Commit

Permalink
sys/net/application_layer/gcoap: add coap-coaps proxy handling
Browse files Browse the repository at this point in the history
  • Loading branch information
mariemC committed Apr 22, 2024
1 parent d5c83d8 commit a3ddaf2
Showing 1 changed file with 48 additions and 16 deletions.
64 changes: 48 additions & 16 deletions sys/net/application_layer/gcoap/forward_proxy.c
Original file line number Diff line number Diff line change
Expand Up @@ -35,6 +35,8 @@
#define CLIENT_EP_FLAGS_ETAG_LEN_POS 0U

typedef struct {
coap_pkt_t pdu;
sock_udp_ep_t server_ep;
sock_udp_ep_t ep;
uint16_t mid;
uint8_t flags;
Expand All @@ -45,6 +47,9 @@ typedef struct {
event_t event;
} client_ep_t;

static char _forward_proxy_thread[PROXY_STACK_SIZE];
static kernel_pid_t _forward_proxy_pid;

extern uint16_t gcoap_next_msg_id(void);
extern void gcoap_forward_proxy_post_event(void *arg);

Expand Down Expand Up @@ -84,8 +89,34 @@ gcoap_listener_t forward_proxy_listener = {
_request_matcher_forward_proxy
};

static void *_forward_proxy_thread_start(void *arg)
{
(void)arg;

msg_t msg;

while (1) {
msg_receive(&msg);
client_ep_t *cep = (client_ep_t *)msg.content.ptr;
switch (msg.type) {
case FORWARD_PROXY_MSG_SEND:
gcoap_req_send((uint8_t *)cep->pdu.hdr, coap_get_total_len(&cep->pdu),
&cep->server_ep, _forward_resp_handler, cep);
break;
default:
DEBUG_PUTS("gcoap_forward_proxy: unknown message type\n");
break;
}
}
return NULL;
}

void gcoap_forward_proxy_init(void)
{
_forward_proxy_pid = thread_create(_forward_proxy_thread, sizeof(_forward_proxy_thread),
THREAD_PRIORITY_MAIN - 1,
THREAD_CREATE_STACKTEST, _forward_proxy_thread_start,
NULL, "proxy");
gcoap_register_listener(&forward_proxy_listener);
}

Expand Down Expand Up @@ -394,20 +425,17 @@ static int _gcoap_forward_proxy_via_coap(coap_pkt_t *client_pkt,
client_ep_t *client_ep,
uri_parser_result_t *urip)
{
coap_pkt_t pkt;
sock_udp_ep_t origin_server_ep;

ssize_t len;
gcoap_request_memo_t *memo = NULL;

if (!_parse_endpoint(&origin_server_ep, urip)) {
if (!_parse_endpoint(&client_ep->server_ep, urip)) {
return -EINVAL;
}

/* do not forward requests if they already exist, e.g., due to CON
and retransmissions. In the future, the proxy should set an
empty ACK message to stop the retransmissions of a client */
gcoap_forward_proxy_find_req_memo(&memo, client_pkt, &origin_server_ep);
gcoap_forward_proxy_find_req_memo(&memo, client_pkt, &client_ep->server_ep);
if (memo) {
DEBUG("gcoap_forward_proxy: request already exists, ignore!\n");
_free_client_ep(client_ep);
Expand All @@ -424,28 +452,31 @@ static int _gcoap_forward_proxy_via_coap(coap_pkt_t *client_pkt,

unsigned token_len = coap_get_token_len(client_pkt);

coap_pkt_init(&pkt, proxy_req_buf, CONFIG_GCOAP_PDU_BUF_SIZE,
coap_pkt_init(&client_ep->pdu, proxy_req_buf, CONFIG_GCOAP_PDU_BUF_SIZE,
sizeof(coap_hdr_t) + token_len);

pkt.hdr->ver_t_tkl = client_pkt->hdr->ver_t_tkl;
pkt.hdr->code = client_pkt->hdr->code;
pkt.hdr->id = client_pkt->hdr->id;
client_ep->pdu.hdr->ver_t_tkl = client_pkt->hdr->ver_t_tkl;
client_ep->pdu.hdr->code = client_pkt->hdr->code;
client_ep->pdu.hdr->id = client_pkt->hdr->id;

if (token_len) {
memcpy(coap_get_token(&pkt), coap_get_token(client_pkt), token_len);
memcpy(coap_get_token(&client_ep->pdu), coap_get_token(client_pkt), token_len);
}

/* copy all options from client_pkt to pkt */
len = _gcoap_forward_proxy_copy_options(&pkt, client_pkt, client_ep, urip);
len = _gcoap_forward_proxy_copy_options(&client_ep->pdu, client_pkt, client_ep, urip);

if (len == -EINVAL) {
return -EINVAL;
}

len = gcoap_req_send((uint8_t *)pkt.hdr, len,
&origin_server_ep,
_forward_resp_handler, (void *)client_ep,
GCOAP_SOCKET_TYPE_UNDEF);
/* DTLS communication is blocking the gcoap thread,
* therefore the communication should be handled in the proxy thread */

msg_t msg = { .type = FORWARD_PROXY_MSG_SEND,
.content.ptr = client_ep };
msg_try_send(&msg, _forward_proxy_pid);

return len;
}

Expand Down Expand Up @@ -484,7 +515,8 @@ int gcoap_forward_proxy_request_process(coap_pkt_t *pkt,
}

/* target is using CoAP */
if (!strncmp("coap", urip.scheme, urip.scheme_len)) {
if (!strncmp("coap", urip.scheme, urip.scheme_len) ||
!strncmp("coaps", urip.scheme, urip.scheme_len)) {
int res = _gcoap_forward_proxy_via_coap(pkt, cep, &urip);
if (res < 0) {
_free_client_ep(cep);
Expand Down

0 comments on commit a3ddaf2

Please sign in to comment.