📄 test_sresolv.c
字号:
__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; int s = ctx->socket; int c = ctx->sink; struct sockaddr_storage ss[1]; struct sockaddr *sa = (void *)ss; socklen_t salen = sizeof ss, binlen; char *bin; int i, n; char const *domain = "example.com"; char query[512]; BEGIN(); TEST_1(ctx->sink != -1 && ctx->sink != 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_make(res, test_answer, ctx, s, /* Send query */ sres_type_naptr, domain)); TEST_1((n = 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 = sendto(c, bin, binlen, 0, sa, salen); if (i != 1) bin[i] ^= 0xff; else bin[3] ^= SRES_FORMAT_ERR; if (n == -1) perror("sendto"); sres_resolver_receive(res, s); 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_make(res, test_answer, ctx, s, /* Send query */ sres_type_naptr, domain)); TEST_1((n = recvfrom(c, query, sizeof query, 0, sa, &salen)) != -1); memcpy(bin, query, 2); /* Copy ID */ } n = sendto(c, bin, i, 0, sa, salen); if (n == -1) perror("sendto"); sres_resolver_receive(res, s); if (ctx->query) q = NULL; } free(bin); END();}/* Test API function argument validation */staticint test_api_errors(sres_context_t *noctx){ sres_context_t ctx[1]; sres_resolver_t *res; int s, fd; int sockets[20]; struct sockaddr sa[1] = {{ 0 }}; char *template = NULL; FILE *f; BEGIN(); memset(ctx, 0, sizeof ctx); template = su_sprintf(ctx->home, ".test_sresolv_api.conf.XXXXXX"); TEST_1(template); TEST_1(res = sres_resolver_new(NULL)); sres_resolver_unref(res);#ifndef _WIN32 fd = mkstemp(template); TEST_1(fd != -1);#else fd = open(template, O_WRONLY); TEST_1(fd != -1);#endif f = fdopen(fd, "w"); TEST_1(f); fprintf(f, "domain example.com\n"); fclose(f); /* Test also LOCALDOMAIN handling */ putenv("LOCALDOMAIN=localdomain"); TEST_1(res = sres_resolver_new(template)); unlink(template); TEST_1(sres_resolver_sockets(NULL, NULL, 20) == -1); TEST_1(sres_resolver_sockets(res, NULL, 20) >= 1); TEST_1(sres_resolver_sockets(res, sockets, 20) >= 1); s = sockets[0]; TEST(sres_resolver_ref(NULL), NULL); TEST(errno, EFAULT); sres_resolver_unref(NULL); TEST(sres_resolver_add_mutex(NULL, NULL, NULL, NULL), -1); TEST(errno, EFAULT); TEST(sres_resolver_set_userdata(NULL, NULL), NULL); TEST(errno, EFAULT); TEST(sres_resolver_get_userdata(NULL), NULL); TEST(sres_resolver_get_userdata(res), NULL); TEST(sres_resolver_set_userdata(res, sa), NULL); TEST(sres_resolver_set_userdata(res, sa), sa); TEST(sres_resolver_get_userdata(res), sa); TEST(sres_resolver_set_userdata(res, NULL), sa); TEST(sres_resolver_get_userdata(res), NULL);#if HAVE_SU_WAIT_H errno = 0; TEST(sres_resolver_create(NULL, NULL, TAG_END()), NULL); TEST(errno, EFAULT); errno = 0; TEST(sres_resolver_root_socket(NULL), -1); TEST(errno, EFAULT); errno = 0; TEST(sres_query(NULL, test_answer, ctx, sres_type_a, "example.com"), NULL); TEST(errno, EFAULT); errno = 0; TEST(sres_query_sockaddr(NULL, test_answer, ctx, sres_qtype_any, sa), NULL); TEST(errno, EFAULT); errno = 0; TEST(sres_resolver_destroy(NULL), -1); TEST(errno, EFAULT); errno = 0; TEST(sres_resolver_root_socket(res), -1); TEST(errno, EINVAL); errno = 0; TEST(sres_query(res, test_answer, ctx, sres_type_a, "example.com"), NULL); TEST(errno, EINVAL); errno = 0; TEST(sres_query_sockaddr(res, test_answer, ctx, sres_qtype_any, sa), NULL); TEST(errno, EINVAL); errno = 0; TEST(sres_resolver_destroy(res), -1); /* res should be alive after this! */ TEST(errno, EINVAL); errno = 0;#endif errno = 0; TEST(sres_query_make(NULL, test_answer, ctx, s, sres_type_a, "com"), NULL); TEST(errno, EFAULT); errno = 0; TEST(sres_query_make(res, test_answer, ctx, s, sres_type_a, NULL), NULL); TEST(errno, EFAULT); errno = 0; TEST(sres_query_make_sockaddr(res, test_answer, ctx, s, sres_qtype_any, sa), NULL); TEST(errno, EAFNOSUPPORT); errno = 0; TEST(sres_cached_answers(NULL, sres_qtype_any, "example.com"), NULL); TEST(errno, EFAULT); errno = 0; TEST(sres_cached_answers(res, sres_qtype_any, NULL), NULL); TEST(errno, EFAULT); errno = 0; TEST(sres_cached_answers(res, sres_qtype_any, name2048), NULL); TEST(errno, ENAMETOOLONG); errno = 0; TEST(sres_cached_answers_sockaddr(res, sres_qtype_any, sa), NULL); TEST(errno, EAFNOSUPPORT); errno = 0; sres_free_answer(res, NULL); sres_free_answers(res, NULL); sres_sort_answers(res, NULL); sres_free_answer(NULL, NULL); sres_free_answers(NULL, NULL); sres_sort_answers(NULL, NULL); sres_resolver_unref(res); END();}staticint test_init(sres_context_t *ctx, char const *conf_file){ BEGIN(); ctx->query = NULL, ctx->result = NULL;#if HAVE_SU_WAIT_H su_init(); TEST_1(ctx->root = su_root_create(NULL)); ctx->resolver = sres_resolver_create(ctx->root, conf_file, TAG_END()); TEST_1(ctx->resolver); ctx->socket = sres_resolver_root_socket(ctx->resolver);#elif 1 { sres_resolver_t *res; int i, n; TEST_1(ctx->resolver = res = sres_resolver_new(conf_file)); n = sres_resolver_sockets(res, NULL, 0); ctx->n_sockets = n; TEST_1(n > 0); TEST_1(ctx->sockets = calloc(n, sizeof(*ctx->sockets))); TEST_1(ctx->pollfds = calloc(n, sizeof(*ctx->pollfds))); TEST(sres_resolver_sockets(res, ctx->sockets, n), n); for (i = 0; i < n; i++) { ctx->pollfds[i].fd = ctx->sockets[i]; ctx->pollfds[i].events = POLLIN | POLLERR; } ctx->socket = ctx->sockets[0]; }#endif TEST(sres_resolver_ref(ctx->resolver), ctx->resolver); sres_resolver_unref(ctx->resolver); TEST_1(pthread_mutex_init(ctx->mutex, NULL) == 0); TEST_1(sres_resolver_add_mutex(ctx->resolver, ctx->mutex, (void *)pthread_mutex_lock, (void *)pthread_mutex_unlock) == 0); END();}staticint test_deinit(sres_context_t *ctx){ offset += 2 * 36000000; sres_resolver_timer(ctx->resolver, ctx->socket); /* Zap everything */ sres_free_answers(ctx->resolver, ctx->result); ctx->result = NULL; su_free(ctx->home, (void *)ctx->sinkconf); ctx->sinkconf = NULL;#if HAVE_SU_WAIT_H sres_resolver_destroy(ctx->resolver), ctx->resolver = 0; su_root_destroy(ctx->root), ctx->root = 0; su_deinit();#else { int i; for (i = 0; i < ctx->n_sockets; i++) su_close(ctx->sockets[i]); sres_resolver_unref(ctx->resolver), ctx->resolver = 0; free(ctx->sockets); free(ctx->pollfds); }#endif 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; int 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 HAVE_SA_LEN /* 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-- The problem address (0.0.0.2) is valid in BSD and we fail this test. */ /* We have sa_len on BSDish systems only... */ printf("%s:%u: %s test should be updated\n", __FILE__, __LINE__, __func__);#else TEST(sres_query_make(res, test_answer, ctx, socket, sres_type_a, "example.com"), NULL);#endif sres_resolver_unref(ctx->resolver); 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(void){ fprintf(stderr, "usage: %s [-v] [-l level] [-] [conf-file] [error-conf-file]\n", name);}#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], "--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(); su_log_set_level(sresolv_log, level); } else usage(); } su_init(); if (o_attach) { char buf[8]; fprintf(stderr, "test_sresolv: started with pid %u" " (press enter to continue)\n", getpid()); fgets(buf, sizeof buf, stdin); }#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 (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); } 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]); } } error |= test_api_errors(ctx); return error;}
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -