Page 1 of 1

ESP32 SNTP not work over a pure IPv6 environment

Posted: Mon May 08, 2023 7:40 am
by hsy1000
I used ESP-IDF 4.4v. In order to distinguish my code from the problem of ESP-IDF, I test in the example of ESP-IDF.
esp-idf/examples/protocols/sntp
Modify like this:

Code: Select all

diff --git a/examples/protocols/sntp/main/sntp_example_main.c b/examples/protocols/sntp/main/sntp_example_main.c
index 3733241640..313fcfe001 100644
--- a/examples/protocols/sntp/main/sntp_example_main.c
+++ b/examples/protocols/sntp/main/sntp_example_main.c
@@ -21,6 +21,15 @@
 #include "protocol_examples_common.h"
 #include "esp_sntp.h"
 
+#include "esp_netif_net_stack.h"
+#include "lwip/netif.h"
+#include "ping/ping_sock.h"
+#include "lwip/err.h"
+#include "lwip/sys.h"
+#include "lwip/inet.h"
+#include "lwip/netdb.h"
+#include "lwip/sockets.h"
+
 static const char *TAG = "example";
 
 /* Variable holding number of times ESP32 restarted since first boot.
@@ -116,6 +125,17 @@ void app_main(void)
     esp_deep_sleep(1000000LL * deep_sleep_sec);
 }
 
+void test_task(void * arg)
+{
+	example_connect();
+
+    while(1)
+	{
+		vTaskDelay(50 / portTICK_PERIOD_MS);
+	}
+    vTaskDelete(NULL);
+}
+
 static void obtain_time(void)
 {
     ESP_ERROR_CHECK( nvs_flash_init() );
@@ -134,7 +154,9 @@ static void obtain_time(void)
      * Read "Establishing Wi-Fi or Ethernet Connection" section in
      * examples/protocols/README.md for more information about this function.
      */
-    ESP_ERROR_CHECK(example_connect());
+	xTaskCreate(test_task, "test_task", 20480, NULL, 10, NULL);
+	
+	vTaskDelay(10000 / portTICK_PERIOD_MS);
 
     initialize_sntp();
 
@@ -142,7 +164,7 @@ static void obtain_time(void)
     time_t now = 0;
     struct tm timeinfo = { 0 };
     int retry = 0;
-    const int retry_count = 10;
+    const int retry_count = 30;
     while (sntp_get_sync_status() == SNTP_SYNC_STATUS_RESET && ++retry < retry_count) {
         ESP_LOGI(TAG, "Waiting for system time to be set... (%d/%d)", retry, retry_count);
         vTaskDelay(2000 / portTICK_PERIOD_MS);
@@ -153,11 +175,44 @@ static void obtain_time(void)
     ESP_ERROR_CHECK( example_disconnect() );
 }
 
