From 3fe8f53c8ecf71214d04a4d0cc36c0381451fa10 Mon Sep 17 00:00:00 2001 From: Jin-Seong Kim Date: Tue, 8 Aug 2017 17:29:58 +0900 Subject: [PATCH] netutils/libcoap : bug fixes for CoAP over TCP This commit is patch for bug fixes for CoAP over TCP 1. patch for memory leakage issue - some pdus are not freed when coap_send returns COAP_INVALID_TID 2. add waiting routine on libcoap-server - waiting until g_operating_status is SERVER_STOPPED state - duplicated libcoap-server process can cause abort during long-run test 3. add debug logs for further tracing Change-Id: Ib1173a6f24691eebae5860727227d85c09972ef3 Signed-off-by: Jin-Seong Kim --- apps/examples/libcoap_client/libcoap-client.c | 19 +++++++++------ apps/examples/libcoap_server/libcoap-server.c | 9 +++++-- apps/netutils/libcoap/net.c | 35 +++++++++++++++++++++------ apps/netutils/libcoap/resource.c | 5 ++-- 4 files changed, 48 insertions(+), 20 deletions(-) diff --git a/apps/examples/libcoap_client/libcoap-client.c b/apps/examples/libcoap_client/libcoap-client.c index 117898e..90b4fe3 100644 --- a/apps/examples/libcoap_client/libcoap-client.c +++ b/apps/examples/libcoap_client/libcoap-client.c @@ -431,6 +431,7 @@ void message_handler(struct coap_context_t *ctx, const coap_address_t *remote, c } } else if (ctx->protocol == COAP_PROTO_TCP || ctx->protocol == COAP_PROTO_TLS) { /* TODO: do nothing? */ + debug("message_handler : do nothing\n"); } else { /* should not enter here */ } @@ -455,12 +456,12 @@ void message_handler(struct coap_context_t *ctx, const coap_address_t *remote, c code = (unsigned short)coap_get_code(received, transport); + debug("message_handler : code %d, sent %p\n", code, sent); + /* output the received data, if any */ if (code == COAP_RESPONSE_CODE(205)) { /* set obs timer if we have successfully subscribed a resource */ - info("message_handler : code %d, sent %p\n", code, sent); - if (sent && coap_check_option2(received, COAP_OPTION_SUBSCRIPTION, &opt_iter, transport)) { printf("message_handler : observation relationship established, set timeout to %d\n", obs_seconds); set_timeout(&obs_wait, obs_seconds); @@ -544,6 +545,7 @@ void message_handler(struct coap_context_t *ctx, const coap_address_t *remote, c } } else { /* no 2.05 */ + debug("message_handler : response class %d\n", COAP_RESPONSE_CLASS(code)); /* check if an error was signaled and output payload if so */ if (COAP_RESPONSE_CLASS(code) >= 4) { fprintf(stderr, "%d.%02d", (code >> 5), code & 0x1F); @@ -559,8 +561,12 @@ void message_handler(struct coap_context_t *ctx, const coap_address_t *remote, c } /* finally send new request, if needed */ - if (pdu && coap_send(ctx, remote, pdu) == COAP_INVALID_TID) { - debug("message_handler: error sending response"); + if (pdu != NULL) { + if (coap_send(ctx, remote, pdu) == COAP_INVALID_TID) { + debug("message_handler: error sending response"); + } + } else { + debug("message_handler: pdu is NULL\n"); } coap_delete_pdu(pdu); @@ -1323,10 +1329,7 @@ int main(int argc, char **argv) case COAP_PROTO_TCP: case COAP_PROTO_TLS: tid = coap_send(ctx, &dst, pdu); - - if (tid == COAP_INVALID_TID) { - coap_delete_pdu(pdu); - } + coap_delete_pdu(pdu); break; default : /* should not enter here */ diff --git a/apps/examples/libcoap_server/libcoap-server.c b/apps/examples/libcoap_server/libcoap-server.c index 5858923..d5f4bfc 100644 --- a/apps/examples/libcoap_server/libcoap-server.c +++ b/apps/examples/libcoap_server/libcoap-server.c @@ -513,12 +513,17 @@ int main(int argc, char **argv) if (g_operating_status == SERVER_RUNNING) { if (quit) { printf("coap-server : set quit flag %d\n", quit); - /* To prevent memory leakage */ - if (addr_str != NULL) + while (g_operating_status != SERVER_STOPPED) { + usleep(100000); + } + printf("coap-server : server process has been stopped\n"); + if (addr_str) { free(addr_str); + } } else { printf("coap-server : another libcoap-server is running\n"); } + return 0; } diff --git a/apps/netutils/libcoap/net.c b/apps/netutils/libcoap/net.c index 467bf68..2669fc0 100644 --- a/apps/netutils/libcoap/net.c +++ b/apps/netutils/libcoap/net.c @@ -777,14 +777,29 @@ coap_tid_t coap_send_message_type(coap_context_t *context, const coap_address_t coap_pdu_t *response; coap_tid_t result = COAP_INVALID_TID; - if (request) { - /* TODO : Considering TCP Case */ - response = coap_pdu_init(type, 0, request->transport_hdr->udp.id, sizeof(coap_pdu_t)); - if (response) { - result = coap_send(context, dst, response); - coap_delete_pdu(response); + coap_transport_t transport; + + switch (context->protocol) { + case COAP_PROTO_UDP: + case COAP_PROTO_DTLS: + transport = COAP_UDP; + if (request) { + response = coap_pdu_init(type, 0, request->transport_hdr->udp.id, sizeof(coap_pdu_t)); + if (response) { + result = coap_send(context, dst, response); + coap_delete_pdu(response); + } } + break; + case COAP_PROTO_TCP: + case COAP_PROTO_TLS: + transport = coap_get_tcp_header_type_from_initbyte(((unsigned char *)request)[0] >> 4); + result = COAP_TCP_TID; + break; + default: + break; } + return result; } @@ -1294,7 +1309,6 @@ coap_pdu_t *coap_new_error_response2(coap_pdu_t *request, unsigned char code, co } /* Now create the response and fill with options and payload data. */ - /* TODO : Considering TCP Case */ if (protocol == COAP_PROTO_UDP || protocol == COAP_PROTO_DTLS) { response = coap_pdu_init(type, code, request->transport_hdr->udp.id, COAP_MAX_PDU_SIZE); } else if (protocol == COAP_PROTO_TCP || protocol == COAP_PROTO_TLS) { @@ -1694,7 +1708,12 @@ static inline void handle_response(coap_context_t *context, coap_queue_t *sent, context->response_handler(context, &rcvd->remote, sent ? sent->pdu : NULL, rcvd->pdu, rcvd->id); } else { /* send ACK if rcvd is confirmable (i.e. a separate response) */ - coap_send_ack(context, &rcvd->remote, rcvd->pdu); + if (context->protocol == COAP_PROTO_UDP || context->protocol == COAP_PROTO_DTLS) { + coap_send_ack(context, &rcvd->remote, rcvd->pdu); + } else { + debug("handle_response : do nothing\n"); + /* TODO: CoAP over TCP doesn't have ACK message */ + } } } diff --git a/apps/netutils/libcoap/resource.c b/apps/netutils/libcoap/resource.c index 70cfd28..332fd3e 100644 --- a/apps/netutils/libcoap/resource.c +++ b/apps/netutils/libcoap/resource.c @@ -765,9 +765,10 @@ static void coap_notify_observers(coap_context_t *context, coap_resource_t *r) warn("coap_check_notify : failed to create TCP response\n"); } else { tid = coap_send(context, &obs->subscriber, tcp_resp); - if (COAP_INVALID_TID == tid) { - coap_delete_pdu(tcp_resp); + if (tid == COAP_INVALID_TID) { + debug("coap_check_notify: coap_send failed\n"); } + coap_delete_pdu(tcp_resp); } break; default: -- 2.7.4