X-Git-Url: https://git.exim.org/users/heiko/exim.git/blobdiff_plain/5f3d09836c17cb80a1953196c98371ed70396903..80591636e0439c7bc83b1fb322fd110b397f4217:/test/src/fakens.c?ds=sidebyside diff --git a/test/src/fakens.c b/test/src/fakens.c index 33bfe4f3e..aff5f40f6 100644 --- a/test/src/fakens.c +++ b/test/src/fakens.c @@ -51,11 +51,17 @@ and the domain is not found. It converts the the result to PASS_ON instead of HOST_NOT_FOUND. Any DNS record line in a zone file can be prefixed with "DELAY=" and -a number of milliseconds (followed by whitespace). +a number of milliseconds (followed by one space). -Any DNS record line in a zone file can be prefixed with "DNSSEC" and -at least one space; if all the records found by a lookup are marked -as such then the response will have the "AD" bit set. */ +Any DNS record line in a zone file can be prefixed with "DNSSEC "; +if all the records found by a lookup are marked +as such then the response will have the "AD" bit set. + +Any DNS record line in a zone file can be prefixed with "AA " +if all the records found by a lookup are marked +as such then the response will have the "AA" bit set. + +*/ #include #include @@ -292,6 +298,8 @@ Arguments: qtypelen the length of qtype pkptr points to the output buffer pointer; this is updated countptr points to the record count; this is updated + dnssec points to the AD flag indicator; this updated + aa points to the AA flag indicator; this updated Returns: 0 on success, else HOST_NOT_FOUND or NO_DATA or NO_RECOVERY or PASS_ON - the latter if a "PASS ON NOT FOUND" line is seen @@ -299,7 +307,7 @@ Returns: 0 on success, else HOST_NOT_FOUND or NO_DATA or NO_RECOVERY or static int find_records(FILE *f, uschar *zone, uschar *domain, uschar *qtype, - int qtypelen, uschar **pkptr, int *countptr, BOOL * dnssec) + int qtypelen, uschar **pkptr, int *countptr, BOOL * dnssec, BOOL * aa) { int yield = HOST_NOT_FOUND; int domainlen = Ustrlen(domain); @@ -324,6 +332,7 @@ rrdomain[0] = 0; /* No previous domain */ (void)fseek(f, 0, SEEK_SET); /* Start again at the beginning */ *dnssec = TRUE; /* cancelled by first nonsecure rec found */ +*aa = TRUE; /* cancelled by first non-authoritive record */ /* Scan for RRs */ @@ -336,6 +345,7 @@ while (fgets(CS buffer, sizeof(buffer), f) != NULL) int tvalue = typeptr->value; int qtlen = qtypelen; BOOL rr_sec = FALSE; + BOOL rr_aa = FALSE; int delay = 0; p = buffer; @@ -354,23 +364,27 @@ while (fgets(CS buffer, sizeof(buffer), f) != NULL) p = buffer; for (;;) - { - if (Ustrncmp(p, US"DNSSEC ", 7) == 0) /* tagged as secure */ - { - rr_sec = TRUE; - p += 7; - } - else if (Ustrncmp(p, US"DELAY=", 6) == 0) /* delay beforee response */ - { - for (p += 6; *p >= '0' && *p <= '9'; p++) - delay = delay*10 + *p - '0'; - while (isspace(*p)) p++; - } - else - break; - } + { + if (Ustrncmp(p, US"DNSSEC ", 7) == 0) /* tagged as secure */ + { + rr_sec = TRUE; + p += 7; + } + else if (Ustrncmp(p, US"AA ", 3) == 0) /* tagged as authoritive */ + { + rr_aa = TRUE; + p += 3; + } + else if (Ustrncmp(p, US"DELAY=", 6) == 0) /* delay before response */ + { + for (p += 6; *p >= '0' && *p <= '9'; p++) delay = delay*10 + *p - '0'; + if (isspace(*p)) p++; + } + else + break; + } - if (!isspace(*p)) + if (!isspace(*p)) /* new domain name */ { uschar *pp = rrdomain; uschar *PP = RRdomain; @@ -389,7 +403,7 @@ while (fgets(CS buffer, sizeof(buffer), f) != NULL) pp[-1] = 0; PP[-1] = 0; } - } + } /* else use previous line's domain name */ /* Compare domain names; first check for a wildcard */ @@ -428,6 +442,9 @@ while (fgets(CS buffer, sizeof(buffer), f) != NULL) if (!rr_sec) *dnssec = FALSE; /* cancel AD return */ + if (!rr_aa) + *aa = FALSE; /* cancel AA return */ + yield = 0; *countptr = *countptr + 1; @@ -566,6 +583,55 @@ alarmfn(int sig) { } + +/************************************************* +* Special-purpose domains * +*************************************************/ + +static int +special_manyhome(uschar * packet, uschar * domain) +{ +uschar *pk = packet + 12; +uschar *rdlptr; +int i, j; + +memset(packet, 0, 12); + +for (i = 104; i <= 111; i++) for (j = 0; j <= 255; j++) + { + pk = packname(domain, pk); + *pk++ = (ns_t_a >> 8) & 255; + *pk++ = (ns_t_a) & 255; + *pk++ = 0; + *pk++ = 1; /* class = IN */ + pk += 4; /* TTL field; don't care */ + rdlptr = pk; /* remember rdlength field */ + pk += 2; + + *pk++ = 10; *pk++ = 250; *pk++ = i; *pk++ = j; + + rdlptr[0] = ((pk - rdlptr - 2) >> 8) & 255; + rdlptr[1] = (pk - rdlptr - 2) & 255; + } + +packet[6] = (2048 >> 8) & 255; +packet[7] = 2048 & 255; +packet[10] = 0; +packet[11] = 0; + +(void)fwrite(packet, 1, pk - packet, stdout); +return 0; +} + +static int +special_again(uschar * packet, uschar * domain) +{ +int delay = atoi(CCS domain); /* digits at the start of the name */ +if (delay > 0) sleep(delay); +return TRY_AGAIN; +} + + /************************************************* * Entry point and main program * *************************************************/ @@ -587,9 +653,10 @@ uschar *zonefile = NULL; uschar domain[256]; uschar buffer[256]; uschar qtype[12]; -uschar packet[512]; +uschar packet[2048 * 32 + 32]; uschar *pk = packet; BOOL dnssec; +BOOL aa; signal(SIGALRM, alarmfn); @@ -636,7 +703,8 @@ Ustrncpy(qtype, argv[3], sizeof(qtype)); qtypelen = Ustrlen(qtype); for (p = qtype; *p != 0; p++) *p = toupper(*p); -/* Find the domain, lower case it, check that it is in a zone that we handle, +/* Find the domain, lower case it, deal with any specials, +check that it is in a zone that we handle, and set up the zone file name. The zone names in the table all start with a dot. */ @@ -646,6 +714,14 @@ Ustrncpy(domain, argv[2], domlen); domain[domlen] = 0; for (i = 0; i < domlen; i++) domain[i] = tolower(domain[i]); +if (Ustrcmp(domain, "manyhome.test.ex") == 0 && Ustrcmp(qtype, "A") == 0) + return special_manyhome(packet, domain); +else if (domlen >= 14 && Ustrcmp(domain + domlen - 14, "test.again.dns") == 0) + return special_again(packet, domain); +else if (domlen >= 13 && Ustrcmp(domain + domlen - 13, "test.fail.dns") == 0) + return NO_RECOVERY; + + if (Ustrchr(domain, '.') == NULL && qualify != NULL && Ustrcmp(domain, "dontqualify") != 0) { @@ -693,7 +769,7 @@ if (f == NULL) /* Find the records we want, and add them to the result. */ count = 0; -yield = find_records(f, zone, domain, qtype, qtypelen, &pk, &count, &dnssec); +yield = find_records(f, zone, domain, qtype, qtypelen, &pk, &count, &dnssec, &aa); if (yield == NO_RECOVERY) goto END_OFF; packet[6] = (count >> 8) & 255; @@ -708,6 +784,9 @@ packet[11] = 0; if (dnssec) ((HEADER *)packet)->ad = 1; +if (aa) + ((HEADER *)packet)->aa = 1; + /* Close the zone file, write the result, and return. */ END_OFF: @@ -716,6 +795,6 @@ END_OFF: return yield; } -/* vi: aw ai sw=2 +/* vi: aw ai sw=2 sts=2 ts=8 et */ /* End of fakens.c */