From d2306569d16a9839bc0c3300ffb913d8cfc8a4e0 Mon Sep 17 00:00:00 2001 From: Jon Shallow Date: Sat, 25 Jun 2022 17:38:20 +0100 Subject: [PATCH] proxy: Make proxy requests separate responses As an incoming proxy request may delay its response (e.g. initiate an ongoing connection), send back empty ACK immediately so that the client does not timeout and re-transmit the request. Do not process duplicated (i.e. re-transmitted) proxy requests. Correct a couple of typos in example proxy code. --- examples/coap-server.c | 4 ++-- src/net.c | 30 ++++++++++++++++++++++++++++++ 2 files changed, 32 insertions(+), 2 deletions(-) diff --git a/examples/coap-server.c b/examples/coap-server.c index ab072e8f..b3aa9a2a 100644 --- a/examples/coap-server.c +++ b/examples/coap-server.c @@ -1110,7 +1110,7 @@ hnd_proxy_uri(coap_resource_t *resource COAP_UNUSED, */ pdu = coap_pdu_init(req_type, req_code, coap_new_message_id(ongoing), - coap_session_max_pdu_size(session)); + coap_session_max_pdu_size(ongoing)); if (!pdu) { coap_pdu_set_code(response, COAP_RESPONSE_CODE_INTERNAL_ERROR); goto cleanup; @@ -1208,7 +1208,7 @@ add_in: coap_delete_optlist(optlist); if (size) { - if (!coap_add_data_large_request(session, pdu, size, data, + if (!coap_add_data_large_request(ongoing, pdu, size, data, release_proxy_body_data, body_data)) { coap_log(LOG_DEBUG, "cannot add data to proxy request\n"); } diff --git a/src/net.c b/src/net.c index 82c56293..706c9c0d 100644 --- a/src/net.c +++ b/src/net.c @@ -2600,6 +2600,7 @@ handle_request(coap_context_t *context, coap_session_t *session, coap_pdu_t *pdu int is_proxy_scheme = 0; int skip_hop_limit_check = 0; int resp; + int send_early_empty_ack = 0; coap_binary_t token = { pdu->token_length, pdu->token }; coap_string_t *query = NULL; coap_opt_t *observe = NULL; @@ -2900,6 +2901,24 @@ handle_request(coap_context_t *context, coap_session_t *session, coap_pdu_t *pdu } } + /* TODO for non-proxy requests */ + if (resource == context->proxy_uri_resource && + COAP_PROTO_NOT_RELIABLE(session->proto) && + pdu->type == COAP_MESSAGE_CON) { + /* Make the proxy response separate and fix response later */ + send_early_empty_ack = 1; + } + if (send_early_empty_ack) { + coap_send_ack(session, pdu); + if (pdu->mid == session->last_con_mid) { + /* request has already been processed - do not process it again */ + coap_log(LOG_DEBUG, + "Duplicate request with mid=0x%04x - not processed\n", + pdu->mid); + goto drop_it_no_debug; + } + session->last_con_mid = pdu->mid; + } if (session->block_mode & COAP_BLOCK_USE_LIBCOAP) { if (coap_handle_request_put_block(context, session, pdu, response, resource, uri_path, observe, @@ -2925,6 +2944,15 @@ handle_request(coap_context_t *context, coap_session_t *session, coap_pdu_t *pdu coap_check_code_lg_xmit(session, response, resource, query, pdu->code); skip_handler: + if (send_early_empty_ack && + response->type == COAP_MESSAGE_ACK) { + /* Response is now separate - convert to CON as needed */ + response->type = COAP_MESSAGE_CON; + /* Check for empty ACK - need to drop as already sent */ + if (response->code == 0) { + goto drop_it_no_debug; + } + } respond = no_response(pdu, response, session, resource); if (respond != RESPONSE_DROP) { coap_mid_t mid = pdu->mid; @@ -2969,6 +2997,7 @@ skip_handler: goto clean_up; } if (!coap_pdu_encode_header(response, session->proto)) { + coap_delete_node(node); goto clean_up; } @@ -2995,6 +3024,7 @@ skip_handler: coap_session_str(session), response->mid); coap_show_pdu(LOG_DEBUG, response); +drop_it_no_debug: coap_delete_pdu(response); } clean_up: