From 13f51a03187404927e00d28acb11c5bee47a9f98 Mon Sep 17 00:00:00 2001 From: Dirk Ziegelmeier Date: Fri, 21 Apr 2017 22:10:52 +0200 Subject: [PATCH] Fix bug #50824: Bug in SNTP POLL mode Ignore all broken packets Stop timeouts only when correct packet is received --- src/apps/sntp/sntp.c | 30 ++++++++++++++---------------- 1 file changed, 14 insertions(+), 16 deletions(-) diff --git a/src/apps/sntp/sntp.c b/src/apps/sntp/sntp.c index a1360555..ba0f76a2 100644 --- a/src/apps/sntp/sntp.c +++ b/src/apps/sntp/sntp.c @@ -435,10 +435,6 @@ sntp_recv(void *arg, struct udp_pcb* pcb, struct pbuf *p, const ip_addr_t *addr, LWIP_UNUSED_ARG(arg); LWIP_UNUSED_ARG(pcb); - /* packet received: stop retry timeout */ - sys_untimeout(sntp_try_next_server, NULL); - sys_untimeout(sntp_request, NULL); - err = ERR_ARG; #if SNTP_CHECK_RESPONSE >= 1 /* check server address and port */ @@ -453,7 +449,7 @@ sntp_recv(void *arg, struct udp_pcb* pcb, struct pbuf *p, const ip_addr_t *addr, if (p->tot_len == SNTP_MSG_LEN) { mode = pbuf_get_at(p, SNTP_OFFSET_LI_VN_MODE) & SNTP_MODE_MASK; /* if this is a SNTP response... */ - if (((sntp_opmode == SNTP_OPMODE_POLL) && (mode == SNTP_MODE_SERVER)) || + if (((sntp_opmode == SNTP_OPMODE_POLL) && (mode == SNTP_MODE_SERVER)) || ((sntp_opmode == SNTP_OPMODE_LISTENONLY) && (mode == SNTP_MODE_BROADCAST))) { stratum = pbuf_get_at(p, SNTP_OFFSET_STRATUM); @@ -462,8 +458,7 @@ sntp_recv(void *arg, struct udp_pcb* pcb, struct pbuf *p, const ip_addr_t *addr, err = SNTP_ERR_KOD; LWIP_DEBUGF(SNTP_DEBUG_STATE, ("sntp_recv: Received Kiss-of-Death\n")); } else { - pbuf_copy_partial(p, ×tamps, sizeof(timestamps), - SNTP_OFFSET_TIMESTAMPS); + pbuf_copy_partial(p, ×tamps, sizeof(timestamps), SNTP_OFFSET_TIMESTAMPS); #if SNTP_CHECK_RESPONSE >= 2 /* check originate_timetamp against sntp_last_timestamp_sent */ if (timestamps.orig.sec != sntp_last_timestamp_sent.sec || @@ -493,12 +488,18 @@ sntp_recv(void *arg, struct udp_pcb* pcb, struct pbuf *p, const ip_addr_t *addr, err = ERR_TIMEOUT; } #endif /* SNTP_CHECK_RESPONSE >= 1 */ + pbuf_free(p); + if (err == ERR_OK) { + /* correct packet received: process it it */ sntp_process(×tamps); /* Set up timeout for next request (only if poll response was received)*/ if (sntp_opmode == SNTP_OPMODE_POLL) { + sys_untimeout(sntp_try_next_server, NULL); + sys_untimeout(sntp_request, NULL); + /* Correct response, reset retry timeout */ SNTP_RESET_RETRY_TIMEOUT(); @@ -506,17 +507,14 @@ sntp_recv(void *arg, struct udp_pcb* pcb, struct pbuf *p, const ip_addr_t *addr, LWIP_DEBUGF(SNTP_DEBUG_STATE, ("sntp_recv: Scheduled next time request: %"U32_F" ms\n", (u32_t)SNTP_UPDATE_DELAY)); } - } else if (err != ERR_TIMEOUT) { - /* Errors are only processed in case of an explicit poll response */ + } else if (err == SNTP_ERR_KOD) { + /* KOD errors are only processed in case of an explicit poll response */ if (sntp_opmode == SNTP_OPMODE_POLL) { - if (err == SNTP_ERR_KOD) { - /* Kiss-of-death packet. Use another server or increase UPDATE_DELAY. */ - sntp_try_next_server(NULL); - } else { - /* another error, try the same server again */ - sntp_retry(NULL); - } + /* Kiss-of-death packet. Use another server or increase UPDATE_DELAY. */ + sntp_try_next_server(NULL); } + } else { + /* ignore any broken packet, poll mode: retry after timeout to avoid flooding */ } }