Skip to content

Commit

Permalink
Proxy: Fix memory leaks in proxy logic
Browse files Browse the repository at this point in the history
  • Loading branch information
mrdeep1 committed Jan 14, 2025
1 parent 21c7029 commit 109842b
Show file tree
Hide file tree
Showing 3 changed files with 41 additions and 10 deletions.
1 change: 1 addition & 0 deletions include/coap3/coap_proxy_internal.h
Original file line number Diff line number Diff line change
Expand Up @@ -40,6 +40,7 @@ struct coap_proxy_list_t {
coap_proxy_req_t *req_list; /**< Incoming list of request info */
size_t req_count; /**< Count of incoming request info */
coap_uri_t uri; /**< URI info for connection */
u_char *uri_host_keep; /**< memory for uri.host */
coap_tick_t idle_timeout_ticks; /**< Idle timeout (0 == no timeout) */
coap_tick_t last_used; /**< Last time entry was used */
};
Expand Down
3 changes: 3 additions & 0 deletions include/coap3/coap_uri.h
Original file line number Diff line number Diff line change
Expand Up @@ -61,6 +61,9 @@ typedef enum coap_uri_scheme_t {
* coap_split_uri() or coap_split_proxy_uri() and can be used as input for
* option-creation functions. Alternatively, coap_uri_into_optlist() can
* be used to convert coap_uri_t into CoAP options.
*
* Note: host, path and query point to data which must remain there for the
* lifetime of the coap_uri_t.
*/
typedef struct {
coap_str_const_t host; /**< The host part of the URI */
Expand Down
47 changes: 37 additions & 10 deletions src/coap_proxy.c
Original file line number Diff line number Diff line change
Expand Up @@ -46,6 +46,7 @@ coap_proxy_cleanup(coap_context_t *context) {
coap_delete_cache_key(context->proxy_list[i].req_list[j].cache_key);
}
coap_free_type(COAP_STRING, context->proxy_list[i].req_list);
coap_free_type(COAP_STRING, context->proxy_list[i].uri_host_keep);
}
coap_free_type(COAP_STRING, context->proxy_list);
}
Expand Down Expand Up @@ -86,7 +87,6 @@ coap_get_uri_proxy_scheme_info(const coap_pdu_t *request,
coap_uri_t *uri,
coap_string_t **uri_path,
coap_string_t **uri_query) {

const char *opt_val = (const char *)coap_opt_value(opt);
int opt_len = coap_opt_length(opt);
coap_opt_iterator_t opt_iter;
Expand Down Expand Up @@ -126,6 +126,8 @@ coap_get_uri_proxy_scheme_info(const coap_pdu_t *request,
uri->host.length = coap_opt_length(opt);
uri->host.s = coap_opt_value(opt);
} else {
uri->host.s = NULL;
uri->host.length = 0;
coap_log_warn("Proxy Scheme requires Uri-Host\n");
return 0;
}
Expand Down Expand Up @@ -207,7 +209,9 @@ static coap_proxy_list_t *
coap_proxy_get_session(coap_session_t *session, const coap_pdu_t *request,
coap_pdu_t *response,
coap_proxy_server_list_t *server_list,
coap_proxy_server_t *server_use) {
coap_proxy_server_t *server_use,
coap_string_t **uri_path,
coap_string_t **uri_query) {
size_t i;
coap_proxy_list_t *new_proxy_list;
coap_proxy_list_t *proxy_list = session->context->proxy_list;
Expand All @@ -216,8 +220,6 @@ coap_proxy_get_session(coap_session_t *session, const coap_pdu_t *request,
coap_opt_iterator_t opt_iter;
coap_opt_t *proxy_scheme;
coap_opt_t *proxy_uri;
coap_string_t *uri_path = NULL;
coap_string_t *uri_query = NULL;

/* Round robin the defined next server list (which usually is just one */
server_list->next_entry++;
Expand All @@ -241,8 +243,9 @@ coap_proxy_get_session(coap_session_t *session, const coap_pdu_t *request,
*/
proxy_scheme = coap_check_option(request, COAP_OPTION_PROXY_SCHEME, &opt_iter);
if (proxy_scheme) {
if (!coap_get_uri_proxy_scheme_info(request, proxy_scheme, &server_use->uri, &uri_path,
&uri_query)) {
if (!coap_get_uri_proxy_scheme_info(request, proxy_scheme, &server_use->uri,
uri_path,
uri_query)) {
response->code = COAP_RESPONSE_CODE(505);
return NULL;
}
Expand Down Expand Up @@ -313,7 +316,21 @@ coap_proxy_get_session(coap_session_t *session, const coap_pdu_t *request,
session->context->proxy_list = proxy_list = new_proxy_list;
memset(&proxy_list[i], 0, sizeof(proxy_list[i]));

/* Keep a copy of the host as PDU pointed to will be going away */
proxy_list[i].uri = server_use->uri;
proxy_list[i].uri_host_keep = coap_malloc_type(COAP_STRING,
server_use->uri.host.length);
if (! proxy_list[i].uri_host_keep)
return NULL;
memcpy(proxy_list[i].uri_host_keep, server_use->uri.host.s,
server_use->uri.host.length);
proxy_list[i].uri.host.s = proxy_list[i].uri_host_keep;
/* Unset uri parts which point to going away PDU */
proxy_list[i].uri.path.s = NULL;
proxy_list[i].uri.path.length = 0;
proxy_list[i].uri.query.s = NULL;
proxy_list[i].uri.query.length = 0;

if (server_list->track_client_session) {
proxy_list[i].incoming = session;
}
Expand Down Expand Up @@ -405,7 +422,9 @@ coap_proxy_get_ongoing_session(coap_session_t *session,
const coap_pdu_t *request,
coap_pdu_t *response,
coap_proxy_server_list_t *server_list,
coap_proxy_server_t *server_use) {
coap_proxy_server_t *server_use,
coap_string_t **uri_path,
coap_string_t **uri_query) {

coap_address_t dst;
coap_proto_t proto;
Expand All @@ -414,7 +433,8 @@ coap_proxy_get_ongoing_session(coap_session_t *session,
coap_context_t *context = session->context;
static char client_sni[256];

proxy_entry = coap_proxy_get_session(session, request, response, server_list, server_use);
proxy_entry = coap_proxy_get_session(session, request, response, server_list,
server_use, uri_path, uri_query);
if (!proxy_entry) {
/* Response code should be set */
return NULL;
Expand Down Expand Up @@ -565,14 +585,18 @@ coap_proxy_forward_request_lkd(coap_session_t *session,
coap_opt_t *option;
coap_opt_iterator_t opt_iter;
coap_proxy_server_t server_use;
coap_string_t *uri_path = NULL;
coap_string_t *uri_query = NULL;

/* Set up ongoing session (if not already done) */

proxy_entry = coap_proxy_get_ongoing_session(session, request, response,
server_list, &server_use);
if (!proxy_entry)
server_list, &server_use,
&uri_path, &uri_query);
if (!proxy_entry) {
/* response code already set */
return 0;
}

/* Need to save the request pdu entry */
new_req_list = coap_realloc_type(COAP_STRING, proxy_entry->req_list,
Expand Down Expand Up @@ -629,6 +653,9 @@ coap_proxy_forward_request_lkd(coap_session_t *session,
coap_log_err("Failed to create options for URI\n");
goto failed;
}
/* Finished with server_use, so release computed options */
coap_delete_string(uri_path);
coap_delete_string(uri_query);

/* Copy the remaining options across */
coap_option_iterator_init(request, &opt_iter, COAP_OPT_ALL);
Expand Down

0 comments on commit 109842b

Please sign in to comment.