+int get_ip_addr_from_hostname(char *hostname, ip_addr_t *target_addr, int family)
+{
+	struct addrinfo hint;
+	struct addrinfo *res = NULL;
+	memset(&hint, 0, sizeof(hint));
+	hint.ai_family = family;
+	hint.ai_socktype = SOCK_STREAM;
+	hint.ai_flags = hint.ai_flags | AI_CANONNAME;
+
+	/* convert domain name to IP address */
+	int ret = getaddrinfo(hostname, NULL, &hint, &res);
+	if (ret != 0)
+	{
+		return -1;
+	}
+	if (res->ai_family == AF_INET)
+	{
+		struct in_addr addr4 = ((struct sockaddr_in *) (res->ai_addr))->sin_addr;
+		inet_addr_to_ip4addr(ip_2_ip4(target_addr), &addr4);
+	}
+	else
+	{
+		struct in6_addr addr6 = ((struct sockaddr_in6 *) (res->ai_addr))->sin6_addr;
+		inet6_addr_to_ip6addr(ip_2_ip6(target_addr), &addr6);
+	}
+	freeaddrinfo(res);
+	return 0;
+}
+
 static void initialize_sntp(void)
 {
     ESP_LOGI(TAG, "Initializing SNTP");
     sntp_setoperatingmode(SNTP_OPMODE_POLL);
-    sntp_setservername(0, "pool.ntp.org");
+	ip_addr_t target_addr;
+	memset(&target_addr, 0, sizeof(target_addr));
+	get_ip_addr_from_hostname("2.pool.ntp.org", &target_addr, AF_INET6);
+	ESP_LOGI(TAG, "IPv6 addr %08x, %08x, %08x, %08x", target_addr.u_addr.ip6.addr[0], target_addr.u_addr.ip6.addr[1], target_addr.u_addr.ip6.addr[2], target_addr.u_addr.ip6.addr[3]);
+	sntp_setserver(0, &target_addr);
     sntp_set_time_sync_notification_cb(time_sync_notification_cb);
 #ifdef CONFIG_SNTP_TIME_SYNC_METHOD_SMOOTH
     sntp_set_sync_mode(SNTP_SYNC_MODE_SMOOTH);
I also modify the sdkconfig. see the attachment

here is the result.

Code: Select all

I (5528) example_connect: Got IPv6 event: Interface "example_connect: sta" address: fe80:0000:0000:0000:b68a:0aff:fe24:ed98, type: ESP_IP6_ADDR_IS_LINK_LOCAL
I (5778) wifi:<ba-add>idx:0 (ifx:0, 0a:52:7f:ab:a0:47), tid:0, ssn:0, winSize:64
I (7528) example_connect: Got IPv6 event: Interface "example_connect: sta" address: 2001:0002:0000:aab1:b68a:0aff:fe24:ed98, type: ESP_IP6_ADDR_IS_GLOBAL
I (10528) example: Initializing SNTP
I (10528) example: IPv6 addr 02000120, aa1b0000, 00000000, 8d6fb6c1
I (10528) example: Waiting for system time to be set... (1/30)
I (12538) example: Waiting for system time to be set... (2/30)
I (14538) example: Waiting for system time to be set... (3/30)
I (16538) example: Waiting for system time to be set... (4/30)
I (18538) example: Waiting for system time to be set... (5/30)
I (20538) example: Waiting for system time to be set... (6/30)
I (22538) example: Waiting for system time to be set... (7/30)
I (24538) example: Waiting for system time to be set... (8/30)
I (26538) example: Waiting for system time to be set... (9/30)
I (28538) example: Waiting for system time to be set... (10/30)
I (30538) example: Waiting for system time to be set... (11/30)
I (32538) example: Waiting for system time to be set... (12/30)
I (34538) example: Waiting for system time to be set... (13/30)
I (36538) example: Waiting for system time to be set... (14/30)
I (38538) example: Waiting for system time to be set... (15/30)
I (40538) example: Waiting for system time to be set... (16/30)
I (42538) example: Waiting for system time to be set... (17/30)
I (44538) example: Waiting for system time to be set... (18/30)
I (46538) example: Waiting for system time to be set... (19/30)
I (48538) example: Waiting for system time to be set... (20/30)
I (50538) example: Waiting for system time to be set... (21/30)
I (52538) example: Waiting for system time to be set... (22/30)
I (54538) example: Waiting for system time to be set... (23/30)
I (56538) example: Waiting for system time to be set... (24/30)
I (58538) example: Waiting for system time to be set... (25/30)
I (60538) example: Waiting for system time to be set... (26/30)
I (62538) example: Waiting for system time to be set... (27/30)
I (64538) example: Waiting for system time to be set... (28/30)
I (66538) example: Waiting for system time to be set... (29/30)
I (68538) wifi:state: run -> init (0)
I (68538) wifi:pm stop, total sleep time: 61287149 us / 64606828 us

I (68538) wifi:<ba-del>idx
I (68538) wifi:new:<11,0>, old:<11,0>, ap:<255,255>, sta:<11,0>, prof:1
I (68628) wifi:flush txq
I (68628) wifi:stop sw txq
I (68628) wifi:lmac stop hw txq
I (68628) wifi:Deinit lldesc rx mblock:10
I (68638) example: The current date/time in New York is: Wed Dec 31 19:01:08 1969
I (68638) example: The current date/time in Shanghai is: Thu Jan  1 08:01:08 1970
I (68638) example: Entering deep sleep for 10 seconds
I use wireshake to capture packets, and you can see that the device does not perform SNTP at all.
BTW, if I provide a URL, in a pure IPv6 environment, SNTP won't even parse it for IPv6, just IPv4.