Return to unit1650.c CVS log | Up to [ELWIX - Embedded LightWeight unIX -] / embedaddon / curl / tests / unit |
1.1 ! misho 1: /*************************************************************************** ! 2: * _ _ ____ _ ! 3: * Project ___| | | | _ \| | ! 4: * / __| | | | |_) | | ! 5: * | (__| |_| | _ <| |___ ! 6: * \___|\___/|_| \_\_____| ! 7: * ! 8: * Copyright (C) 2018 - 2020, Daniel Stenberg, <daniel@haxx.se>, et al. ! 9: * ! 10: * This software is licensed as described in the file COPYING, which ! 11: * you should have received as part of this distribution. The terms ! 12: * are also available at https://curl.haxx.se/docs/copyright.html. ! 13: * ! 14: * You may opt to use, copy, modify, merge, publish, distribute and/or sell ! 15: * copies of the Software, and permit persons to whom the Software is ! 16: * furnished to do so, under the terms of the COPYING file. ! 17: * ! 18: * This software is distributed on an "AS IS" basis, WITHOUT WARRANTY OF ANY ! 19: * KIND, either express or implied. ! 20: * ! 21: ***************************************************************************/ ! 22: #include "curlcheck.h" ! 23: ! 24: #include "doh.h" ! 25: ! 26: static CURLcode unit_setup(void) ! 27: { ! 28: return CURLE_OK; ! 29: } ! 30: ! 31: static void unit_stop(void) ! 32: { ! 33: ! 34: } ! 35: ! 36: #ifndef CURL_DISABLE_DOH ! 37: #define DNS_PREAMBLE "\x00\x00\x01\x00\x00\x01\x00\x00\x00\x00\x00\x00" ! 38: #define LABEL_TEST "\x04\x74\x65\x73\x74" ! 39: #define LABEL_HOST "\x04\x68\x6f\x73\x74" ! 40: #define LABEL_NAME "\x04\x6e\x61\x6d\x65" ! 41: #define DNSA_TYPE "\x01" ! 42: #define DNSAAAA_TYPE "\x1c" ! 43: #define DNSA_EPILOGUE "\x00\x00" DNSA_TYPE "\x00\x01" ! 44: #define DNSAAAA_EPILOGUE "\x00\x00" DNSAAAA_TYPE "\x00\x01" ! 45: ! 46: #define DNS_Q1 DNS_PREAMBLE LABEL_TEST LABEL_HOST LABEL_NAME DNSA_EPILOGUE ! 47: #define DNS_Q2 DNS_PREAMBLE LABEL_TEST LABEL_HOST LABEL_NAME DNSAAAA_EPILOGUE ! 48: ! 49: struct dohrequest { ! 50: /* input */ ! 51: const char *name; ! 52: DNStype type; ! 53: ! 54: /* output */ ! 55: const char *packet; ! 56: size_t size; ! 57: int rc; ! 58: }; ! 59: ! 60: ! 61: static struct dohrequest req[] = { ! 62: {"test.host.name", DNS_TYPE_A, DNS_Q1, sizeof(DNS_Q1)-1, 0 }, ! 63: {"test.host.name", DNS_TYPE_AAAA, DNS_Q2, sizeof(DNS_Q2)-1, 0 }, ! 64: {"zzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzz" ! 65: ".host.name", ! 66: DNS_TYPE_AAAA, NULL, 0, DOH_DNS_BAD_LABEL } ! 67: }; ! 68: ! 69: struct dohresp { ! 70: /* input */ ! 71: const char *packet; ! 72: size_t size; ! 73: DNStype type; ! 74: ! 75: /* output */ ! 76: int rc; ! 77: const char *out; ! 78: }; ! 79: ! 80: #define DNS_FOO_EXAMPLE_COM \ ! 81: "\x00\x00\x01\x00\x00\x01\x00\x01\x00\x00\x00\x00\x03\x66\x6f\x6f" \ ! 82: "\x07\x65\x78\x61\x6d\x70\x6c\x65\x03\x63\x6f\x6d\x00\x00\x01\x00" \ ! 83: "\x01\xc0\x0c\x00\x01\x00\x01\x00\x00\x00\x37\x00\x04\x7f\x00\x00" \ ! 84: "\x01" ! 85: ! 86: static const char full49[] = DNS_FOO_EXAMPLE_COM; ! 87: ! 88: static struct dohresp resp[] = { ! 89: {"\x00\x00", 2, DNS_TYPE_A, DOH_TOO_SMALL_BUFFER, NULL }, ! 90: {"\x00\x01\x00\x01\x00\x01\x00\x01\x00\x01\x00\x01", 12, ! 91: DNS_TYPE_A, DOH_DNS_BAD_ID, NULL }, ! 92: {"\x00\x00\x00\x01\x00\x01\x00\x01\x00\x01\x00\x01", 12, ! 93: DNS_TYPE_A, DOH_DNS_BAD_RCODE, NULL }, ! 94: {"\x00\x00\x01\x00\x00\x01\x00\x01\x00\x00\x00\x00\x03\x66\x6f\x6f", 16, ! 95: DNS_TYPE_A, DOH_DNS_OUT_OF_RANGE, NULL }, ! 96: {"\x00\x00\x01\x00\x00\x01\x00\x01\x00\x00\x00\x00\x03\x66\x6f\x6f\x00", 17, ! 97: DNS_TYPE_A, DOH_DNS_OUT_OF_RANGE, NULL }, ! 98: {"\x00\x00\x01\x00\x00\x01\x00\x01\x00\x00\x00\x00\x03\x66\x6f\x6f\x00" ! 99: "\x00\x01\x00\x01", 21, ! 100: DNS_TYPE_A, DOH_DNS_OUT_OF_RANGE, NULL }, ! 101: {"\x00\x00\x01\x00\x00\x01\x00\x01\x00\x00\x00\x00\x03\x66\x6f\x6f\x00" ! 102: "\x00\x01\x00\x01" ! 103: "\x04", 18, ! 104: DNS_TYPE_A, DOH_DNS_OUT_OF_RANGE, NULL }, ! 105: ! 106: {"\x00\x00\x01\x00\x00\x01\x00\x01\x00\x00\x00\x00\x04\x63\x75\x72" ! 107: "\x6c\x04\x63\x75\x72\x6c\x00\x00\x05\x00\x01\xc0\x0c\x00\x05\x00" ! 108: "\x01\x00\x00\x00\x37\x00\x11\x08\x61\x6e\x79\x77\x68\x65\x72\x65" ! 109: "\x06\x72\x65\x61\x6c\x6c\x79\x00", 56, ! 110: DNS_TYPE_A, DOH_OK, "anywhere.really "}, ! 111: ! 112: {DNS_FOO_EXAMPLE_COM, 49, DNS_TYPE_A, DOH_OK, "127.0.0.1 "}, ! 113: ! 114: {"\x00\x00\x01\x00\x00\x01\x00\x01\x00\x00\x00\x00\x04\x61\x61\x61" ! 115: "\x61\x07\x65\x78\x61\x6d\x70\x6c\x65\x03\x63\x6f\x6d\x00\x00\x1c" ! 116: "\x00\x01\xc0\x0c\x00\x1c\x00\x01\x00\x00\x00\x37\x00\x10\x20\x20" ! 117: "\x20\x20\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x20\x20", 62, ! 118: DNS_TYPE_AAAA, DOH_OK, ! 119: "2020:2020:0000:0000:0000:0000:0000:2020 " }, ! 120: ! 121: {"\x00\x00\x01\x00\x00\x01\x00\x01\x00\x00\x00\x00\x04\x63\x75\x72" ! 122: "\x6c\x04\x63\x75\x72\x6c\x00\x00\x05\x00\x01\xc0\x0c\x00\x05\x00" ! 123: "\x01\x00\x00\x00\x37\x00" ! 124: "\x07\x03\x61\x6e\x79\xc0\x27\x00", 46, ! 125: DNS_TYPE_A, DOH_DNS_LABEL_LOOP, NULL}, ! 126: ! 127: /* packet with NSCOUNT == 1 */ ! 128: {"\x00\x00\x01\x00\x00\x01\x00\x01\x00\x01\x00\x00\x04\x61\x61\x61" ! 129: "\x61\x07\x65\x78\x61\x6d\x70\x6c\x65\x03\x63\x6f\x6d\x00\x00\x1c" ! 130: "\x00\x01\xc0\x0c\x00\x1c\x00\x01\x00\x00\x00\x37\x00\x10\x20\x20" ! 131: "\x20\x20\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x20\x20" ! 132: LABEL_TEST LABEL_HOST LABEL_NAME DNSAAAA_EPILOGUE "\x00\x00\x00\x01" ! 133: "\00\x04\x01\x01\x01\x01", /* RDDATA */ ! 134: ! 135: 62 + 30, ! 136: DNS_TYPE_AAAA, DOH_OK, ! 137: "2020:2020:0000:0000:0000:0000:0000:2020 " }, ! 138: ! 139: /* packet with ARCOUNT == 1 */ ! 140: {"\x00\x00\x01\x00\x00\x01\x00\x01\x00\x00\x00\x01\x04\x61\x61\x61" ! 141: "\x61\x07\x65\x78\x61\x6d\x70\x6c\x65\x03\x63\x6f\x6d\x00\x00\x1c" ! 142: "\x00\x01\xc0\x0c\x00\x1c\x00\x01\x00\x00\x00\x37\x00\x10\x20\x20" ! 143: "\x20\x20\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x20\x20" ! 144: LABEL_TEST LABEL_HOST LABEL_NAME DNSAAAA_EPILOGUE "\x00\x00\x00\x01" ! 145: "\00\x04\x01\x01\x01\x01", /* RDDATA */ ! 146: ! 147: 62 + 30, ! 148: DNS_TYPE_AAAA, DOH_OK, ! 149: "2020:2020:0000:0000:0000:0000:0000:2020 " }, ! 150: ! 151: }; ! 152: ! 153: UNITTEST_START ! 154: { ! 155: size_t size = 0; ! 156: unsigned char buffer[256]; ! 157: size_t i; ! 158: unsigned char *p; ! 159: for(i = 0; i < sizeof(req) / sizeof(req[0]); i++) { ! 160: int rc = doh_encode(req[i].name, req[i].type, ! 161: buffer, sizeof(buffer), &size); ! 162: if(rc != req[i].rc) { ! 163: fprintf(stderr, "req %zu: Expected return code %d got %d\n", i, ! 164: req[i].rc, rc); ! 165: return 1; ! 166: } ! 167: else if(size != req[i].size) { ! 168: fprintf(stderr, "req %zu: Expected size %zu got %zu\n", i, ! 169: req[i].size, size); ! 170: fprintf(stderr, "DNS encode made: %s\n", hexdump(buffer, size)); ! 171: return 2; ! 172: } ! 173: else if(req[i].packet && memcmp(req[i].packet, buffer, size)) { ! 174: fprintf(stderr, "DNS encode made: %s\n", hexdump(buffer, size)); ! 175: fprintf(stderr, "... instead of: %s\n", ! 176: hexdump((unsigned char *)req[i].packet, size)); ! 177: return 3; ! 178: } ! 179: } ! 180: ! 181: for(i = 0; i < sizeof(resp) / sizeof(resp[0]); i++) { ! 182: struct dohentry d; ! 183: int rc; ! 184: char *ptr; ! 185: size_t len; ! 186: int u; ! 187: memset(&d, 0, sizeof(d)); ! 188: rc = doh_decode((const unsigned char *)resp[i].packet, resp[i].size, ! 189: resp[i].type, &d); ! 190: if(rc != resp[i].rc) { ! 191: fprintf(stderr, "resp %zu: Expected return code %d got %d\n", i, ! 192: resp[i].rc, rc); ! 193: return 4; ! 194: } ! 195: len = sizeof(buffer); ! 196: ptr = (char *)buffer; ! 197: for(u = 0; u < d.numaddr; u++) { ! 198: size_t o; ! 199: struct dohaddr *a; ! 200: a = &d.addr[u]; ! 201: if(resp[i].type == DNS_TYPE_A) { ! 202: p = &a->ip.v4[0]; ! 203: msnprintf(ptr, len, "%u.%u.%u.%u ", p[0], p[1], p[2], p[3]); ! 204: o = strlen(ptr); ! 205: len -= o; ! 206: ptr += o; ! 207: } ! 208: else { ! 209: int j; ! 210: for(j = 0; j < 16; j += 2) { ! 211: size_t l; ! 212: msnprintf(ptr, len, "%s%02x%02x", j?":":"", a->ip.v6[j], ! 213: a->ip.v6[j + 1]); ! 214: l = strlen(ptr); ! 215: len -= l; ! 216: ptr += l; ! 217: } ! 218: msnprintf(ptr, len, " "); ! 219: len--; ! 220: ptr++; ! 221: } ! 222: } ! 223: for(u = 0; u < d.numcname; u++) { ! 224: size_t o; ! 225: msnprintf(ptr, len, "%s ", d.cname[u].alloc); ! 226: o = strlen(ptr); ! 227: len -= o; ! 228: ptr += o; ! 229: } ! 230: de_cleanup(&d); ! 231: if(resp[i].out && strcmp((char *)buffer, resp[i].out)) { ! 232: fprintf(stderr, "resp %zu: Expected %s got %s\n", i, ! 233: resp[i].out, buffer); ! 234: return 1; ! 235: } ! 236: } ! 237: ! 238: { ! 239: /* pass all sizes into the decoder until full */ ! 240: for(i = 0; i < sizeof(full49)-1; i++) { ! 241: struct dohentry d; ! 242: int rc; ! 243: memset(&d, 0, sizeof(d)); ! 244: rc = doh_decode((const unsigned char *)full49, i, DNS_TYPE_A, &d); ! 245: if(!rc) { ! 246: /* none of them should work */ ! 247: fprintf(stderr, "%zu: %d\n", i, rc); ! 248: return 5; ! 249: } ! 250: } ! 251: /* and try all pieces from the other end of the packet */ ! 252: for(i = 1; i < sizeof(full49); i++) { ! 253: struct dohentry d; ! 254: int rc; ! 255: memset(&d, 0, sizeof(d)); ! 256: rc = doh_decode((const unsigned char *)&full49[i], sizeof(full49)-i-1, ! 257: DNS_TYPE_A, &d); ! 258: if(!rc) { ! 259: /* none of them should work */ ! 260: fprintf(stderr, "2 %zu: %d\n", i, rc); ! 261: return 7; ! 262: } ! 263: } ! 264: { ! 265: int rc; ! 266: struct dohentry d; ! 267: struct dohaddr *a; ! 268: memset(&d, 0, sizeof(d)); ! 269: rc = doh_decode((const unsigned char *)full49, sizeof(full49)-1, ! 270: DNS_TYPE_A, &d); ! 271: fail_if(d.numaddr != 1, "missing address"); ! 272: a = &d.addr[0]; ! 273: p = &a->ip.v4[0]; ! 274: msnprintf((char *)buffer, sizeof(buffer), ! 275: "%u.%u.%u.%u", p[0], p[1], p[2], p[3]); ! 276: if(rc || strcmp((char *)buffer, "127.0.0.1")) { ! 277: fprintf(stderr, "bad address decoded: %s, rc == %d\n", buffer, rc); ! 278: return 7; ! 279: } ! 280: fail_if(d.numcname, "bad cname counter"); ! 281: } ! 282: } ! 283: } ! 284: UNITTEST_STOP ! 285: ! 286: #else /* CURL_DISABLE_DOH */ ! 287: UNITTEST_START ! 288: { ! 289: return 1; /* nothing to do, just fail */ ! 290: } ! 291: UNITTEST_STOP ! 292: ! 293: ! 294: #endif