X-Git-Url: http://git.meshlink.io/?a=blobdiff_plain;ds=sidebyside;f=tests%2Fdns-spin-test.c;fp=tests%2Fdns-spin-test.c;h=51af02d1df66f89fd322712b95f30d3ec757c6ba;hb=5133886fe11d7650bc89b46746731ca2eab2185d;hp=0000000000000000000000000000000000000000;hpb=3b898d826ec5e97f287481ea1612483e6f3cc066;p=catta diff --git a/tests/dns-spin-test.c b/tests/dns-spin-test.c new file mode 100644 index 0000000..51af02d --- /dev/null +++ b/tests/dns-spin-test.c @@ -0,0 +1,122 @@ +/*** + This file is part of avahi. + + avahi is free software; you can redistribute it and/or modify it + under the terms of the GNU Lesser General Public License as + published by the Free Software Foundation; either version 2.1 of the + License, or (at your option) any later version. + + avahi is distributed in the hope that it will be useful, but WITHOUT + ANY WARRANTY; without even the implied warranty of MERCHANTABILITY + or FITNESS FOR A PARTICULAR PURPOSE. See the GNU Lesser General + Public License for more details. + + You should have received a copy of the GNU Lesser General Public + License along with avahi; if not, write to the Free Software + Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 + USA. +***/ + +/* Regression test for Avahi bug #84. + * This program tests whether the avahi_dns_packet_consume_name function + * returns (rather than spinning forever). For a function as simple as + * avahi_dns_packet_consume_name, we assume that 1 second of CPU time ≈ forever + */ + +#ifdef HAVE_CONFIG_H +# include +#endif + +#include +#include +#include +#include +#include +#include + +#include + +#define MAX_CPU_SECONDS 1 + +#define TEST_NAME "dns-spin-test" + +static void fail(const char *fmt, ...) __attribute__((format(printf, 1, 2), noreturn)); +static void unresolved(const char *fmt, ...) __attribute__((format(printf, 1, 2), noreturn)); +static void stdlib_fail(const char *msg) __attribute__((noreturn)); +static void handle(int sig) __attribute__((noreturn)); + +void stdlib_fail(const char *msg) { + perror(msg); + + printf("UNRESOLVED: " TEST_NAME " (stdlib failure)\n"); + + exit(77); +} + +void unresolved(const char *fmt, ...) { + va_list ap; + + printf("UNRESOLVED: " TEST_NAME ": "); + va_start(ap, fmt); + vprintf(fmt, ap); + va_end(ap); + printf("\n"); + + exit(77); +} + +void fail(const char *fmt, ...) { + va_list ap; + + va_start(ap, fmt); + vprintf(fmt, ap); + va_end(ap); + printf("\n"); + + exit(EXIT_FAILURE); +} + +void handle(AVAHI_GCC_UNUSED int sig) { + fail("Interrupted after %d second of CPU time", MAX_CPU_SECONDS); +} + +#define TRY_EXCEPT(cmd, badresult) \ + do { \ + if ((cmd) == (badresult)) \ + unresolved("%s returned %s", #cmd, #badresult); \ + } while (0) + +int main(AVAHI_GCC_UNUSED int argc, AVAHI_GCC_UNUSED char *argv[]) { + struct itimerval itval; + AvahiDnsPacket *packet; + char name[512]; + int ret; + uint8_t badrr[] = { + 0xC0, AVAHI_DNS_PACKET_HEADER_SIZE, /* self-referential QNAME pointer */ + 0, 1, /* QTYPE A (host addr) */ + 0, 1, /* QCLASS IN (internet/ipv4) */ + }; + + if (signal(SIGVTALRM, handle) == SIG_ERR) + stdlib_fail("signal(SIGVTALRM)"); + + memset(&itval, 0, sizeof(itval)); + itval.it_value.tv_sec = MAX_CPU_SECONDS; + + if (setitimer(ITIMER_VIRTUAL, &itval, NULL) == -1) + stdlib_fail("setitimer()"); + + TRY_EXCEPT(packet = avahi_dns_packet_new_query(512), NULL); + TRY_EXCEPT(avahi_dns_packet_append_bytes(packet, badrr, sizeof(badrr)), NULL); + + /* This is expected to fail (if it returns) */ + ret = avahi_dns_packet_consume_name(packet, name, sizeof(name)); + + if (ret != -1) + fail("avahi_dns_packet_consume_name() returned %d; -1 was expected", ret); + + return EXIT_SUCCESS; +} + +/* vim:ts=4:sw=4:et + */