]> granicus.if.org Git - pdns/commitdiff
Fix type conversions, add some checks
authorRemi Gacogne <remi.gacogne@powerdns.com>
Wed, 27 Apr 2016 08:26:20 +0000 (10:26 +0200)
committerRemi Gacogne <remi.gacogne@powerdns.com>
Wed, 27 Apr 2016 08:26:20 +0000 (10:26 +0200)
There is no known bug involved, only hardening.

40 files changed:
pdns/auth-carbon.cc
pdns/communicator.hh
pdns/dns.cc
pdns/dns.hh
pdns/dns_random.cc
pdns/dnscrypt.hh
pdns/dnsdist-carbon.cc
pdns/dnsdist-console.cc
pdns/dnsdist-ecs.cc
pdns/dnsdist-lua2.cc
pdns/dnsdist-rings.cc
pdns/dnsdist-tcp.cc
pdns/dnsdist.cc
pdns/dnsdist.hh
pdns/dnsname.cc
pdns/dnspacket.cc
pdns/dnspacket.hh
pdns/dnsparser.cc
pdns/dnsparser.hh
pdns/dnsproxy.cc
pdns/dnsrecords.cc
pdns/dnsrulactions.hh
pdns/dnswriter.cc
pdns/dnswriter.hh
pdns/ednssubnet.cc
pdns/iputils.cc
pdns/iputils.hh
pdns/lua-iputils.cc
pdns/lwres.cc
pdns/lwres.hh
pdns/mastercommunicator.cc
pdns/misc.cc
pdns/misc.hh
pdns/nameserver.cc
pdns/nproxy.cc
pdns/pdns_recursor.cc
pdns/pdnsutil.cc
pdns/reczones.cc
pdns/sstuff.hh
pdns/syncres.hh

index 1dbc0332683f05ac868e5171a90a4345a2227c2f..c270dbc97de335ad7e8c44b068e89f645c9501fc 100644 (file)
@@ -56,11 +56,7 @@ try
        continue;
       }
       s.setBlocking();
