1d4afb5ceSopenharmony_ci/* 2d4afb5ceSopenharmony_ci * lws-api-test-async-dns 3d4afb5ceSopenharmony_ci * 4d4afb5ceSopenharmony_ci * Written in 2019 by Andy Green <andy@warmcat.com> 5d4afb5ceSopenharmony_ci * 6d4afb5ceSopenharmony_ci * This file is made available under the Creative Commons CC0 1.0 7d4afb5ceSopenharmony_ci * Universal Public Domain Dedication. 8d4afb5ceSopenharmony_ci * 9d4afb5ceSopenharmony_ci * This api test confirms various kinds of async dns apis 10d4afb5ceSopenharmony_ci */ 11d4afb5ceSopenharmony_ci 12d4afb5ceSopenharmony_ci#include <libwebsockets.h> 13d4afb5ceSopenharmony_ci#include <signal.h> 14d4afb5ceSopenharmony_ci 15d4afb5ceSopenharmony_cistatic int interrupted, dtest, ok, fail, _exp = 26; 16d4afb5ceSopenharmony_cistruct lws_context *context; 17d4afb5ceSopenharmony_ci 18d4afb5ceSopenharmony_ci/* 19d4afb5ceSopenharmony_ci * These are used to test the apis to parse and print ipv4 / ipv6 literal 20d4afb5ceSopenharmony_ci * address strings for various cases. 21d4afb5ceSopenharmony_ci * 22d4afb5ceSopenharmony_ci * Expected error cases are not used to test the ip data -> string api. 23d4afb5ceSopenharmony_ci */ 24d4afb5ceSopenharmony_ci 25d4afb5ceSopenharmony_cistatic const struct ipparser_tests { 26d4afb5ceSopenharmony_ci const char *test; 27d4afb5ceSopenharmony_ci int rlen; 28d4afb5ceSopenharmony_ci const char *emit_test; 29d4afb5ceSopenharmony_ci int emit_len; 30d4afb5ceSopenharmony_ci uint8_t b[16]; 31d4afb5ceSopenharmony_ci} ipt[] = { 32d4afb5ceSopenharmony_ci { "2001:db8:85a3:0:0:8a2e:370:7334", 16, 33d4afb5ceSopenharmony_ci "2001:db8:85a3::8a2e:370:7334", 28, 34d4afb5ceSopenharmony_ci { 0x20, 0x01, 0x0d, 0xb8, 0x85, 0xa3, 0x00, 0x00, 35d4afb5ceSopenharmony_ci 0x00, 0x00, 0x8a, 0x2e, 0x03, 0x70, 0x73, 0x34 } }, 36d4afb5ceSopenharmony_ci 37d4afb5ceSopenharmony_ci { "2001:db8:85a3::8a2e:370:7334", 16, 38d4afb5ceSopenharmony_ci "2001:db8:85a3::8a2e:370:7334", 28, 39d4afb5ceSopenharmony_ci { 0x20, 0x01, 0x0d, 0xb8, 0x85, 0xa3, 0x00, 0x00, 40d4afb5ceSopenharmony_ci 0x00, 0x00, 0x8a, 0x2e, 0x03, 0x70, 0x73, 0x34 } }, 41d4afb5ceSopenharmony_ci 42d4afb5ceSopenharmony_ci { "::1", 16, "::1", 3, 43d4afb5ceSopenharmony_ci { 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 1 } }, 44d4afb5ceSopenharmony_ci 45d4afb5ceSopenharmony_ci { "::", 16, "::", 2, 46d4afb5ceSopenharmony_ci { 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0 } }, 47d4afb5ceSopenharmony_ci 48d4afb5ceSopenharmony_ci { "::ffff:192.0.2.128", 16, "::ffff:192.0.2.128", 18, 49d4afb5ceSopenharmony_ci { 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 50d4afb5ceSopenharmony_ci 0x00, 0x00, 0xff, 0xff, 0xc0, 0x00, 0x02, 0x80 } }, 51d4afb5ceSopenharmony_ci 52d4afb5ceSopenharmony_ci { "cats", -1, "", 0, 53d4afb5ceSopenharmony_ci { 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 1 } }, 54d4afb5ceSopenharmony_ci 55d4afb5ceSopenharmony_ci { "onevalid.bogus.warmcat.com", -1, "", 0, 56d4afb5ceSopenharmony_ci { 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 1 } }, 57d4afb5ceSopenharmony_ci 58d4afb5ceSopenharmony_ci { "1.cat.dog.com", -1, "", 0, 59d4afb5ceSopenharmony_ci { 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 1 } }, 60d4afb5ceSopenharmony_ci 61d4afb5ceSopenharmony_ci { ":::1", -8, "", 0, 62d4afb5ceSopenharmony_ci { 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 1 } }, 63d4afb5ceSopenharmony_ci 64d4afb5ceSopenharmony_ci { "0:0::0:1", 16, "::1", 3, 65d4afb5ceSopenharmony_ci { 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 1 } }, 66d4afb5ceSopenharmony_ci 67d4afb5ceSopenharmony_ci { "1.2.3.4", 4, "1.2.3.4", 7, { 1, 2, 3, 4 } }, 68d4afb5ceSopenharmony_ci}; 69d4afb5ceSopenharmony_ci 70d4afb5ceSopenharmony_cistatic const struct async_dns_tests { 71d4afb5ceSopenharmony_ci const char *dns_name; 72d4afb5ceSopenharmony_ci int recordtype; 73d4afb5ceSopenharmony_ci int addrlen; 74d4afb5ceSopenharmony_ci uint8_t ads[16]; 75d4afb5ceSopenharmony_ci} adt[] = { 76d4afb5ceSopenharmony_ci { "warmcat.com", LWS_ADNS_RECORD_A, 4, 77d4afb5ceSopenharmony_ci { 46, 105, 127, 147, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, } }, 78d4afb5ceSopenharmony_ci { "libwebsockets.org", LWS_ADNS_RECORD_A, 4, 79d4afb5ceSopenharmony_ci { 46, 105, 127, 147, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, } }, 80d4afb5ceSopenharmony_ci { "doesntexist", LWS_ADNS_RECORD_A, 0, 81d4afb5ceSopenharmony_ci { 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, } }, 82d4afb5ceSopenharmony_ci { "localhost", LWS_ADNS_RECORD_A, 4, 83d4afb5ceSopenharmony_ci { 127, 0, 0, 1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, } }, 84d4afb5ceSopenharmony_ci { "ipv4only.warmcat.com", LWS_ADNS_RECORD_A, 4, 85d4afb5ceSopenharmony_ci { 46, 105, 127, 147, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, } }, 86d4afb5ceSopenharmony_ci { "onevalid.bogus.warmcat.com", LWS_ADNS_RECORD_A, 4, 87d4afb5ceSopenharmony_ci { 46, 105, 127, 147, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, } }, 88d4afb5ceSopenharmony_ci#if defined(LWS_WITH_IPV6) 89d4afb5ceSopenharmony_ci { "warmcat.com", LWS_ADNS_RECORD_AAAA, 16, /* check ipv6 */ 90d4afb5ceSopenharmony_ci { 0x20, 0x01, 0x41, 0xd0, 0x00, 0x02, 0xee, 0x93, 91d4afb5ceSopenharmony_ci 0, 0, 0, 0, 0, 0, 0, 1, } }, 92d4afb5ceSopenharmony_ci { "ipv6only.warmcat.com", LWS_ADNS_RECORD_AAAA, 16, /* check ipv6 */ 93d4afb5ceSopenharmony_ci { 0x20, 0x01, 0x41, 0xd0, 0x00, 0x02, 0xee, 0x93, 94d4afb5ceSopenharmony_ci 0, 0, 0, 0, 0, 0, 0, 1, } }, 95d4afb5ceSopenharmony_ci#endif 96d4afb5ceSopenharmony_ci}; 97d4afb5ceSopenharmony_ci 98d4afb5ceSopenharmony_cistatic lws_sorted_usec_list_t sul; 99d4afb5ceSopenharmony_ci 100d4afb5ceSopenharmony_cistruct lws * 101d4afb5ceSopenharmony_cicb1(struct lws *wsi_unused, const char *ads, const struct addrinfo *a, int n, 102d4afb5ceSopenharmony_ci void *opaque); 103d4afb5ceSopenharmony_ci 104d4afb5ceSopenharmony_cistatic void 105d4afb5ceSopenharmony_cinext_test_cb(lws_sorted_usec_list_t *sul) 106d4afb5ceSopenharmony_ci{ 107d4afb5ceSopenharmony_ci int m; 108d4afb5ceSopenharmony_ci 109d4afb5ceSopenharmony_ci lwsl_notice("%s: querying %s\n", __func__, adt[dtest].dns_name); 110d4afb5ceSopenharmony_ci 111d4afb5ceSopenharmony_ci m = lws_async_dns_query(context, 0, 112d4afb5ceSopenharmony_ci adt[dtest].dns_name, 113d4afb5ceSopenharmony_ci (adns_query_type_t)adt[dtest].recordtype, cb1, NULL, 114d4afb5ceSopenharmony_ci context); 115d4afb5ceSopenharmony_ci if (m != LADNS_RET_CONTINUING && m != LADNS_RET_FOUND && m != LADNS_RET_FAILED_WSI_CLOSED) { 116d4afb5ceSopenharmony_ci lwsl_err("%s: adns 1: %s failed: %d\n", __func__, adt[dtest].dns_name, m); 117d4afb5ceSopenharmony_ci interrupted = 1; 118d4afb5ceSopenharmony_ci } 119d4afb5ceSopenharmony_ci} 120d4afb5ceSopenharmony_ci 121d4afb5ceSopenharmony_cistruct lws * 122d4afb5ceSopenharmony_cicb1(struct lws *wsi_unused, const char *ads, const struct addrinfo *a, int n, 123d4afb5ceSopenharmony_ci void *opaque) 124d4afb5ceSopenharmony_ci{ 125d4afb5ceSopenharmony_ci const struct addrinfo *ac = a; 126d4afb5ceSopenharmony_ci int ctr = 0, alen; 127d4afb5ceSopenharmony_ci uint8_t *addr; 128d4afb5ceSopenharmony_ci char buf[64]; 129d4afb5ceSopenharmony_ci 130d4afb5ceSopenharmony_ci dtest++; 131d4afb5ceSopenharmony_ci 132d4afb5ceSopenharmony_ci if (!ac) 133d4afb5ceSopenharmony_ci lwsl_warn("%s: no results\n", __func__); 134d4afb5ceSopenharmony_ci 135d4afb5ceSopenharmony_ci /* dump the results */ 136d4afb5ceSopenharmony_ci 137d4afb5ceSopenharmony_ci while (ac) { 138d4afb5ceSopenharmony_ci if (ac->ai_family == AF_INET) { 139d4afb5ceSopenharmony_ci addr = (uint8_t *)&(((struct sockaddr_in *) 140d4afb5ceSopenharmony_ci ac->ai_addr)->sin_addr.s_addr); 141d4afb5ceSopenharmony_ci alen = 4; 142d4afb5ceSopenharmony_ci } else { 143d4afb5ceSopenharmony_ci addr = (uint8_t *)&(((struct sockaddr_in6 *) 144d4afb5ceSopenharmony_ci ac->ai_addr)->sin6_addr.s6_addr); 145d4afb5ceSopenharmony_ci alen = 16; 146d4afb5ceSopenharmony_ci } 147d4afb5ceSopenharmony_ci strcpy(buf, "unknown"); 148d4afb5ceSopenharmony_ci lws_write_numeric_address(addr, alen, buf, sizeof(buf)); 149d4afb5ceSopenharmony_ci 150d4afb5ceSopenharmony_ci lwsl_warn("%s: %d: %s %d %s\n", __func__, ctr++, ads, alen, buf); 151d4afb5ceSopenharmony_ci 152d4afb5ceSopenharmony_ci ac = ac->ai_next; 153d4afb5ceSopenharmony_ci } 154d4afb5ceSopenharmony_ci 155d4afb5ceSopenharmony_ci ac = a; 156d4afb5ceSopenharmony_ci while (ac) { 157d4afb5ceSopenharmony_ci if (ac->ai_family == AF_INET) { 158d4afb5ceSopenharmony_ci addr = (uint8_t *)&(((struct sockaddr_in *) 159d4afb5ceSopenharmony_ci ac->ai_addr)->sin_addr.s_addr); 160d4afb5ceSopenharmony_ci alen = 4; 161d4afb5ceSopenharmony_ci } else { 162d4afb5ceSopenharmony_ci#if defined(LWS_WITH_IPV6) 163d4afb5ceSopenharmony_ci addr = (uint8_t *)&(((struct sockaddr_in6 *) 164d4afb5ceSopenharmony_ci ac->ai_addr)->sin6_addr.s6_addr); 165d4afb5ceSopenharmony_ci alen = 16; 166d4afb5ceSopenharmony_ci#else 167d4afb5ceSopenharmony_ci goto again; 168d4afb5ceSopenharmony_ci#endif 169d4afb5ceSopenharmony_ci } 170d4afb5ceSopenharmony_ci if (alen == adt[dtest - 1].addrlen && 171d4afb5ceSopenharmony_ci !memcmp(adt[dtest - 1].ads, addr, (unsigned int)alen)) { 172d4afb5ceSopenharmony_ci ok++; 173d4afb5ceSopenharmony_ci goto next; 174d4afb5ceSopenharmony_ci } 175d4afb5ceSopenharmony_ci#if !defined(LWS_WITH_IPV6) 176d4afb5ceSopenharmony_ciagain: 177d4afb5ceSopenharmony_ci#endif 178d4afb5ceSopenharmony_ci ac = ac->ai_next; 179d4afb5ceSopenharmony_ci } 180d4afb5ceSopenharmony_ci 181d4afb5ceSopenharmony_ci /* testing for NXDOMAIN? */ 182d4afb5ceSopenharmony_ci 183d4afb5ceSopenharmony_ci if (!a && !adt[dtest - 1].addrlen) { 184d4afb5ceSopenharmony_ci ok++; 185d4afb5ceSopenharmony_ci goto next; 186d4afb5ceSopenharmony_ci } 187d4afb5ceSopenharmony_ci 188d4afb5ceSopenharmony_ci lwsl_err("%s: dns test %d: no match\n", __func__, dtest); 189d4afb5ceSopenharmony_ci fail++; 190d4afb5ceSopenharmony_ci 191d4afb5ceSopenharmony_cinext: 192d4afb5ceSopenharmony_ci lws_async_dns_freeaddrinfo(&a); 193d4afb5ceSopenharmony_ci if (dtest == (int)LWS_ARRAY_SIZE(adt)) 194d4afb5ceSopenharmony_ci interrupted = 1; 195d4afb5ceSopenharmony_ci else 196d4afb5ceSopenharmony_ci lws_sul_schedule(context, 0, &sul, next_test_cb, 1); 197d4afb5ceSopenharmony_ci 198d4afb5ceSopenharmony_ci return NULL; 199d4afb5ceSopenharmony_ci} 200d4afb5ceSopenharmony_ci 201d4afb5ceSopenharmony_cistatic lws_sorted_usec_list_t sul_l; 202d4afb5ceSopenharmony_ci 203d4afb5ceSopenharmony_cistruct lws * 204d4afb5ceSopenharmony_cicb_loop(struct lws *wsi_unused, const char *ads, const struct addrinfo *a, int n, 205d4afb5ceSopenharmony_ci void *opaque) 206d4afb5ceSopenharmony_ci{ 207d4afb5ceSopenharmony_ci if (!a) { 208d4afb5ceSopenharmony_ci lwsl_err("%s: no results\n", __func__); 209d4afb5ceSopenharmony_ci return NULL; 210d4afb5ceSopenharmony_ci } 211d4afb5ceSopenharmony_ci 212d4afb5ceSopenharmony_ci lwsl_notice("%s: addrinfo %p\n", __func__, a);\ 213d4afb5ceSopenharmony_ci lws_async_dns_freeaddrinfo(&a); 214d4afb5ceSopenharmony_ci 215d4afb5ceSopenharmony_ci return NULL; 216d4afb5ceSopenharmony_ci} 217d4afb5ceSopenharmony_ci 218d4afb5ceSopenharmony_ci 219d4afb5ceSopenharmony_cistatic void 220d4afb5ceSopenharmony_cisul_retry_l(struct lws_sorted_usec_list *sul) 221d4afb5ceSopenharmony_ci{ 222d4afb5ceSopenharmony_ci int m; 223d4afb5ceSopenharmony_ci 224d4afb5ceSopenharmony_ci lwsl_user("%s: starting new query\n", __func__); 225d4afb5ceSopenharmony_ci 226d4afb5ceSopenharmony_ci m = lws_async_dns_query(context, 0, "warmcat.com", 227d4afb5ceSopenharmony_ci (adns_query_type_t)LWS_ADNS_RECORD_A, 228d4afb5ceSopenharmony_ci cb_loop, NULL, context); 229d4afb5ceSopenharmony_ci switch (m) { 230d4afb5ceSopenharmony_ci case LADNS_RET_FAILED_WSI_CLOSED: 231d4afb5ceSopenharmony_ci lwsl_warn("%s: LADNS_RET_FAILED_WSI_CLOSED " 232d4afb5ceSopenharmony_ci "(== from cache / success in this test)\n", __func__); 233d4afb5ceSopenharmony_ci break; 234d4afb5ceSopenharmony_ci case LADNS_RET_NXDOMAIN: 235d4afb5ceSopenharmony_ci lwsl_warn("%s: LADNS_RET_NXDOMAIN\n", __func__); 236d4afb5ceSopenharmony_ci break; 237d4afb5ceSopenharmony_ci case LADNS_RET_TIMEDOUT: 238d4afb5ceSopenharmony_ci lwsl_warn("%s: LADNS_RET_TIMEDOUT\n", __func__); 239d4afb5ceSopenharmony_ci break; 240d4afb5ceSopenharmony_ci case LADNS_RET_FAILED: 241d4afb5ceSopenharmony_ci lwsl_warn("%s: LADNS_RET_FAILED\n", __func__); 242d4afb5ceSopenharmony_ci break; 243d4afb5ceSopenharmony_ci case LADNS_RET_FOUND: 244d4afb5ceSopenharmony_ci lwsl_warn("%s: LADNS_RET_FOUND\n", __func__); 245d4afb5ceSopenharmony_ci break; 246d4afb5ceSopenharmony_ci case LADNS_RET_CONTINUING: 247d4afb5ceSopenharmony_ci lwsl_warn("%s: LADNS_RET_CONTINUING\n", __func__); 248d4afb5ceSopenharmony_ci break; 249d4afb5ceSopenharmony_ci } 250d4afb5ceSopenharmony_ci 251d4afb5ceSopenharmony_ci lws_sul_schedule(context, 0, &sul_l, sul_retry_l, 5 * LWS_US_PER_SEC); 252d4afb5ceSopenharmony_ci} 253d4afb5ceSopenharmony_ci 254d4afb5ceSopenharmony_civoid sigint_handler(int sig) 255d4afb5ceSopenharmony_ci{ 256d4afb5ceSopenharmony_ci interrupted = 1; 257d4afb5ceSopenharmony_ci} 258d4afb5ceSopenharmony_ci 259d4afb5ceSopenharmony_ciint 260d4afb5ceSopenharmony_cimain(int argc, const char **argv) 261d4afb5ceSopenharmony_ci{ 262d4afb5ceSopenharmony_ci int n = 1, logs = LLL_USER | LLL_ERR | LLL_WARN | LLL_NOTICE; 263d4afb5ceSopenharmony_ci struct lws_context_creation_info info; 264d4afb5ceSopenharmony_ci const char *p; 265d4afb5ceSopenharmony_ci 266d4afb5ceSopenharmony_ci /* the normal lws init */ 267d4afb5ceSopenharmony_ci 268d4afb5ceSopenharmony_ci signal(SIGINT, sigint_handler); 269d4afb5ceSopenharmony_ci 270d4afb5ceSopenharmony_ci if ((p = lws_cmdline_option(argc, argv, "-d"))) 271d4afb5ceSopenharmony_ci logs = atoi(p); 272d4afb5ceSopenharmony_ci 273d4afb5ceSopenharmony_ci lws_set_log_level(logs, NULL); 274d4afb5ceSopenharmony_ci lwsl_user("LWS API selftest: Async DNS\n"); 275d4afb5ceSopenharmony_ci 276d4afb5ceSopenharmony_ci memset(&info, 0, sizeof info); /* otherwise uninitialized garbage */ 277d4afb5ceSopenharmony_ci info.port = CONTEXT_PORT_NO_LISTEN; 278d4afb5ceSopenharmony_ci info.options = LWS_SERVER_OPTION_DO_SSL_GLOBAL_INIT; 279d4afb5ceSopenharmony_ci 280d4afb5ceSopenharmony_ci context = lws_create_context(&info); 281d4afb5ceSopenharmony_ci if (!context) { 282d4afb5ceSopenharmony_ci lwsl_err("lws init failed\n"); 283d4afb5ceSopenharmony_ci return 1; 284d4afb5ceSopenharmony_ci } 285d4afb5ceSopenharmony_ci 286d4afb5ceSopenharmony_ci if (lws_cmdline_option(argc, argv, "-l")) { 287d4afb5ceSopenharmony_ci lws_sul_schedule(context, 0, &sul_l, sul_retry_l, LWS_US_PER_SEC); 288d4afb5ceSopenharmony_ci goto evloop; 289d4afb5ceSopenharmony_ci } 290d4afb5ceSopenharmony_ci 291d4afb5ceSopenharmony_ci 292d4afb5ceSopenharmony_ci /* ip address parser tests */ 293d4afb5ceSopenharmony_ci 294d4afb5ceSopenharmony_ci for (n = 0; n < (int)LWS_ARRAY_SIZE(ipt); n++) { 295d4afb5ceSopenharmony_ci uint8_t u[16]; 296d4afb5ceSopenharmony_ci int m = lws_parse_numeric_address(ipt[n].test, u, sizeof(u)); 297d4afb5ceSopenharmony_ci 298d4afb5ceSopenharmony_ci if (m != ipt[n].rlen) { 299d4afb5ceSopenharmony_ci lwsl_err("%s: fail %s ret %d\n", 300d4afb5ceSopenharmony_ci __func__, ipt[n].test, m); 301d4afb5ceSopenharmony_ci fail++; 302d4afb5ceSopenharmony_ci continue; 303d4afb5ceSopenharmony_ci } 304d4afb5ceSopenharmony_ci 305d4afb5ceSopenharmony_ci if (m > 0) { 306d4afb5ceSopenharmony_ci if (memcmp(ipt[n].b, u, (unsigned int)m)) { 307d4afb5ceSopenharmony_ci lwsl_err("%s: fail %s compare\n", __func__, 308d4afb5ceSopenharmony_ci ipt[n].test); 309d4afb5ceSopenharmony_ci lwsl_hexdump_notice(u, (unsigned int)m); 310d4afb5ceSopenharmony_ci fail++; 311d4afb5ceSopenharmony_ci continue; 312d4afb5ceSopenharmony_ci } 313d4afb5ceSopenharmony_ci } 314d4afb5ceSopenharmony_ci ok++; 315d4afb5ceSopenharmony_ci } 316d4afb5ceSopenharmony_ci 317d4afb5ceSopenharmony_ci /* ip address formatter tests */ 318d4afb5ceSopenharmony_ci 319d4afb5ceSopenharmony_ci for (n = 0; n < (int)LWS_ARRAY_SIZE(ipt); n++) { 320d4afb5ceSopenharmony_ci char buf[64]; 321d4afb5ceSopenharmony_ci int m; 322d4afb5ceSopenharmony_ci 323d4afb5ceSopenharmony_ci /* don't attempt to reverse the ones that are meant to fail */ 324d4afb5ceSopenharmony_ci if (ipt[n].rlen < 0) 325d4afb5ceSopenharmony_ci continue; 326d4afb5ceSopenharmony_ci 327d4afb5ceSopenharmony_ci m = lws_write_numeric_address(ipt[n].b, ipt[n].rlen, buf, 328d4afb5ceSopenharmony_ci sizeof(buf)); 329d4afb5ceSopenharmony_ci if (m != ipt[n].emit_len) { 330d4afb5ceSopenharmony_ci lwsl_err("%s: fail %s ret %d\n", 331d4afb5ceSopenharmony_ci __func__, ipt[n].emit_test, m); 332d4afb5ceSopenharmony_ci fail++; 333d4afb5ceSopenharmony_ci continue; 334d4afb5ceSopenharmony_ci } 335d4afb5ceSopenharmony_ci 336d4afb5ceSopenharmony_ci if (m > 0) { 337d4afb5ceSopenharmony_ci if (strcmp(ipt[n].emit_test, buf)) { 338d4afb5ceSopenharmony_ci lwsl_err("%s: fail %s compare\n", __func__, 339d4afb5ceSopenharmony_ci ipt[n].test); 340d4afb5ceSopenharmony_ci lwsl_hexdump_notice(buf, (unsigned int)m); 341d4afb5ceSopenharmony_ci fail++; 342d4afb5ceSopenharmony_ci continue; 343d4afb5ceSopenharmony_ci } 344d4afb5ceSopenharmony_ci } 345d4afb5ceSopenharmony_ci ok++; 346d4afb5ceSopenharmony_ci } 347d4afb5ceSopenharmony_ci 348d4afb5ceSopenharmony_ci#if !defined(LWS_WITH_IPV6) 349d4afb5ceSopenharmony_ci _exp -= 2; 350d4afb5ceSopenharmony_ci#endif 351d4afb5ceSopenharmony_ci 352d4afb5ceSopenharmony_ci /* kick off the async dns tests */ 353d4afb5ceSopenharmony_ci 354d4afb5ceSopenharmony_ci lws_sul_schedule(context, 0, &sul, next_test_cb, 1); 355d4afb5ceSopenharmony_ci 356d4afb5ceSopenharmony_cievloop: 357d4afb5ceSopenharmony_ci /* the usual lws event loop */ 358d4afb5ceSopenharmony_ci 359d4afb5ceSopenharmony_ci n = 1; 360d4afb5ceSopenharmony_ci while (n >= 0 && !interrupted) 361d4afb5ceSopenharmony_ci n = lws_service(context, 0); 362d4afb5ceSopenharmony_ci 363d4afb5ceSopenharmony_ci lws_context_destroy(context); 364d4afb5ceSopenharmony_ci 365d4afb5ceSopenharmony_ci if (fail || ok != _exp) 366d4afb5ceSopenharmony_ci lwsl_user("Completed: PASS: %d / %d, FAIL: %d\n", ok, _exp, 367d4afb5ceSopenharmony_ci fail); 368d4afb5ceSopenharmony_ci else 369d4afb5ceSopenharmony_ci lwsl_user("Completed: ALL PASS: %d / %d\n", ok, _exp); 370d4afb5ceSopenharmony_ci 371d4afb5ceSopenharmony_ci return !(ok == _exp && !fail); 372d4afb5ceSopenharmony_ci} 373