X-Git-Url: http://www.chiark.greenend.org.uk/ucgi/~ianmdlvl/git?p=adns.git;a=blobdiff_plain;f=src%2Finternal.h;h=24c5c829f69162094a67c121337bc179eb5050f8;hp=92b0d107fd041f94f59cd975cb35b283a1bbdc22;hb=c0af047b137721acff216e6d5665433ff2a366cb;hpb=b582ca0f999ffd51e26c5543d2023ea137af3bec diff --git a/src/internal.h b/src/internal.h index 92b0d10..24c5c82 100644 --- a/src/internal.h +++ b/src/internal.h @@ -39,9 +39,11 @@ typedef unsigned char byte; #include #include #include +#include #include +#define ADNS_FEATURE_MANYAF #include "adns.h" #include "dlist.h" @@ -68,9 +70,6 @@ typedef unsigned char byte; #define DNS_IDOFFSET 0 #define DNS_CLASS_IN 1 -#define DNS_INADDR_ARPA "in-addr", "arpa" -#define DNS_IP6_ARPA "ip6", "arpa" - #define MAX_POLLFDS ADNS_POLLFDS_RECOMMENDED /* Some preprocessor hackery */ @@ -109,6 +108,11 @@ typedef enum { rcode_refused } dns_rcode; +enum { + adns__qf_addr_answer= 0x01000000,/* addr query received an answer */ + adns__qf_addr_cname = 0x02000000 /* addr subquery performed on cname */ +}; + /* Shared data structures */ typedef struct { @@ -125,17 +129,10 @@ typedef struct { struct timeval now; } parseinfo; -union gen_addr { - struct in_addr v4; - struct in6_addr v6; -}; - -struct af_addr { int af; union gen_addr addr; }; - -#define NREVDOMAINS 2 /* keep in sync with addrfam! */ +#define MAXREVLABELS 34 /* keep in sync with addrfam! */ struct revparse_state { - unsigned map; /* which domains are still live */ - byte ipv[NREVDOMAINS][32]; /* address components so far */ + uint16_t labstart[MAXREVLABELS]; + uint8_t lablen[MAXREVLABELS]; }; union checklabel_state { @@ -149,8 +146,11 @@ typedef struct { union { struct { adns_rrtype rev_rrtype; - struct af_addr addr; + adns_sockaddr addr; } ptr; + struct { + unsigned want, have; + } addr; } tinfo; /* type-specific state for the query itself: zero-init if you * don't know better. */ @@ -196,7 +196,8 @@ typedef struct typeinfo { adns_status (*checklabel)(adns_state ads, adns_queryflags flags, union checklabel_state *cls, qcontext *ctx, - int labnum, const char *label, int lablen); + int labnum, const char *dgram, + int labstart, int lablen); /* Check a label from the query domain string. The label is not * necessarily null-terminated. The hook can refuse the query's submission * by returning a nonzero status. State can be stored in *cls between @@ -228,7 +229,7 @@ typedef struct typeinfo { adns_status adns__ckl_hostname(adns_state ads, adns_queryflags flags, union checklabel_state *cls, qcontext *ctx, int labnum, - const char *label, int lablen); + const char *dgram, int labstart, int lablen); /* implemented in query.c, used by types.c as default * and as part of implementation for some fancier types * doesn't require any state */ @@ -390,8 +391,7 @@ struct adns__state { struct pollfd pollfds_buf[MAX_POLLFDS]; adns_rr_addr servers[MAXSERVERS]; struct sortlist { - int af; - union gen_addr base, mask; + adns_sockaddr base, mask; } sortlist[MAXSORTLIST]; char **searchlist; unsigned short rand48xsubi[3]; @@ -399,21 +399,20 @@ struct adns__state { /* From addrfam.c: */ -extern int adns__af_supported_p(int af); -/* Return nonzero if the address family af known to the library and supported - * by the other addrfam operations. Note that the other operations will - * abort on an unrecognized address family rather than returning an error - * code. +extern int adns__addrs_equal_raw(const struct sockaddr *a, + int bf, const void *b); +/* Returns nonzero a's family is bf and a's protocol address field + * refers to the same protocol address as that stored at ba. */ -extern int adns__genaddr_equal_p(int af, const union gen_addr *a, - int bf, const void *b); -/* b should point to a `struct in_addr' or equivalent for the address family - * bf. Returns nonzero if the two addresses are equal. +extern int adns__addrs_equal(const adns_sockaddr *a, + const adns_sockaddr *b); +/* Returns nonzero if the two refer to the same protocol address + * (disregarding port, IPv6 scope, etc). */ -extern int adns__sockaddr_equal_p(const struct sockaddr *sa, - const struct sockaddr *sb); +extern int adns__sockaddrs_equal(const struct sockaddr *sa, + const struct sockaddr *sb); /* Return nonzero if the two socket addresses are equal (in all significant * respects). */ @@ -421,39 +420,33 @@ extern int adns__sockaddr_equal_p(const struct sockaddr *sa, extern int adns__addr_width(int af); /* Return the width of addresses of family af, in bits. */ -extern void adns__prefix_mask(int af, int len, union gen_addr *mask_r); -/* Store in mask_r an address mask for address family af, whose first len - * bits are set and the remainder are clear. This is what you want for - * converting a prefix length into a netmask. +extern void adns__prefix_mask(adns_sockaddr *sa, int len); +/* Stores in sa's protocol address field an address mask for address + * family af, whose first len bits are set and the remainder are + * clear. On entry, sa's af field must be set. This is what you want + * for converting a prefix length into a netmask. */ -extern int adns__guess_prefix_length(int af, const union gen_addr *addr); +extern int adns__guess_prefix_length(const adns_sockaddr *addr); /* Given a network base address, guess the appropriate prefix length based on * the appropriate rules for the address family (e.g., for IPv4, this uses * the old address classes). */ -extern int adns__addr_match_p(int addraf, const union gen_addr *addr, - int netaf, const union gen_addr *base, - const union gen_addr *mask); -/* Given an address af (with family addraf) and a network (with family netaf, - * base address base, and netmask mask), return nonzero if the address lies - * within the network. +extern int adns__addr_matches(int af, const void *addr, + const adns_sockaddr *base, + const adns_sockaddr *mask); +/* Return nonzero if the protocol address specified by af and addr + * lies within the network specified by base and mask. */ -extern void adns__sockaddr_extract(const struct sockaddr *sa, - union gen_addr *a_r, int *port_r); -/* Extract fields from the socket address, filling in *a_r and *port_r with - * the address and (integer, host byte-order) port number, respectively. - * Either (or, pointlessly, both) of a_r and port_r may be null to mean - * `don't care'. +extern void adns__addr_inject(const void *a, adns_sockaddr *sa); +/* Injects the protocol address *a into the socket adress sa. Assumes + * that sa->sa_family is already set correctly. */ -extern void adns__sockaddr_inject(const union gen_addr *a, int port, - struct sockaddr *sa); -/* Inject fields into the socket adress sa. If a is not null, copy the - * address in; if port is not -1, then copy the port (converting from host - * byte-order). Assumes that sa->sa_family is already set correctly. +extern const void *adns__sockaddr_addr(const struct sockaddr *sa); +/* Returns the address of the protocol address field in sa. */ char *adns__sockaddr_ntoa(const struct sockaddr *sa, char *buf); @@ -476,23 +469,26 @@ extern int adns__make_reverse_domain(const struct sockaddr *sa, * allocate an output buffer failed. */ -extern int adns__revparse_label(struct revparse_state *rps, int labnum, - const char *label, int lablen); +extern bool adns__revparse_label(struct revparse_state *rps, int labnum, + const char *dgram, + int labstart, int lablen); /* Parse a label in a reverse-domain name, given its index labnum (starting * from zero), a pointer to its contents (which need not be null-terminated), * and its length. The state in *rps is initialized implicitly when labnum * is zero. * - * Returns zero if the parse was successful, nonzero if the domain name is - * definitely invalid and the parse must be abandoned. + * Returns 1 if the parse is proceeding successfully, 0 if the domain + * name is definitely invalid and the parse must be abandoned. */ -extern int adns__revparse_done(struct revparse_state *rps, int nlabels, - adns_rrtype *rrtype_r, struct af_addr *addr_r); -/* Finishes parsing a reverse-domain name, given the total number of labels - * in the name. On success, fills in the address in *addr_r, and the forward - * query type in *rrtype_r (because that turns out to be useful). Returns - * nonzero if the parse must be abandoned. +extern bool adns__revparse_done(struct revparse_state *rps, + const char *dgram, int nlabels, + adns_rrtype *rrtype_r, adns_sockaddr *addr_r); +/* Finishes parsing a reverse-domain name, given the total number of + * labels in the name. On success, fills in the af and protocol + * address in *addr_r, and the forward query type in *rrtype_r + * (because that turns out to be useful). Returns 1 if the parse + * was successful. */ /* From setup.c: */ @@ -870,6 +866,8 @@ void adns__update_expires(adns_query qu, unsigned long ttl, int vbuf__append_quoted1035(vbuf *vb, const byte *buf, int len); +bool adns__labels_equal(const byte *a, int al, const byte *b, int bl); + /* From event.c: */ void adns__tcp_broken(adns_state ads, const char *what, const char *why); @@ -918,6 +916,9 @@ static inline int ctype_digit(int c) { return c>='0' && c<='9'; } static inline int ctype_alpha(int c) { return (c >= 'a' && c <= 'z') || (c >= 'A' && c <= 'Z'); } +static inline int ctype_toupper(int c) { + return ctype_alpha(c) ? (c & ~32) : c; +} static inline int ctype_822special(int c) { return strchr("()<>@,;:\\\".[]",c) != 0; }