int rfc2671RROptPack(char *buf, size_t sz, ssize_t edns_sz) { // set the OPT record correctly. base it on a macro size of the Squid DNS read buffer static rfc1035_rr opt; // EDNS OPT record says only what our DNS buffer size is so far. snprintf(opt.name, RFC1035_MAXHOSTNAMESZ, "."); opt.type = RFC1035_TYPE_OPT; opt._class = min(edns_sz, (ssize_t)SQUID_UDP_SO_RCVBUF-1); opt.ttl = 0; // relevant? opt.rdata = NULL; opt.rdlength = 0; return rfc1035RRPack(buf, sz, &opt); }
ssize_t rfc1035BuildAReply(const char *hostname, const ACL_ARGV *ip_argv, const char *dnsname, const char *dns_ip, unsigned short qid, char *buf, size_t sz) { rfc1035_message h; rfc1035_rr rr; size_t offset = 0; unsigned int nip; int i; memset(&h, '\0', sizeof(h)); h.id = qid; h.qr = 1; h.opcode = 0; /* QUERY */ h.aa = 0; h.tc = 0; h.rd = 1; h.ra = 0; h.rcode = 0; h.qdcount = 1; h.ancount = ip_argv->argc; h.nscount = (dnsname && *dnsname) ? 1 : 0; h.arcount = (h.nscount && dns_ip && *dns_ip) ? 1 : 0; offset += rfc1035HeaderPack(buf + offset, sz - offset, &h); offset += rfc1035QuestionPack(buf + offset, sz - offset, hostname, RFC1035_TYPE_A, RFC1035_CLASS_IN); for (i = 0; i < ip_argv->argc; i++) { memset(&rr, 0, sizeof(rr)); snprintf(rr.name, sizeof(rr.name), "%s", hostname); rr.type = RFC1035_TYPE_A; rr.tclass = RFC1035_CLASS_IN; rr.ttl = 5; rr.rdlength = 4; nip = inet_addr(ip_argv->argv[i]); rr.rdata = (char*) acl_mycalloc(1, rr.rdlength); memcpy(rr.rdata, &nip, rr.rdlength); offset += rfc1035RRPack(&rr, buf + offset, sz - offset); acl_myfree(rr.rdata); } if (h.nscount) { memset(&rr, 0, sizeof(rr)); snprintf(rr.name, sizeof(rr.name), "%s", dnsname); rr.type = RFC1035_TYPE_NS; rr.tclass = RFC1035_CLASS_IN; rr.ttl = 5; rr.rdlength = (unsigned short) strlen(dnsname); rr.rdata = acl_mystrdup(dnsname); offset += rfc1035RRPack(&rr, buf + offset, sz - offset); acl_myfree(rr.rdata); } if (h.arcount) { memset(&rr, 0, sizeof(rr)); snprintf(rr.name, sizeof(rr.name), "%s", dnsname); rr.type = RFC1035_TYPE_NS; rr.tclass = RFC1035_CLASS_IN; rr.ttl = 5; rr.rdlength = (unsigned short) strlen(dns_ip); rr.rdata = acl_mystrdup(dns_ip); offset += rfc1035RRPack(&rr, buf + offset, sz - offset); acl_myfree(rr.rdata); } return ((int) offset); }