X-Git-Url: http://www.chiark.greenend.org.uk/ucgi/~ianmdlvl/git?a=blobdiff_plain;f=regress%2Fhplayback.c.m4;h=4fb12044e73b130d2bda88ce7819b707b0f8ca11;hb=31ce0ac48818d84aae5e7bfb3fe61049787e16fb;hp=e459ee65d30a050969aed7eabb4d2a6ef577d502;hpb=3d5cde09d167be1609d27d0d93de2096250a310c;p=adns.git diff --git a/regress/hplayback.c.m4 b/regress/hplayback.c.m4 index e459ee6..4fb1204 100644 --- a/regress/hplayback.c.m4 +++ b/regress/hplayback.c.m4 @@ -2,16 +2,16 @@ m4_dnl hplayback.c.m4 m4_dnl (part of complex test harness, not of the library) m4_dnl - playback routines -m4_dnl This file is -m4_dnl Copyright (C) 1997-2000 Ian Jackson -m4_dnl -m4_dnl It is part of adns, which is -m4_dnl Copyright (C) 1997-2000 Ian Jackson -m4_dnl Copyright (C) 1999 Tony Finch +m4_dnl This file is part of adns, which is +m4_dnl Copyright (C) 1997-2000,2003,2006,2014-2016,2020 Ian Jackson +m4_dnl Copyright (C) 2014 Mark Wooding +m4_dnl Copyright (C) 1999-2000,2003,2006 Tony Finch +m4_dnl Copyright (C) 1991 Massachusetts Institute of Technology +m4_dnl (See the file INSTALL for full details.) m4_dnl m4_dnl This program is free software; you can redistribute it and/or modify m4_dnl it under the terms of the GNU General Public License as published by -m4_dnl the Free Software Foundation; either version 2, or (at your option) +m4_dnl the Free Software Foundation; either version 3, or (at your option) m4_dnl any later version. m4_dnl m4_dnl This program is distributed in the hope that it will be useful, @@ -20,31 +20,32 @@ m4_dnl MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the m4_dnl GNU General Public License for more details. m4_dnl m4_dnl You should have received a copy of the GNU General Public License -m4_dnl along with this program; if not, write to the Free Software Foundation, -m4_dnl Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. +m4_dnl along with this program; if not, write to the Free Software Foundation. m4_include(hmacros.i4) #include #include -#include #include #include +#include #include #include #include +#include + +#include +#include +#include + #include "harness.h" -static FILE *Tinputfile, *Treportfile; +static FILE *Tinputfile, *Tfuzzrawfile, *Treportfile; static vbuf vb2; -extern void Tshutdown(void) { - adns__vbuf_free(&vb2); -} - -static void Tensurereportfile(void) { +static void Tensure_reportfile(void) { const char *fdstr; int fd; @@ -55,6 +56,36 @@ static void Tensurereportfile(void) { Treportfile= fdopen(fd,"a"); if (!Treportfile) Tfailed("fdopen ADNS_TEST_REPORT_FD"); } +static void Tensure_fuzzrawfile(void) { + static int done; + + if (done) return; + done++; + + const char *fdstr= getenv("ADNS_TEST_FUZZRAW_DUMP_FD"); + if (!fdstr) return; + + int fd= atoi(fdstr); + Tfuzzrawfile= fdopen(fd,"ab"); + if (!Tfuzzrawfile) Tfailed("fdopen ADNS_TEST_FUZZRAW_DUMP_FD"); +} + +static void FR_write(const void *p, size_t sz) { + if (!Tfuzzrawfile) return; + ssize_t got = fwrite(p,1,sz,Tfuzzrawfile); + if (ferror(Tfuzzrawfile)) Tfailed("write fuzzraw output file"); + assert(got==sz); +} + +#define FR_WRITE(x) (FR_write(&(x), sizeof((x)))) + +extern void Tshutdown(void) { + adns__vbuf_free(&vb2); + if (Tfuzzrawfile) { + if (fclose(Tfuzzrawfile)) Tfailed("close fuzzraw output file"); + } +} + static void Psyntax(const char *where) { fprintf(stderr,"adns test harness: syntax error in test log input file: %s\n",where); exit(-1); @@ -65,17 +96,27 @@ static void Pcheckinput(void) { if (feof(Tinputfile)) Psyntax("eof at syscall reply"); } -static void Tensureinputfile(void) { - const char *fdstr; +void T_gettimeofday_hook(void) { + static struct timeval previously; + struct timeval delta; + memset(&delta,0,sizeof(delta)); + timersub(¤ttime, &previously, &delta); + previously = currenttime; + FR_WRITE(delta); +} + +void Tensuresetup(void) { int fd; int chars; unsigned long sec, usec; + Tensure_reportfile(); + Tensure_fuzzrawfile(); + if (Tinputfile) return; Tinputfile= stdin; - fdstr= getenv("ADNS_TEST_IN_FD"); - if (fdstr) { - fd= atoi(fdstr); + fd = Ttestinputfd(); + if (fd >= 0) { Tinputfile= fdopen(fd,"r"); if (!Tinputfile) Tfailed("fdopen ADNS_TEST_IN_FD"); } setvbuf(Tinputfile,0,_IONBF,0); @@ -123,6 +164,7 @@ static int Perrno(const char *stuff) { if (te->n) return te->v; r= strtoul(stuff+2,&ep,10); if (*ep) Psyntax("errno value not recognised, not numeric"); + if (r==0 || r>255) Psyntax("numeric errno out of range 1..255"); return r; } @@ -145,19 +187,44 @@ static void P_updatetime(void) { } static void Pfdset(fd_set *set, int max) { - int r, c; + int c; + unsigned long ul; char *ep; + + if (!set) { + Pstring("null","null fdset pointer"); + return; + } if (vb2.buf[vb2.used++] != hm_squote[hm_squote) Psyntax("fd set start not ["); FD_ZERO(set); - for (;;) { - r= strtoul(vb2.buf+vb2.used,&ep,10); - if (r>=max) Psyntax("fd set member > max"); - FD_SET(r,set); - vb2.used= ep - (char*)vb2.buf; - c= vb2.buf[vb2.used++]; - if (c == hm_squote]hm_squote) break; - if (c != hm_squote,hm_squote) Psyntax("fd set separator not ,"); + if (vb2.buf[vb2.used] == hm_squote]hm_squote) { + vb2.used++; + } else { + for (;;) { + ul= strtoul(vb2.buf+vb2.used,&ep,10); + if (ul>=max) Psyntax("fd set member > max"); + if (ep == (char*)vb2.buf+vb2.used) Psyntax("empty entry in fd set"); + FD_SET(ul,set); + vb2.used= ep - (char*)vb2.buf; + c= vb2.buf[vb2.used++]; + if (c == hm_squote]hm_squote) break; + if (c != hm_squote,hm_squote) Psyntax("fd set separator not ,"); + } + } + + uint16_t accum; + int inaccum=0, fd; + for (fd=0; ; fd++) { + if (fd>=max || inaccum==16) { + FR_WRITE(accum); + inaccum= 0; + } + if (fd>=max) + break; + accum <<= 1; + accum |= !!FD_ISSET(fd,set); + inaccum++; } } @@ -205,23 +272,43 @@ static void Ppollfds(struct pollfd *fds, int nfds) { #endif static void Paddr(struct sockaddr *addr, int *lenr) { - struct sockaddr_in *sa= (struct sockaddr_in*)addr; - char *p, *ep; - long ul; - - assert(*lenr >= sizeof(*sa)); - p= strchr(vb2.buf+vb2.used,':'); - if (!p) Psyntax("no port on address"); - *p++= 0; - memset(sa,0,sizeof(*sa)); - sa->sin_family= AF_INET; - if (!inet_aton(vb2.buf+vb2.used,&sa->sin_addr)) Psyntax("invalid address"); - ul= strtoul(p,&ep,10); - if (*ep && *ep != hm_squote hm_squote) Psyntax("invalid port (bad syntax)"); + adns_rr_addr a; + char *p, *q, *ep; + int err; + unsigned long ul; + + p= vb2.buf+vb2.used; + if (*p!='[') { + q= strchr(p,':'); + if (!q) Psyntax("missing :"); + *q++= 0; + } else { + p++; + q= strchr(p,']'); + if (!q) Psyntax("missing ]"); + *q++= 0; + if (*q!=':') Psyntax("expected : after ]"); + q++; + } + ul= strtoul(q,&ep,10); + if (*ep && *ep != ' ') Psyntax("invalid port (bad syntax)"); if (ul >= 65536) Psyntax("port too large"); - sa->sin_port= htons(ul); - *lenr= sizeof(*sa); + if (Tfuzzrawfile) { + int tl = strlen(p); + FR_WRITE(tl); + FR_write(p,tl); + uint16_t port16 = ul; + FR_WRITE(port16); + } + + a.len= sizeof(a.addr); + err= adns_text2addr(p, (int)ul, 0, &a.addr.sa,&a.len); + if (err) Psyntax("invalid address"); + + assert(*lenr >= a.len); + memcpy(addr, &a.addr, a.len); + *lenr= a.len; vb2.used= ep - (char*)vb2.buf; } @@ -252,11 +339,11 @@ static int Pbytes(byte *buf, int maxlen) { } void Q_vb(void) { - int r; + const char *nl; - Tensureinputfile(); + Tensuresetup(); if (!adns__vbuf_ensure(&vb2,vb.used+2)) Tnomem(); - r= fread(vb2.buf,1,vb.used+2,Tinputfile); + fread(vb2.buf,1,vb.used+2,Tinputfile); if (feof(Tinputfile)) { fprintf(stderr,"adns test harness: input ends prematurely; program did:\n %.*s\n", vb.used,vb.buf); @@ -272,18 +359,17 @@ void Q_vb(void) { vb.used,vb.buf, vb.used,vb2.buf+1); exit(1); } + nl= memchr(vb.buf,'\n',vb.used); + fprintf(Treportfile," %.*s\n", (int)(nl ? nl - (const char*)vb.buf : vb.used), vb.buf); } m4_define(`hm_syscall', ` hm_create_proto_h int H$1(hm_args_massage($3,void)) { int r, amtread; + hm_create_nothing m4_define(`hm_rv_fd',`char *ep;') m4_define(`hm_rv_any',`char *ep;') - m4_define(`hm_rv_len',`') - m4_define(`hm_rv_must',`') - m4_define(`hm_rv_succfail',`') - m4_define(`hm_rv_fcntl',`') $2 hm_create_hqcall_vars @@ -299,35 +385,64 @@ int H$1(hm_args_massage($3,void)) { if (!adns__vbuf_ensure(&vb2,1000)) Tnomem(); fgets(vb2.buf,vb2.avail,Tinputfile); Pcheckinput(); - Tensurereportfile(); - fprintf(Treportfile,"syscallr %s",vb2.buf); + Tensuresetup(); + fprintf(Treportfile,"%s",vb2.buf); amtread= strlen(vb2.buf); if (amtread<=0 || vb2.buf[--amtread]!=hm_squote\nhm_squote) Psyntax("badly formed line"); vb2.buf[amtread]= 0; if (memcmp(vb2.buf," $1=",hm_r_offset)) Psyntax("syscall reply mismatch"); +#ifdef FUZZRAW_SYNC + hm_fr_syscall_ident($1) + FR_WRITE(sync_expect); +#endif + + m4_define(`hm_rv_check_errno',` if (vb2.buf[hm_r_offset] == hm_squoteEhm_squote) { int e; e= Perrno(vb2.buf+hm_r_offset); P_updatetime(); errno= e; + FR_WRITE(e); return -1; } - - m4_define(`hm_rv_succfail',` + r= 0; + FR_WRITE(r); + ') + m4_define(`hm_rv_check_success',` if (memcmp(vb2.buf+hm_r_offset,"OK",2)) Psyntax("success/fail not E* or OK"); vb2.used= hm_r_offset+2; r= 0; ') - m4_define(`hm_rv_len',`hm_rv_succfail') - m4_define(`hm_rv_must',`hm_rv_succfail') - m4_define(`hm_rv_any',` - r= strtoul(vb2.buf+hm_r_offset,&ep,10); - if (*ep && *ep!=hm_squote hm_squote) Psyntax("return value not E* or positive number"); + m4_define(`hm_rv_any_nowrite',` + hm_rv_check_errno + unsigned long ul_r= strtoul(vb2.buf+hm_r_offset,&ep,10); + if (ul_r < 0 || ul_r > INT_MAX || + (*ep && *ep!=hm_squote hm_squote)) + Psyntax("return value not E* or positive number"); + r= ul_r; vb2.used= ep - (char*)vb2.buf; ') + + m4_define(`hm_rv_succfail',` + hm_rv_check_errno + hm_rv_check_success + ') + m4_define(`hm_rv_len',` + hm_rv_check_errno + hm_rv_check_success + ') + m4_define(`hm_rv_must',` + hm_rv_check_success + ') + m4_define(`hm_rv_any',` + hm_rv_any_nowrite + FR_WRITE(r); + ') m4_define(`hm_rv_fd',`hm_rv_any') + m4_define(`hm_rv_select',`hm_rv_any_nowrite') + m4_define(`hm_rv_poll',`hm_rv_any_nowrite') m4_define(`hm_rv_fcntl',` r= 0; if (cmd == F_GETFL) { @@ -340,7 +455,7 @@ int H$1(hm_args_massage($3,void)) { Psyntax("fcntl flags not O_NONBLOCK|... or ~O_NONBLOCK&..."); } } else if (cmd == F_SETFL) { - hm_rv_succfail + hm_rv_check_success } else { Psyntax("fcntl not F_GETFL or F_SETFL"); } @@ -356,7 +471,11 @@ int H$1(hm_args_massage($3,void)) { if (vb2.used != amtread) Psyntax("junk at end of line"); hm_create_nothing - m4_define(`hm_arg_bytes_out',`r= Pbytes($'`2,$'`4);') + m4_define(`hm_arg_bytes_out',` + r= Pbytes($'`2,$'`4); + FR_WRITE(r); + FR_write(buf,r); + ') $3 P_updatetime(); @@ -364,4 +483,8 @@ int H$1(hm_args_massage($3,void)) { } ') +m4_define(`hm_specsyscall', `') + m4_include(`hsyscalls.i4') + +hm_stdsyscall_close