1/* $Id$ */ 2 3/*** 4 This file is part of avahi. 5 6 avahi is free software; you can redistribute it and/or modify it 7 under the terms of the GNU Lesser General Public License as 8 published by the Free Software Foundation; either version 2.1 of the 9 License, or (at your option) any later version. 10 11 avahi is distributed in the hope that it will be useful, but WITHOUT 12 ANY WARRANTY; without even the implied warranty of MERCHANTABILITY 13 or FITNESS FOR A PARTICULAR PURPOSE. See the GNU Lesser General 14 Public License for more details. 15 16 You should have received a copy of the GNU Lesser General Public 17 License along with avahi; if not, write to the Free Software 18 Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 19 USA. 20***/ 21 22/* Regression test for Avahi bug #84. 23 * This program tests whether the avahi_dns_packet_consume_name function 24 * returns (rather than spinning forever). For a function as simple as 25 * avahi_dns_packet_consume_name, we assume that 1 second of CPU time ��� forever 26 */ 27 28#ifdef HAVE_CONFIG_H 29# include <config.h> 30#endif 31 32#include <string.h> 33#include <stdint.h> 34#include <stdio.h> 35#include <stdlib.h> 36#include <signal.h> 37#include <sys/time.h> 38 39#include "dns.h" 40 41#define MAX_CPU_SECONDS 1 42 43#define TEST_NAME "dns-spin-test" 44 45static void fail(const char *fmt, ...) __attribute__((format(printf, 1, 2), noreturn)); 46static void unresolved(const char *fmt, ...) __attribute__((format(printf, 1, 2), noreturn)); 47static void stdlib_fail(const char *msg) __attribute__((noreturn)); 48static void handle(int sig) __attribute__((noreturn)); 49 50void stdlib_fail(const char *msg) { 51 perror(msg); 52 53 printf("UNRESOLVED: " TEST_NAME " (stdlib failure)\n"); 54 55 exit(77); 56} 57 58void unresolved(const char *fmt, ...) { 59 va_list ap; 60 61 printf("UNRESOLVED: " TEST_NAME ": "); 62 va_start(ap, fmt); 63 vprintf(fmt, ap); 64 va_end(ap); 65 printf("\n"); 66 67 exit(77); 68} 69 70void fail(const char *fmt, ...) { 71 va_list ap; 72 73 va_start(ap, fmt); 74 vprintf(fmt, ap); 75 va_end(ap); 76 printf("\n"); 77 78 exit(EXIT_FAILURE); 79} 80 81void handle(AVAHI_GCC_UNUSED int sig) { 82 fail("Interrupted after %d second of CPU time", MAX_CPU_SECONDS); 83} 84 85#define TRY_EXCEPT(cmd, badresult) \ 86 do { \ 87 if ((cmd) == (badresult)) \ 88 unresolved("%s returned %s", #cmd, #badresult); \ 89 } while (0) 90 91int main(AVAHI_GCC_UNUSED int argc, AVAHI_GCC_UNUSED char *argv[]) { 92 struct itimerval itval; 93 AvahiDnsPacket *packet; 94 char name[512]; 95 int ret; 96 uint8_t badrr[] = { 97 0xC0, AVAHI_DNS_PACKET_HEADER_SIZE, /* self-referential QNAME pointer */ 98 0, 1, /* QTYPE A (host addr) */ 99 0, 1, /* QCLASS IN (internet/ipv4) */ 100 }; 101 102 if (signal(SIGVTALRM, handle) == SIG_ERR) 103 stdlib_fail("signal(SIGVTALRM)"); 104 105 memset(&itval, 0, sizeof(itval)); 106 itval.it_value.tv_sec = MAX_CPU_SECONDS; 107 108 if (setitimer(ITIMER_VIRTUAL, &itval, NULL) == -1) 109 stdlib_fail("setitimer()"); 110 111 TRY_EXCEPT(packet = avahi_dns_packet_new_query(512), NULL); 112 TRY_EXCEPT(avahi_dns_packet_append_bytes(packet, badrr, sizeof(badrr)), NULL); 113 114 /* This is expected to fail (if it returns) */ 115 ret = avahi_dns_packet_consume_name(packet, name, sizeof(name)); 116 117 if (ret != -1) 118 fail("avahi_dns_packet_consume_name() returned %d; -1 was expected", ret); 119 120 return EXIT_SUCCESS; 121} 122 123/* vim:ts=4:sw=4:et 124 */ 125