"Fossies" - the Fresh Open Source Software Archive

Member "pdns-auth-4.2.0/pdns/protobuf.cc" (27 Aug 2019, 9262 Bytes) of package /linux/misc/dns/pdns-auth-4.2.0.tar.gz:


As a special service "Fossies" has tried to format the requested source page into HTML format using (guessed) C and C++ source code syntax highlighting (style: standard) with prefixed line numbers and code folding option. Alternatively you can here view or download the uninterpreted source code file. For more information about "protobuf.cc" see the Fossies "Dox" file reference documentation and the latest Fossies "Diffs" side-by-side code changes report: 4.1.13_vs_4.2.0.

    1 
    2 #include "gettime.hh"
    3 #include "dnsparser.hh"
    4 #include "protobuf.hh"
    5 #include "dnsparser.hh"
    6 #include "gettime.hh"
    7 
    8 void DNSProtoBufMessage::setType(DNSProtoBufMessageType type)
    9 {
   10 #ifdef HAVE_PROTOBUF
   11   switch(type) {
   12   case DNSProtoBufMessage::DNSProtoBufMessageType::Query:
   13     d_message.set_type(PBDNSMessage_Type_DNSQueryType);
   14     break;
   15   case DNSProtoBufMessage::DNSProtoBufMessageType::Response:
   16     d_message.set_type(PBDNSMessage_Type_DNSResponseType);
   17     break;
   18   case DNSProtoBufMessage::DNSProtoBufMessageType::OutgoingQuery:
   19     d_message.set_type(PBDNSMessage_Type_DNSOutgoingQueryType);
   20     break;
   21   case DNSProtoBufMessage::DNSProtoBufMessageType::IncomingResponse:
   22     d_message.set_type(PBDNSMessage_Type_DNSIncomingResponseType);
   23     break;
   24   default:
   25     throw std::runtime_error("Unsupported protobuf type: "+std::to_string(type));
   26   }
   27 #endif /* HAVE_PROTOBUF */
   28 }
   29 
   30 DNSProtoBufMessage::DNSProtoBufMessage(DNSProtoBufMessageType type)
   31 {
   32   setType(type);
   33 }
   34 
   35 void DNSProtoBufMessage::setQuestion(const DNSName& qname, uint16_t qtype, uint16_t qclass)
   36 {
   37 #ifdef HAVE_PROTOBUF
   38   PBDNSMessage_DNSQuestion* question = d_message.mutable_question();
   39   if (question) {
   40     if(!qname.empty())
   41       question->set_qname(qname.toString());
   42     question->set_qtype(qtype);
   43     question->set_qclass(qclass);
   44   }
   45 #endif /* HAVE_PROTOBUF */
   46 }
   47 
   48 void DNSProtoBufMessage::setBytes(size_t bytes)
   49 {
   50 #ifdef HAVE_PROTOBUF
   51   d_message.set_inbytes(bytes);
   52 #endif /* HAVE_PROTOBUF */
   53 }
   54 
   55 void DNSProtoBufMessage::setResponseCode(uint8_t rcode)
   56 {
   57 #ifdef HAVE_PROTOBUF
   58   PBDNSMessage_DNSResponse* response = d_message.mutable_response();
   59   if (response) {
   60     response->set_rcode(rcode);
   61   }
   62 #endif /* HAVE_PROTOBUF */
   63 }
   64 
   65 void DNSProtoBufMessage::setTime(time_t sec, uint32_t usec)
   66 {
   67 #ifdef HAVE_PROTOBUF
   68   d_message.set_timesec(sec);
   69   d_message.set_timeusec(usec);
   70 #endif /* HAVE_PROTOBUF */
   71 }
   72 
   73 void DNSProtoBufMessage::setQueryTime(time_t sec, uint32_t usec)
   74 {
   75 #ifdef HAVE_PROTOBUF
   76   PBDNSMessage_DNSResponse* response = d_message.mutable_response();
   77   if (response) {
   78     response->set_querytimesec(sec);
   79     response->set_querytimeusec(usec);
   80   }
   81 #endif /* HAVE_PROTOBUF */
   82 }
   83 
   84 void DNSProtoBufMessage::setEDNSSubnet(const Netmask& subnet, uint8_t mask)
   85 {
   86 #ifdef HAVE_PROTOBUF
   87   if (!subnet.empty()) {
   88     ComboAddress ca(subnet.getNetwork());
   89     ca.truncate(mask);
   90     if (ca.sin4.sin_family == AF_INET) {
   91       d_message.set_originalrequestorsubnet(&ca.sin4.sin_addr.s_addr, sizeof(ca.sin4.sin_addr.s_addr));
   92     }
   93     else if (ca.sin4.sin_family == AF_INET6) {
   94       d_message.set_originalrequestorsubnet(&ca.sin6.sin6_addr.s6_addr, sizeof(ca.sin6.sin6_addr.s6_addr));
   95     }
   96   }
   97 #endif /* HAVE_PROTOBUF */
   98 }
   99 
  100 void DNSProtoBufMessage::addTag(const std::string& strValue)
  101 {
  102 #ifdef HAVE_PROTOBUF
  103 
  104   PBDNSMessage_DNSResponse* response = d_message.mutable_response();
  105   if (!response)
  106     return;
  107 
  108   response->add_tags(strValue);
  109 
  110 #endif /* HAVE_PROTOBUF */
  111 }
  112 
  113 void DNSProtoBufMessage::addRR(const DNSName& qname, uint16_t uType, uint16_t uClass, uint32_t uTTL, const std::string& strBlob)
  114 {
  115 #ifdef HAVE_PROTOBUF
  116 
  117   PBDNSMessage_DNSResponse* response = d_message.mutable_response();
  118   if (!response)
  119     return;
  120   PBDNSMessage_DNSResponse_DNSRR* rr = response->add_rrs();
  121   if (rr) {
  122     rr->set_name(qname.toString());
  123     rr->set_type(uType);
  124     rr->set_class_(uClass);
  125     rr->set_ttl(uTTL);
  126     rr->set_rdata(strBlob.c_str(), strBlob.size());
  127   }
  128 
  129 #endif /* HAVE_PROTOBUF */
  130 }
  131 
  132 void DNSProtoBufMessage::addRRsFromPacket(const char* packet, const size_t len, bool includeCNAME)
  133 {
  134 #ifdef HAVE_PROTOBUF
  135   if (len < sizeof(struct dnsheader))
  136     return;
  137 
  138   const struct dnsheader* dh = (const struct dnsheader*) packet;
  139 
  140   if (ntohs(dh->ancount) == 0)
  141     return;
  142 
  143   if (ntohs(dh->qdcount) == 0)
  144     return;
  145 
  146   PBDNSMessage_DNSResponse* response = d_message.mutable_response();
  147   if (!response)
  148     return;
  149 
  150   std::string packetStr(packet, len);
  151   PacketReader pr(packetStr);
  152 
  153   size_t idx = 0;
  154   DNSName rrname;
  155   uint16_t qdcount = ntohs(dh->qdcount);
  156   uint16_t ancount = ntohs(dh->ancount);
  157   uint16_t rrtype;
  158   uint16_t rrclass;
  159   string blob;
  160   struct dnsrecordheader ah;
  161 
  162   rrname = pr.getName();
  163   rrtype = pr.get16BitInt();
  164   rrclass = pr.get16BitInt();
  165 
  166   /* consume remaining qd if any */
  167   if (qdcount > 1) {
  168     for(idx = 1; idx < qdcount; idx++) {
  169       rrname = pr.getName();
  170       rrtype = pr.get16BitInt();
  171       rrclass = pr.get16BitInt();
  172       (void) rrtype;
  173       (void) rrclass;
  174     }
  175   }
  176 
  177   /* parse AN */
  178   for (idx = 0; idx < ancount; idx++) {
  179     rrname = pr.getName();
  180     pr.getDnsrecordheader(ah);
  181 
  182     if (ah.d_type == QType::A || ah.d_type == QType::AAAA) {
  183       pr.xfrBlob(blob);
  184 
  185       PBDNSMessage_DNSResponse_DNSRR* rr = response->add_rrs();
  186       if (rr) {
  187         rr->set_name(rrname.toString());
  188         rr->set_type(ah.d_type);
  189         rr->set_class_(ah.d_class);
  190         rr->set_ttl(ah.d_ttl);
  191         rr->set_rdata(blob.c_str(), blob.length());
  192       }
  193     } else if (ah.d_type == QType::CNAME && includeCNAME) {
  194       PBDNSMessage_DNSResponse_DNSRR* rr = response->add_rrs();
  195       if (rr) {
  196         rr->set_name(rrname.toString());
  197         rr->set_type(ah.d_type);
  198         rr->set_class_(ah.d_class);
  199         rr->set_ttl(ah.d_ttl);
  200         DNSName target;
  201         pr.xfrName(target, true);
  202         rr->set_rdata(target.toString());
  203       }
  204     }
  205     else {
  206       pr.xfrBlob(blob);
  207     }
  208   }
  209 #endif /* HAVE_PROTOBUF */
  210 }
  211 
  212 void DNSProtoBufMessage::setRequestor(const std::string& requestor)
  213 {
  214 #ifdef HAVE_PROTOBUF
  215   d_message.set_from(requestor);
  216 #endif /* HAVE_PROTOBUF */
  217 }
  218 
  219 void DNSProtoBufMessage::setRequestor(const ComboAddress& requestor)
  220 {
  221 #ifdef HAVE_PROTOBUF
  222   if (requestor.sin4.sin_family == AF_INET) {
  223     d_message.set_from(&requestor.sin4.sin_addr.s_addr, sizeof(requestor.sin4.sin_addr.s_addr));
  224   }
  225   else if (requestor.sin4.sin_family == AF_INET6) {
  226     d_message.set_from(&requestor.sin6.sin6_addr.s6_addr, sizeof(requestor.sin6.sin6_addr.s6_addr));
  227   }
  228 #endif /* HAVE_PROTOBUF */
  229 }
  230 
  231 void DNSProtoBufMessage::setRequestorId(const std::string& requestorId)
  232 {
  233 #ifdef HAVE_PROTOBUF
  234   d_message.set_requestorid(requestorId);
  235 #endif /* HAVE_PROTOBUF */
  236 }
  237 
  238 void DNSProtoBufMessage::setDeviceId(const std::string& deviceId)
  239 {
  240 #ifdef HAVE_PROTOBUF
  241   d_message.set_deviceid(deviceId);
  242 #endif /* HAVE_PROTOBUF */
  243 }
  244 
  245 void DNSProtoBufMessage::setServerIdentity(const std::string& serverId)
  246 {
  247 #ifdef HAVE_PROTOBUF
  248   d_message.set_serveridentity(serverId);
  249 #endif /* HAVE_PROTOBUF */
  250 }
  251 
  252 void DNSProtoBufMessage::setResponder(const std::string& responder)
  253 {
  254 #ifdef HAVE_PROTOBUF
  255   d_message.set_to(responder);
  256 #endif /* HAVE_PROTOBUF */
  257 }
  258 
  259 void DNSProtoBufMessage::setResponder(const ComboAddress& responder)
  260 {
  261 #ifdef HAVE_PROTOBUF
  262   if (responder.sin4.sin_family == AF_INET) {
  263     d_message.set_to(&responder.sin4.sin_addr.s_addr, sizeof(responder.sin4.sin_addr.s_addr));
  264   }
  265   else if (responder.sin4.sin_family == AF_INET6) {
  266     d_message.set_to(&responder.sin6.sin6_addr.s6_addr, sizeof(responder.sin6.sin6_addr.s6_addr));
  267   }
  268 #endif /* HAVE_PROTOBUF */
  269 }
  270 
  271 void DNSProtoBufMessage::serialize(std::string& data) const
  272 {
  273 #ifdef HAVE_PROTOBUF
  274   d_message.SerializeToString(&data);
  275 #endif /* HAVE_PROTOBUF */
  276 }
  277 
  278 std::string DNSProtoBufMessage::toDebugString() const
  279 {
  280 #ifdef HAVE_PROTOBUF
  281   return d_message.DebugString();
  282 #else
  283   return std::string();
  284 #endif /* HAVE_PROTOBUF */
  285 }
  286 
  287 #ifdef HAVE_PROTOBUF
  288 
  289 void DNSProtoBufMessage::setUUID(const boost::uuids::uuid& uuid)
  290 {
  291   std::string* messageId = d_message.mutable_messageid();
  292   messageId->resize(uuid.size());
  293   std::copy(uuid.begin(), uuid.end(), messageId->begin());
  294 }
  295 
  296 void DNSProtoBufMessage::setInitialRequestID(const boost::uuids::uuid& uuid)
  297 {
  298   std::string* messageId = d_message.mutable_initialrequestid();
  299   messageId->resize(uuid.size());
  300   std::copy(uuid.begin(), uuid.end(), messageId->begin());
  301 }
  302 
  303 void DNSProtoBufMessage::update(const boost::uuids::uuid& uuid, const ComboAddress* requestor, const ComboAddress* responder, bool isTCP, uint16_t id)
  304 {
  305   struct timespec ts;
  306   gettime(&ts, true);
  307   setTime(ts.tv_sec, ts.tv_nsec / 1000);
  308 
  309   setUUID(uuid);
  310   d_message.set_id(ntohs(id));
  311 
  312   if (requestor) {
  313     d_message.set_socketfamily(requestor->sin4.sin_family == AF_INET ? PBDNSMessage_SocketFamily_INET : PBDNSMessage_SocketFamily_INET6);
  314   }
  315   else if (responder) {
  316     d_message.set_socketfamily(responder->sin4.sin_family == AF_INET ? PBDNSMessage_SocketFamily_INET : PBDNSMessage_SocketFamily_INET6);
  317   }
  318 
  319   d_message.set_socketprotocol(isTCP ? PBDNSMessage_SocketProtocol_TCP : PBDNSMessage_SocketProtocol_UDP);
  320 
  321   if (responder) {
  322     setResponder(*responder);
  323   }
  324   if (requestor) {
  325     setRequestor(*requestor);
  326   }
  327 }
  328 
  329 
  330 DNSProtoBufMessage::DNSProtoBufMessage(DNSProtoBufMessageType type, const boost::uuids::uuid& uuid, const ComboAddress* requestor, const ComboAddress* responder, const DNSName& domain, int qtype, uint16_t qclass, uint16_t qid, bool isTCP, size_t bytes)
  331 {
  332   update(uuid, requestor, responder, isTCP, qid);
  333 
  334   setType(type);
  335 
  336   setBytes(bytes);
  337   setQuestion(domain, qtype, qclass);
  338 }
  339 
  340 void DNSProtoBufMessage::copyFrom(const DNSProtoBufMessage& msg)
  341 {
  342   d_message.CopyFrom(msg.d_message);
  343 }
  344 
  345 #endif /* HAVE_PROTOBUF */