📄 test_sresolv.c
字号:
ctx->sinkidx = 0; sres_close(ctx->sink), ctx->sink = INVALID_SOCKET; END();}#endifint test_timeout(sres_context_t *ctx){ sres_resolver_t *res = ctx->resolver; sres_record_t **result; /* const sres_soa_record_t *rr_soa; */ char const *domain = "test"; BEGIN(); sres_query(res, test_answer, ctx, sres_type_a, domain); ctx->timeout = 1; TEST_RUN(ctx); ctx->timeout = 0; TEST_P(ctx->result, NULL); result = sres_cached_answers(res, sres_type_a, domain);#if 0 /* Currently, we do not create error records */ TEST_1(result); TEST_1(result[0] != NULL); rr_soa = result[0]->sr_soa; TEST(rr_soa->soa_record->r_type, sres_type_soa); TEST(rr_soa->soa_record->r_class, sres_class_in); TEST_S(rr_soa->soa_record->r_name, "example.com."); TEST(rr_soa->soa_record->r_status, SRES_TIMEOUT_ERR); sres_free_answers(res, result);#else TEST_1(result == NULL);#endif END();}static void test_answer(sres_context_t *ctx, sres_query_t *q, sres_record_t **answer){ ctx->query = q; if (ctx->result) sres_free_answers(ctx->resolver, ctx->result); ctx->result = answer; BREAK(ctx);}static void test_answer_multi(sres_context_t *ctx, sres_query_t *q, sres_record_t **answer){ static int count = 0; ctx->query = q; count++; sres_free_answers(ctx->resolver, answer); if (count == 6) BREAK(ctx);}#include <sys/time.h>/* Fake time() implementation, used by sresolv library */time_t time(time_t *tp){ struct timeval tv[1];#ifndef _WIN32 gettimeofday(tv, NULL);#else return 0;#endif if (tp) *tp = tv->tv_sec + offset; return tv->tv_sec + offset;}int test_expiration(sres_context_t *ctx){ sres_resolver_t *res = ctx->resolver; sres_record_t **result; char const *domain = "example.com"; BEGIN(); offset = 3600; /* Time suddenly proceeds by an hour.. */ sres_resolver_timer(res, -1); result = sres_cached_answers(res, sres_qtype_any, domain); TEST_P(result, NULL); /* the cache should be empty after 15 secs */ END();}#define is_hexdigit(c) ((c >= '0' && c <= '9') || (c >= 'a' && c <= 'f'))#define hex(c) ((c >= '0' && c <= '9') ? (c - '0') : (c - 'a' + 10))/* Convert lowercase hex to binary */staticvoid *hex2bin(char const *test_name, char const *hex1, char const *hex2, size_t *binsize){ char output[2048]; char *bin; char const *b; size_t j; if (hex1 == NULL || binsize == NULL) return NULL; for (b = hex1, j = 0; b;) { while (b[0]) { if (is_hexdigit(b[0])) { if (!is_hexdigit(b[1])) { fprintf(stderr, "%s: hex2bin: invalid hex '%c'\n", test_name, b[1]); exit(2); } output[j++] = (hex(b[0]) << 4) | hex(b[1]); if (j == sizeof(output)) { fprintf(stderr, "%s:%u: hex2bin: buffer too small\n", __FILE__, __LINE__); exit(2); } b++; } else if (b[0] != ' ') { fprintf(stderr, "%s: hex2bin: invalid nonhex '%c'\n", test_name, b[0]); exit(2); } b++; } b = hex2, hex2 = NULL; } bin = malloc(j); if (bin == NULL) perror("malloc"), exit(2); return memcpy(bin, output, *binsize = j);}static char const hextest[] = " 34 44 85 80 00 01 00 04 " "00 01 00 08 07 65 78 61 6d 70 6c 65 03 63 6f 6d " "00 00 23 00 01 c0 0c 00 23 00 01 00 00 00 3c 00 " "26 00 28 00 0f 01 73 07 53 49 50 2b 44 32 55 00 " "04 5f 73 69 70 04 5f 75 64 70 07 65 78 61 6d 70 " "6c 65 03 63 6f 6d 00 c0 42 00 23 00 01 00 00 00 " "3c 00 3e 00 32 00 0f 01 75 08 54 45 53 54 2b 44 " "32 55 2d 2f 28 74 73 74 3a 28 5b 5e 40 5d 2b 40 " "29 29 3f 65 78 61 6d 70 6c 65 2e 63 6f 6d 24 2f " "5c 31 6f 70 65 72 61 74 6f 72 2e 63 6f 6d 2f 69 " "00 c0 42 00 23 00 01 00 00 00 3c 00 26 00 50 00 " "19 01 73 07 53 49 50 2b 44 32 54 00 04 5f 73 69 " "70 04 5f 74 63 70 07 65 78 61 6d 70 6c 65 03 63 " "6f 6d 00 c0 be 00 23 00 01 00 00 00 3c 00 28 00 " "14 00 32 01 73 08 53 49 50 53 2b 44 32 54 00 05 " "5f 73 69 70 73 04 5f 74 63 70 07 65 78 61 6d 70 " "6c 65 03 63 6f 6d 00 c0 f2 00 02 00 01 00 00 00 " "3c 00 05 02 6e 73 c0 f2 05 73 69 70 30 30 c0 f2 " "00 01 00 01 00 00 00 3c 00 04 c2 02 bc 85 c1 10 " "00 1c 00 01 00 00 00 3c 00 10 3f f0 00 10 30 12 " "c0 00 02 c0 95 ff fe e2 4b 78 05 73 69 70 30 32 " "c0 f2 00 01 00 01 00 00 00 3c 00 04 c2 02 bc 87 " "c1 42 00 1c 00 01 00 00 00 3c 00 10 3f fe 12 00 " "30 12 c0 06 02 06 5b ff fe 55 46 2f 05 73 69 70 " "30 31 c0 f2 00 01 00 01 00 00 00 3c 00 04 c2 02 " "bc 86 c1 74 00 1c 00 01 00 00 00 3c 00 10 3f f0 " "00 12 30 12 c0 06 0a 08 20 ff fe 7d e7 ac c1 0b " "00 01 00 01 00 00 00 3c 00 04 c2 02 bc 85 c1 0b " "00 26 00 01 00 00 00 3c 00 11 00 3f fe 12 00 30 " "12 c0 00 02 10 a4 ff fe 8d 6a 46 ";int test_net(sres_context_t *ctx){ sres_resolver_t *res = ctx->resolver; sres_query_t *q = NULL; sres_socket_t c = ctx->sink; struct sockaddr_storage ss[1]; struct sockaddr *sa = (void *)ss; socklen_t salen = sizeof ss; char *bin; size_t i, binlen; ssize_t n; char const *domain = "example.com"; char query[512]; BEGIN(); TEST_1(ctx->sink != INVALID_SOCKET && ctx->sink != (sres_socket_t)0); /* Prepare for test_answer() callback */ sres_free_answers(ctx->resolver, ctx->result); ctx->result = NULL; ctx->query = NULL; /* Get canned response */ TEST_1(bin = hex2bin(__func__, hextest, NULL, &binlen)); /* Send responses with one erroneus byte */ for (i = 1; i < binlen; i++) { if (!q) { /* We got an error => make new query */ TEST_1(q = sres_query(res, test_answer, ctx, /* Send query */ sres_type_naptr, domain)); TEST_1((n = sres_recvfrom(c, query, sizeof query, 0, sa, &salen)) != -1); memcpy(bin, query, 2); /* Copy ID */ } if (i != 1) bin[i] ^= 0xff; else bin[3] ^= SRES_FORMAT_ERR; /* format error -> EDNS0 failure */ n = sres_sendto(c, bin, binlen, 0, sa, salen); if (i != 1) bin[i] ^= 0xff; else bin[3] ^= SRES_FORMAT_ERR; if (n == -1) perror("sendto"); while (!poll_sockets(ctx)) ; if (ctx->query) q = NULL; } /* Send runt responses */ for (i = 1; i <= binlen; i++) { if (!q) { /* We got an error => make new query */ TEST_1(q = sres_query(res, test_answer, ctx, /* Send query */ sres_type_naptr, domain)); TEST_1((n = sres_recvfrom(c, query, sizeof query, 0, sa, &salen)) != -1); memcpy(bin, query, 2); /* Copy ID */ } n = sres_sendto(c, bin, i, 0, sa, salen); if (n == -1) perror("sendto"); while (!poll_sockets(ctx)) ; if (ctx->query) q = NULL; } free(bin); END();}staticint test_init(sres_context_t *ctx, char const *conf_file){ BEGIN(); sres_resolver_t *res; int i, n; ctx->query = NULL, ctx->result = NULL; TEST_1(ctx->resolver = res = sres_resolver_new(conf_file)); TEST(su_home_threadsafe((su_home_t *)ctx->resolver), 0); n = sres_resolver_sockets(res, NULL, 0); ctx->n_sockets = n; TEST_1(n < SRES_MAX_NAMESERVERS); TEST(sres_resolver_sockets(res, ctx->sockets, n), n); for (i = 0; i < n; i++) { ctx->fds[i].fd = ctx->sockets[i]; ctx->fds[i].events = POLLIN | POLLERR; } TEST_P(sres_resolver_ref(ctx->resolver), ctx->resolver); sres_resolver_unref(ctx->resolver); END();}staticint test_deinit(sres_context_t *ctx){ offset += 2 * 36000000; sres_resolver_timer(ctx->resolver, -1); /* Zap everything */ sres_free_answers(ctx->resolver, ctx->result); ctx->result = NULL; su_free(ctx->home, (void *)ctx->sinkconf); ctx->sinkconf = NULL; sres_resolver_unref(ctx->resolver); ctx->resolver = NULL; offset = 0; memset(ctx, 0, sizeof ctx); ctx->home->suh_size = sizeof ctx; return 0;}staticint test_conf_errors(sres_context_t *ctx, char const *conf_file){ sres_resolver_t *res; sres_socket_t socket; int n; BEGIN(); TEST_1(res = sres_resolver_new(conf_file)); n = sres_resolver_sockets(res, NULL, 0); TEST_1(n > 0); TEST(sres_resolver_sockets(res, &socket, 1), n);#if !__linux /* We fail this test in most systems */ /* conf_file looks like this:--8<--8<--8<--8<--8<--8<--8<--8<--8<--8<--8<--8<--nameserver 0.0.0.2nameserver 1.1.1.1.1search example.comport $port-->8-->8-->8-->8-->8-->8-->8-->8-->8-->8-->8-->8-- */ printf("%s:%u: %s test should be updated\n", __FILE__, __LINE__, __func__);#else TEST_P(sres_query(res, test_answer, ctx, sres_type_a, "example.com"), NULL);#endif sres_resolver_unref(res); END();}voidfill_stack(void){ int i,array[32768]; for (i = 0; i < 32768; i++) array[i] = i ^ 0xdeadbeef;}#if HAVE_ALARMstatic RETSIGTYPE sig_alarm(int s){ fprintf(stderr, "%s: FAIL! test timeout!\n", name); exit(1);}#endifvoid usage(int exitcode){ fprintf(stderr, "usage: %s OPTIONS [-] [conf-file] [error-conf-file]\n" "\twhere OPTIONS are\n" "\t -v be verbose\n" "\t -a abort on error\n" "\t -l level\n", name); exit(exitcode);}#include <sofia-sip/su_log.h>extern su_log_t sresolv_log[];int main(int argc, char **argv){ int i; int error = 0; int o_attach = 0, o_alarm = 1; sres_context_t ctx[1] = {{{SU_HOME_INIT(ctx)}}}; for (i = 1; argv[i]; i++) { if (argv[i][0] != '-') break; else if (strcmp(argv[i], "-") == 0) { i++; break; } else if (strcmp(argv[i], "-v") == 0) tstflags |= tst_verbatim; else if (strcmp(argv[i], "-a") == 0) tstflags |= tst_abort; else if (strcmp(argv[i], "--no-alarm") == 0) { o_alarm = 0; } else if (strcmp(argv[i], "--attach") == 0) { o_attach = 1; } else if (strncmp(argv[i], "-l", 2) == 0) { int level = 3; char *rest = NULL; if (argv[i][2]) level = strtol(argv[i] + 2, &rest, 10); else if (argv[i + 1]) level = strtol(argv[i + 1], &rest, 10), i++; else level = 3, rest = ""; if (rest == NULL || *rest) usage(1); su_log_set_level(sresolv_log, level); } else usage(1); } if (o_attach) { char buf[8], *line; fprintf(stderr, "test_sresolv: started with pid %u" " (press enter to continue)\n", getpid()); line = fgets(buf, sizeof buf, stdin); (void) line; }#if HAVE_ALARM else if (o_alarm) { alarm(60); signal(SIGALRM, sig_alarm); }#endif if (!(TSTFLAGS & tst_verbatim)) { su_log_soft_set_level(sresolv_log, 0); }#if 0 if (sink_make(ctx) == 0) { error |= test_init(ctx, ctx->sinkconf); error |= sink_init(ctx); error |= test_net(ctx); error |= test_timeout(ctx); error |= sink_deinit(ctx); error |= test_deinit(ctx); }#endif offset = 0; if (argv[i]) { /* These tests are run with (local) nameserver, */ int initerror = test_init(ctx, argv[i]); if (!initerror) { error |= test_a(ctx); error |= test_soa(ctx); error |= test_naptr(ctx);#if HAVE_SIN6 error |= test_a6(ctx); error |= test_a6_prefix(ctx); error |= test_aaaa(ctx);#endif error |= test_srv(ctx); error |= test_cname(ctx); error |= test_ptr_ipv4(ctx); error |= test_ptr_ipv4_sockaddr(ctx);#if HAVE_SIN6 error |= test_ptr_ipv6(ctx); error |= test_ptr_ipv6_sockaddr(ctx);#endif error |= test_cache(ctx);#if HAVE_SIN6 error |= test_query_one_type(ctx);#endif error |= test_expiration(ctx); } error |= test_deinit(ctx) | initerror; if (argv[i + 1]) { error |= test_conf_errors(ctx, argv[i + 1]); } } return error;}#else /* HAVE_POLL */int main(int argc, char **argv){ printf("*** Test not supported without POLL API ***\n"); return 0;}#endif /* HAVE_POLL */
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -