diff options
author | des <des@FreeBSD.org> | 2015-04-26 11:23:26 +0000 |
---|---|---|
committer | des <des@FreeBSD.org> | 2015-04-26 11:23:26 +0000 |
commit | fe0c01d26579d19ddf439fb46ef0bd3cc2bc7f4c (patch) | |
tree | 01c1d94467622a175fad10cd34a2f6f05d32c1b7 /services | |
parent | cabe860377233bc13a6d101fdb59bb834cab980a (diff) | |
download | FreeBSD-src-fe0c01d26579d19ddf439fb46ef0bd3cc2bc7f4c.zip FreeBSD-src-fe0c01d26579d19ddf439fb46ef0bd3cc2bc7f4c.tar.gz |
import unbound 1.5.2
Diffstat (limited to 'services')
-rw-r--r-- | services/listen_dnsport.c | 62 | ||||
-rw-r--r-- | services/localzone.c | 29 | ||||
-rw-r--r-- | services/localzone.h | 9 |
3 files changed, 76 insertions, 24 deletions
diff --git a/services/listen_dnsport.c b/services/listen_dnsport.c index 0ce0a6b..1addfa9 100644 --- a/services/listen_dnsport.c +++ b/services/listen_dnsport.c @@ -372,29 +372,47 @@ create_udp_sock(int family, int socktype, struct sockaddr* addr, * (and also uses the interface mtu to determine the size of the packets). * So there won't be any EMSGSIZE error. Against DNS fragmentation attacks. * FreeBSD already has same semantics without setting the option. */ -# if defined(IP_PMTUDISC_OMIT) - int action = IP_PMTUDISC_OMIT; -# else - int action = IP_PMTUDISC_DONT; -# endif + int omit_set = 0; + int action; +# if defined(IP_PMTUDISC_OMIT) + action = IP_PMTUDISC_OMIT; if (setsockopt(s, IPPROTO_IP, IP_MTU_DISCOVER, &action, (socklen_t)sizeof(action)) < 0) { - log_err("setsockopt(..., IP_MTU_DISCOVER, " -# if defined(IP_PMTUDISC_OMIT) - "IP_PMTUDISC_OMIT" + + if (errno != EINVAL) { + log_err("setsockopt(..., IP_MTU_DISCOVER, IP_PMTUDISC_OMIT...) failed: %s", + strerror(errno)); + +# ifndef USE_WINSOCK + close(s); # else - "IP_PMTUDISC_DONT" + closesocket(s); # endif - "...) failed: %s", - strerror(errno)); + *noproto = 0; + *inuse = 0; + return -1; + } + } + else + { + omit_set = 1; + } +# endif + if (omit_set == 0) { + action = IP_PMTUDISC_DONT; + if (setsockopt(s, IPPROTO_IP, IP_MTU_DISCOVER, + &action, (socklen_t)sizeof(action)) < 0) { + log_err("setsockopt(..., IP_MTU_DISCOVER, IP_PMTUDISC_DONT...) failed: %s", + strerror(errno)); # ifndef USE_WINSOCK - close(s); + close(s); # else - closesocket(s); + closesocket(s); # endif - *noproto = 0; - *inuse = 0; - return -1; + *noproto = 0; + *inuse = 0; + return -1; + } } # elif defined(IP_DONTFRAG) int off = 0; @@ -580,15 +598,16 @@ create_local_accept_sock(const char *path, int* noproto) { #ifdef HAVE_SYS_UN_H int s; - struct sockaddr_un sun; + struct sockaddr_un usock; + verbose(VERB_ALGO, "creating unix socket %s", path); #ifdef HAVE_STRUCT_SOCKADDR_UN_SUN_LEN /* this member exists on BSDs, not Linux */ - sun.sun_len = (sa_family_t)sizeof(sun); + usock.sun_len = (socklen_t)sizeof(usock); #endif - sun.sun_family = AF_LOCAL; + usock.sun_family = AF_LOCAL; /* length is 92-108, 104 on FreeBSD */ - (void)strlcpy(sun.sun_path, path, sizeof(sun.sun_path)); + (void)strlcpy(usock.sun_path, path, sizeof(usock.sun_path)); if ((s = socket(PF_LOCAL, SOCK_STREAM, 0)) == -1) { log_err("Cannot create local socket %s (%s)", @@ -603,7 +622,7 @@ create_local_accept_sock(const char *path, int* noproto) return -1; } - if (bind(s, (struct sockaddr *)&sun, + if (bind(s, (struct sockaddr *)&usock, (socklen_t)sizeof(struct sockaddr_un)) == -1) { log_err("Cannot bind local socket %s (%s)", path, strerror(errno)); @@ -623,6 +642,7 @@ create_local_accept_sock(const char *path, int* noproto) (void)noproto; /*unused*/ return s; #else + (void)path; log_err("Local sockets are not supported"); *noproto = 1; return -1; diff --git a/services/localzone.c b/services/localzone.c index d285a12..57510bd 100644 --- a/services/localzone.c +++ b/services/localzone.c @@ -48,6 +48,7 @@ #include "util/data/packed_rrset.h" #include "util/data/msgencode.h" #include "util/net_help.h" +#include "util/netevent.h" #include "util/data/msgreply.h" #include "util/data/msgparse.h" @@ -1022,6 +1023,10 @@ void local_zones_print(struct local_zones* zones) log_nametypeclass(0, "static zone", z->name, 0, z->dclass); break; + case local_zone_inform: + log_nametypeclass(0, "inform zone", + z->name, 0, z->dclass); + break; default: log_nametypeclass(0, "badtyped zone", z->name, 0, z->dclass); @@ -1169,9 +1174,25 @@ lz_zone_answer(struct local_zone* z, struct query_info* qinfo, return 0; } +/** print log information for an inform zone query */ +static void +lz_inform_print(struct local_zone* z, struct query_info* qinfo, + struct comm_reply* repinfo) +{ + char ip[128], txt[512]; + char zname[LDNS_MAX_DOMAINLEN+1]; + uint16_t port = ntohs(((struct sockaddr_in*)&repinfo->addr)->sin_port); + dname_str(z->name, zname); + addr_to_str(&repinfo->addr, repinfo->addrlen, ip, sizeof(ip)); + snprintf(txt, sizeof(txt), "%s inform %s@%u", zname, ip, + (unsigned)port); + log_nametypeclass(0, txt, qinfo->qname, qinfo->qtype, qinfo->qclass); +} + int local_zones_answer(struct local_zones* zones, struct query_info* qinfo, - struct edns_data* edns, sldns_buffer* buf, struct regional* temp) + struct edns_data* edns, sldns_buffer* buf, struct regional* temp, + struct comm_reply* repinfo) { /* see if query is covered by a zone, * if so: - try to match (exact) local data @@ -1190,6 +1211,9 @@ local_zones_answer(struct local_zones* zones, struct query_info* qinfo, lock_rw_rdlock(&z->lock); lock_rw_unlock(&zones->lock); + if(z->type == local_zone_inform && repinfo) + lz_inform_print(z, qinfo, repinfo); + if(local_data_answer(z, qinfo, edns, buf, temp, labs, &ld)) { lock_rw_unlock(&z->lock); return 1; @@ -1209,6 +1233,7 @@ const char* local_zone_type2str(enum localzone_type t) case local_zone_typetransparent: return "typetransparent"; case local_zone_static: return "static"; case local_zone_nodefault: return "nodefault"; + case local_zone_inform: return "inform"; } return "badtyped"; } @@ -1227,6 +1252,8 @@ int local_zone_str2type(const char* type, enum localzone_type* t) *t = local_zone_typetransparent; else if(strcmp(type, "redirect") == 0) *t = local_zone_redirect; + else if(strcmp(type, "inform") == 0) + *t = local_zone_inform; else return 0; return 1; } diff --git a/services/localzone.h b/services/localzone.h index 788fbfb..29ba866 100644 --- a/services/localzone.h +++ b/services/localzone.h @@ -49,6 +49,7 @@ struct config_file; struct edns_data; struct query_info; struct sldns_buffer; +struct comm_reply; /** * Local zone type @@ -70,7 +71,9 @@ enum localzone_type { local_zone_redirect, /** remove default AS112 blocking contents for zone * nodefault is used in config not during service. */ - local_zone_nodefault + local_zone_nodefault, + /** log client address, but no block (transparent) */ + local_zone_inform }; /** @@ -220,12 +223,14 @@ void local_zones_print(struct local_zones* zones); * @param edns: edns info (parsed). * @param buf: buffer with query ID and flags, also for reply. * @param temp: temporary storage region. + * @param repinfo: source address for checks. may be NULL. * @return true if answer is in buffer. false if query is not answered * by authority data. If the reply should be dropped altogether, the return * value is true, but the buffer is cleared (empty). */ int local_zones_answer(struct local_zones* zones, struct query_info* qinfo, - struct edns_data* edns, struct sldns_buffer* buf, struct regional* temp); + struct edns_data* edns, struct sldns_buffer* buf, struct regional* temp, + struct comm_reply* repinfo); /** * Parse the string into localzone type. |