From a5cd7dcbd94c0ebb2c9a43a8b545656b2463692f Mon Sep 17 00:00:00 2001 From: Jon Shallow Date: Wed, 25 Jul 2018 22:09:57 +0100 Subject: [PATCH] net.c,coap_session.c: Flush out session->sendqueue when PDU is delayed Delayed PDUs (found by the limiting of 1 CON request outstanding) are added to session->sendqueue by coap_session_delay_pdu(). The session->sendqueue is only flushed out when a session becomes established by calling coap_session_connected(). This fix now calls coap_session_connected() whenever the current CON count is decremented. Additionally, CON tracking now only tracks UDP & DTLS sessions. coap_session_connected() is updated to not sent out more than one CON request. --- src/coap_session.c | 11 +++++++++-- src/net.c | 18 ++++++++++++++---- 2 files changed, 23 insertions(+), 6 deletions(-) diff --git a/src/coap_session.c b/src/coap_session.c index b5ca7c5d..340a36fc 100644 --- a/src/coap_session.c +++ b/src/coap_session.c @@ -304,7 +304,8 @@ void coap_session_send_csm(coap_session_t *session) { } void coap_session_connected(coap_session_t *session) { - debug("*** %s: session connected\n", coap_session_str(session)); + if (session->state != COAP_SESSION_STATE_ESTABLISHED) + coap_log(LOG_DEBUG, "*** %s: session connected\n", coap_session_str(session)); session->state = COAP_SESSION_STATE_ESTABLISHED; session->partial_write = 0; @@ -322,7 +323,13 @@ void coap_session_connected(coap_session_t *session) { coap_queue_t *q = session->sendqueue; session->sendqueue = q->next; q->next = NULL; - debug("** %s tid=%d: transmitted after delay\n", coap_session_str(session), (int)q->pdu->tid); + if (q->pdu->type == COAP_MESSAGE_CON && COAP_PROTO_NOT_RELIABLE(session->proto)) { + if (session->con_active >= COAP_DEFAULT_NSTART) + break; + session->con_active++; + } + coap_log(LOG_DEBUG, "** %s: tid=%d: transmitted after delay\n", + coap_session_str(session), (int)q->pdu->tid); bytes_written = coap_session_send_pdu(session, q->pdu); if (q->pdu->type == COAP_MESSAGE_CON && COAP_PROTO_NOT_RELIABLE(session->proto)) { if (coap_wait_ack(session->context, session, q) >= 0) diff --git a/src/net.c b/src/net.c index 8632b901..0ed70f5e 100644 --- a/src/net.c +++ b/src/net.c @@ -648,8 +648,9 @@ coap_send_pdu(coap_session_t *session, coap_pdu_t *pdu, coap_queue_t *node) { assert(session->endpoint != NULL); sock = &session->endpoint->sock; } - if (pdu->type == COAP_MESSAGE_CON) + if (pdu->type == COAP_MESSAGE_CON && COAP_PROTO_NOT_RELIABLE(session->proto)) session->con_active++; + bytes_written = coap_socket_send_pdu(sock, session, pdu); if (LOG_DEBUG <= coap_get_log_level()) { coap_show_pdu(pdu); @@ -713,8 +714,9 @@ coap_send_pdu(coap_session_t *session, coap_pdu_t *pdu, coap_queue_t *node) { (session->sock.flags & COAP_SOCKET_WANT_WRITE)) return coap_session_delay_pdu(session, pdu, node); - if (pdu->type == COAP_MESSAGE_CON) + if (pdu->type == COAP_MESSAGE_CON && COAP_PROTO_NOT_RELIABLE(session->proto)) session->con_active++; + bytes_written = coap_session_send_pdu(session, pdu); #endif /* WITH_LWIP */ @@ -2100,8 +2102,12 @@ coap_dispatch(coap_context_t *context, coap_session_t *session, /* find transaction in sendqueue to stop retransmission */ coap_remove_from_queue(&context->sendqueue, session, pdu->tid, &sent); - if (session->con_active) + if (session->con_active) { session->con_active--; + if (session->state == COAP_SESSION_STATE_ESTABLISHED) + /* Flush out any entries on session->sendqueue */ + coap_session_connected(session); + } if (pdu->code == 0) goto cleanup; @@ -2122,8 +2128,12 @@ coap_dispatch(coap_context_t *context, coap_session_t *session, coap_log(LOG_ALERT, "got RST for message %d\n", pdu->tid); - if (session->con_active) + if (session->con_active) { session->con_active--; + if (session->state == COAP_SESSION_STATE_ESTABLISHED) + /* Flush out any entries on session->sendqueue */ + coap_session_connected(session); + } /* find transaction in sendqueue to stop retransmission */ coap_remove_from_queue(&context->sendqueue, session, pdu->tid, &sent);