-      ret=writen2(s.getHandle(), msg.c_str(), msg.size());
-      if(ret < 0)
-       L<<Logger::Warning<<"Error writing carbon data to "<<remote.toStringWithPort()<<": "<<strerror(errno)<<endl;
-      if(ret==0)
-       L<<Logger::Warning<<"EOF writing carbon data to "<<remote.toStringWithPort()<<endl;
+      writen2(s.getHandle(), msg.c_str(), msg.size());
     }
     catch(std::exception& e) {
       L<<Logger::Warning<<"Problem sending carbon data: "<<e.what()<<endl;
index 99e3b125a4a2d8cb66d54215deda35455050ab8b..24f9f0236704e7fbee7f0f7627fe99141834f77b 100644 (file)
@@ -258,8 +258,10 @@ private:
       if(!getaddrinfo(name.toString().c_str(), 0, &hints, &res)) {
         struct addrinfo* address = res;
         do {
-          memcpy(&remote, address->ai_addr, address->ai_addrlen);
-          addresses->push_back(remote.toString());
+          if (address->ai_addrlen <= sizeof(remote)) {
+            memcpy(&remote, address->ai_addr, address->ai_addrlen);
+            addresses->push_back(remote.toString());
+          }
         } while((address = address->ai_next));
         freeaddrinfo(res);
       }
index f36738ce59e4a3ff9a928e2f091e68252e3b8513..d0d5b0c427e90a2796c8007d49cce94287fdb3d7 100644 (file)
@@ -44,7 +44,7 @@ std::string RCode::to_s(unsigned short rcode) {
 class BoundsCheckingPointer
 {
 public:
-  explicit BoundsCheckingPointer(const char* a, unsigned int length)
+  explicit BoundsCheckingPointer(const char* a, size_t length)
     : d_ptr(a), d_length(length) 
     {}
   
@@ -53,7 +53,7 @@ public:
     {}
   
     
-  char operator[](unsigned int offset) const
+  char operator[](size_t offset) const
   {
     if(offset < d_length)
       return d_ptr[offset];
@@ -61,7 +61,7 @@ public:
   }
 private:  
   const char* d_ptr;
-  const unsigned int d_length;
+  const size_t d_length;
 };
 
 
index d0beef7327b3f7d505815e6c3f70d677eddac19f..de2d4b8dab18e4edd9d931d2fe2ca4ea6b414025 100644 (file)
@@ -145,6 +145,8 @@ struct EDNS0Record
         uint16_t Z; 
 } GCCPACKATTRIBUTE;
 
+static_assert(sizeof(EDNS0Record) == 4, "EDNS0Record size must be 4");
+
 #if defined(__FreeBSD__) || defined(__APPLE__) || defined(__OpenBSD__) || defined(__DragonFly__) || defined(__FreeBSD_kernel__)
 #include <machine/endian.h>
 #elif __linux__ || __GNU__
index 7812ef25214712f2302bc8023dd9e588cc77d009..415542b3b0453cd8474c65bac74fa94e6dc19481 100644 (file)
@@ -33,6 +33,7 @@ void dns_random_init(const char data[16])
   struct timeval now;
   gettimeofday(&now, 0);
 
+  static_assert(sizeof(g_counter) >= (sizeof(now.tv_usec) + sizeof(now.tv_sec)), "g_counter must be large enough to get tv_sec + tv_usec");
   memcpy(g_counter, &now.tv_usec, sizeof(now.tv_usec));
   memcpy(g_counter+sizeof(now.tv_usec), &now.tv_sec, sizeof(now.tv_sec));
   g_in = getpid() | (getppid()<<16);
index 2d9215df2f34aef758864798325cb34ccba834f9..5f3a0281c6ac7d8f4c2f452b03a28ae639011a75 100644 (file)
@@ -48,7 +48,7 @@ struct DnsCryptCertSignedData
 
 struct DnsCryptCert
 {
-  unsigned char magic[4];
+  unsigned char magic[DNSCRYPT_CERT_MAGIC_SIZE];
   unsigned char esVersion[2];
   unsigned char protocolMinorVersion[2];
   unsigned char signature[DNSCRYPT_SIGNATURE_SIZE];
index bd3c042b491519aa2fa5fdbf5ae349302e600a2f..9cab108bd9183d4477958a655ab6462e03d14704 100644 (file)
@@ -112,11 +112,7 @@ try
           continue;
         }
         s.setBlocking();
-        ret=writen2(s.getHandle(), msg.c_str(), msg.size());
-        if(ret < 0)
-          warnlog("Error writing carbon data to %s: %s", server.toStringWithPort(), strerror(errno));
-        if(ret==0)
-          warnlog("EOF writing carbon data to %s", server.toStringWithPort());
+        writen2(s.getHandle(), msg.c_str(), msg.size());
       }
       catch(std::exception& e) {
         warnlog("Problem sending carbon data: %s", e.what());
index 22b128b249fb4006174b0ade11acb3751ffae42d..1701634474c93d7ede06fa2f218e7885f6a8d400 100644 (file)
@@ -34,7 +34,7 @@ void doClient(ComboAddress server, const std::string& command)
 
   if(!command.empty()) {
     string msg=sodEncryptSym(command, g_key, ours);
-    putMsgLen32(fd, msg.length());
+    putMsgLen32(fd, (uint32_t) msg.length());
     if(!msg.empty())
       writen2(fd, msg);
     uint32_t len;
@@ -86,7 +86,7 @@ void doClient(ComboAddress server, const std::string& command)
       continue;
 
     string msg=sodEncryptSym(line, g_key, ours);
-    putMsgLen32(fd, msg.length());
+    putMsgLen32(fd, (uint32_t) msg.length());
     writen2(fd, msg);
     uint32_t len;
     if(!getMsgLen32(fd, &len)) {
index 8f29ade2c67a6c8ecb1ece4660210b81771f703a..b1bca7b0435f30948bd0347aad23de72c4a595e9 100644 (file)
@@ -231,6 +231,7 @@ void generateOptRR(const std::string& optRData, string& res)
   
   dh.d_type = htons(QType::OPT);
   dh.d_class = htons(q_EdnsUDPPayloadSize);
+  static_assert(sizeof(EDNS0Record) == sizeof(dh.d_ttl), "sizeof(EDNS0Record) must match sizeof(dnsrecordheader.d_ttl)");
   memcpy(&dh.d_ttl, &edns0, sizeof edns0);
   dh.d_clen = htons((uint16_t) optRData.length());
   res.assign((const char *) &name, sizeof name);
index c21fe1899c0bbd92c559d3385d00def37206f045..9d52658aa150e0f61ae67febdd0135eb3670cbc1 100644 (file)
@@ -455,12 +455,9 @@ void moreLua(bool client)
     g_lua.writeFunction("generateDNSCryptCertificate", [](const std::string& providerPrivateKeyFile, const std::string& certificateFile, const std::string privateKeyFile, uint32_t serial, time_t begin, time_t end) {
         setLuaNoSideEffect();
 #ifdef HAVE_DNSCRYPT
-        unsigned char privateKey[DNSCRYPT_PRIVATE_KEY_SIZE];
         unsigned char providerPrivateKey[DNSCRYPT_PROVIDER_PRIVATE_KEY_SIZE];
         sodium_mlock(providerPrivateKey, sizeof(providerPrivateKey));
-        sodium_mlock(privateKey, sizeof(privateKey));
         sodium_memzero(providerPrivateKey, sizeof(providerPrivateKey));
-        sodium_memzero(privateKey, sizeof(privateKey));
 
         try {
           DnsCryptPrivateKey privateKey;
@@ -483,9 +480,7 @@ void moreLua(bool client)
         }
 
         sodium_memzero(providerPrivateKey, sizeof(providerPrivateKey));
-        sodium_memzero(privateKey, sizeof(privateKey));
         sodium_munlock(providerPrivateKey, sizeof(providerPrivateKey));
-        sodium_munlock(privateKey, sizeof(privateKey));
 #else
       g_outputBuffer="Error: DNSCrypt support is not enabled.\n";
 #endif
index 0ae0ea124e22c526df54d783f0e92946171761a2..90fbd5fe1218caff68ce5b0df8e51b8d8afe69f9 100644 (file)
@@ -1,7 +1,7 @@
 #include "dnsdist.hh"
 #include "lock.hh"
 
-unsigned int Rings::numDistinctRequestors()
+size_t Rings::numDistinctRequestors()
 {
   std::set<ComboAddress, ComboAddress::addressOnlyLessThan> s;
   ReadLock rl(&queryLock);
index ebebb350697de85843c5468c5540be87855baee1..6bd095fe64ad9356afa243cc973b40e175e25c48 100644 (file)
@@ -99,7 +99,7 @@ static bool getNonBlockingMsgLen(int fd, uint16_t* len, int timeout)
 try
 {
   uint16_t raw;
-  int ret = readn2WithTimeout(fd, &raw, sizeof raw, timeout);
+  size_t ret = readn2WithTimeout(fd, &raw, sizeof raw, timeout);
   if(ret != sizeof raw)
     return false;
   *len = ntohs(raw);
@@ -113,7 +113,7 @@ static bool putNonBlockingMsgLen(int fd, uint16_t len, int timeout)
 try
 {
   uint16_t raw = htons(len);
-  int ret = writen2WithTimeout(fd, &raw, sizeof raw, timeout);
+  size_t ret = writen2WithTimeout(fd, &raw, sizeof raw, timeout);
   return ret == sizeof raw;
 }
 catch(...) {
@@ -185,7 +185,6 @@ void* tcpClientThread(int pipefd)
     delete citmp;    
 
     uint16_t qlen, rlen;
-    string poolname;
     string largerQuery;
     vector<uint8_t> rewrittenResponse;
     shared_ptr<DownstreamState> ds;
@@ -229,7 +228,7 @@ void* tcpClientThread(int pipefd)
 
           if (!decrypted) {
             if (response.size() > 0) {
-              sendResponseToClient(ci.fd, reinterpret_cast<char*>(response.data()), response.size());
+              sendResponseToClient(ci.fd, reinterpret_cast<char*>(response.data()), (uint16_t) response.size());
             }
             break;
           }
@@ -299,7 +298,7 @@ void* tcpClientThread(int pipefd)
           handleEDNSClientSubnet(queryBuffer, dq.size, consumed, &newLen, largerQuery, &ednsAdded, &ecsAdded, ci.remote);
           if (largerQuery.empty() == false) {
             query = largerQuery.c_str();
-            dq.len = largerQuery.size();
+            dq.len = (uint16_t) largerQuery.size();
             dq.size = largerQuery.size();
           } else {
             dq.len = newLen;
@@ -311,7 +310,7 @@ void* tcpClientThread(int pipefd)
           char cachedResponse[4096];
           uint16_t cachedResponseSize = sizeof cachedResponse;
           uint32_t allowExpired = ds ? 0 : g_staleCacheEntriesTTL;
-          if (packetCache->get(dq, consumed, dq.dh->id, cachedResponse, &cachedResponseSize, &cacheKey, allowExpired)) {
+          if (packetCache->get(dq, (uint16_t) consumed, dq.dh->id, cachedResponse, &cachedResponseSize, &cacheKey, allowExpired)) {
 #ifdef HAVE_DNSCRYPT
             if (!encryptResponse(cachedResponse, &cachedResponseSize, sizeof cachedResponse, true, dnsCryptQuery)) {
               goto drop;
@@ -541,7 +540,7 @@ bool getMsgLen32(int fd, uint32_t* len)
 try
 {
   uint32_t raw;
-  int ret = readn2(fd, &raw, sizeof raw);
+  size_t ret = readn2(fd, &raw, sizeof raw);
   if(ret != sizeof raw)
     return false;
   *len = ntohl(raw);
@@ -557,7 +556,7 @@ bool putMsgLen32(int fd, uint32_t len)
 try
 {
   uint32_t raw = htonl(len);
-  int ret = writen2(fd, &raw, sizeof raw);
+  size_t ret = writen2(fd, &raw, sizeof raw);
   return ret==sizeof raw;
 }
 catch(...) {
index 92e20968ae5aa09b0b100848346a06c4710d18c2..750e65a6b1d03e8d0defe91528b24c900c1bd7d5 100644 (file)
@@ -127,7 +127,7 @@ try
 {
   unsigned int consumed;
   DNSName qname(packet, *len, sizeof(dnsheader), false, 0, 0, &consumed);
-  *len=sizeof(dnsheader)+consumed+DNS_TYPE_SIZE+DNS_CLASS_SIZE;
+  *len=(uint16_t) (sizeof(dnsheader)+consumed+DNS_TYPE_SIZE+DNS_CLASS_SIZE);
   struct dnsheader* dh =(struct dnsheader*)packet;
   dh->ancount = dh->arcount = dh->nscount=0;
 }
@@ -343,7 +343,7 @@ void* responderThread(std::shared_ptr<DownstreamState> state)
     if (got < (ssize_t) sizeof(dnsheader))
       continue;
 
-    uint16_t responseLen = (size_t) got;
+    uint16_t responseLen = (uint16_t) got;
 
     if(dh->id >= state->idStates.size())
       continue;
@@ -601,7 +601,7 @@ std::shared_ptr<ServerPool> createPoolIfNotExists(pools_t& pools, const string&
 void addServerToPool(pools_t& pools, const string& poolName, std::shared_ptr<DownstreamState> server)
 {
   std::shared_ptr<ServerPool> pool = createPoolIfNotExists(pools, poolName);
-  unsigned int count = pool->servers.size();
+  unsigned int count = (unsigned int) pool->servers.size();
   if (!poolName.empty()) {
     vinfolog("Adding server to pool %s", poolName);
   } else {
@@ -870,7 +870,7 @@ try
             if(!HarvestDestinationAddress(&msgh, &dest)) {
               dest.sin4.sin_family = 0;
             }
-            sendUDPResponse(cs->udpFD, reinterpret_cast<char*>(response.data()), response.size(), 0, dest, remote);
+            sendUDPResponse(cs->udpFD, reinterpret_cast<char*>(response.data()), (uint16_t) response.size(), 0, dest, remote);
           }
           continue;
         }
index cd2aced74c037fd714e79936a2bcab7a904f5d4b..6146ddfcab63e63742340d8282976a19eb89c4f6 100644 (file)
@@ -261,7 +261,7 @@ struct Rings {
   pthread_rwlock_t queryLock;
 
   std::unordered_map<int, vector<boost::variant<string,double> > > getTopBandwidth(unsigned int numentries);
-  unsigned int numDistinctRequestors();
+  size_t numDistinctRequestors();
 };
 
 extern Rings g_rings;
index 55849c5a9177885b473c4c65c10805c747915d28..2604439e4fa41a399ecc578425470894f532c80a 100644 (file)
@@ -25,7 +25,7 @@ DNSName::DNSName(const char* p)
     if(!strchr(p, '\\')) {
       unsigned char lenpos=0;
       unsigned char labellen=0;
-      unsigned int plen=strlen(p);
+      size_t plen=strlen(p);
       const char* const pbegin=p, *pend=p+plen;
       d_storage.reserve(plen+1);
       for(auto iter = pbegin; iter != pend; ) {
index c52f43ad68f9a10af09f6daeaa5f1149c9c66b76..df8d34070beb2e2faac62ee4e12d6e16d480fabb 100644 (file)
@@ -447,7 +447,7 @@ void DNSPacket::spoofQuestion(const DNSPacket *qd)
   }
 }
 
-int DNSPacket::noparse(const char *mesg, int length)
+int DNSPacket::noparse(const char *mesg, size_t length)
 {
   d_rawpacket.assign(mesg,length); 
   if(length < 12) { 
@@ -532,7 +532,7 @@ bool DNSPacket::getTKEYRecord(TKEYRecordContent *tr, DNSName *keyname) const
     it into our class. Results of calling this function multiple times on one packet are
     unknown. Returns -1 if the packet cannot be parsed.
 */
-int DNSPacket::parse(const char *mesg, int length)
+int DNSPacket::parse(const char *mesg, size_t length)
 try
 {
   d_rawpacket.assign(mesg,length); 
index efa030c6b2bdfa86c172c28be641e37a1c1bf863..4f9a51a1a2c3ccb32ec68220432d06da8c7f8aec 100644 (file)
@@ -67,8 +67,8 @@ public:
   DNSPacket();
   DNSPacket(const DNSPacket &orig);
 
-  int noparse(const char *mesg, int len); //!< just suck the data inward
-  int parse(const char *mesg, int len); //!< parse a raw UDP or TCP packet and suck the data inward
+  int noparse(const char *mesg, size_t len); //!< just suck the data inward
+  int parse(const char *mesg, size_t len); //!< parse a raw UDP or TCP packet and suck the data inward
   const string& getString(); //!< for serialization - just passes the whole packet
 
   // address & socket manipulation
index 4e28afdad6701ba63b9d68bfc7e68ea67b98a2b3..6884c8a203f672920fcbc8a660e7394cf969a525 100644 (file)
@@ -581,7 +581,7 @@ public:
     const char* p = d_packet + d_offset;
     moveOffset(4);
     uint32_t ret;
-    memcpy(&ret, (void*)p, 4);
+    memcpy(&ret, (void*)p, sizeof(ret));
     return ntohl(ret);
   }
   uint16_t get16BitInt()
@@ -589,7 +589,7 @@ public:
     const char* p = d_packet + d_offset;
     moveOffset(2);
     uint16_t ret;
-    memcpy(&ret, (void*)p, 2);
+    memcpy(&ret, (void*)p, sizeof(ret));
     return ntohs(ret);
   }
   
@@ -642,10 +642,10 @@ void ageDNSPacket(char* packet, size_t length, uint32_t seconds)
   {
     dnsheader dh;
     memcpy((void*)&dh, (const dnsheader*)packet, sizeof(dh));
-    int numrecords = ntohs(dh.ancount) + ntohs(dh.nscount) + ntohs(dh.arcount);
+    uint64_t numrecords = ntohs(dh.ancount) + ntohs(dh.nscount) + ntohs(dh.arcount);
     DNSPacketMangler dpm(packet, length);
-    
-    int n;
+
+    uint64_t n;
     for(n=0; n < ntohs(dh.qdcount) ; ++n) {
       dpm.skipLabel();
       dpm.skipBytes(4); // qtype, qclass
index a0d6a727ace5e6aeae571e741e573a8321e05248..c54b456f91f064782a0a71d1c05569c433a7f8e5 100644 (file)
@@ -71,7 +71,10 @@ public:
   PacketReader(const vector<uint8_t>& content) 
     : d_pos(0), d_startrecordpos(0), d_content(content)
   {
-    d_recordlen = content.size();
+    if(content.size() > std::numeric_limits<uint16_t>::max())
+      throw std::out_of_range("packet too large");
+
+    d_recordlen = (uint16_t) content.size();
     not_used = 0;
   }
 
@@ -224,7 +227,7 @@ public:
       return iter->second.second;
     
     if(boost::starts_with(name, "TYPE") || boost::starts_with(name, "type"))
-      return pdns_stou(name.substr(4));
+      return (uint16_t) pdns_stou(name.substr(4));
     
     throw runtime_error("Unknown DNS type '"+name+"'");
   }
index d6464bb693466405c5b0b245cd0fa5f217a5b150..fe77c57077216d5df5c17d3b5d642861c98c9dc6 100644 (file)
@@ -186,7 +186,7 @@ void DNSProxy::mainloop(void)
 {
   try {
     char buffer[1500];
-    int len;
+    ssize_t len;
 
     struct msghdr msgh;
     struct iovec iov;
@@ -194,7 +194,7 @@ void DNSProxy::mainloop(void)
 
     for(;;) {
       len=recv(d_sock, buffer, sizeof(buffer),0); // answer from our backend
-      if(len<12) {
+      if(len<(ssize_t)sizeof(dnsheader)) {
         if(len<0)
           L<<Logger::Error<<"Error receiving packet from recursor backend: "<<stringerror()<<endl;
         else if(len==0)
@@ -229,8 +229,8 @@ void DNSProxy::mainloop(void)
         memcpy(buffer,&d,sizeof(d));  // commit spoofed id
 
         DNSPacket p,q;
-        p.parse(buffer,len);
-        q.parse(buffer,len);
+        p.parse(buffer,(size_t)len);
+        q.parse(buffer,(size_t)len);
 
         if(p.qtype.getCode() != i->second.qtype || p.qdomain != i->second.qname) {
           L<<Logger::Error<<"Discarding packet from recursor backend with id "<<(d.id^d_xor)<<
index 86ff4078a65033aa6e30edf18589cbd311ebf85e..60eab9cef8be0f6ef9bd0ba92259ae7db4e6081c 100644 (file)
@@ -117,7 +117,7 @@ ComboAddress ARecordContent::getCA(int port) const
   ComboAddress ret;
   ret.sin4.sin_family=AF_INET;
   ret.sin4.sin_port=htons(port);
-  memcpy(&ret.sin4.sin_addr.s_addr, &d_ip, 4);
+  memcpy(&ret.sin4.sin_addr.s_addr, &d_ip, sizeof(ret.sin4.sin_addr.s_addr));
   return ret;
 }
 
@@ -128,7 +128,7 @@ ComboAddress AAAARecordContent::getCA(int port) const
 
   ret.sin4.sin_family=AF_INET6;
   ret.sin6.sin6_port = htons(port);
-  memcpy(&ret.sin6.sin6_addr.s6_addr, d_ip6.c_str(), 16);
+  memcpy(&ret.sin6.sin6_addr.s6_addr, d_ip6.c_str(), sizeof(ret.sin6.sin6_addr.s6_addr));
   return ret;
 }
 
@@ -414,7 +414,7 @@ void EUI48RecordContent::toPacket(DNSPacketWriter& pw)
 string EUI48RecordContent::getZoneRepresentation(bool noDot) const
 {
     char tmp[18]; 
-    snprintf(tmp,18,"%02x-%02x-%02x-%02x-%02x-%02x", 
+    snprintf(tmp,sizeof(tmp),"%02x-%02x-%02x-%02x-%02x-%02x",
            d_eui48[0], d_eui48[1], d_eui48[2], 
            d_eui48[3], d_eui48[4], d_eui48[5]);
     return tmp;
@@ -458,7 +458,7 @@ void EUI64RecordContent::toPacket(DNSPacketWriter& pw)
 string EUI64RecordContent::getZoneRepresentation(bool noDot) const
 {
     char tmp[24]; 
-    snprintf(tmp,24,"%02x-%02x-%02x-%02x-%02x-%02x-%02x-%02x",
+    snprintf(tmp,sizeof(tmp),"%02x-%02x-%02x-%02x-%02x-%02x-%02x-%02x",
            d_eui64[0], d_eui64[1], d_eui64[2],
            d_eui64[3], d_eui64[4], d_eui64[5],
            d_eui64[6], d_eui64[7]);
@@ -528,6 +528,7 @@ bool getEDNSOpts(const MOADNSParser& mdp, EDNSOpts* eo)
        
         EDNS0Record stuff;
         uint32_t ttl=ntohl(val.first.d_ttl);
+        static_assert(sizeof(EDNS0Record) == sizeof(uint32_t), "sizeof(EDNS0Record) must match sizeof(uint32_t)");
         memcpy(&stuff, &ttl, sizeof(stuff));
         
         eo->d_extRCode=stuff.extRCode;
@@ -552,6 +553,7 @@ DNSRecord makeOpt(int udpsize, int extRCode, int Z)
   stuff.version=0;
   stuff.Z=htons(Z);
   DNSRecord dr;
+  static_assert(sizeof(EDNS0Record) == sizeof(dr.d_ttl), "sizeof(EDNS0Record) must match sizeof(DNSRecord.d_ttl)");
   memcpy(&dr.d_ttl, &stuff, sizeof(stuff));
   dr.d_ttl=ntohl(dr.d_ttl);
   dr.d_name=DNSName(".");
index 25f997d2e5370778e9998177df37f181e023d0f2..1a0578c952689fd371c6ed7149e4800e19e9e21b 100644 (file)
@@ -548,7 +548,7 @@ public:
         if(qtype != QType::ANY && ((addr.sin4.sin_family == AF_INET && qtype != QType::A) ||
                                    (addr.sin4.sin_family == AF_INET6 && qtype != QType::AAAA)))
           continue;
-        totrdatalen += addr.sin4.sin_family == AF_INET ? 4 : 16;
+        totrdatalen += addr.sin4.sin_family == AF_INET ? sizeof(addr.sin4.sin_addr.s_addr) : sizeof(addr.sin6.sin6_addr.s6_addr);
         addrs.push_back(addr);
       }
     }
@@ -579,7 +579,7 @@ public:
                                          0, QClass::IN, // IN
                                          0, 0, 0, 60,   // TTL
                                          0, (unsigned char)wireData.length()};
-
+      static_assert(sizeof(recordstart) == 12, "sizeof(recordstart) must be equal to 12, otherwise the above check is invalid");
 
       memcpy(dest, recordstart, sizeof(recordstart));
       dest += sizeof(recordstart);
@@ -587,26 +587,28 @@ public:
       dq->len += wireData.length() + sizeof(recordstart);
       dq->dh->ancount++;
     }
-    else for(const auto& addr : addrs) 
-    {
-      unsigned char rdatalen = addr.sin4.sin_family == AF_INET ? 4 : 16;
-      const unsigned char recordstart[]={0xc0, 0x0c,    // compressed name
-                                         0, (unsigned char) (addr.sin4.sin_family == AF_INET ? QType::A : QType::AAAA),
-                                         0, QClass::IN, // IN
-                                         0, 0, 0, 60,   // TTL
-                                         0, rdatalen};
-
-      memcpy(dest, recordstart, sizeof(recordstart));
-      dest += sizeof(recordstart);
-
-      memcpy(dest, 
-             rdatalen==4 ? (void*)&addr.sin4.sin_addr.s_addr : (void*)&addr.sin6.sin6_addr.s6_addr,
-             rdatalen); 
-      dest += rdatalen;
-      dq->len += rdatalen + sizeof(recordstart);
-      dq->dh->ancount++;
+    else {
+      for(const auto& addr : addrs) {
+        unsigned char rdatalen = addr.sin4.sin_family == AF_INET ? sizeof(addr.sin4.sin_addr.s_addr) : sizeof(addr.sin6.sin6_addr.s6_addr);
+        const unsigned char recordstart[]={0xc0, 0x0c,    // compressed name
+                                           0, (unsigned char) (addr.sin4.sin_family == AF_INET ? QType::A : QType::AAAA),
+                                           0, QClass::IN, // IN
+                                           0, 0, 0, 60,   // TTL
+                                           0, rdatalen};
+        static_assert(sizeof(recordstart) == 12, "sizeof(recordstart) must be equal to 12, otherwise the above check is invalid");
+
+        memcpy(dest, recordstart, sizeof(recordstart));
+        dest += sizeof(recordstart);
+
+        memcpy(dest,
+               addr.sin4.sin_family == AF_INET ? (void*)&addr.sin4.sin_addr.s_addr : (void*)&addr.sin6.sin6_addr.s6_addr,
+               rdatalen);
+        dest += rdatalen;
+        dq->len += rdatalen + sizeof(recordstart);
+        dq->dh->ancount++;
+      }
     }
-    
+
     dq->dh->ancount = htons(dq->dh->ancount);
     
     return Action::HeaderModify;
index a50ee77f2671ba3f8dc6c8186fea6ddfb35a2553..390d77c34456564566904cb25d371ef497166a27 100644 (file)
@@ -91,7 +91,7 @@ void DNSPacketWriter::startRecord(const DNSName& name, uint16_t qtype, uint32_t
   d_sor=d_content.size() + d_stuff; // start of real record
 }
 
-void DNSPacketWriter::addOpt(int udpsize, int extRCode, int Z, const vector<pair<uint16_t,string> >& options)
+void DNSPacketWriter::addOpt(uint16_t udpsize, int extRCode, int Z, const vector<pair<uint16_t,string> >& options)
 {
   uint32_t ttl=0;
 
@@ -101,6 +101,7 @@ void DNSPacketWriter::addOpt(int udpsize, int extRCode, int Z, const vector<pair
   stuff.version=0;
   stuff.Z=htons(Z);
 
+  static_assert(sizeof(EDNS0Record) == sizeof(ttl), "sizeof(EDNS0Record) must match sizeof(ttl)");
   memcpy(&ttl, &stuff, sizeof(stuff));
 
   ttl=ntohl(ttl); // will be reversed later on
@@ -118,10 +119,10 @@ void DNSPacketWriter::xfr48BitInt(uint64_t val)
   unsigned char bytes[6];
   uint16_t theLeft = htons((val >> 32)&0xffffU);
   uint32_t theRight = htonl(val & 0xffffffffU);
-  memcpy(bytes, (void*)&theLeft, 2);
-  memcpy(bytes+2, (void*)&theRight, 4);
+  memcpy(bytes, (void*)&theLeft, sizeof(theLeft));
+  memcpy(bytes+2, (void*)&theRight, sizeof(theRight));
 
-  d_record.insert(d_record.end(), bytes, bytes + 6);
+  d_record.insert(d_record.end(), bytes, bytes + sizeof(bytes));
 }
 
 
index b4fd614e4bec33d1c6dc03fcd667a714277bf083..f3fb2765e5440e26fa0ad48e26cccf3e6032f6b5 100644 (file)
@@ -49,7 +49,7 @@ public:
 
   /** Shorthand way to add an Opt-record, for example for EDNS0 purposes */
   typedef vector<pair<uint16_t,std::string> > optvect_t;
-  void addOpt(int udpsize, int extRCode, int Z, const optvect_t& options=optvect_t());
+  void addOpt(uint16_t udpsize, int extRCode, int Z, const optvect_t& options=optvect_t());
 
   /** needs to be called after the last record is added, but can be called again and again later on. Is called internally by startRecord too.
       The content of the vector<> passed to the constructor is inconsistent until commit is called.
index f804c60a3a27f030391a0ed79b2a3ebb719ce55e..cdc4f93a5b6e417cf09e792807db4d576877325b 100644 (file)
@@ -43,9 +43,10 @@ bool getEDNSSubnetOptsFromString(const string& options, EDNSSubnetOpts* eso)
 bool getEDNSSubnetOptsFromString(const char* options, unsigned int len, EDNSSubnetOpts* eso)
 {
   //cerr<<"options.size:"<<options.size()<<endl;
-  if(len <= 4)
-    return false;  
   EDNSSubnetOptsWire esow;
+  static_assert (sizeof(esow) == 4, "sizeof(EDNSSubnetOptsWire) must be 4 bytes");
+  if(len <= sizeof(esow))
+    return false;
   memcpy(&esow, options, sizeof(esow));
   esow.family = ntohs(esow.family);
   //cerr<<"Family when parsing from string: "<<esow.family<<endl;
@@ -53,21 +54,21 @@ bool getEDNSSubnetOptsFromString(const char* options, unsigned int len, EDNSSubn
   unsigned int octetsin = ((esow.sourceMask - 1)>> 3)+1;
   //cerr<<"octetsin:"<<octetsin<<endl;
   if(esow.family == 1) {
-    if(len != 4+octetsin)
+    if(len != sizeof(esow)+octetsin)
       return false;
-    if(octetsin > 4)
+    if(octetsin > sizeof(address.sin4.sin_addr.s_addr))
       return false;
     memset(&address, 0, sizeof(address));
     address.sin4.sin_family = AF_INET;
-    memcpy(&address.sin4.sin_addr.s_addr, options+4, octetsin);
+    memcpy(&address.sin4.sin_addr.s_addr, options+sizeof(esow), octetsin);
   } else if(esow.family == 2) {
-    if(len != 4+octetsin)
+    if(len != sizeof(esow)+octetsin)
       return false;
-    if(octetsin > 16)
+    if(octetsin > sizeof(address.sin6.sin6_addr.s6_addr))
       return false;
     memset(&address, 0, sizeof(address));
     address.sin4.sin_family = AF_INET6;
-    memcpy(&address.sin6.sin6_addr.s6_addr, options+4, octetsin);
+    memcpy(&address.sin6.sin6_addr.s6_addr, options+sizeof(esow), octetsin);
   }
   else
     return false;
@@ -82,7 +83,7 @@ string makeEDNSSubnetOptsString(const EDNSSubnetOpts& eso)
   string ret;
   EDNSSubnetOptsWire esow;
   uint16_t family = htons(eso.source.getNetwork().sin4.sin_family == AF_INET ? 1 : 2);
-  memcpy(&esow.family, &family, 2);
+  esow.family = family;
   esow.sourceMask = eso.source.getBits();
   esow.scopeMask = eso.scope.getBits();
   ret.assign((const char*)&esow, sizeof(esow));
index 545a50d83afc4c24f7700f2b1ed5f7d8750968f5..bc66780d3d3d799e6fcf9526cea38e5620cc9a92 100644 (file)
@@ -118,7 +118,7 @@ bool IsAnyAddress(const ComboAddress& addr)
   return false;
 }
 
-int sendfromto(int sock, const char* data, int len, int flags, const ComboAddress& from, const ComboAddress& to)
+ssize_t sendfromto(int sock, const char* data, size_t len, int flags, const ComboAddress& from, const ComboAddress& to)
 {
   struct msghdr msgh;
   struct iovec iov;
index e614a20ead83505609b8b74cebeb2ba2ef09d24b..d935073592433db405633df206a1448d1d277a10 100644 (file)
@@ -94,7 +94,7 @@ union ComboAddress {
     if(sin4.sin_family == AF_INET)
       return sin4.sin_addr.s_addr == rhs.sin4.sin_addr.s_addr;
     else
-      return memcmp(&sin6.sin6_addr.s6_addr, &rhs.sin6.sin6_addr.s6_addr, 16)==0;
+      return memcmp(&sin6.sin6_addr.s6_addr, &rhs.sin6.sin6_addr.s6_addr, sizeof(sin6.sin6_addr.s6_addr))==0;
   }
 
   bool operator!=(const ComboAddress& rhs) const
@@ -115,7 +115,7 @@ union ComboAddress {
     if(sin4.sin_family == AF_INET)
       return sin4.sin_addr.s_addr < rhs.sin4.sin_addr.s_addr;
     else
-      return memcmp(&sin6.sin6_addr.s6_addr, &rhs.sin6.sin6_addr.s6_addr, 16) < 0;
+      return memcmp(&sin6.sin6_addr.s6_addr, &rhs.sin6.sin6_addr.s6_addr, sizeof(sin6.sin6_addr.s6_addr)) < 0;
   }
 
   bool operator>(const ComboAddress& rhs) const
@@ -152,7 +152,7 @@ union ComboAddress {
       if(a.sin4.sin_family == AF_INET)
         return a.sin4.sin_addr.s_addr < b.sin4.sin_addr.s_addr;
       else
-        return memcmp(&a.sin6.sin6_addr.s6_addr, &b.sin6.sin6_addr.s6_addr, 16) < 0;
+        return memcmp(&a.sin6.sin6_addr.s6_addr, &b.sin6.sin6_addr.s6_addr, sizeof(a.sin6.sin6_addr.s6_addr)) < 0;
     }
   };
 
@@ -165,7 +165,7 @@ union ComboAddress {
       if(a.sin4.sin_family == AF_INET)
         return a.sin4.sin_addr.s_addr == b.sin4.sin_addr.s_addr;
       else
-        return !memcmp(&a.sin6.sin6_addr.s6_addr, &b.sin6.sin6_addr.s6_addr, 16);
+        return !memcmp(&a.sin6.sin6_addr.s6_addr, &b.sin6.sin6_addr.s6_addr, sizeof(a.sin6.sin6_addr.s6_addr));
     }
   };
 
@@ -245,8 +245,8 @@ union ComboAddress {
     ret.sin4.sin_port=sin4.sin_port;
     
     const unsigned char*ptr = (unsigned char*) &sin6.sin6_addr.s6_addr;
-    ptr+=12;
-    memcpy(&ret.sin4.sin_addr.s_addr, ptr, 4);
+    ptr+=(sizeof(sin6.sin6_addr.s6_addr) - sizeof(ret.sin4.sin_addr.s_addr));
+    memcpy(&ret.sin4.sin_addr.s_addr, ptr, sizeof(ret.sin4.sin_addr.s_addr));
     return ret;
   }
 
@@ -323,7 +323,7 @@ public:
     d_network=makeComboAddress(split.first);
     
     if(!split.second.empty()) {
-      d_bits = pdns_stou(split.second);
+      d_bits = (uint8_t)pdns_stou(split.second);
       if(d_bits<32)
         d_mask=~(0xFFFFFFFF>>d_bits);
       else
@@ -365,7 +365,7 @@ public:
       }
       // still here, now match remaining bits
       uint8_t bits= d_bits % 8;
-      uint8_t mask= ~(0xFF>>bits);
+      uint8_t mask= (uint8_t) ~(0xFF>>bits);
 
       return((us[n] & mask) == (them[n] & mask));
     }
@@ -854,7 +854,7 @@ bool IsAnyAddress(const ComboAddress& addr);
 bool HarvestDestinationAddress(struct msghdr* msgh, ComboAddress* destination);
 bool HarvestTimestamp(struct msghdr* msgh, struct timeval* tv);
 void fillMSGHdr(struct msghdr* msgh, struct iovec* iov, char* cbuf, size_t cbufsize, char* data, size_t datalen, ComboAddress* addr);
-int sendfromto(int sock, const char* data, int len, int flags, const ComboAddress& from, const ComboAddress& to);
+ssize_t sendfromto(int sock, const char* data, size_t len, int flags, const ComboAddress& from, const ComboAddress& to);
 ssize_t sendMsgWithTimeout(int fd, const char* buffer, size_t len, int timeout, ComboAddress& dest, const ComboAddress& local, unsigned int localItf);
 
 #endif
index 61c9185d17bc96ffe5102b98a79d182dcabf6548..c0987929a637635c081510c40578b5f11a56206a 100644 (file)
@@ -265,89 +265,4 @@ extern "C" int luaopen_iputils(lua_State* L)
   return 1;
 }
 
-#if 0
-int makeIPv6sockaddr(const std::string& addr, struct sockaddr_in6* ret)
-{
-  if(addr.empty())
-    return -1;
-  string ourAddr(addr);
-  int port = -1;
-  if(addr[0]=='[') { // [::]:53 style address
-    string::size_type pos = addr.find(']');
-    if(pos == string::npos || pos + 2 > addr.size() || addr[pos+1]!=':')
-      return -1;
-    ourAddr.assign(addr.c_str() + 1, pos-1);
-    port = pdns_stou(addr.substr(pos+2));
-  }
-  ret->sin6_scope_id=0;
-  ret->sin6_family=AF_INET6;
-  if(inet_pton(AF_INET6, ourAddr.c_str(), (void*)&ret->sin6_addr) != 1) {
-    struct addrinfo* res;
-    struct addrinfo hints;
-    memset(&hints, 0, sizeof(hints));
-    
-    hints.ai_family = AF_INET6;
-    hints.ai_flags = AI_NUMERICHOST;
-    
-    int error;
-    if((error=getaddrinfo(ourAddr.c_str(), 0, &hints, &res))) { // this is correct
-      return -1;
-    }
-  
-    memcpy(ret, res->ai_addr, res->ai_addrlen);
-    freeaddrinfo(res);
-  }
-
-  if(port >= 0)
-    ret->sin6_port = htons(port);
-
-  return 0;
-}
-
-int makeIPv4sockaddr(const std::string& str, struct sockaddr_in* ret)
-{
-  if(str.empty()) {
-    return -1;
-  }
-  struct in_addr inp;
-  
-  string::size_type pos = str.find(':');
-  if(pos == string::npos) { // no port specified, not touching the port
-    if(inet_aton(str.c_str(), &inp)) {
-      ret->sin_addr.s_addr=inp.s_addr;
-      return 0;
-    }
-    return -1;
-  }
-  if(!*(str.c_str() + pos + 1)) // trailing :
-    return -1; 
-    
-  char *eptr = (char*)str.c_str() + str.size();
-  int port = strtol(str.c_str() + pos + 1, &eptr, 10);
-  if(*eptr)
-    return -1;
-  
-  ret->sin_port = htons(port);
-  if(inet_aton(str.substr(0, pos).c_str(), &inp)) {
-    ret->sin_addr.s_addr=inp.s_addr;
-    return 0;
-  }
-  return -1;
-}
-
-
-pair<string, string> splitField(const string& inp, char sepa)
-{
-  pair<string, string> ret;
-  string::size_type cpos=inp.find(sepa);
-  if(cpos==string::npos)
-    ret.first=inp;
-  else {
-    ret.first=inp.substr(0, cpos);
-    ret.second=inp.substr(cpos+1);
-  }
-  return ret;
-}
-
-#endif
 #endif
index f74e9d70a4a6a73c366f58f0fed393b10723aef7..3313d26c92436c9eb2e215319f407c276cd8e1e5 100644 (file)
@@ -56,8 +56,8 @@
  */
 int asyncresolve(const ComboAddress& ip, const DNSName& domain, int type, bool doTCP, bool sendRDQuery, int EDNS0Level, struct timeval* now, boost::optional<Netmask>& srcmask, LWResult *lwr)
 {
-  int len; 
-  int bufsize=g_outgoingEDNSBufsize;
+  size_t len;
+  size_t bufsize=g_outgoingEDNSBufsize;
   scoped_array<unsigned char> buf(new unsigned char[bufsize]);
   vector<uint8_t> vpacket;
   //  string mapped0x20=dns0x20(domain);
@@ -95,7 +95,7 @@ int asyncresolve(const ComboAddress& ip, const DNSName& domain, int type, bool d
     if(ip.sin4.sin_family==AF_INET6)
       g_stats.ipv6queries++;
 
-    if((ret=asendto((const char*)&*vpacket.begin(), (int)vpacket.size(), 0, ip, pw.getHeader()->id, 
+    if((ret=asendto((const char*)&*vpacket.begin(), vpacket.size(), 0, ip, pw.getHeader()->id,
                     domain, type, &queryfd)) < 0) {
       return ret; // passes back the -2 EMFILE
     }
@@ -132,7 +132,7 @@ int asyncresolve(const ComboAddress& ip, const DNSName& domain, int type, bool d
       if(!(ret > 0))
         return ret;
       
-      memcpy(&tlen, packet.c_str(), 2);
+      memcpy(&tlen, packet.c_str(), sizeof(tlen));
       len=ntohs(tlen); // switch to the 'len' shared with the rest of the function
       
       ret=arecvtcp(packet, len, &s, false);
index 01338f5d081d8f13c11772ad3d1f22c14087090c..a293d6a03c9ea8052166910c4e7e3703a3747d2f 100644 (file)
 #include "dns.hh"
 #include "namespaces.hh"
 
-int asendto(const char *data, int len, int flags, const ComboAddress& ip, uint16_t id, 
+int asendto(const char *data, size_t len, int flags, const ComboAddress& ip, uint16_t id,
             const DNSName& domain, uint16_t qtype,  int* fd);
-int arecvfrom(char *data, int len, int flags, const ComboAddress& ip, int *d_len, uint16_t id, 
-              const DNSName& domain, uint16_t, int fd, struct timeval* now);
+int arecvfrom(char *data, size_t len, int flags, const ComboAddress& ip, size_t *d_len, uint16_t id,
+              const DNSName& domain, uint16_t qtype, int fd, struct timeval* now);
 
 class LWResException : public PDNSException
 {
index c621b6250e65a35ea28c648966868a6de6cf39bc..e335c0cd675a0b277786624713cd8695943f53a7 100644 (file)
@@ -158,7 +158,8 @@ time_t CommunicatorClass::doNotifications()
   ComboAddress from;
   Utility::socklen_t fromlen;
   char buffer[1500];
-  int size, sock;
+  int sock;
+  ssize_t size;
 
   // receive incoming notifications on the nonblocking socket and take them off the list
   while(waitFor2Data(d_nsock4, d_nsock6, 0, 0, &sock) > 0) {
@@ -170,7 +171,7 @@ time_t CommunicatorClass::doNotifications()
 
     p.setRemote(&from);
 
-    if(p.parse(buffer,size)<0) {
+    if(p.parse(buffer,(size_t)size)<0) {
       L<<Logger::Warning<<"Unable to parse SOA notification answer from "<<p.getRemote()<<endl;
       continue;
     }
index 1b7a545b134906997e47ee3a3c67e5e89fc0334a..42b88ea093be6bc5114b0879ec08c8945293bb72 100644 (file)
 
 bool g_singleThreaded;
 
-int writen2(int fd, const void *buf, size_t count)
+size_t writen2(int fd, const void *buf, size_t count)
 {
   const char *ptr = (char*)buf;
   const char *eptr = ptr + count;
 
-  int res;
+  ssize_t res;
   while(ptr != eptr) {
     res = ::write(fd, ptr, eptr - ptr);
     if(res < 0) {
@@ -78,16 +78,16 @@ int writen2(int fd, const void *buf, size_t count)
     else if (res == 0)
       throw std::runtime_error("could not write all bytes, got eof in writen2");
 
-    ptr += res;
+    ptr += (size_t) res;
   }
 
   return count;
 }
 
-int readn2(int fd, void* buffer, unsigned int len)
+size_t readn2(int fd, void* buffer, size_t len)
 {
-  unsigned int pos=0;
-  int res;
+  size_t pos=0;
+  ssize_t res;
   for(;;) {
     res = read(fd, (char*)buffer + pos, len - pos);
     if(res == 0)
@@ -99,14 +99,14 @@ int readn2(int fd, void* buffer, unsigned int len)
         unixDie("failed in readn2");
     }
 
-    pos+=res;
+    pos+=(size_t)res;
     if(pos == len)
       break;
   }
   return len;
 }
 
-int readn2WithTimeout(int fd, void* buffer, size_t len, int timeout)
+size_t readn2WithTimeout(int fd, void* buffer, size_t len, int timeout)
 {
   size_t pos = 0;
   do {
@@ -139,7 +139,7 @@ int readn2WithTimeout(int fd, void* buffer, size_t len, int timeout)
   return len;
 }
 
-int writen2WithTimeout(int fd, const void * buffer, size_t len, int timeout)
+size_t writen2WithTimeout(int fd, const void * buffer, size_t len, int timeout)
 {
   size_t pos = 0;
   do {
@@ -204,67 +204,7 @@ uint32_t getLong(const char* p)
   return getLong((unsigned char *)p);
 }
 
-
-
-/** strips a domain suffix from a domain, returns true if it stripped */
-bool stripDomainSuffix(string *qname, const string &domain)
-{
-  if(!endsOn(*qname, domain))
-    return false;
-
-  if(toLower(*qname)==toLower(domain))
-    *qname="@";
-  else {
-    if((*qname)[qname->size()-domain.size()-1]!='.')
-      return false;
-
-    qname->resize(qname->size()-domain.size()-1);
-  }
-  return true;
-}
-
-/** Chops off the start of a domain, so goes from 'www.ds9a.nl' to 'ds9a.nl' to 'nl' to ''. Return zero on the empty string */
-bool chopOff(string &domain)
-{
-  if(domain.empty())
-    return false;
-
-  string::size_type fdot=domain.find('.');
-
-  if(fdot==string::npos)
-    domain="";
-  else {
-    string::size_type remain = domain.length() - (fdot + 1);
-    char tmp[remain];
-    memcpy(tmp, domain.c_str()+fdot+1, remain);
-    domain.assign(tmp, remain); // don't dare to do this w/o tmp holder :-)
-  }
-  return true;
-}
-
-/** Chops off the start of a domain, so goes from 'www.ds9a.nl.' to 'ds9a.nl.' to 'nl.' to '.' Return zero on the empty string */
-bool chopOffDotted(string &domain)
-{
-  if(domain.empty() || (domain.size()==1 && domain[0]=='.'))
-    return false;
-
-  string::size_type fdot=domain.find('.');
-  if(fdot == string::npos)
-    return false;
-
-  if(fdot==domain.size()-1)
-    domain=".";
-  else  {
-    string::size_type remain = domain.length() - (fdot + 1);
-    char tmp[remain];
-    memcpy(tmp, domain.c_str()+fdot+1, remain);
-    domain.assign(tmp, remain);
-  }
-  return true;
-}
-
-
-bool ciEqual(const string& a, const string& b)
+static bool ciEqual(const string& a, const string& b)
 {
   if(a.size()!=b.size())
     return false;
@@ -277,7 +217,7 @@ bool ciEqual(const string& a, const string& b)
 }
 
 /** does domain end on suffix? Is smart about "wwwds9a.nl" "ds9a.nl" not matching */
-bool endsOn(const string &domain, const string &suffix)
+static bool endsOn(const string &domain, const string &suffix)
 {
   if( suffix.empty() || ciEqual(domain, suffix) )
     return true;
@@ -297,6 +237,23 @@ bool endsOn(const string &domain, const string &suffix)
   return true;
 }
 
+/** strips a domain suffix from a domain, returns true if it stripped */
+bool stripDomainSuffix(string *qname, const string &domain)
+{
+  if(!endsOn(*qname, domain))
+    return false;
+
+  if(toLower(*qname)==toLower(domain))
+    *qname="@";
+  else {
+    if((*qname)[qname->size()-domain.size()-1]!='.')
+      return false;
+
+    qname->resize(qname->size()-domain.size()-1);
+  }
+  return true;
+}
+
 static void parseService4(const string &descr, ServiceTuple &st)
 {
   vector<string>parts;
index 7b2713fbf5bb148a117929376d3107c9fbf9f23f..302273eaf5e435d76c8edd1a3909451f7f3df928 100644 (file)
@@ -52,10 +52,6 @@ using namespace ::boost::multi_index;
 
 typedef enum { TSIG_MD5, TSIG_SHA1, TSIG_SHA224, TSIG_SHA256, TSIG_SHA384, TSIG_SHA512, TSIG_GSS } TSIGHashEnum;
 
-bool chopOff(string &domain);
-bool chopOffDotted(string &domain);
-
-bool endsOn(const string &domain, const string &suffix);
 string nowTime();
 const string unquotify(const string &item);
 string humanDuration(time_t passed);
@@ -146,11 +142,11 @@ vstringtok (Container &container, string const &in,
   }
 }
 
-int writen2(int fd, const void *buf, size_t count);
-inline int writen2(int fd, const std::string &s) { return writen2(fd, s.data(), s.size()); }
-int readn2(int fd, void* buffer, unsigned int len);
-int readn2WithTimeout(int fd, void* buffer, size_t len, int timeout);
-int writen2WithTimeout(int fd, const void * buffer, size_t len, int timeout);
+size_t writen2(int fd, const void *buf, size_t count);
+inline size_t writen2(int fd, const std::string &s) { return writen2(fd, s.data(), s.size()); }
+size_t readn2(int fd, void* buffer, size_t len);
+size_t readn2WithTimeout(int fd, void* buffer, size_t len, int timeout);
+size_t writen2WithTimeout(int fd, const void * buffer, size_t len, int timeout);
 
 const string toLower(const string &upper);
 const string toLowerCanonic(const string &upper);
index 57c0056250b8aed33af2205bdbfdb4b4f2c36259..561fc98e75aa305910da8ad58e377d690a287534 100644 (file)
@@ -309,7 +309,7 @@ DNSPacket *UDPNameserver::receive(DNSPacket *prefilled)
 {
   ComboAddress remote;
   extern StatBag S;
-  int len=-1;
+  ssize_t len=-1;
   char mesg[DNSPacket::s_udpTruncationThreshold];
   Utility::sock_t sock=-1;
 
@@ -380,7 +380,7 @@ DNSPacket *UDPNameserver::receive(DNSPacket *prefilled)
   else
     packet->d_dt.set(); // timing    
 
-  if(packet->parse(mesg, len)<0) {
+  if(packet->parse(mesg, (size_t) len)<0) {
     S.inc("corrupt-packets");
     S.ringAccount("remotes-corrupt", packet->d_remote);
 
index c82468e76a7528b37ed61e13710a28dd6c516149..0f5391d773c6ee1fcbabbcdf6bcbbd14db5b0ced 100644 (file)
@@ -153,10 +153,6 @@ try
   if(nif.domain != mdp.d_qname) {
     syslogFmt(boost::format("Response from inner nameserver for different domain '%s' than original notification '%s'") % mdp.d_qname.toString() % nif.domain.toString());
   } else {
-    struct dnsheader dh;
-    memcpy(&dh, buffer, sizeof(dh));
-    dh.id = nif.origID;
-    
     if(sendto(nif.origSocket, buffer, len, 0, (sockaddr*) &nif.source, nif.source.getSocklen()) < 0) {
       syslogFmt(boost::format("Unable to send notification response to external nameserver %s - %s") % nif.source.toStringWithPort() % stringerror());
     }
index 3cee6bde2053f20ef4472f498d677f13954f3660..c369d3dca6b45f1c6294b71f994eb6acc3c671d0 100644 (file)
@@ -243,7 +243,7 @@ int asendtcp(const string& data, Socket* sock)
 void handleTCPClientReadable(int fd, FDMultiplexer::funcparam_t& var);
 
 // -1 is error, 0 is timeout, 1 is success
-int arecvtcp(string& data, int len, Socket* sock, bool incompleteOkay)
+int arecvtcp(string& data, size_t len, Socket* sock, bool incompleteOkay)
 {
   data.clear();
   PacketID pident;
@@ -267,10 +267,10 @@ void handleGenUDPQueryResponse(int fd, FDMultiplexer::funcparam_t& var)
 {
   PacketID pident=*any_cast<PacketID>(&var);
   char resp[512];
-  int ret=recv(fd, resp, sizeof(resp), 0);
+  ssize_t ret=recv(fd, resp, sizeof(resp), 0);
   t_fdm->removeReadFD(fd);
   if(ret >= 0) {
-    string data(resp, ret);
+    string data(resp, (size_t) ret);
     MT->sendEvent(pident, &data);
   }
   else {
@@ -427,7 +427,7 @@ public:
   // returns -1 for errors which might go away, throws for ones that won't
   static int makeClientSocket(int family)
   {
-    int ret=(int)socket(family, SOCK_DGRAM, 0 ); // turns out that setting CLO_EXEC and NONBLOCK from here is not a performance win on Linux (oddly enough)
+    int ret=socket(family, SOCK_DGRAM, 0 ); // turns out that setting CLO_EXEC and NONBLOCK from here is not a performance win on Linux (oddly enough)
 
     if(ret < 0 && errno==EMFILE) // this is not a catastrophic error
       return ret;
@@ -464,7 +464,7 @@ static __thread UDPClientSocks* t_udpclientsocks;
 
 /* these two functions are used by LWRes */
 // -2 is OS error, -1 is error that depends on the remote, > 0 is success
-int asendto(const char *data, int len, int flags,
+int asendto(const char *data, size_t len, int flags,
             const ComboAddress& toaddr, uint16_t id, const DNSName& domain, uint16_t qtype, int* fd)
 {
 
@@ -509,7 +509,7 @@ int asendto(const char *data, int len, int flags,
 }
 
 // -1 is error, 0 is timeout, 1 is success
-int arecvfrom(char *data, int len, int flags, const ComboAddress& fromaddr, int *d_len,
+int arecvfrom(char *data, size_t len, int flags, const ComboAddress& fromaddr, size_t *d_len,
               uint16_t id, const DNSName& domain, uint16_t qtype, int fd, struct timeval* now)
 {
   static optional<unsigned int> nearMissLimit;
@@ -530,7 +530,7 @@ int arecvfrom(char *data, int len, int flags, const ComboAddress& fromaddr, int
     if(packet.empty()) // means "error"
       return -1;
 
-    *d_len=(int)packet.size();
+    *d_len=packet.size();
     memcpy(data,packet.c_str(),min(len,*d_len));
     if(*nearMissLimit && pident.nearMisses > *nearMissLimit) {
       L<<Logger::Error<<"Too many ("<<pident.nearMisses<<" > "<<*nearMissLimit<<") bogus answers for '"<<domain<<"' from "<<fromaddr.toString()<<", assuming spoof attempt."<<endl;
@@ -1264,7 +1264,7 @@ void handleNewTCPQuestion(int fd, FDMultiplexer::funcparam_t& )
 {
   ComboAddress addr;
   socklen_t addrlen=sizeof(addr);
-  int newsock=(int)accept(fd, (struct sockaddr*)&addr, &addrlen);
+  int newsock=accept(fd, (struct sockaddr*)&addr, &addrlen);
   if(newsock>=0) {
     if(MT->numProcesses() > g_maxMThreads) {
       g_stats.overCapacityDrops++;
@@ -1456,7 +1456,7 @@ string* doProcessUDPQuestion(const std::string& question, const ComboAddress& fr
 
 void handleNewUDPQuestion(int fd, FDMultiplexer::funcparam_t& var)
 {
-  int len;
+  ssize_t len;
   char data[1500];
   ComboAddress fromaddr;
   struct msghdr msgh;
@@ -1500,7 +1500,7 @@ void handleNewUDPQuestion(int fd, FDMultiplexer::funcparam_t& var)
           L<<Logger::Error<<"Ignoring non-query opcode "<<dh->opcode<<" from "<<fromaddr.toString()<<" on server socket!"<<endl;
       }
       else {
-        string question(data, len);
+        string question(data, (size_t)len);
        struct timeval tv={0,0};
        HarvestTimestamp(&msgh, &tv);
        ComboAddress dest;
@@ -1517,8 +1517,8 @@ void handleNewUDPQuestion(int fd, FDMultiplexer::funcparam_t& var)
           }
           else {
             dest.sin4.sin_family = fromaddr.sin4.sin_family;
-            socklen_t len = dest.getSocklen();
-            getsockname(fd, (sockaddr*)&dest, &len); // if this fails, we're ok with it
+            socklen_t slen = dest.getSocklen();
+            getsockname(fd, (sockaddr*)&dest, &slen); // if this fails, we're ok with it
           }
         }
         if(g_weDistributeQueries)
@@ -1608,7 +1608,7 @@ void makeTCPServerSockets()
 #endif
 
     sin.sin4.sin_port = htons(st.port);
-    int socklen=sin.sin4.sin_family==AF_INET ? sizeof(sin.sin4) : sizeof(sin.sin6);
+    socklen_t socklen=sin.sin4.sin_family==AF_INET ? sizeof(sin.sin4) : sizeof(sin.sin6);
     if (::bind(fd, (struct sockaddr *)&sin, socklen )<0)
       throw PDNSException("Binding TCP server socket for "+ st.host +": "+stringerror());
 
@@ -1686,7 +1686,7 @@ void makeUDPServerSockets()
         throw PDNSException("SO_REUSEPORT: "+stringerror());
     }
 #endif
-  int socklen=sin.getSocklen();      
+  socklen_t socklen=sin.getSocklen();
     if (::bind(fd, (struct sockaddr *)&sin, socklen)<0)
       throw PDNSException("Resolver binding to server socket on port "+ std::to_string(st.port) +" for "+ st.host+": "+stringerror());
 
@@ -2048,7 +2048,7 @@ void handleRCC(int fd, FDMultiplexer::funcparam_t& var)
 
   // If we are inside a chroot, we need to strip
   if (!arg()["chroot"].empty()) {
-    int len = arg()["chroot"].length();
+    size_t len = arg()["chroot"].length();
     remote = remote.substr(len);
   }
 
@@ -2071,10 +2071,10 @@ void handleTCPClientReadable(int fd, FDMultiplexer::funcparam_t& var)
 
   shared_array<char> buffer(new char[pident->inNeeded]);
 
-  int ret=recv(fd, buffer.get(), pident->inNeeded,0);
+  ssize_t ret=recv(fd, buffer.get(), pident->inNeeded,0);
   if(ret > 0) {
     pident->inMSG.append(&buffer[0], &buffer[ret]);
-    pident->inNeeded-=ret;
+    pident->inNeeded-=(size_t)ret;
     if(!pident->inNeeded || pident->inIncompleteOkay) {
       //      cerr<<"Got entire load of "<<pident->inMSG.size()<<" bytes"<<endl;
       PacketID pid=*pident;
@@ -2098,9 +2098,9 @@ void handleTCPClientReadable(int fd, FDMultiplexer::funcparam_t& var)
 void handleTCPClientWritable(int fd, FDMultiplexer::funcparam_t& var)
 {
   PacketID* pid=any_cast<PacketID>(&var);
-  int ret=send(fd, pid->outMSG.c_str() + pid->outPos, pid->outMSG.size() - pid->outPos,0);
+  ssize_t ret=send(fd, pid->outMSG.c_str() + pid->outPos, pid->outMSG.size() - pid->outPos,0);
   if(ret > 0) {
-    pid->outPos+=ret;
+    pid->outPos+=(ssize_t)ret;
     if(pid->outPos==pid->outMSG.size()) {
       PacketID tmp=*pid;
       t_fdm->removeWriteFD(fd);
@@ -2134,14 +2134,14 @@ void doResends(MT_t::waiters_t::iterator& iter, PacketID resend, const string& c
 void handleUDPServerResponse(int fd, FDMultiplexer::funcparam_t& var)
 {
   PacketID pid=any_cast<PacketID>(var);
-  int len;
+  ssize_t len;
   char data[g_outgoingEDNSBufsize];
   ComboAddress fromaddr;
   socklen_t addrlen=sizeof(fromaddr);
 
   len=recvfrom(fd, data, sizeof(data), 0, (sockaddr *)&fromaddr, &addrlen);
 
-  if(len < (int)sizeof(dnsheader)) {
+  if(len < (ssize_t) sizeof(dnsheader)) {
     if(len < 0)
       ; //      cerr<<"Error on fd "<<fd<<": "<<stringerror()<<"\n";
     else {
index 98a9819722e954d249e492a89f95f89add391f86..3ca36583440c0ffdf759a9c15249f3a8aa696015 100644 (file)
@@ -1516,7 +1516,7 @@ bool showZone(DNSSECKeeper& dk, const DNSName& zone)
       strftime(buf, sizeof(buf)-1, "%a %F %H:%M:%S", &tm);
     else
       strncpy(buf, "Never", sizeof(buf)-1);
-
+    buf[sizeof(buf)-1] = '\0';
     cout<<"Last time we got update from master: "<<buf<<endl;
     SOAData sd;
     if(B.getSOAUncached(zone, sd)) {
index c1e8453d456dc7557ae75a49066b3b10ec71f631..39a6c0029a5ff98da40353c86d8a5df838b9b95a 100644 (file)
@@ -55,6 +55,7 @@ void primeHints(void)
     for(char c='a';c<='m';++c) {
       static char templ[40];
       strncpy(templ,"a.root-servers.net.", sizeof(templ) - 1);
+      templ[sizeof(templ)-1] = '\0';
       *templ=c;
       aaaarr.d_name=arr.d_name=DNSName(templ);
       nsrr.d_content=std::make_shared<NSRecordContent>(DNSName(templ));
index 23eade607dca9992bdbd5abf414683f9ef05d907..2630237b2234421989b79b405e57ab20fb055947 100644 (file)
@@ -47,7 +47,7 @@ public:
   //! Construct a socket of specified address family and socket type.
   Socket(int af, int st, ProtocolType pt=0)
   {
-    if((d_socket=(int)socket(af,st, pt))<0)
+    if((d_socket=socket(af,st, pt))<0)
       throw NetworkError(strerror(errno));
     setCloseOnExec(d_socket);
 
@@ -67,7 +67,7 @@ public:
     struct sockaddr_in remote;
     socklen_t remlen=sizeof(remote);
     memset(&remote, 0, sizeof(remote));
-    int s=(int)::accept(d_socket,(sockaddr *)&remote, &remlen);
+    int s=::accept(d_socket,(sockaddr *)&remote, &remlen);
     if(s<0) {
       if(errno==EAGAIN)
         return 0;
@@ -151,7 +151,7 @@ public:
   void recvFrom(string &dgram, ComboAddress &ep)
   {
     socklen_t remlen=sizeof(ep);
-    int bytes;
+    ssize_t bytes;
     if((bytes=recvfrom(d_socket, d_buffer, d_buflen, 0, (sockaddr *)&ep , &remlen)) <0)
       throw NetworkError("After recvfrom: "+string(strerror(errno)));
     
@@ -162,7 +162,7 @@ public:
   {
     struct sockaddr_in remote;
     socklen_t remlen=sizeof(remote);
-    int bytes;
+    ssize_t bytes;
     if((bytes=recvfrom(d_socket, d_buffer, d_buflen, 0, (sockaddr *)&remote, &remlen))<0) {
       if(errno!=EAGAIN) {
         throw NetworkError("After async recvfrom: "+string(strerror(errno)));
@@ -177,7 +177,7 @@ public:
 
 
   //! For datagram sockets, send a datagram to a destination
-  void sendTo(const char* msg, unsigned int len, const ComboAddress &ep)
+  void sendTo(const char* msg, size_t len, const ComboAddress &ep)
   {
     if(sendto(d_socket, msg, len, 0, (sockaddr *)&ep, ep.getSocklen())<0)
       throw NetworkError("After sendto: "+string(strerror(errno)));
@@ -206,8 +206,8 @@ public:
     if(data.empty())
       return;
 
-    int toWrite=(int)data.length();
-    int res;
+    size_t toWrite=data.length();
+    ssize_t res;
     const char *ptr=data.c_str();
 
     do {
@@ -216,8 +216,8 @@ public:
         throw NetworkError("Writing to a socket: "+string(strerror(errno)));
       if(!res)
         throw NetworkError("EOF on socket");
-      toWrite-=res;
-      ptr+=res;
+      toWrite-=(size_t)res;
+      ptr+=(size_t)res;
     }while(toWrite);
 
   }
@@ -227,9 +227,9 @@ public:
       \param ptr Location to write from
       \param toWrite number of bytes to try
   */
-  unsigned int tryWrite(const char *ptr, int toWrite)
+  size_t tryWrite(const char *ptr, size_t toWrite)
   {
-    int res;
+    ssize_t res;
     res=::send(d_socket,ptr,toWrite,0);
     if(res==0)
       throw NetworkError("EOF on writing to a socket");
@@ -245,9 +245,9 @@ public:
 
   //! Writes toWrite bytes from ptr to the socket
   /** Writes toWrite bytes from ptr to the socket. Returns how many bytes were written */
-  unsigned int write(const char *ptr, int toWrite)
+  size_t write(const char *ptr, size_t toWrite)
   {
-    int res;
+    ssize_t res;
     res=::send(d_socket,ptr,toWrite,0);
     if(res<0) {
       throw NetworkError("Writing to a socket: "+string(strerror(errno)));
@@ -255,11 +255,11 @@ public:
     return res;
   }
 
-  void writenWithTimeout(const void *buffer, unsigned int n, int timeout)
+  void writenWithTimeout(const void *buffer, size_t n, int timeout)
   {
-    unsigned int bytes=n;
+    size_t bytes=n;
     const char *ptr = (char*)buffer;
-    int ret;
+    ssize_t ret;
     while(bytes) {
       ret=::write(d_socket, ptr, bytes);
       if(ret < 0) {
@@ -278,8 +278,8 @@ public:
         throw NetworkError("Did not fulfill TCP write due to EOF");
       }
 
-      ptr += ret;
-      bytes -= ret;
+      ptr += (size_t) ret;
+      bytes -= (size_t) ret;
     }
   }
 
@@ -288,7 +288,7 @@ public:
   {
     char c;
 
-    int res=::recv(d_socket,&c,1,0);
+    ssize_t res=::recv(d_socket,&c,1,0);
     if(res)
       return c;
     return -1;
@@ -308,22 +308,22 @@ public:
   //! Reads a block of data from the socket to a string
   void read(string &data)
   {
-    int res=::recv(d_socket,d_buffer,d_buflen,0);
+    ssize_t res=::recv(d_socket,d_buffer,d_buflen,0);
     if(res<0) 
       throw NetworkError("Reading from a socket: "+string(strerror(errno)));
     data.assign(d_buffer,res);
   }
 
   //! Reads a block of data from the socket to a block of memory
-  int read(char *buffer, int bytes)
+  size_t read(char *buffer, size_t bytes)
   {
-    int res=::recv(d_socket,buffer,bytes,0);
+    ssize_t res=::recv(d_socket,buffer,bytes,0);
     if(res<0) 
       throw NetworkError("Reading from a socket: "+string(strerror(errno)));
-    return res;
+    return (size_t) res;
   }
 
-  int readWithTimeout(char* buffer, int n, int timeout)
+  ssize_t readWithTimeout(char* buffer, size_t n, int timeout)
   {
     int err = waitForRWData(d_socket, true, timeout, 0);
 
@@ -351,7 +351,7 @@ public:
 private:
   char *d_buffer;
   int d_socket;
-  int d_buflen;
+  size_t d_buflen;
 };
 
 
index 62e452a5fe2785a0573fdee5ea5ea97bb24ad2ac..564af638c3741ad05e02271dacee4477c1a85a2b 100644 (file)
@@ -510,7 +510,7 @@ extern __thread SyncRes::StaticStorage* t_sstorage;
 class Socket;
 /* external functions, opaque to us */
 int asendtcp(const string& data, Socket* sock);
-int arecvtcp(string& data, int len, Socket* sock, bool incompleteOkay);
+int arecvtcp(string& data, size_t len, Socket* sock, bool incompleteOkay);
 
 
 struct PacketID
@@ -527,7 +527,7 @@ struct PacketID
 
   Socket* sock;  // or wait for an event on a TCP fd
   string inMSG; // they'll go here
-  int inNeeded; // if this is set, we'll read until inNeeded bytes are read
+  size_t inNeeded; // if this is set, we'll read until inNeeded bytes are read
   bool inIncompleteOkay;
 
   string outMSG; // the outgoing message that needs to be sent