/*++ /* NAME /* dns_lookup 3 /* SUMMARY /* domain name service lookup /* SYNOPSIS /* #include <dns.h> /* /* int dns_lookup(name, type, rflags, list, fqdn, why) /* const char *name; /* unsigned type; /* unsigned rflags; /* DNS_RR **list; /* VSTRING *fqdn; /* VSTRING *why; /* /* int dns_lookup_l(name, rflags, list, fqdn, why, lflags, ltype, ...) /* const char *name; /* unsigned rflags; /* DNS_RR **list; /* VSTRING *fqdn; /* VSTRING *why; /* int lflags; /* unsigned ltype; /* /* int dns_lookup_v(name, rflags, list, fqdn, why, lflags, ltype) /* const char *name; /* unsigned rflags; /* DNS_RR **list; /* VSTRING *fqdn; /* VSTRING *why; /* int lflags; /* unsigned *ltype; /* /* int dns_get_h_errno() /* AUXILIARY FUNCTIONS /* extern int var_dns_ncache_ttl_fix; /* /* int dns_lookup_r(name, type, rflags, list, fqdn, why, rcode) /* const char *name; /* unsigned type; /* unsigned rflags; /* DNS_RR **list; /* VSTRING *fqdn; /* VSTRING *why; /* int *rcode; /* /* int dns_lookup_rl(name, rflags, list, fqdn, why, rcode, lflags, /* ltype, ...) /* const char *name; /* unsigned rflags; /* DNS_RR **list; /* VSTRING *fqdn; /* VSTRING *why; /* int *rcode; /* int lflags; /* unsigned ltype; /* /* int dns_lookup_rv(name, rflags, list, fqdn, why, rcode, lflags, /* ltype) /* const char *name; /* unsigned rflags; /* DNS_RR **list; /* VSTRING *fqdn; /* VSTRING *why; /* int *rcode; /* int lflags; /* unsigned *ltype; /* /* int dns_lookup_x(name, type, rflags, list, fqdn, why, rcode, lflags) /* const char *name; /* unsigned type; /* unsigned rflags; /* DNS_RR **list; /* VSTRING *fqdn; /* VSTRING *why; /* int *rcode; /* unsigned lflags; /* DESCRIPTION /* dns_lookup() looks up DNS resource records. When requested to /* look up data other than type CNAME, it will follow a limited /* number of CNAME indirections. All result names (including /* null terminator) will fit a buffer of size DNS_NAME_LEN. /* All name results are validated by \fIvalid_hostname\fR(); /* an invalid name is reported as a DNS_INVAL result, while /* malformed replies are reported as transient errors. /* /* Note: in dns_lookup*() results and queries, a name may start /* with a "*" label, which is valid according to RFC 1034 /* section 4.3.3. Such a name will not pass valid_hostname() /* checks in the rest of Postfix, because it is not a valid /* host or domain name. /* /* dns_get_h_errno() returns the last error. This deprecates /* usage of the global h_errno variable. We should not rely /* on that being updated. /* /* dns_lookup_l() and dns_lookup_v() allow the user to specify /* a list of resource types. /* /* dns_lookup_x, dns_lookup_r(), dns_lookup_rl() and dns_lookup_rv() /* accept or return additional information. /* /* The var_dns_ncache_ttl_fix variable controls a workaround /* for res_search(3) implementations that break the /* DNS_REQ_FLAG_NCACHE_TTL feature. The workaround does not /* support EDNS0 or DNSSEC, but it should be sufficient for /* DNSBL/DNSWL lookups. /* INPUTS /* .ad /* .fi /* .IP name /* The name to be looked up in the domain name system. /* This name must pass the valid_hostname() test; it /* must not be an IP address. /* .IP type /* The resource record type to be looked up (T_A, T_MX etc.). /* .IP rflags /* Resolver flags. These are a bitwise OR of: /* .RS /* .IP RES_DEBUG /* Print debugging information. /* .IP RES_DNSRCH /* Search local domain and parent domains. /* .IP RES_DEFNAMES /* Append local domain to unqualified names. /* .IP RES_USE_DNSSEC /* Request DNSSEC validation. This flag is silently ignored /* when the system stub resolver API, resolver(3), does not /* implement DNSSEC. /* Automatically turns on the RES_TRUSTAD flag on systems that /* support this flag (this behavior will be more configurable /* in a later release). /* .RE /* .IP lflags /* Flags that control the operation of the dns_lookup*() /* functions. DNS_REQ_FLAG_NONE requests no special processing. /* Otherwise, specify one or more of the following: /* .RS /* .IP DNS_REQ_FLAG_STOP_INVAL /* This flag is used by dns_lookup_l() and dns_lookup_v(). /* Invoke dns_lookup() for the resource types in the order as /* specified, and return when dns_lookup() returns DNS_INVAL. /* .IP DNS_REQ_FLAG_STOP_NULLMX /* This flag is used by dns_lookup_l() and dns_lookup_v(). /* Invoke dns_lookup() for the resource types in the order as /* specified, and return when dns_lookup() returns DNS_NULLMX. /* .IP DNS_REQ_FLAG_STOP_MX_POLICY /* This flag is used by dns_lookup_l() and dns_lookup_v(). /* Invoke dns_lookup() for the resource types in the order as /* specified, and return when dns_lookup() returns DNS_POLICY /* for an MX query. /* .IP DNS_REQ_FLAG_STOP_OK /* This flag is used by dns_lookup_l() and dns_lookup_v(). /* Invoke dns_lookup() for the resource types in the order as /* specified, and return when dns_lookup() returns DNS_OK. /* .IP DNS_REQ_FLAG_NCACHE_TTL /* When the lookup result status is DNS_NOTFOUND, return the /* SOA record(s) from the authority section in the reply, if /* available. The per-record reply TTL specifies how long the /* DNS_NOTFOUND answer is valid. The caller should pass the /* record(s) to dns_rr_free(). /* Logs a warning if the RES_DNSRCH or RES_DEFNAMES resolver /* flags are set, and disables those flags. /* .RE /* .IP ltype /* The resource record types to be looked up. In the case of /* dns_lookup_l(), this is a null-terminated argument list. /* In the case of dns_lookup_v(), this is a null-terminated /* integer array. /* OUTPUTS /* .ad /* .fi /* .IP list /* A null pointer, or a pointer to a variable that receives a /* list of requested resource records. /* .IP fqdn /* A null pointer, or storage for the fully-qualified domain /* name found for \fIname\fR. /* .IP why /* A null pointer, or storage for the reason for failure. /* .IP rcode /* Pointer to storage for the reply RCODE value. This gives /* more detailed information than DNS_FAIL, DNS_RETRY, etc. /* DIAGNOSTICS /* If DNSSEC validation is requested but the response is not /* DNSSEC validated, dns_lookup() will send a one-time probe /* query as configured with the \fBdnssec_probe\fR configuration /* parameter, and will log a warning when the probe response /* was not DNSSEC validated. /* .PP /* dns_lookup() returns one of the following codes and sets the /* \fIwhy\fR argument accordingly: /* .IP DNS_OK /* The DNS query succeeded. /* .IP DNS_POLICY /* The DNS query succeeded, but the answer did not pass the /* policy filter. /* .IP DNS_NOTFOUND /* The DNS query succeeded; the requested information was not found. /* .IP DNS_NULLMX /* The DNS query succeeded; the requested service is unavailable. /* This is returned when the list argument is not a null /* pointer, and an MX lookup result contains a null server /* name (so-called "nullmx" record). /* .IP DNS_INVAL /* The DNS query succeeded; the result failed the valid_hostname() test. /* /* NOTE: the valid_hostname() test is skipped for results that /* the caller suppresses explicitly. For example, when the /* caller requests MX record lookup but specifies a null /* resource record list argument, no syntax check will be done /* for MX server names. /* .IP DNS_RETRY /* The query failed, or the reply was malformed. /* The problem is considered transient. /* .IP DNS_FAIL /* The query failed. /* BUGS /* dns_lookup() implements a subset of all possible resource types: /* CNAME, MX, A, and some records with similar formatting requirements. /* It is unwise to specify the T_ANY wildcard resource type. /* /* It takes a surprising amount of code to accomplish what appears /* to be a simple task. Later versions of the mail system may implement /* their own DNS client software. /* SEE ALSO /* dns_rr(3) resource record memory and list management /* LICENSE /* .ad /* .fi /* The Secure Mailer license must be distributed with this software. /* AUTHOR(S) /* Wietse Venema /* IBM T.J. Watson Research /* P.O. Box 704 /* Yorktown Heights, NY 10598, USA /* /* Wietse Venema /* Google, Inc. /* 111 8th Avenue /* New York, NY 10011, USA /* /* SRV Support by /* Tomas Korbar /* Red Hat, Inc.
/*--*/
/* *Structuretokeeptrackofthingswhiledecodinganameserverreply.
*/ #define DEF_DNS_REPLY_SIZE 4096/* in case we're using TCP */ #define MAX_DNS_REPLY_SIZE 65536/* in case we're using TCP */ #define MAX_DNS_QUERY_SIZE 2048/* XXX */
typedefstruct DNS_REPLY { unsignedchar *buf; /* raw reply data */
size_t buf_len; /* reply buffer length */ int rcode; /* unfiltered reply code */ int dnssec_ad; /* DNSSEC AD bit */ int query_count; /* number of queries */ int answer_count; /* number of answers */ int auth_count; /* number of authority records */ unsignedchar *query_start; /* start of query data */ unsignedchar *answer_start; /* start of answer data */ unsignedchar *end; /* first byte past reply */
} DNS_REPLY;
/* *Extractresourcerecordsoftherequestedtype.PickupCNAME *informationjustincasetherequesteddataisnotfound.
*/
status = dns_get_answer(orig_name, &reply, type, rrlist, fqdn,
cname, c_len, &maybe_secure); if (DNS_WANT_DNSSEC_VALIDATION(flags)
&& !DNS_SEC_STATS_TEST(DNS_SEC_FLAG_AVAILABLE | \
DNS_SEC_FLAG_DONT_PROBE))
dns_sec_probe(flags); /* XXX Clobbers 'reply' */ switch (status) { default: if (why)
vstring_sprintf(why, "Name service error for name=%s type=%s: " "Malformed or unexpected name server reply",
name, dns_strtype(type)); return (status); case DNS_NULLMX: if (why)
vstring_sprintf(why, "Domain %s does not accept mail (nullMX)",
name);
DNS_SET_H_ERRNO(&dns_res_state, NO_DATA); return (status); case DNS_NULLSRV: if (why)
vstring_sprintf(why, "Domain %s does not support SRV requests",
name);
DNS_SET_H_ERRNO(&dns_res_state, NO_DATA); return (status); case DNS_OK: if (rrlist && dns_rr_filter_maps) { if (dns_rr_filter_execute(rrlist) < 0) { if (why)
vstring_sprintf(why, "Error looking up name=%s type=%s: " "Invalid DNS reply filter syntax",
name, dns_strtype(type));
dns_rr_free(*rrlist);
*rrlist = 0;
status = DNS_RETRY;
} elseif (*rrlist == 0) { if (why)
vstring_sprintf(why, "Error looking up name=%s type=%s: " "DNS reply filter drops all results",
name, dns_strtype(type));
status = DNS_POLICY;
}
} return (status); case DNS_RECURSE: if (msg_verbose)
msg_info("dns_lookup: %s aliased to %s", name, cname); #if RES_USE_DNSSEC
/* *OnceanintermediateCNAMEreplyisnotvalidated,all *consequentRRsaredeemednotvalidated,sowedon'taskfor *furtherDNSSECreplies.
*/ if (maybe_secure == 0)
flags &= ~RES_USE_DNSSEC; #endif
name = cname;
}
} if (why)
vstring_sprintf(why, "Name server loop for %s", name);
msg_warn("dns_lookup: Name server loop for %s", name); return (DNS_NOTFOUND);
}
/* dns_lookup_rl - DNS lookup interface with types list */
int dns_lookup_rl(constchar *name, unsigned flags, DNS_RR **rrlist,
VSTRING *fqdn, VSTRING *why, int *rcode, int lflags,...)
{
va_list ap; unsigned type, next; int status = DNS_NOTFOUND; int hpref_status = INT_MIN;
VSTRING *hpref_rtext = 0; int hpref_rcode; int hpref_h_errno;
DNS_RR *rr;
/* Save intermediate highest-priority result. */ #define SAVE_HPREF_STATUS() do { \
hpref_status = status; \ if (rcode) \
hpref_rcode = *rcode; \ if (why && status != DNS_OK) \
vstring_strcpy(hpref_rtext ? hpref_rtext : \
(hpref_rtext = vstring_alloc(VSTRING_LEN(why))), \
vstring_str(why)); \
hpref_h_errno = DNS_GET_H_ERRNO(&dns_res_state); \
} while (0)
/* Restore intermediate highest-priority result. */ #define RESTORE_HPREF_STATUS() do { \
status = hpref_status; \ if (rcode) \
*rcode = hpref_rcode; \ if (why && status != DNS_OK) \
vstring_strcpy(why, vstring_str(hpref_rtext)); \
DNS_SET_H_ERRNO(&dns_res_state, hpref_h_errno); \
} while (0)
if (rrlist)
*rrlist = 0;
va_start(ap, lflags); for (type = va_arg(ap, unsigned); type != 0; type = next) {
next = va_arg(ap, unsigned); if (msg_verbose)
msg_info("lookup %s type %s flags %s",
name, dns_strtype(type), dns_str_resflags(flags));
status = dns_lookup_x(name, type, flags, rrlist ? &rr : (DNS_RR **) 0,
fqdn, why, rcode, lflags); if (rrlist && rr) {
*rrlist = dns_rr_append(*rrlist, rr); if (DNS_RR_IS_TRUNCATED(*rrlist)) break;
} if (status == DNS_OK) { if (lflags & DNS_REQ_FLAG_STOP_OK) break;
} elseif (status == DNS_INVAL) { if (lflags & DNS_REQ_FLAG_STOP_INVAL) break;
} elseif (status == DNS_POLICY) { if (type == T_MX && (lflags & DNS_REQ_FLAG_STOP_MX_POLICY)) break;
} elseif (status == DNS_NULLMX) { if (lflags & DNS_REQ_FLAG_STOP_NULLMX) break;
} /* XXX Stop after NXDOMAIN error. */ if (next == 0) break; if (status >= hpref_status)
SAVE_HPREF_STATUS(); /* save last info */
}
va_end(ap); if (status < hpref_status)
RESTORE_HPREF_STATUS(); /* else report last info */ if (hpref_rtext)
vstring_free(hpref_rtext); return (status);
}
/* dns_lookup_rv - DNS lookup interface with types vector */
int dns_lookup_rv(constchar *name, unsigned flags, DNS_RR **rrlist,
VSTRING *fqdn, VSTRING *why, int *rcode, int lflags, unsigned *types)
{ unsigned type, next; int status = DNS_NOTFOUND; int hpref_status = INT_MIN;
VSTRING *hpref_rtext = 0; int hpref_rcode; int hpref_h_errno;
DNS_RR *rr;
if (rrlist)
*rrlist = 0; for (type = *types++; type != 0; type = next) {
next = *types++; if (msg_verbose)
msg_info("lookup %s type %s flags %s",
name, dns_strtype(type), dns_str_resflags(flags));
status = dns_lookup_x(name, type, flags, rrlist ? &rr : (DNS_RR **) 0,
fqdn, why, rcode, lflags); if (rrlist && rr) {
*rrlist = dns_rr_append(*rrlist, rr); if (DNS_RR_IS_TRUNCATED(*rrlist)) break;
} if (status == DNS_OK) { if (lflags & DNS_REQ_FLAG_STOP_OK) break;
} elseif (status == DNS_INVAL) { if (lflags & DNS_REQ_FLAG_STOP_INVAL) break;
} elseif (status == DNS_POLICY) { if (type == T_MX && (lflags & DNS_REQ_FLAG_STOP_MX_POLICY)) break;
} elseif (status == DNS_NULLMX) { if (lflags & DNS_REQ_FLAG_STOP_NULLMX) break;
} /* XXX Stop after NXDOMAIN error. */ if (next == 0) break; if (status >= hpref_status)
SAVE_HPREF_STATUS(); /* save last info */
} if (status < hpref_status)
RESTORE_HPREF_STATUS(); /* else report last info */ if (hpref_rtext)
vstring_free(hpref_rtext); return (status);
}
/* dns_get_h_errno - get the last lookup status */
int dns_get_h_errno(void)
{ return (DNS_GET_H_ERRNO(&dns_res_state));
}
Messung V0.5 in Prozent
¤ Die Informationen auf dieser Webseite wurden
nach bestem Wissen sorgfältig zusammengestellt. Es wird jedoch weder Vollständigkeit, noch Richtigkeit,
noch Qualität der bereit gestellten Informationen zugesichert.0.9Bemerkung:
(vorverarbeitet am 2026-08-09)
¤
Die Informationen auf dieser Webseite wurden
nach bestem Wissen sorgfältig zusammengestellt. Es wird jedoch weder Vollständigkeit, noch Richtigkeit,
noch Qualität der bereit gestellten Informationen zugesichert.
Bemerkung:
Die farbliche Syntaxdarstellung und die Messung sind noch experimentell.