ATF_TC_BODY(symbol_lookup, tc) { GElf_Sym main_sym, r_debug_state_sym; struct proc_handle *phdl; proc_breakpoint_t saved; int error; phdl = start_prog(tc, false); error = proc_name2sym(phdl, target_prog_file, "main", &main_sym, NULL); ATF_REQUIRE_EQ_MSG(error, 0, "failed to look up 'main'"); error = proc_name2sym(phdl, ldelf_object, r_debug_state, &r_debug_state_sym, NULL); ATF_REQUIRE_EQ_MSG(error, 0, "failed to look up '%s'", r_debug_state); set_bkpt(phdl, (uintptr_t)r_debug_state_sym.st_value, &saved); ATF_CHECK_EQ_MSG(proc_continue(phdl), 0, "failed to resume execution"); verify_bkpt(phdl, &r_debug_state_sym, r_debug_state, ldelf_object); remove_bkpt(phdl, (uintptr_t)r_debug_state_sym.st_value, &saved); set_bkpt(phdl, (uintptr_t)main_sym.st_value, &saved); ATF_CHECK_EQ_MSG(proc_continue(phdl), 0, "failed to resume execution"); verify_bkpt(phdl, &main_sym, "main", target_prog_file); remove_bkpt(phdl, (uintptr_t)main_sym.st_value, &saved); ATF_CHECK_EQ_MSG(proc_detach(phdl, PRELEASE_HANG), 0, "failed to detach"); proc_free(phdl); }
ATF_TC_BODY(symbol_lookup, tc) { GElf_Sym main_sym, r_debug_state_sym; struct proc_handle *phdl; u_long saved; int error; phdl = start_prog(tc, false); error = proc_name2sym(phdl, target_prog_file, "main", &main_sym, NULL); ATF_REQUIRE_EQ_MSG(error, 0, "failed to look up 'main'"); error = proc_name2sym(phdl, ldelf_object, "r_debug_state", &r_debug_state_sym, NULL); ATF_REQUIRE_EQ_MSG(error, 0, "failed to look up 'r_debug_state'"); set_bkpt(phdl, r_debug_state_sym.st_value, &saved); ATF_CHECK_EQ_MSG(proc_continue(phdl), 0, "failed to resume execution"); verify_bkpt(phdl, &r_debug_state_sym, "r_debug_state", ldelf_object); remove_bkpt(phdl, r_debug_state_sym.st_value, saved); set_bkpt(phdl, main_sym.st_value, &saved); ATF_CHECK_EQ_MSG(proc_continue(phdl), 0, "failed to resume execution"); verify_bkpt(phdl, &main_sym, "main", target_prog_file); remove_bkpt(phdl, main_sym.st_value, saved); ATF_CHECK_EQ_MSG(proc_continue(phdl), 0, "failed to resume execution"); proc_free(phdl); }
static void* test_pipe_reader(void* args) { test_pipe_thread_data_t* td = args; char rcvbuf[td->pktsize]; char comparebuf[td->pktsize]; ssize_t rsize; int i, d; for(i=0; i < td->numpkts; i++) { memset(comparebuf, i, td->pktsize); rsize = recv(td->so, rcvbuf, td->pktsize, MSG_WAITALL); if (rsize < 0) { perror("recv"); atf_tc_fail("recv returned < 0"); } ATF_CHECK_EQ_MSG(td->pktsize, rsize, "expected %zd=send(...) but got %zd", td->pktsize, rsize); d = memcmp(comparebuf, rcvbuf, td->pktsize); ATF_CHECK_EQ_MSG(0, d, "Received data miscompare on packet %d", i); } return (0); }
ATF_TC_BODY(signal_forward, tc) { struct proc_handle *phdl; int state, status; phdl = start_prog(tc, true); ATF_CHECK_EQ_MSG(proc_continue(phdl), 0, "failed to resume execution"); /* The process should have been interrupted by a signal. */ state = proc_wstatus(phdl); ATF_REQUIRE_EQ_MSG(state, PS_STOP, "process has unexpected state %d", state); /* Continue execution and allow the signal to be delivered. */ ATF_CHECK_EQ_MSG(proc_continue(phdl), 0, "failed to resume execution"); /* * Make sure the process exited with status 0. If it didn't receive the * SIGUSR1 that it sent to itself, it'll exit with a non-zero exit * status, causing the test to fail. */ state = proc_wstatus(phdl); ATF_REQUIRE_EQ_MSG(state, PS_UNDEAD, "process has unexpected state %d", state); status = proc_getwstat(phdl); ATF_REQUIRE(status >= 0); ATF_REQUIRE(WIFEXITED(status)); ATF_REQUIRE_EQ(WEXITSTATUS(status), 0); proc_free(phdl); }
ATF_TC_BODY(rcvbuf_oversized, tc) { int i; int sv[2]; const ssize_t pktsize = 1024; const size_t sndbufsize = 8192; const size_t rcvbufsize = 131072; const size_t geometric_mean_bufsize = 32768; const int numpkts = geometric_mean_bufsize / pktsize; char sndbuf[pktsize]; char recv_buf[pktsize]; ssize_t ssize, rsize; /* setup the socket pair */ do_socketpair_nonblocking(sv); ATF_REQUIRE_EQ(0, setsockopt(sv[0], SOL_SOCKET, SO_SNDBUF, &sndbufsize, sizeof(sndbufsize))); ATF_REQUIRE_EQ(0, setsockopt(sv[1], SOL_SOCKET, SO_RCVBUF, &rcvbufsize, sizeof(rcvbufsize))); /* * Send and receive packets that are collectively greater than the send * buffer, but less than the receive buffer */ for (i=0; i < numpkts; i++) { /* Fill the buffer */ memset(sndbuf, i, pktsize); /* send the packet */ ssize = send(sv[0], sndbuf, pktsize, MSG_EOR); if (ssize < 0) { perror("send"); atf_tc_fail("send returned < 0"); } ATF_CHECK_EQ_MSG(pktsize, ssize, "expected %zd=send(...) but got %zd", pktsize, ssize); /* Receive it */ rsize = recv(sv[1], recv_buf, pktsize, MSG_WAITALL); if (rsize < 0) { perror("recv"); atf_tc_fail("recv returned < 0"); } ATF_CHECK_EQ_MSG(pktsize, rsize, "expected %zd=send(...) but got %zd", pktsize, rsize); /* Verify the contents */ ATF_CHECK_EQ_MSG(0, memcmp(sndbuf, recv_buf, pktsize), "Received data miscompare"); } /* Trying to receive again should return EAGAIN */ rsize = recv(sv[1], recv_buf, pktsize, MSG_WAITALL); ATF_CHECK_EQ(EAGAIN, errno); ATF_CHECK_EQ(-1, rsize); }
ATF_TC_BODY(cast_ulong2, tc) { double dv = 1.9; long double ldv = dv; unsigned long l1 = dv; unsigned long l2 = ldv; ATF_CHECK_EQ_MSG(l1, 1, "double 1.9 casted to unsigned long should be 1, but is %lu", l1); ATF_CHECK_EQ_MSG(l2, 1, "long double 1.9 casted to unsigned long should be 1, but is %lu", l2); }
ATF_TC_BODY(map_alias_name2sym, tc) { GElf_Sym sym1, sym2; prsyminfo_t si1, si2; struct proc_handle *phdl; int error; phdl = start_prog(tc, false); /* Initialize the rtld_db handle. */ (void)proc_rdagent(phdl); /* * Make sure that "target_prog:main" and "a.out:main" return the same * symbol. */ error = proc_name2sym(phdl, target_prog_file, "main", &sym1, &si1); ATF_REQUIRE_EQ_MSG(error, 0, "failed to look up 'main' via %s", target_prog_file); error = proc_name2sym(phdl, aout_object, "main", &sym2, &si2); ATF_REQUIRE_EQ_MSG(error, 0, "failed to look up 'main' via %s", aout_object); ATF_CHECK_EQ(memcmp(&sym1, &sym2, sizeof(sym1)), 0); ATF_CHECK_EQ(si1.prs_id, si2.prs_id); ATF_CHECK_EQ_MSG(proc_continue(phdl), 0, "failed to resume execution"); proc_free(phdl); }
ATF_TC_BODY(send_recv_nonblocking, tc) { int s; int sv[2]; const int bufsize = 64; const char *data = "data"; char recv_buf[bufsize]; size_t datalen; ssize_t ssize, rsize; /* setup the socket pair */ do_socketpair_nonblocking(sv); /* Verify that there is nothing to receive */ rsize = recv(sv[1], recv_buf, bufsize, MSG_WAITALL); ATF_CHECK_EQ(EAGAIN, errno); ATF_CHECK_EQ(-1, rsize); /* send and receive a small packet */ datalen = strlen(data) + 1; /* +1 for the null */ ssize = send(sv[0], data, datalen, MSG_EOR); if (ssize < 0) { perror("send"); atf_tc_fail("send returned < 0"); } ATF_CHECK_EQ_MSG(datalen, ssize, "expected %zd=send(...) but got %zd", datalen, ssize); rsize = recv(sv[1], recv_buf, bufsize, MSG_WAITALL); ATF_CHECK_EQ(datalen, rsize); }
ATF_TC_BODY(send_recv_with_connect, tc) { const char* path; int sv[2]; const int bufsize = 64; const char *data = "data"; char recv_buf[bufsize]; size_t datalen; ssize_t ssize, rsize; mk_pair_of_sockets(sv); /* send and receive a small packet */ datalen = strlen(data) + 1; /* +1 for the null */ ssize = send(sv[0], data, datalen, MSG_EOR); if (ssize < 0) { perror("send"); atf_tc_fail("send returned < 0"); } ATF_CHECK_EQ_MSG(datalen, ssize, "expected %zd=send(...) but got %zd", datalen, ssize); rsize = recv(sv[1], recv_buf, bufsize, MSG_WAITALL); ATF_CHECK_EQ(datalen, rsize); }
ATF_TC_BODY(symbol_lookup_fail, tc) { char symname[32]; GElf_Sym sym; struct proc_handle *phdl; prmap_t *map; int error; phdl = start_prog(tc, false); /* Initialize the rtld_db handle. */ (void)proc_rdagent(phdl); map = proc_name2map(phdl, target_prog_file); ATF_REQUIRE_MSG(map != NULL, "failed to look up map for '%s'", target_prog_file); /* * We shouldn't be able to find symbols at the beginning of a mapped * file. */ error = proc_addr2sym(phdl, map->pr_vaddr, symname, sizeof(symname), &sym); ATF_REQUIRE_MSG(error != 0, "unexpectedly found a symbol"); ATF_CHECK_EQ_MSG(proc_continue(phdl), 0, "failed to resume execution"); proc_free(phdl); }
ATF_TC_BODY(cast_ulong, tc) { double nv; unsigned long uv; nv = 5.6; uv = (unsigned long)nv; ATF_CHECK_EQ_MSG(uv, 5, "%.3f casted to unsigned long is %lu", nv, uv); }
void test_sendrecv_symmetric_buffers(size_t bufsize, int blocking) { int s; int sv[2]; const size_t pktsize = bufsize / 2; char sndbuf[pktsize]; char recv_buf[pktsize]; ssize_t ssize, rsize; /* setup the socket pair */ if (blocking) do_socketpair(sv); else do_socketpair_nonblocking(sv); /* Setup the buffers */ s = setsockopt(sv[0], SOL_SOCKET, SO_SNDBUF, &bufsize, sizeof(bufsize)); ATF_REQUIRE_EQ(0, s); s = setsockopt(sv[1], SOL_SOCKET, SO_RCVBUF, &bufsize, sizeof(bufsize)); ATF_REQUIRE_EQ(0, s); /* Fill the send buffer */ bzero(sndbuf, pktsize); /* send and receive the packet */ ssize = send(sv[0], sndbuf, pktsize, MSG_EOR); if (ssize < 0) { perror("send"); atf_tc_fail("send returned < 0"); } ATF_CHECK_EQ_MSG(pktsize, ssize, "expected %zd=send(...) but got %zd", pktsize, ssize); rsize = recv(sv[1], recv_buf, pktsize, MSG_WAITALL); if (rsize < 0) { perror("recv"); atf_tc_fail("recv returned < 0"); } ATF_CHECK_EQ_MSG(pktsize, rsize, "expected %zd=send(...) but got %zd", pktsize, rsize); }
/* * Wait for the specified process to hit a breakpoint at the specified symbol. */ static void verify_bkpt(struct proc_handle *phdl, GElf_Sym *sym, const char *symname, const char *mapname) { char mapbname[MAXPATHLEN], *name; GElf_Sym tsym; prmap_t *map; size_t namesz; u_long addr; int error, state; state = proc_wstatus(phdl); ATF_REQUIRE_EQ_MSG(state, PS_STOP, "process has state %d", state); /* Get the program counter and decrement it. */ error = proc_regget(phdl, REG_PC, &addr); ATF_REQUIRE_EQ_MSG(error, 0, "failed to obtain PC for '%s'", target_prog_file); proc_bkptregadj(&addr); /* * Make sure the PC matches the expected value obtained from the symbol * definition we looked up earlier. */ ATF_CHECK_EQ_MSG(addr, sym->st_value, "program counter 0x%lx doesn't match expected value 0x%jx", addr, (uintmax_t)sym->st_value); /* * Ensure we can look up the r_debug_state symbol using its starting * address and that the resulting symbol matches the one we found using * a name lookup. */ namesz = strlen(symname) + 1; name = malloc(namesz); ATF_REQUIRE(name != NULL); error = proc_addr2sym(phdl, addr, name, namesz, &tsym); ATF_REQUIRE_EQ_MSG(error, 0, "failed to look up symbol at 0x%lx", addr); ATF_REQUIRE_EQ(memcmp(sym, &tsym, sizeof(*sym)), 0); ATF_REQUIRE_EQ_MSG(strcmp(symname, name), 0, "expected symbol name '%s' doesn't match '%s'", symname, name); free(name); map = proc_addr2map(phdl, addr); ATF_REQUIRE_MSG(map != NULL, "failed to look up map for address 0x%lx", addr); basename_r(map->pr_mapname, mapbname); ATF_REQUIRE_EQ_MSG(strcmp(mapname, mapbname), 0, "expected map name '%s' doesn't match '%s'", mapname, mapbname); }
ATF_TC_BODY(sendto_recvfrom, tc) { const char* path; struct sockaddr_storage from; int s; int sv[2]; const int bufsize = 64; const char *data = "data"; char recv_buf[bufsize]; size_t datalen; ssize_t ssize, rsize; socklen_t fromlen; /* setup the socket pair */ path = mk_pair_of_sockets(sv); /* send and receive a small packet */ datalen = strlen(data) + 1; /* +1 for the null */ ssize = sendto(sv[0], data, datalen, MSG_EOR, NULL, 0); if (ssize < 0) { perror("send"); atf_tc_fail("send returned < 0"); } ATF_CHECK_EQ_MSG(datalen, ssize, "expected %zd=send(...) but got %zd", datalen, ssize); fromlen = sizeof(from); rsize = recvfrom(sv[1], recv_buf, bufsize, MSG_WAITALL, (struct sockaddr*)&from, &fromlen); if (ssize < 0) { perror("recvfrom"); atf_tc_fail("recvfrom returned < 0"); } ATF_CHECK_EQ(datalen, rsize); /* * FreeBSD does not currently provide the source address for SEQ_PACKET * AF_UNIX sockets, and POSIX does not require it, so these two checks * are disabled. If FreeBSD gains that feature in the future, then * these checks may be reenabled */ /* ATF_CHECK_EQ(PF_LOCAL, from.ss_family); */ /* ATF_CHECK_STREQ(path, ((struct sockaddr_un*)&from)->sun_path); */ }
static void checked_mmap(int prot, int flags, int fd, int error, const char *msg) { void *p; p = mmap(NULL, getpagesize(), prot, flags, fd, 0); if (p == MAP_FAILED) { if (error == 0) ATF_CHECK_MSG(0, "%s failed with errno %d", msg, errno); else ATF_CHECK_EQ_MSG(error, errno, "%s failed with wrong errno %d (expected %d)", msg, errno, error); } else { ATF_CHECK_MSG(error == 0, "%s succeeded", msg); munmap(p, getpagesize()); } }
static void* test_pipe_writer(void* args) { test_pipe_thread_data_t* td = args; char sndbuf[td->pktsize]; ssize_t ssize; int i; for(i=0; i < td->numpkts; i++) { memset(sndbuf, i, td->pktsize); ssize = send(td->so, sndbuf, td->pktsize, MSG_EOR); if (ssize < 0) { perror("send"); atf_tc_fail("send returned < 0"); } ATF_CHECK_EQ_MSG(td->pktsize, ssize, "expected %zd=send(...) but got %zd", td->pktsize, ssize); } return (0); }
ATF_TC_BODY(map_prefix_name2map, tc) { struct proc_handle *phdl; prmap_t *map1, *map2; phdl = start_prog(tc, false); /* Initialize the rtld_db handle. */ (void)proc_rdagent(phdl); /* Make sure that "ld-elf" and "ld-elf.so" return the same map. */ map1 = proc_name2map(phdl, "ld-elf"); ATF_REQUIRE_MSG(map1 != NULL, "failed to look up map for 'ld-elf'"); map2 = proc_name2map(phdl, "ld-elf.so"); ATF_REQUIRE_MSG(map2 != NULL, "failed to look up map for 'ld-elf.so'"); ATF_CHECK_EQ(strcmp(map1->pr_mapname, map2->pr_mapname), 0); ATF_CHECK_EQ_MSG(proc_continue(phdl), 0, "failed to resume execution"); proc_free(phdl); }
ATF_TC_BODY(map_alias_name2map, tc) { struct proc_handle *phdl; prmap_t *map1, *map2; phdl = start_prog(tc, false); /* Initialize the rtld_db handle. */ (void)proc_rdagent(phdl); /* Ensure that "target_prog" and "a.out" return the same map. */ map1 = proc_name2map(phdl, target_prog_file); ATF_REQUIRE_MSG(map1 != NULL, "failed to look up map for '%s'", target_prog_file); map2 = proc_name2map(phdl, aout_object); ATF_REQUIRE_MSG(map2 != NULL, "failed to look up map for '%s'", aout_object); ATF_CHECK_EQ(strcmp(map1->pr_mapname, map2->pr_mapname), 0); ATF_CHECK_EQ_MSG(proc_continue(phdl), 0, "failed to resume execution"); proc_free(phdl); }
void test_pipe_simulator(size_t sndbufsize, size_t rcvbufsize) { int s, num_sent, num_received; int sv[2]; const size_t pktsize = MIN(sndbufsize, rcvbufsize) / 4; int numpkts; char sndbuf[pktsize]; char rcvbuf[pktsize]; char comparebuf[pktsize]; ssize_t ssize, rsize; bool currently_sending = true; /* setup the socket pair */ do_socketpair_nonblocking(sv); /* Setup the buffers */ ATF_REQUIRE_EQ(0, setsockopt(sv[0], SOL_SOCKET, SO_SNDBUF, &sndbufsize, sizeof(sndbufsize))); ATF_REQUIRE_EQ(0, setsockopt(sv[1], SOL_SOCKET, SO_RCVBUF, &rcvbufsize, sizeof(rcvbufsize))); /* Send a total amount of data comfortably greater than the buffers */ numpkts = MAX(sndbufsize, rcvbufsize) * 8 / pktsize; for (num_sent=0, num_received=0; num_sent < numpkts || num_received < numpkts; ) { if (currently_sending && num_sent < numpkts) { /* The simulated sending process */ /* fill the buffer */ memset(sndbuf, num_sent, pktsize); ssize = send(sv[0], sndbuf, pktsize, MSG_EOR); if (ssize < 0) { /* * XXX: This is bug-compatible with the kernel. * The kernel returns EMSGSIZE when it should * return EAGAIN */ if (errno == EAGAIN || errno == EMSGSIZE) currently_sending = false; else { perror("send"); atf_tc_fail("send failed"); } } else { ATF_CHECK_EQ_MSG(pktsize, ssize, "expected %zd=send(...) but got %zd", pktsize, ssize); num_sent++; } } else { /* The simulated receiving process */ rsize = recv(sv[1], rcvbuf, pktsize, MSG_WAITALL); if (rsize < 0) { if (errno == EAGAIN) { currently_sending = true; ATF_REQUIRE_MSG(num_sent < numpkts, "Packets were lost!"); } else { perror("recv"); atf_tc_fail("recv failed"); } } else { ATF_CHECK_EQ_MSG(pktsize, rsize, "expected %zd=recv(...) but got %zd", pktsize, rsize); memset(comparebuf, num_received, pktsize); ATF_CHECK_EQ_MSG(0, memcmp(comparebuf, rcvbuf, pktsize), "Received data miscompare"); num_received++; } } } }
ATF_TC_BODY(tsig_tcp, tc) { const dns_name_t *tsigowner = NULL; dns_fixedname_t fkeyname; dns_message_t *msg = NULL; dns_name_t *keyname; dns_tsig_keyring_t *ring = NULL; dns_tsigkey_t *key = NULL; isc_buffer_t *buf = NULL; isc_buffer_t *querytsig = NULL; isc_buffer_t *tsigin = NULL; isc_buffer_t *tsigout = NULL; isc_result_t result; unsigned char secret[16] = { 0 }; dst_context_t *tsigctx = NULL; dst_context_t *outctx = NULL; UNUSED(tc); result = dns_test_begin(stderr, ISC_TRUE); ATF_REQUIRE_EQ(result, ISC_R_SUCCESS); /* isc_log_setdebuglevel(lctx, 99); */ dns_fixedname_init(&fkeyname); keyname = dns_fixedname_name(&fkeyname); result = dns_name_fromstring(keyname, "test", 0, NULL); ATF_REQUIRE_EQ(result, ISC_R_SUCCESS); result = dns_tsigkeyring_create(mctx, &ring); ATF_REQUIRE_EQ(result, ISC_R_SUCCESS); result = dns_tsigkey_create(keyname, dns_tsig_hmacsha256_name, secret, sizeof(secret), ISC_FALSE, NULL, 0, 0, mctx, ring, &key); ATF_REQUIRE_EQ(result, ISC_R_SUCCESS); /* * Create request. */ result = isc_buffer_allocate(mctx, &buf, 65535); ATF_REQUIRE_EQ(result, ISC_R_SUCCESS); render(buf, 0, key, &tsigout, &querytsig, NULL); isc_buffer_free(&buf); /* * Create response message 1. */ result = isc_buffer_allocate(mctx, &buf, 65535); ATF_REQUIRE_EQ(result, ISC_R_SUCCESS); render(buf, DNS_MESSAGEFLAG_QR, key, &querytsig, &tsigout, NULL); /* * Process response message 1. */ result = dns_message_create(mctx, DNS_MESSAGE_INTENTPARSE, &msg); ATF_CHECK_EQ_MSG(result, ISC_R_SUCCESS, "dns_message_create: %s", dns_result_totext(result)); result = dns_message_settsigkey(msg, key); ATF_CHECK_EQ_MSG(result, ISC_R_SUCCESS, "dns_message_settsigkey: %s", dns_result_totext(result)); result = dns_message_parse(msg, buf, 0); ATF_CHECK_EQ_MSG(result, ISC_R_SUCCESS, "dns_message_parse: %s", dns_result_totext(result)); printmessage(msg); result = dns_message_setquerytsig(msg, querytsig); ATF_CHECK_EQ_MSG(result, ISC_R_SUCCESS, "dns_message_setquerytsig: %s", dns_result_totext(result)); result = dns_tsig_verify(buf, msg, NULL, NULL); ATF_CHECK_EQ_MSG(result, ISC_R_SUCCESS, "dns_tsig_verify: %s", dns_result_totext(result)); ATF_CHECK_EQ(msg->verified_sig, 1); ATF_CHECK_EQ(msg->tsigstatus, dns_rcode_noerror); /* * Check that we have a TSIG in the first message. */ ATF_REQUIRE(dns_message_gettsig(msg, &tsigowner) != NULL); result = dns_message_getquerytsig(msg, mctx, &tsigin); ATF_CHECK_EQ_MSG(result, ISC_R_SUCCESS, "dns_message_getquerytsig: %s", dns_result_totext(result)); tsigctx = msg->tsigctx; msg->tsigctx = NULL; isc_buffer_free(&buf); dns_message_destroy(&msg); result = dst_context_create3(key->key, mctx, DNS_LOGCATEGORY_DNSSEC, ISC_FALSE, &outctx); ATF_REQUIRE_EQ(result, ISC_R_SUCCESS); /* * Start digesting. */ result = add_mac(outctx, tsigout); ATF_REQUIRE_EQ(result, ISC_R_SUCCESS); /* * Create response message 2. */ result = isc_buffer_allocate(mctx, &buf, 65535); ATF_REQUIRE_EQ(result, ISC_R_SUCCESS); ATF_REQUIRE_EQ(result, ISC_R_SUCCESS); render(buf, DNS_MESSAGEFLAG_QR, key, &tsigout, &tsigout, outctx); /* * Process response message 2. */ result = dns_message_create(mctx, DNS_MESSAGE_INTENTPARSE, &msg); ATF_CHECK_EQ_MSG(result, ISC_R_SUCCESS, "dns_message_create: %s", dns_result_totext(result)); msg->tcp_continuation = 1; msg->tsigctx = tsigctx; tsigctx = NULL; result = dns_message_settsigkey(msg, key); ATF_CHECK_EQ_MSG(result, ISC_R_SUCCESS, "dns_message_settsigkey: %s", dns_result_totext(result)); result = dns_message_parse(msg, buf, 0); ATF_CHECK_EQ_MSG(result, ISC_R_SUCCESS, "dns_message_parse: %s", dns_result_totext(result)); printmessage(msg); result = dns_message_setquerytsig(msg, tsigin); ATF_CHECK_EQ_MSG(result, ISC_R_SUCCESS, "dns_message_setquerytsig: %s", dns_result_totext(result)); result = dns_tsig_verify(buf, msg, NULL, NULL); ATF_CHECK_EQ_MSG(result, ISC_R_SUCCESS, "dns_tsig_verify: %s", dns_result_totext(result)); ATF_CHECK_EQ(msg->verified_sig, 1); ATF_CHECK_EQ(msg->tsigstatus, dns_rcode_noerror); /* * Check that we don't have a TSIG in the second message. */ tsigowner = NULL; ATF_REQUIRE(dns_message_gettsig(msg, &tsigowner) == NULL); tsigctx = msg->tsigctx; msg->tsigctx = NULL; isc_buffer_free(&buf); dns_message_destroy(&msg); /* * Create response message 3. */ result = isc_buffer_allocate(mctx, &buf, 65535); ATF_REQUIRE_EQ(result, ISC_R_SUCCESS); render(buf, DNS_MESSAGEFLAG_QR, key, &tsigout, &tsigout, outctx); result = add_tsig(outctx, key, buf); ATF_CHECK_EQ_MSG(result, ISC_R_SUCCESS, "add_tsig: %s", dns_result_totext(result)); /* * Process response message 3. */ result = dns_message_create(mctx, DNS_MESSAGE_INTENTPARSE, &msg); ATF_CHECK_EQ_MSG(result, ISC_R_SUCCESS, "dns_message_create: %s", dns_result_totext(result)); msg->tcp_continuation = 1; msg->tsigctx = tsigctx; tsigctx = NULL; result = dns_message_settsigkey(msg, key); ATF_CHECK_EQ_MSG(result, ISC_R_SUCCESS, "dns_message_settsigkey: %s", dns_result_totext(result)); result = dns_message_parse(msg, buf, 0); ATF_CHECK_EQ_MSG(result, ISC_R_SUCCESS, "dns_message_parse: %s", dns_result_totext(result)); printmessage(msg); /* * Check that we had a TSIG in the third message. */ ATF_REQUIRE(dns_message_gettsig(msg, &tsigowner) != NULL); result = dns_message_setquerytsig(msg, tsigin); ATF_CHECK_EQ_MSG(result, ISC_R_SUCCESS, "dns_message_setquerytsig: %s", dns_result_totext(result)); result = dns_tsig_verify(buf, msg, NULL, NULL); ATF_CHECK_EQ_MSG(result, ISC_R_SUCCESS, "dns_tsig_verify: %s", dns_result_totext(result)); ATF_CHECK_EQ(msg->verified_sig, 1); ATF_CHECK_EQ(msg->tsigstatus, dns_rcode_noerror); if (tsigin != NULL) isc_buffer_free(&tsigin); result = dns_message_getquerytsig(msg, mctx, &tsigin); ATF_CHECK_EQ_MSG(result, ISC_R_SUCCESS, "dns_message_getquerytsig: %s", dns_result_totext(result)); isc_buffer_free(&buf); dns_message_destroy(&msg); if (outctx != NULL) dst_context_destroy(&outctx); if (querytsig != NULL) isc_buffer_free(&querytsig); if (tsigin != NULL) isc_buffer_free(&tsigin); if (tsigout != NULL) isc_buffer_free(&tsigout); if (buf != NULL) isc_buffer_free(&buf); if (msg != NULL) dns_message_destroy(&msg); if (key != NULL) dns_tsigkey_detach(&key); if (ring != NULL) dns_tsigkeyring_detach(&ring); dns_test_end(); }
static void render(isc_buffer_t *buf, unsigned flags, dns_tsigkey_t *key, isc_buffer_t **tsigin, isc_buffer_t **tsigout, dst_context_t *tsigctx) { dns_message_t *msg = NULL; dns_compress_t cctx; isc_result_t result; result = dns_message_create(mctx, DNS_MESSAGE_INTENTRENDER, &msg); ATF_CHECK_EQ_MSG(result, ISC_R_SUCCESS, "dns_message_create: %s", dns_result_totext(result)); msg->id = 50; msg->rcode = dns_rcode_noerror; msg->flags = flags; if (tsigin == tsigout) msg->tcp_continuation = 1; if (tsigctx == NULL) { result = dns_message_settsigkey(msg, key); ATF_CHECK_EQ_MSG(result, ISC_R_SUCCESS, "dns_message_settsigkey: %s", dns_result_totext(result)); result = dns_message_setquerytsig(msg, *tsigin); ATF_CHECK_EQ_MSG(result, ISC_R_SUCCESS, "dns_message_setquerytsig: %s", dns_result_totext(result)); } result = dns_compress_init(&cctx, -1, mctx); ATF_CHECK_EQ_MSG(result, ISC_R_SUCCESS, "dns_compress_init: %s", dns_result_totext(result)); result = dns_message_renderbegin(msg, &cctx, buf); ATF_CHECK_EQ_MSG(result, ISC_R_SUCCESS, "dns_message_renderbegin: %s", dns_result_totext(result)); result = dns_message_renderend(msg); ATF_CHECK_EQ_MSG(result, ISC_R_SUCCESS, "dns_message_renderend: %s", dns_result_totext(result)); if (tsigctx != NULL) { isc_region_t r; isc_buffer_usedregion(buf, &r); result = dst_context_adddata(tsigctx, &r); } else { if (tsigin == tsigout && *tsigin != NULL) isc_buffer_free(tsigin); result = dns_message_getquerytsig(msg, mctx, tsigout); ATF_CHECK_EQ_MSG(result, ISC_R_SUCCESS, "dns_message_getquerytsig: %s", dns_result_totext(result)); } dns_compress_invalidate(&cctx); dns_message_destroy(&msg); }