OpenSDN source code
 All Classes Namespaces Files Functions Variables Typedefs Enumerations Enumerator Friends Macros Pages
dns_handler.cc
Go to the documentation of this file.
1 /*
2  * Copyright (c) 2013 Juniper Networks, Inc. All rights reserved.
3  */
4 
5 #include <stdint.h>
6 #include "base/os.h"
7 #include "vr_defs.h"
8 #include "base/address_util.h"
10 #include "services/dns_proto.h"
11 #include "services/dhcp_proto.h"
12 #include "bind/bind_resolver.h"
13 #include "cmn/agent_cmn.h"
15 #include "base/timer.h"
16 #include "oper/operdb_init.h"
17 #include "oper/global_vrouter.h"
18 #include "oper/vn.h"
19 
20 DnsHandler::DnsHandler(Agent *agent, boost::shared_ptr<PktInfo> info,
21  boost::asio::io_context &io)
22  : ProtoHandler(agent, info, io), resp_ptr_(NULL), dns_resp_size_(0),
23  xid_(-1), action_(NONE), rkey_(NULL),
24  query_name_update_(false), pend_req_(0), default_method_(false),
25  curr_index_(0) {
26  dns_ = (dnshdr *) pkt_info_->data;
27 }
28 
30  for (ResolvList::iterator it = resolv_list_.begin();
31  it != resolv_list_.end(); ++it) {
32  delete *it;
33  }
34  if (rkey_) {
35  delete rkey_;
36  }
37 
38  uint8_t count = 0;
39  while (count < dns_resolvers_.size()) {
40  if (dns_resolvers_[count]) {
41  dns_resolvers_[count]->timer_->Cancel();
43  delete dns_resolvers_[count];
44  }
45  count++;
46  }
47  count = 0;
48  while (count < def_dns_resolvers_.size()) {
49  if (def_dns_resolvers_[count]) {
50  def_dns_resolvers_[count]->timer_->Cancel();
52  delete def_dns_resolvers_[count];
53  }
54  count++;
55  }
56 
57  dns_resolvers_.clear();
58  def_dns_resolvers_.clear();
59 }
60 
61 
63 
64  uint8_t count = 0;
65  uint8_t resolvers_count = Agent::GetInstance()->GetDnslist().size();
66  dns_resolvers_.resize(resolvers_count);
67 
68  std::vector<string>dns_servers;
69  while (count < resolvers_count) {
70 
71  boost::split(dns_servers, Agent::GetInstance()->GetDnslist()[count],
72  boost::is_any_of(":"));
73  DnsResolverInfo *resolver = new DnsResolverInfo();
74 
75  boost::system::error_code ec;
76  resolver->ep_.address(AddressFromString(dns_servers[0], &ec));
77  assert(ec.value() == 0);
78  uint16_t dns_port = DNS_SERVER_PORT;
79  if (dns_servers.size() > 1)
80  dns_port = strtoul(dns_servers[1].c_str(), NULL, 10);
81  resolver->ep_.port(dns_port);
82  resolver->retries_ = 0;
83  std::stringstream ss;
84  ss << "DnsHandlerTimer " << count;
86  *(agent()->event_manager()->io_service()), ss.str(),
87  TaskScheduler::GetInstance()->GetTaskId("Agent::Services"),
89  dns_resolvers_[count] = resolver;
90 
91  count++;
92  }
93 }
94 
96  uint8_t count = 0;
97  DnsProto *dns_proto = agent()->GetDnsProto();
98  std::vector<IpAddress> const &def_slist = dns_proto->GetDefaultServerList();
99  def_dns_resolvers_.resize(def_slist.size());
100  while (count < def_slist.size()) {
101  DnsResolverInfo *resolver = new DnsResolverInfo();
102 
103  resolver->ep_.address(def_slist[count]);
104  resolver->ep_.port(DNS_SERVER_PORT);
105  resolver->retries_ = 0;
106  std::stringstream ss;
107  ss << "DefDnsHandlerTimer " << count;
108  resolver->timer_ = TimerManager::CreateTimer(
109  *(agent()->event_manager()->io_service()), ss.str(),
110  TaskScheduler::GetInstance()->GetTaskId("Agent::Services"),
112  def_dns_resolvers_[count] = resolver;
113  count++;
114  }
115 }
116 
118  switch(pkt_info_->type) {
119  case PktType::MESSAGE:
120  return HandleMessage();
121 
122  default:
123  return HandleRequest();
124  }
125 }
126 
128  DnsProto *dns_proto = agent()->GetDnsProto();
129  dns_proto->IncrStatsReq();
130 
131  uint16_t ret = DNS_ERR_NO_ERROR;
132  const Interface *itf =
134  if (!itf || (itf->type() != Interface::VM_INTERFACE) ||
135  dns_->flags.req) {
136  dns_proto->IncrStatsDrop();
137  DNS_BIND_TRACE(DnsBindError, "Received Invalid DNS request - dropping"
138  << "; itf = " << itf << "; flags.req = "
139  << dns_->flags.req << "; src addr = "
140  << pkt_info_->ip->ip_src.s_addr <<";");
141  return true;
142  }
143 
144  const VmInterface *vmitf = static_cast<const VmInterface *>(itf);
145  if (!vmitf->layer3_forwarding()) {
146  DNS_BIND_TRACE(DnsBindError, "DNS request on VM port with disabled"
147  "ipv4 service: " << itf);
148  dns_proto->IncrStatsDrop();
149  return true;
150  }
151  // Handle requests (req == 0), queries (op code == 0), updates, non auth
152  if ((dns_->flags.op && dns_->flags.op != DNS_OPCODE_UPDATE) ||
153  (dns_->flags.cd)) {
154  DNS_BIND_TRACE(DnsBindError, "Unimplemented DNS request"
155  << "; flags.op = " << dns_->flags.op << "; flags.cd = "
156  << dns_->flags.cd << ";");
157  ret = DNS_ERR_NO_IMPLEMENT;
158  goto error;
159  }
160 
161  if (!vmitf->vn() ||
162  (pkt_info_->ip_saddr.is_v4() &&
163  !vmitf->vn()->GetIpamData(vmitf->primary_ip_addr(),
164  &ipam_name_, &ipam_type_)) ||
165  (pkt_info_->ip_saddr.is_v6() &&
166  !vmitf->vn()->GetIpamData(vmitf->primary_ip6_addr(),
167  &ipam_name_, &ipam_type_))) {
168  DNS_BIND_TRACE(DnsBindError, "Unable to find Ipam data; interface = "
169  << vmitf->name());
170  ret = DNS_ERR_SERVER_FAIL;
171  goto error;
172  }
173 
174  if (ipam_type_.ipam_dns_method == "default-dns-server" ||
175  ipam_type_.ipam_dns_method == "") {
177  if (dns_->flags.op == DNS_OPCODE_UPDATE) {
178  DNS_BIND_TRACE(DnsBindError, "Default DNS request : Update received, ignoring");
179  ret = DNS_ERR_NO_IMPLEMENT;
180  goto error;
181  }
182  GetDomainName(vmitf, &domain_name_);
183  default_method_ = true;
184  return HandleDefaultDnsRequest(vmitf);
185  } else if (ipam_type_.ipam_dns_method == "virtual-dns-server") {
187  if (!agent()->domain_config_table()->GetVDns(ipam_type_.ipam_dns_server.
188  virtual_dns_server_name, &vdns_type_)) {
189  DNS_BIND_TRACE(DnsBindError, "Unable to find domain; interface = "
190  << vmitf->vm_name());
191  ret = DNS_ERR_SERVER_FAIL;
192  goto error;
193  }
194  domain_name_ = vdns_type_.domain_name;
195  default_method_ = false;
196  return HandleVirtualDnsRequest(vmitf);
197  } else if (ipam_type_.ipam_dns_method == "none") {
198  DNS_BIND_TRACE(DnsBindError, "No DNS support for the VM : "
199  << "ipam_dns_method set to none, ignoring request");
200  ret = DNS_ERR_SERVER_FAIL;
201  goto error;
202  }
203 
204  ret = DNS_ERR_SERVER_FAIL;
205 error:
207  DNS_OPCODE_QUERY, 0, 1, ret,
208  ntohs(dns_->ques_rrcount));
209  SendDnsResponse();
210  return true;
211 }
212 
214  tbb::mutex::scoped_lock lock(mutex_);
215  uint16_t ret = DNS_ERR_NO_ERROR;
216  DnsProto *dns_proto = agent()->GetDnsProto();
217  rkey_ = new QueryKey(vmitf, dns_->xid);
218  if (dns_proto->IsVmRequestDuplicate(rkey_)) {
219  DNS_BIND_TRACE(DnsBindTrace,
220  "Retry DNS query from VM - dropping; interface = "
221  << vmitf->vm_name() << " xid = " << dns_->xid);
222  dns_proto->IncrStatsRetransmitReq();
223  return true;
224  }
225  dns_proto->AddVmRequest(rkey_);
226 
227  if (BindUtil::ParseDnsQuery((uint8_t *)dns_,
228  pkt_info_->GetUdpPayloadLength(),
229  &dns_resp_size_, items_) == false) {
230  DNS_BIND_TRACE(DnsBindTrace, "Default DNS query parsing failed; "
231  "interface = " << vmitf->vm_name() << " xid = " <<
232  dns_->xid);
233  return true;
234  }
235 
236  resp_ptr_ = (uint8_t *)dns_ + dns_resp_size_;
239  ntohs(dns_->ques_rrcount));
241  if (!items_.size()) {
242  // no pending resolution, send response
243  dns_->ans_rrcount = htons(dns_->ans_rrcount);
245  dns_proto->DelVmRequest(rkey_);
246  return true;
247  }
248 
249  if (!def_dns_resolvers_.size()) {
250  DNS_BIND_TRACE(DnsBindTrace, "No DNS resolvers for Default DNS query"
251  " with xid = " << dns_->xid << ";interface = "
252  << vmitf->vm_name());
253  ret = DNS_ERR_SERVER_FAIL;
254  goto fail;
255  }
256 
257  DNS_BIND_TRACE(DnsBindTrace, "Default DNS query received; "
258  "interface = " << vmitf->vm_name() << " xid = " <<
259  dns_->xid << " " << DnsItemsToString(items_));
260 
262  curr_index_ = 0;
263  if (SendToDefaultServer()) {
264  return false;
265  }
266 
267  DNS_BIND_TRACE(DnsBindTrace, "Unable to send DNS query to resolvers;"
268  " xid = " << dns_->xid << "; interface = "
269  << vmitf->vm_name());
270  ret = DNS_ERR_SERVER_FAIL;
271 fail:
273  DNS_OPCODE_QUERY, 0, 1, ret,
274  ntohs(dns_->ques_rrcount));
275  SendDnsResponse();
276  dns_proto->DelVmRequest(rkey_);
277  return true;
278 }
279 
282  if (dns_->flags.ret) {
283  DNS_BIND_TRACE(DnsBindError, "Query failed : " <<
285  " xid = " << dns_->xid << " " <<
288  } else {
289  DNS_BIND_TRACE(DnsBindTrace, "Query successful : xid = " <<
290  dns_->xid << " " << DnsItemsToString(items_) <<
292  }
293  SendDnsResponse();
294 }
295 
297  rkey_ = new QueryKey(vmitf, dns_->xid);
298  DnsProto *dns_proto = agent()->GetDnsProto();
299  if (dns_proto->IsVmRequestDuplicate(rkey_)) {
300  DNS_BIND_TRACE(DnsBindTrace,
301  "Retry DNS query from VM - dropping; interface = " <<
302  vmitf->vm_name() << " xid = " << dns_->xid << " " <<
305  dns_proto->IncrStatsRetransmitReq();
306  return true;
307  }
308  dns_proto->AddVmRequest(rkey_);
309 
311  virtual_dns_server_name);
312 
313  uint16_t ret = DNS_ERR_NO_ERROR;
314  switch (dns_->flags.op) {
315  case DNS_OPCODE_QUERY: {
316  if (BindUtil::ParseDnsQuery((uint8_t *)dns_,
317  pkt_info_->GetUdpPayloadLength(),
318  &dns_resp_size_, items_) == false) {
319  DNS_BIND_TRACE(DnsBindTrace, "vDNS query parsing failed; "
320  "interface = " << vmitf->vm_name() << " xid = " <<
321  dns_->xid);
322  break;
323  }
324  resp_ptr_ = (uint8_t *)dns_ + dns_resp_size_;
326  DNS_OPCODE_QUERY, 0, 1, ret,
327  ntohs(dns_->ques_rrcount));
328  // Check for linklocal service name resolution
330  if (!items_.size()) {
331  // no pending resolution, send response
332  dns_->ans_rrcount = htons(dns_->ans_rrcount);
333  SendDnsResponse();
334  break;
335  }
337 
338  uint8_t count = 0;
339  bool query_success = false;
340 
342  while (count < dns_resolvers_.size()) {
343  if (dns_resolvers_[count]) {
344  uint16_t xid = dns_proto->GetTransId();
345  if (SendDnsQuery(dns_resolvers_[count], xid) == true) {
346  dns_proto->AddDnsQueryIndex(xid, count);
347  query_success = true;
348  }
349  }
350  count++;
351  }
352  if (query_success) {
353  // atleast one query sent succesful, do not delete request yet.
354  return false;
355  }
356  break;
357  }
358 
359  case DNS_OPCODE_UPDATE: {
360  if (vdns_type_.dynamic_records_from_client) {
361  DnsUpdateData *update_data = new DnsUpdateData();
362  DnsProto::DnsUpdateIpc *update =
364  update_data, vmitf, false);
365  if (BindUtil::ParseDnsUpdate((uint8_t *)dns_,
366  pkt_info_->GetUdpPayloadLength(),
367  *update_data)) {
368  update_data->virtual_dns = ipam_type_.ipam_dns_server.
369  virtual_dns_server_name;
370  Update(update);
371  } else {
372  delete update;
373  ret = DNS_ERR_NO_IMPLEMENT;
374  }
375  } else {
376  DNS_BIND_TRACE(DnsBindTrace, "Client not allowed to update "
377  "dynamic records : " << vmitf->vm_name() << " ;Ignoring "
378  "update for " << DnsItemsToString(items_));
379  ret = DNS_ERR_NOT_AUTH;
380  }
382  DNS_OPCODE_UPDATE, 0, 1, ret,
383  ntohs(dns_->ques_rrcount));
384  SendDnsResponse();
385  break;
386  }
387 
388  default: {
389  DNS_BIND_TRACE(DnsBindTrace, "Unsupported op : " << dns_->flags.op
390  << "from vm : " << vmitf->vm_name());
391  break;
392  }
393  }
394 
395  dns_proto->DelVmRequest(rkey_);
396  return true;
397 }
398 
400  uint16_t xid) {
401  uint8_t *pkt = NULL;
402  std::size_t len = 0;
403  DnsProto *dns_proto = agent()->GetDnsProto();
404  bool in_progress = dns_proto->IsDnsQueryInProgress(xid);
405  if (in_progress) {
406  if (resolver->retries_ >= dns_proto->max_retries()) {
407  DNS_BIND_TRACE(DnsBindTrace,
408  "Max retries reached for query; xid = " << xid <<
409  " " << DnsItemsToString(items_));
410  goto cleanup;
411  } else {
412  resolver->retries_++;
413  }
414  } else {
415  dns_proto->AddDnsQuery(xid, this);
416  }
417 
418  pkt = new uint8_t[BindResolver::max_pkt_size];
419  if (!default_method_) {
420  len = BindUtil::BuildDnsQuery(pkt, xid,
421  ipam_type_.ipam_dns_server.virtual_dns_server_name, items_);
422  } else {
423  len = BindUtil::BuildDnsQuery(pkt, xid, "", items_);
424  }
425  if (BindResolver::Resolver()->DnsSend(pkt, resolver->ep_, len)) {
426  DNS_BIND_TRACE(DnsBindTrace, "DNS query sent to named server : " <<
427  resolver->ep_.address().to_string() << "; xid =" <<
428  xid << " " << DnsItemsToString(items_));
429  resolver->timer_->Cancel();
430  resolver->timer_->Start(dns_proto->timeout(),
431  boost::bind(&DnsHandler::TimerExpiry, this, xid));
432  return true;
433  }
434 
435 cleanup:
436  dns_proto->IncrStatsDrop();
437  dns_proto->DelDnsQuery(xid);
438  dns_proto->DelDnsQueryIndex(xid);
439  return false;
440 }
441 
442 // Check the request against configured link local services and
443 // update DnsItems, if found
444 bool DnsHandler::ResolveLinkLocalRequest(DnsItems::iterator &item,
445  DnsItems *linklocal_items) const {
446  GlobalVrouter *global_vrouter = agent_->oper_db()->global_vrouter();
447 
448  switch (item->type) {
449 
450  case DNS_A_RECORD: {
451  std::string base_name;
452  GetBaseName(item->name, &base_name);
453  std::set<IpAddress> service_ips;
454  if (global_vrouter->FindLinkLocalService(item->name, &service_ips) ||
455  (!base_name.empty() &&
456  global_vrouter->FindLinkLocalService(base_name, &service_ips))) {
457  for (std::set<IpAddress>::iterator it = service_ips.begin();
458  it != service_ips.end(); ++it) {
459  item->data = it->to_string();
460  linklocal_items->push_back(*item);
461  }
462  }
463  break;
464  }
465 
466  case DNS_PTR_RECORD: {
467  std::set<std::string> service_names;
468  boost::asio::ip::address addr;
469  if (!BindUtil::GetAddrFromPtrName(item->name, addr) ||
470  !addr.is_v4()) {
471  // TODO: Support link-local services on IPv6 links.
472  break;
473  }
474  if (global_vrouter->FindLinkLocalService(
475  addr.to_v4(), &service_names)) {
476  for (std::set<std::string>::iterator it = service_names.begin();
477  it != service_names.end(); ++it) {
478  item->data = *it;
479  linklocal_items->push_back(*item);
480  }
481  }
482  break;
483  }
484 
485  case DNS_AAAA_RECORD:
486  break;
487 
488  default:
489  break;
490 
491  }
492 
493  return (linklocal_items->size() > 0);
494 }
495 
496 // Resolve link local service name requests locally
498  bool linklocal_request = false;
499  for (DnsItems::iterator it = items_.begin(); it != items_.end(); ) {
500  DnsItems linklocal_items;
501  if (ResolveLinkLocalRequest(it, &linklocal_items)) {
502  linklocal_request = true;
503  for (DnsItems::iterator llit = linklocal_items.begin();
504  llit != linklocal_items.end(); ++llit) {
507  dns_->ans_rrcount++;
508  }
509  // storing the link local items in a different list
510  linklocal_items_.splice(linklocal_items_.begin(), linklocal_items);
511  items_.erase(it++);
512  } else {
513  it++;
514  }
515  }
516  return linklocal_request;
517 }
518 
520  switch (pkt_info_->ipc->cmd) {
522  return HandleDefaultDnsResponse();
523 
525  return HandleBindResponse();
526 
528  return HandleRetryExpiry();
529 
531  return HandleUpdate();
532 
534  return HandleModifyVdns();
535 
537  return HandleUpdateResponse();
538 
540  return UpdateAll();
541 
542  default:
543  DNS_BIND_TRACE(DnsBindError, "Invalid internal DNS message : " <<
544  pkt_info_->ipc->cmd);
545  return true;
546  }
547 }
548 
550  DnsProto::DnsIpc *ipc = static_cast<DnsProto::DnsIpc *>(pkt_info_->ipc);
552  delete ipc;
553  return true;
554 }
555 
557  DnsProto::DnsIpc *ipc = static_cast<DnsProto::DnsIpc *>(pkt_info_->ipc);
558  uint16_t xid = ntohs(*(uint16_t *)ipc->resp);
559  DnsProto *dns_proto = agent()->GetDnsProto();
560  DnsHandler *handler = dns_proto->GetDnsQueryHandler(xid);
561  bool valid_response = false;
562  if (handler) {
563  dns_flags flags;
564  DnsItems ques, ans, auth, add;
565  if (BindUtil::ParseDnsResponse(ipc->resp, ipc->length, xid, flags,
566  ques, ans, auth, add)) {
567  switch(handler->action_) {
569  if (flags.ret) {
570  DNS_BIND_TRACE(DnsBindError, "Query failed : " <<
572  " xid = " << xid << " " <<
575  } else {
576  valid_response = true;
577  handler->Resolve(flags, ques, ans, auth, add);
578  DNS_BIND_TRACE(DnsBindTrace,
579  "Query successful : xid = " <<
580  xid << " " << DnsItemsToString(ans) <<
582  }
583  break;
584 
585  default:
586  DNS_BIND_TRACE(DnsBindTrace,
587  "Invalid DNS action: xid = " << xid);
588  break;
589  }
590  } else {
591  DNS_BIND_TRACE(DnsBindTrace,
592  "Received invalid BIND response: xid = " << xid);
593  }
594 
595  dns_proto->DelDnsQuery(xid);
596  dns_proto->DelDnsQueryIndex(xid);
597 
598  if (valid_response) {
599  dns_proto->DelDnsQueryHandler(handler);
600  /* Delete Request on first valid Response from named Server */
601  dns_proto->DelVmRequest(handler->rkey_);
602  delete handler;
603  } else {
604  if (!handler->DefaultMethodInUse()) {
605  if (!dns_proto->IsDnsHandlerInUse(handler)) {
606  HandleInvalidBindResponse(handler, flags, ques, ans, auth,
607  add, xid);
608  }
609  } else {
610  if (NeedRetryForNextServer(flags.ret)) {
611  /* Try sending query to next available server */
612  handler->IncrCurrIndex();
613  if (!handler->SendToDefaultServer()) {
614  /* Sending query to next server failed, send invalid
615  * response to client
616  */
617  HandleInvalidBindResponse(handler, flags, ques, ans,
618  auth, add, xid);
619  }
620  } else {
621  /* Retry is not required, send invalid response to client */
622  HandleInvalidBindResponse(handler, flags, ques, ans, auth,
623  add, xid);
624  }
625  }
626  }
627  } else {
628  DNS_BIND_TRACE(DnsBindError, "Invalid or Response ignored xid " << xid <<
629  " received from DNS server - dropping");
630  dns_proto->DelDnsQueryIndex(xid);
631  }
632 
633  delete ipc;
634  return true;
635 }
636 
638  const DnsItems &ques, DnsItems &ans,
639  DnsItems &auth, DnsItems &add,
640  uint16_t xid) {
641  DnsProto *dns_proto = agent()->GetDnsProto();
642  if (flags.ret) {
643  /* Send last invalid response to requesting VM */
644  handler->Resolve(flags, ques, ans, auth, add);
645  DNS_BIND_TRACE(DnsBindTrace,
646  "Send invalid BIND response: xid = " << xid);
647  } else {
648  DNS_BIND_TRACE(DnsBindTrace,
649  "No response sent: xid = " << xid);
650  }
651  /* Delete Request on last invalid Response from named Server */
652  dns_proto->DelVmRequest(handler->rkey_);
653  delete handler;
654 }
655 
657  /*
658  * Try next server for following response codes: server_failure(2),
659  * Non-existent domain(3), Not implemented(4), Query refused(5),
660  * Not Authorized(9)
661  */
662  if ((code > 1 && code < 6) || code == 9) {
663  return true;
664  }
665  return false;
666 }
667 
669  if (curr_index() > last_index()) {
670  return false;
671  }
672  DnsProto *dns_proto = agent()->GetDnsProto();
673  uint16_t xid = dns_proto->GetTransId();
674  DnsResolverInfo *resolver;
675  while (curr_index() <= last_index()) {
676  resolver = def_dns_resolvers_[curr_index()];
677  if (!SendDnsQuery(resolver, xid)) {
678  IncrCurrIndex();
679  } else {
680  /* Query sent succesfully */
681  return true;
682  }
683  }
684  return false;
685 }
686 
688  DnsProto::DnsIpc *ipc = static_cast<DnsProto::DnsIpc *>(pkt_info_->ipc);
689  DnsProto *dns_proto = agent()->GetDnsProto();
690  uint16_t xid = ipc->xid;
691  DnsHandler *handler = dns_proto->GetDnsQueryHandler(xid);
692  if (handler) {
693  DnsResolverInfo *resolver;
694  if (handler->DefaultMethodInUse()) {
695  resolver = handler->def_dns_resolvers_[handler->curr_index()];
696  if (!handler->SendDnsQuery(resolver, xid)) {
697  // Try sending query to next available server
698  handler->IncrCurrIndex();
699  if (!handler->SendToDefaultServer()) {
700  dns_proto->DelVmRequest(handler->rkey_);
701  delete handler;
702  }
703  }
704  } else {
705  uint16_t idx = dns_proto->GetDnsQueryServerIndex(ipc->xid);
706  resolver = handler->dns_resolvers_[idx];
707  if (!handler->SendDnsQuery(resolver, xid)) {
708  if (!dns_proto->IsDnsHandlerInUse(handler)) {
709  dns_proto->DelVmRequest(handler->rkey_);
710  delete handler;
711  }
712  }
713  }
714  }
715  delete ipc;
716  return true;
717 }
718 
721  static_cast<DnsProto::DnsUpdateIpc *>(pkt_info_->ipc);
722  delete ipc;
723  return true;
724 }
725 
728  static_cast<DnsProto::DnsUpdateIpc *>(pkt_info_->ipc);
729  if (!ipc->xmpp_data) {
730  DelUpdate(ipc);
731  } else {
732  Update(ipc);
733  }
734  return true;
735 }
736 
739  static_cast<DnsProto::DnsUpdateIpc *>(pkt_info_->ipc);
740  DnsProto *dns_proto = agent()->GetDnsProto();
741  std::vector<DnsProto::DnsUpdateIpc *> change_list;
742  const DnsProto::DnsUpdateSet &update_set = dns_proto->update_set();
743  for (DnsProto::DnsUpdateSet::const_iterator it = update_set.begin();
744  it != update_set.end(); ++it) {
745  if ((ipc->itf &&
746  ((*it)->itf != ipc->itf || (*it)->floatingIp != ipc->floatingIp)) ||
747  !((*it)->xmpp_data) || (*it)->xmpp_data->virtual_dns != ipc->old_vdns)
748  continue;
749 
750  change_list.push_back(*it);
751  // if the server ttl changes, we only readd with the new values
752  if (!ipc->itf && ipc->new_vdns == ipc->old_vdns)
753  continue;
754 
755  for (DnsItems::iterator item = (*it)->xmpp_data->items.begin();
756  item != (*it)->xmpp_data->items.end(); ++item) {
757  // in case of delete, set the class to NONE and ttl to 0
758  (*item).eclass = DNS_CLASS_NONE;
759  (*item).ttl = 0;
760  }
761  for (int i = 0; i < MAX_XMPP_SERVERS; i++) {
762  AgentDnsXmppChannel *channel = agent()->dns_xmpp_channel(i);
763  SendXmppUpdate(channel, (*it)->xmpp_data);
764  }
765  }
766  for (unsigned int i = 0; i < change_list.size(); i++) {
767  dns_proto->DelUpdateRequest(change_list[i]);
768  if (ipc->new_vdns.empty())
769  delete change_list[i];
770  }
771  if (ipc->new_vdns.empty())
772  goto done;
773  for (unsigned int i = 0; i < change_list.size(); i++) {
774  change_list[i]->xmpp_data->virtual_dns = ipc->new_vdns;
775  std::string &zone = change_list[i]->xmpp_data->zone;
776  if (zone.find(".in-addr.arpa") == std::string::npos &&
777  zone.find(".ip6.arpa") == std::string::npos)
778  zone = ipc->new_domain;
779  for (DnsItems::iterator item = change_list[i]->xmpp_data->items.begin();
780  item != change_list[i]->xmpp_data->items.end(); ++item) {
781  (*item).eclass = DNS_CLASS_IN;
782  (*item).ttl = ipc->ttl;
783  }
784  Update(change_list[i]);
785  }
786 
787 done:
788  delete ipc;
789  return true;
790 }
791 
794  static_cast<DnsProto::DnsUpdateAllIpc *>(pkt_info_->ipc);
795  const DnsProto::DnsUpdateSet &update_set =
796  agent()->GetDnsProto()->update_set();
797  for (DnsProto::DnsUpdateSet::const_iterator it = update_set.begin();
798  it != update_set.end(); ++it) {
799  SendXmppUpdate(ipc->channel, (*it)->xmpp_data);
800  }
801 
802  delete ipc;
803  return true;
804 }
805 
807  DnsUpdateData *xmpp_data) {
808  if (channel && agent_->is_dns_xmpp_channel(channel)) {
809  // Split the request in case we have more data items
810  DnsItems done, store;
811  DnsItems::iterator first, last;
812 
813  uint32_t size = xmpp_data->items.size();
814  store.swap(xmpp_data->items);
815  for (uint32_t i = 0; i <= size / max_items_per_xmpp_msg; i++) {
816  if (!store.size())
817  break;
818 
819  first = last = store.begin();
820  if (store.size() > max_items_per_xmpp_msg)
821  std::advance(last, max_items_per_xmpp_msg);
822  else
823  last = store.end();
824  xmpp_data->items.splice(xmpp_data->items.begin(), store, first, last);
825 
827  xid_ = agent()->GetDnsProto()->GetTransId();
828  std::size_t len = 0;
829  if ((len = DnsAgentXmpp::DnsAgentXmppEncode(channel->GetXmppChannel(),
831  xid_, 0, xmpp_data,
832  data)) > 0) {
833  channel->SendMsg(data, len);
834  }
835 
836  done.splice(done.end(), xmpp_data->items, xmpp_data->items.begin(),
837  xmpp_data->items.end());
838  }
839  xmpp_data->items.swap(done);
840  }
841 }
842 
843 void
845  DnsItems &auth, DnsItems &add) {
846  for (DnsItems::iterator it = ans.begin(); it != ans.end(); ++it) {
847  bool name_update_required = true;
848  // Do not update dns response msg offset, for default dns case
849  if (!DefaultMethodInUse()) {
850  // find the matching entry in the request
851  for (DnsItems::const_iterator item = items_.begin();
852  item != items_.end(); ++item) {
853  if (it->name == item->name && it->eclass == item->eclass) {
854  it->name_plen = item->name_plen;
855  it->name_offset = item->offset;
856  name_update_required = false;
857  break;
858  }
859  }
860  }
861  UpdateOffsets(*it, name_update_required);
863  dns_->ans_rrcount++;
864  }
865 
866  for (DnsItems::iterator it = auth.begin(); it != auth.end(); ++it) {
867  UpdateOffsets(*it, true);
868  UpdateGWAddress(*it);
870  dns_->auth_rrcount++;
871  }
872 
873  for (DnsItems::iterator it = add.begin(); it != add.end(); ++it) {
874  UpdateOffsets(*it, true);
875  UpdateGWAddress(*it);
877  dns_->add_rrcount++;
878  }
879 
880  dns_->flags.ret = flags.ret;
881  dns_->flags.auth = flags.auth;
882  dns_->flags.ad = flags.ad;
883  dns_->flags.ra = flags.ra;
884  dns_->ans_rrcount = htons(dns_->ans_rrcount);
885  dns_->auth_rrcount = htons(dns_->auth_rrcount);
886  dns_->add_rrcount = htons(dns_->add_rrcount);
887  SendDnsResponse();
888 }
889 
891  PktInfo in_pkt_info = *pkt_info_.get();
892 
893  uint16_t buff_len = in_pkt_info.packet_buffer()->buffer_len();
894  pkt_info_->AllocPacketBuffer(agent(), PktHandler::DNS, buff_len, 0);
895  char *buff = (char *)pkt_info_->packet_buffer()->data();
896  memset(buff, 0, buff_len);
897  pkt_info_->vrf = in_pkt_info.vrf;
898 
899  uint16_t eth_type = ETHERTYPE_IP;
900  if (in_pkt_info.ip == NULL)
901  eth_type = ETHERTYPE_IPV6;
902 
903  MacAddress dest_mac(in_pkt_info.eth->ether_shost);
904  pkt_info_->eth = (struct ether_header *)(buff);
905  uint16_t eth_len = 0;
906  eth_len += EthHdr(buff, buff_len, in_pkt_info.GetAgentHdr().ifindex,
907  agent()->vhost_interface()->mac(), dest_mac, eth_type);
908 
909  uint16_t data_len = dns_resp_size_;
910  // fill in the response
911  if (in_pkt_info.ip) {
912  // IPv4 request
913  in_addr_t src_ip = in_pkt_info.ip->ip_dst.s_addr;
914  in_addr_t dest_ip = in_pkt_info.ip->ip_src.s_addr;
915 
916  pkt_info_->ip = (struct ip *)(buff + eth_len);
917  pkt_info_->transp.udp = (struct udphdr *)
918  ((uint8_t *)pkt_info_->ip + sizeof(struct ip));
919 
920  data_len += sizeof(udphdr);
921  UdpHdr(data_len, src_ip, DNS_SERVER_PORT,
922  dest_ip, ntohs(in_pkt_info.transp.udp->uh_sport));
923  data_len += sizeof(struct ip);
924  IpHdr(data_len, src_ip, dest_ip, IPPROTO_UDP,
926 
927  } else {
928  // IPv6 request
929  Ip6Address src_ip = in_pkt_info.ip_daddr.to_v6();
930  Ip6Address dest_ip = in_pkt_info.ip_saddr.to_v6();
931 
932  pkt_info_->ip6 = (struct ip6_hdr *)(buff + eth_len);
933  pkt_info_->transp.udp = (struct udphdr *)
934  ((uint8_t *)pkt_info_->ip6 + sizeof(struct ip6_hdr));
935 
936  data_len += sizeof(udphdr);
937  UdpHdr(data_len, src_ip.to_bytes().data(),
938  DNS_SERVER_PORT, dest_ip.to_bytes().data(),
939  ntohs(in_pkt_info.transp.udp->uh_sport), IPPROTO_UDP);
940 
941  data_len += sizeof(struct ip6_hdr);
942  Ip6Hdr(pkt_info_->ip6, data_len, IPPROTO_UDP, 64,
943  src_ip.to_bytes().data(), dest_ip.to_bytes().data());
944  }
945 
946  memcpy(((char *)pkt_info_->transp.udp + sizeof(udphdr)),
947  ((char *)in_pkt_info.transp.udp + sizeof(udphdr)),
949 
950  dns_resp_size_ += data_len + eth_len;
951  pkt_info_->set_len(dns_resp_size_);
952 
953  PacketInterfaceKey key(
954  boost::uuids::nil_uuid(), agent()->pkt_interface_name());
955  Interface *pkt_itf = static_cast<Interface *>
956  (agent()->interface_table()->FindActiveEntry(&key));
957  if (pkt_itf) {
958  UpdateStats();
959  uint32_t interface =
960  (pkt_info_->agent_hdr.cmd == AgentHdr::TRAP_TOR_CONTROL_PKT) ?
961  pkt_info_->agent_hdr.cmd_param : GetInterfaceIndex();
962  uint16_t command =
963  (pkt_info_->agent_hdr.cmd == AgentHdr::TRAP_TOR_CONTROL_PKT) ?
965  Send(interface, pkt_info_->vrf, command, PktHandler::DNS);
966  } else {
968  }
969 }
970 
972  for (DnsItems::iterator it = items_.begin(); it != items_.end(); ++it) {
973  // do not append domain for empty string (request to root ns)
974  if (it->name.size() == 0) {
975  return;
976  }
977 
978  // do not append domain in case of NS query
979  if (it->type == DNS_NS_RECORD) {
980  return;
981  }
982 
983  if (it->name.find('.', 0) == std::string::npos) {
984  it->name.append(".");
985  it->name.append(vdns_type_.domain_name);
986  query_name_update_ = true;
987  }
988  }
989 }
990 
991 // In case we added domain name to the queries, the response to the VM
992 // should not have the domain name. Update the offsets in the DnsItems
993 // accordingly.
994 void DnsHandler::UpdateOffsets(DnsItem &item, bool name_update_required) {
995  if (!query_name_update_)
996  return;
997 
998  uint16_t msg_offset = (resp_ptr_ - (uint8_t *)dns_) | 0xC000;
999  if (name_update_required) {
1000  name_encoder_.AddName(item.name, msg_offset, item.name_plen,
1001  item.name_offset);
1002  }
1003  msg_offset += BindUtil::DataLength(item.name_plen, item.name_offset,
1004  item.name.size()) + 10;
1005  if (item.type == DNS_TYPE_SOA) {
1006  name_encoder_.AddName(item.soa.primary_ns, msg_offset, item.soa.ns_plen,
1007  item.soa.ns_offset);
1008  msg_offset += BindUtil::DataLength(item.soa.ns_plen, item.soa.ns_offset,
1009  item.soa.primary_ns.size());
1010  name_encoder_.AddName(item.soa.mailbox, msg_offset,
1011  item.soa.mailbox_plen, item.soa.mailbox_offset);
1012  } else {
1013  name_encoder_.AddName(item.data, msg_offset,
1014  item.data_plen, item.data_offset);
1015  }
1016 }
1017 
1019  boost::system::error_code ec;
1020  if ((item.type == DNS_A_RECORD || item.type == DNS_AAAA_RECORD) &&
1021  (item.data == agent()->dns_server(0) ||
1022  item.data == agent()->dns_server(1))) {
1023  item.data = pkt_info_->ip_daddr.to_string(ec);
1024  }
1025 }
1026 
1028  DnsProto::DnsUpdateIpc *update = static_cast<DnsProto::DnsUpdateIpc *>(msg);
1029  bool free_update = true;
1030  DnsProto *dns_proto = agent()->GetDnsProto();
1031  DnsProto::DnsUpdateIpc *update_req = dns_proto->FindUpdateRequest(update);
1032  if (update_req) {
1033  DnsUpdateData *data = update_req->xmpp_data;
1034  for (DnsItems::iterator item = update->xmpp_data->items.begin();
1035  item != update->xmpp_data->items.end();) {
1036  if ((*item).IsDelete()) {
1037  if (!data->DelItem(*item))
1038  update->xmpp_data->items.erase(item++);
1039  else
1040  ++item;
1041  } else {
1042  if (!data->AddItem(*item))
1043  update->xmpp_data->items.erase(item++);
1044  else
1045  ++item;
1046  }
1047  }
1048  if (!data->items.size()) {
1049  dns_proto->DelUpdateRequest(update_req);
1050  delete update_req;
1051  }
1052  if (!update->xmpp_data->items.size())
1053  goto done;
1054  } else {
1055  dns_proto->AddUpdateRequest(update);
1056  free_update = false;
1057  }
1058 
1059  for (int i = 0; i < MAX_XMPP_SERVERS; i++) {
1060  AgentDnsXmppChannel *channel = agent()->dns_xmpp_channel(i);
1061  SendXmppUpdate(channel, update->xmpp_data);
1062  }
1063 
1064 done:
1065  if (free_update)
1066  delete update;
1067 }
1068 
1070  DnsProto::DnsUpdateIpc *update = static_cast<DnsProto::DnsUpdateIpc *>(msg);
1071  DnsProto *dns_proto = agent()->GetDnsProto();
1072  DnsProto::DnsUpdateIpc *update_req = dns_proto->FindUpdateRequest(update);
1073  while (update_req) {
1074  for (DnsItems::iterator item = update_req->xmpp_data->items.begin();
1075  item != update_req->xmpp_data->items.end(); ++item) {
1076  // in case of delete, set the class to NONE and ttl to 0
1077  (*item).eclass = DNS_CLASS_NONE;
1078  (*item).ttl = 0;
1079  }
1080  for (int i = 0; i < MAX_XMPP_SERVERS; i++) {
1081  AgentDnsXmppChannel *channel =
1082  agent()->dns_xmpp_channel(i);
1083  SendXmppUpdate(channel, update_req->xmpp_data);
1084  }
1085  dns_proto->DelUpdateRequest(update_req);
1086  delete update_req;
1087  update_req = dns_proto->FindUpdateRequest(update);
1088  }
1089  delete update;
1090 }
1091 
1093  DnsProto *dns_proto = agent()->GetDnsProto();
1094  switch (dns_->flags.ret) {
1095  case DNS_ERR_NO_ERROR:
1096  dns_proto->IncrStatsRes();
1097  break;
1098 
1099  case DNS_ERR_NO_IMPLEMENT:
1100  dns_proto->IncrStatsUnsupp();
1101  break;
1102 
1103  case DNS_ERR_FORMAT_ERROR:
1104  case DNS_ERR_NO_SUCH_NAME:
1105  case DNS_ERR_SERVER_FAIL:
1106  case DNS_ERR_NOT_AUTH:
1107  default:
1108  dns_proto->IncrStatsFail();
1109  break;
1110  }
1111 }
1112 
1113 bool DnsHandler::TimerExpiry(uint16_t xid) {
1115  NULL, NULL);
1116  return false;
1117 }
1118 
1120  std::string *domain_name) const {
1121  std::vector<autogen::DhcpOptionType> options;
1122  if (vm_itf->GetInterfaceDhcpOptions(&options)) {
1123  if (GetDomainNameFromDhcp(options, domain_name))
1124  return;
1125  }
1126 
1127  if (pkt_info_->ip_saddr.is_v4()) {
1128  if (vm_itf->GetSubnetDhcpOptions(&options, false) ||
1129  vm_itf->GetIpamDhcpOptions(&options, false)) {
1130  GetDomainNameFromDhcp(options, domain_name);
1131  return;
1132  }
1133  }
1134 
1135  if (pkt_info_->ip_saddr.is_v6()) {
1136  if (vm_itf->GetSubnetDhcpOptions(&options, true) ||
1137  vm_itf->GetIpamDhcpOptions(&options, true)) {
1138  GetDomainNameFromDhcp(options, domain_name);
1139  return;
1140  }
1141  }
1142 }
1143 
1145  std::vector<autogen::DhcpOptionType> &options,
1146  std::string *domain_name) const {
1147  for (unsigned int i = 0; i < options.size(); ++i) {
1148  uint32_t option_type;
1149  std::stringstream str(options[i].dhcp_option_name);
1150  str >> option_type;
1151  if (option_type == DHCP_OPTION_DOMAIN_NAME) {
1152  *domain_name = options[i].dhcp_option_value;
1153  return true;
1154  }
1155  }
1156  return false;
1157 }
1158 
1159 // remove domain name suffix from given name, if present
1160 void DnsHandler::GetBaseName(const std::string &name, std::string *base) const {
1161  if (domain_name_.empty())
1162  return;
1163 
1164  std::size_t pos = name.find(domain_name_, 1);
1165  while (pos != std::string::npos) {
1166  std::string base_name = name.substr(0, pos - 1);
1167  if (name == base_name + "." + domain_name_ ||
1168  name == base_name + "." + domain_name_ + ".") {
1169  *base = base_name;
1170  return;
1171  }
1172  pos = name.find(domain_name_, pos + 1);
1173  }
1174 }
1175 
1176 std::string DnsHandler::DnsItemsToString(DnsItems &items) const {
1177  std::string str;
1178  for (DnsItems::const_iterator it = items.begin(); it != items.end(); ++it) {
1179  str.append(it->ToString());
1180  str.append(" ");
1181  }
1182  return str;
1183 }
bool GetIpamDhcpOptions(std::vector< autogen::DhcpOptionType > *options, bool ipv6) const
void UpdateStats()
IpAddress ip_saddr
Definition: pkt_handler.h:394
PacketBuffer * packet_buffer() const
Definition: pkt_handler.h:446
void BuildDefaultDnsResolvers()
Definition: dns_handler.cc:95
Action action_
Definition: dns_handler.h:105
Type type() const
Definition: interface.h:112
bool HandleMessage()
Definition: dns_handler.cc:519
void DelVmRequest(DnsHandler::QueryKey *key)
Definition: dns_proto.cc:734
DnsSOAData soa
Definition: bind_util.h:161
#define DNS_BIND_TRACE(obj, arg)
Definition: bind_util.h:21
DnsItems linklocal_items_
Definition: dns_handler.h:119
void UpdateGWAddress(DnsItem &item)
#define DEFAULT_IP_TTL
Definition: pkt_handler.h:44
void GetDomainName(const VmInterface *vm_itf, std::string *domain_name) const
uint32_t ifindex
Definition: pkt_handler.h:180
static Agent * GetInstance()
Definition: agent.h:436
ResolvList resolv_list_
Definition: dns_handler.h:124
uint8_t curr_index()
Definition: dns_handler.h:97
DnsUpdateData * xmpp_data
Definition: dns_proto.h:77
struct ip * ip
Definition: pkt_handler.h:423
std::string DnsItemsToString(DnsItems &items) const
void GetBaseName(const std::string &name, std::string *base) const
void IncrStatsRes()
Definition: dns_proto.h:217
union PktInfo::@8 transp
#define DNS_A_RECORD
Definition: bind_util.h:36
bool HandleDefaultDnsResponse()
Definition: dns_handler.cc:549
bool HandleRequest()
Definition: dns_handler.cc:127
uint16_t dns_resp_size_
Definition: dns_handler.h:103
bool HandleRetryExpiry()
Definition: dns_handler.cc:687
bool GetSubnetDhcpOptions(std::vector< autogen::DhcpOptionType > *options, bool ipv6) const
int16_t GetDnsQueryServerIndex(uint16_t xid)
Definition: dns_proto.cc:722
uint16_t name_plen
Definition: bind_util.h:154
boost::asio::ip::udp::endpoint ep_
Definition: dns_handler.h:108
static int BuildDnsQuery(uint8_t *buf, uint16_t xid, const std::string &domain, const DnsItems &items)
Definition: bind_util.cc:628
bool is_dns_xmpp_channel(AgentDnsXmppChannel *channel)
Definition: agent.h:850
std::vector< string > & GetDnslist()
Definition: agent.h:700
#define DNS_PTR_RECORD
Definition: bind_util.h:40
void DelDnsQuery(uint16_t xid)
Definition: dns_proto.cc:678
const Interface * vhost_interface() const
Definition: agent.h:935
void DelUpdate(InterTaskMsg *msg)
void BuildDnsResolvers()
Definition: dns_handler.cc:62
static const uint16_t max_dns_xmpp_msg_len
bool GetInterfaceDhcpOptions(std::vector< autogen::DhcpOptionType > *options) const
virtual bool SendMsg(uint8_t *msg, std::size_t len)
uint8_t ra
Definition: bind_util.h:85
std::string new_domain
Definition: dns_proto.h:83
void DelUpdateRequest(DnsUpdateIpc *ipc)
Definition: dns_proto.h:184
#define DEFAULT_IP_ID
Definition: pkt_handler.h:48
std::list< DnsItem > DnsItems
Definition: bind_util.h:193
uint16_t ns_offset
Definition: bind_util.h:116
const VmInterface * itf
Definition: dns_proto.h:78
void DelDnsQueryIndex(uint16_t xid)
Definition: dns_proto.cc:718
#define DNS_ERR_NO_SUCH_NAME
Definition: bind_util.h:51
uint8_t auth
Definition: bind_util.h:78
AgentDBEntry * FindActiveEntry(const DBEntry *key)
Definition: agent_db.cc:110
InterfaceTable * interface_table() const
Definition: agent.h:465
uint16_t ans_rrcount
Definition: bind_util.h:106
struct ether_header * eth
Definition: pkt_handler.h:420
#define DNS_ERR_FORMAT_ERROR
Definition: bind_util.h:49
static const int max_pkt_size
Definition: bind_resolver.h:17
void DelDnsQueryHandler(DnsHandler *handler)
Definition: dns_proto.cc:696
bool NeedRetryForNextServer(uint16_t code)
Definition: dns_handler.cc:656
const MacAddress & mac() const
Definition: interface.h:131
#define DNS_ERR_NOT_AUTH
Definition: bind_util.h:53
void IncrStatsRetransmitReq()
Definition: dns_proto.h:216
uint32_t max_retries() const
Definition: dns_proto.h:212
std::string name
Definition: bind_util.h:158
std::vector< DnsResolverInfo * > dns_resolvers_
Definition: dns_handler.h:112
bool SendDnsQuery(DnsResolverInfo *resolver, uint16_t xid)
Definition: dns_handler.cc:399
uint8_t op
Definition: bind_util.h:79
uint16_t data_offset
Definition: bind_util.h:157
#define DNS_CLASS_IN
Definition: bind_util.h:31
static uint8_t * AddAnswerSection(uint8_t *ptr, const DnsItem &item, uint16_t &length)
Definition: bind_util.cc:271
autogen::VirtualDnsType vdns_type_
Definition: dns_handler.h:117
void SendXmppUpdate(AgentDnsXmppChannel *channel, DnsUpdateData *xmpp_data)
Definition: dns_handler.cc:806
void AddName(std::string &name, uint16_t curr_msg_offset, uint16_t &name_plen, uint16_t &name_offset)
Definition: bind_util.cc:1018
void AddDnsQueryIndex(uint16_t xid, int16_t srv_idx)
Definition: dns_proto.cc:714
void AddUpdateRequest(DnsUpdateIpc *ipc)
Definition: dns_proto.h:183
Agent * agent() const
Definition: proto_handler.h:80
boost::shared_ptr< PktInfo > pkt_info_
Definition: proto_handler.h:92
static const std::string & DnsResponseCode(uint16_t code)
Definition: bind_util.cc:139
bool HandleUpdate()
Definition: dns_handler.cc:726
#define DNS_TYPE_SOA
Definition: bind_util.h:39
OperDB * oper_db() const
Definition: agent.cc:1013
int GetTaskId(const std::string &name)
Definition: task.cc:856
bool FindLinkLocalService(const std::string &service_name, IpAddress *service_ip, uint16_t *service_port, std::string *fabric_hostname, Ip4Address *fabric_ip, uint16_t *fabric_port) const
Get link local service configuration info, for a given service name.
static bool ParseDnsResponse(uint8_t *dns, uint16_t dnslen, uint16_t &xid, dns_flags &flags, DnsItems &ques, DnsItems &ans, DnsItems &auth, DnsItems &add)
Definition: bind_util.cc:476
static void RemoveSpecialChars(std::string &name)
Definition: bind_util.cc:1009
bool DefaultMethodInUse()
Definition: dns_handler.h:96
AgentDnsXmppChannel * dns_xmpp_channel(uint8_t idx) const
Definition: agent.h:844
DnsHandler(Agent *agent, boost::shared_ptr< PktInfo > info, boost::asio::io_context &io)
Definition: dns_handler.cc:20
autogen::IpamType ipam_type_
Definition: dns_handler.h:116
std::string new_vdns
Definition: dns_proto.h:81
bool IsDnsQueryInProgress(uint16_t xid)
Definition: dns_proto.cc:682
uint16_t GetTransId()
Definition: dns_proto.cc:637
int EthHdr(const MacAddress &src, const MacAddress &dest, const uint16_t proto)
std::string virtual_dns
Definition: bind_util.h:206
bool IsDnsHandlerInUse(DnsHandler *handler)
Definition: dns_proto.cc:686
GlobalVrouter * global_vrouter() const
Definition: operdb_init.h:54
static bool ParseDnsUpdate(uint8_t *dns, uint16_t dnslen, DnsUpdateData &data)
Definition: bind_util.cc:546
uint8_t req
Definition: bind_util.h:80
std::set< DnsUpdateIpc *, UpdateCompare > DnsUpdateSet
Definition: dns_proto.h:142
void SendDnsIpc(uint8_t *pkt, std::size_t length)
Definition: dns_proto.cc:641
Definition: agent.h:358
uint32_t GetInterfaceIndex() const
Definition: proto_handler.h:82
static bool ParseDnsQuery(uint8_t *dns, uint16_t dnslen, uint16_t *parsed_length, DnsItems &items)
Definition: bind_util.cc:445
std::string domain_name_
Definition: dns_handler.h:115
static TaskScheduler * GetInstance()
Definition: task.cc:547
static Options options
struct udphdr * udp
Definition: pkt_handler.h:427
uint32_t timeout() const
Definition: dns_proto.h:210
void UpdateOffsets(DnsItem &item, bool name_update_required)
Definition: dns_handler.cc:994
boost::asio::ip::address_v6 Ip6Address
Definition: address.h:15
uint16_t xid_
Definition: dns_handler.h:104
void Send(uint32_t itf, uint32_t vrf, uint16_t, PktHandler::PktModuleName)
void IncrStatsUnsupp()
Definition: dns_proto.h:218
uint16_t buffer_len() const
Definition: packet_buffer.h:27
bool layer3_forwarding() const
void AddDnsQuery(uint16_t xid, DnsHandler *handler)
Definition: dns_proto.cc:674
void SendDnsResponse()
Definition: dns_handler.cc:890
static BindResolver * Resolver()
Definition: bind_resolver.h:43
dns_flags flags
Definition: bind_util.h:104
void DefaultDnsSendResponse()
Definition: dns_handler.cc:280
static uint16_t DataLength(uint16_t plen, uint16_t offset, uint16_t size)
Definition: bind_util.h:320
DnsHandler * GetDnsQueryHandler(uint16_t xid)
Definition: dns_proto.cc:707
std::string data
Definition: bind_util.h:160
uint16_t add_rrcount
Definition: bind_util.h:108
#define DNS_ERR_NO_ERROR
Definition: bind_util.h:48
DnsNameEncoder name_encoder_
Definition: dns_handler.h:120
const VnEntry * vn() const
uint16_t auth_rrcount
Definition: bind_util.h:107
tbb::mutex mutex_
Definition: dns_handler.h:125
#define DNS_CLASS_NONE
Definition: bind_util.h:33
bool AddItem(DnsItem &item, bool replace=false) const
Definition: bind_util.h:224
uint8_t cd
Definition: bind_util.h:82
bool HandleUpdateResponse()
Definition: dns_handler.cc:719
bool ResolveLinkLocalRequest(DnsItems::iterator &item, DnsItems *linklocal_items) const
Definition: dns_handler.cc:444
uint32_t vrf
Definition: pkt_handler.h:391
static Timer * CreateTimer(boost::asio::io_context &service, const std::string &name, int task_id=Timer::GetTimerTaskId(), int task_instance=Timer::GetTimerInstanceId(), bool delete_on_completion=false)
Definition: timer.cc:201
void Update(InterTaskMsg *msg)
bool query_name_update_
Definition: dns_handler.h:121
void Ip6Hdr(ip6_hdr *ip, uint16_t plen, uint8_t next_header, uint8_t hlim, uint8_t *src, uint8_t *dest)
uint8_t * resp_ptr_
Definition: dns_handler.h:102
Agent * agent_
Definition: proto_handler.h:91
void AddVmRequest(DnsHandler::QueryKey *key)
Definition: dns_proto.cc:730
bool Cancel()
Definition: timer.cc:150
uint8_t curr_index_
Definition: dns_handler.h:127
DefaultServerList GetDefaultServerList()
Definition: dns_proto.cc:118
#define MAX_XMPP_SERVERS
Definition: agent.h:291
#define DNS_SERVER_PORT
Definition: bind_util.h:28
bool ResolveAllLinkLocalRequests()
Definition: dns_handler.cc:497
std::vector< DnsResolverInfo * > def_dns_resolvers_
Definition: dns_handler.h:113
bool HandleModifyVdns()
Definition: dns_handler.cc:737
const DnsUpdateSet & update_set() const
Definition: dns_proto.h:182
const Ip4Address & primary_ip_addr() const
void IncrCurrIndex()
Definition: dns_handler.h:99
#define DNS_AAAA_RECORD
Definition: bind_util.h:43
static std::size_t DnsAgentXmppEncode(XmppChannel *channel, XmppType type, uint32_t trans_id, uint32_t resp_code, DnsUpdateData *xmpp_data, uint8_t *data)
virtual ~DnsHandler()
Definition: dns_handler.cc:29
bool Run()
Definition: dns_handler.cc:117
const AgentHdr & GetAgentHdr() const
IpAddress AddressFromString(const std::string &ip_address_str, boost::system::error_code *ec)
#define DNS_ERR_NO_IMPLEMENT
Definition: bind_util.h:52
const std::string & vm_name() const
bool GetDomainNameFromDhcp(std::vector< autogen::DhcpOptionType > &options, std::string *domain_name) const
static bool GetAddrFromPtrName(std::string &ptr_name, IpAddress &mask)
Definition: bind_util.cc:933
bool DelItem(DnsItem &item) const
Definition: bind_util.h:236
void IncrStatsFail()
Definition: dns_proto.h:219
void UdpHdr(uint16_t len, in_addr_t src, uint16_t src_port, in_addr_t dest, uint16_t dest_port)
uint16_t mailbox_plen
Definition: bind_util.h:117
DnsProto * GetDnsProto() const
Definition: agent.h:987
void Resolve(dns_flags flags, const DnsItems &ques, DnsItems &ans, DnsItems &auth, DnsItems &add)
Definition: dns_handler.cc:844
void IncrStatsReq()
Definition: dns_proto.h:215
const Ip6Address & primary_ip6_addr() const
bool UpdateAll()
Definition: dns_handler.cc:792
bool Start(int time, Handler handler, ErrorHandler error_handler=NULL)
Definition: timer.cc:108
bool SendToDefaultServer()
Definition: dns_handler.cc:668
bool HandleVirtualDnsRequest(const VmInterface *vmitf)
Definition: dns_handler.cc:296
static const uint32_t max_items_per_xmpp_msg
Definition: dns_handler.h:26
static void BuildDnsHeader(dnshdr *dns, uint16_t xid, DnsReq req, DnsOpcode op, bool rd, bool ra, uint8_t ret, uint16_t ques_count)
Definition: bind_util.cc:608
uint16_t data_plen
Definition: bind_util.h:156
std::string primary_ns
Definition: bind_util.h:113
const Interface * FindInterface(size_t index) const
Definition: interface.cc:323
std::string mailbox
Definition: bind_util.h:114
dnshdr * dns_
Definition: dns_handler.h:101
uint8_t ad
Definition: bind_util.h:83
AgentDnsXmppChannel * channel
Definition: dns_proto.h:103
uint8_t last_index()
Definition: dns_handler.h:98
QueryKey * rkey_
Definition: dns_handler.h:106
const std::string & name() const
Definition: interface.h:114
bool HandleDefaultDnsRequest(const VmInterface *vmitf)
Definition: dns_handler.cc:213
#define DNS_ERR_SERVER_FAIL
Definition: bind_util.h:50
DnsItems items_
Definition: dns_handler.h:118
IpAddress ip_daddr
Definition: pkt_handler.h:395
uint16_t xid
Definition: bind_util.h:103
void UpdateQueryNames()
Definition: dns_handler.cc:971
#define DHCP_OPTION_DOMAIN_NAME
Definition: dhcp_handler.h:31
uint16_t mailbox_offset
Definition: bind_util.h:118
uint16_t xid
Definition: dns_proto.h:50
uint8_t ret
Definition: bind_util.h:81
std::string old_vdns
Definition: dns_proto.h:82
XmppChannel * GetXmppChannel()
bool default_method_
Definition: dns_handler.h:126
uint8_t * resp
Definition: dns_proto.h:48
bool TimerExpiry(uint16_t xid)
DnsItems items
Definition: bind_util.h:208
uint16_t ques_rrcount
Definition: bind_util.h:105
uint16_t name_offset
Definition: bind_util.h:155
DnsHandler * handler
Definition: dns_proto.h:51
uint16_t ns_plen
Definition: bind_util.h:115
void IncrStatsDrop()
Definition: dns_proto.h:220
DnsUpdateIpc * FindUpdateRequest(DnsUpdateIpc *ipc)
Definition: dns_proto.h:185
bool HandleBindResponse()
Definition: dns_handler.cc:556
void IpHdr(uint16_t len, in_addr_t src, in_addr_t dest, uint8_t protocol, uint16_t id, uint8_t ttl)
std::size_t length
Definition: dns_proto.h:49
static bool DeleteTimer(Timer *Timer)
Definition: timer.cc:222
bool GetIpamData(const IpAddress &vm_addr, std::string *ipam_name, autogen::IpamType *ipam_type) const
Definition: vn.cc:641
bool IsVmRequestDuplicate(DnsHandler::QueryKey *key)
Definition: dns_proto.cc:738
#define DNS_NS_RECORD
Definition: bind_util.h:37
uint16_t type
Definition: bind_util.h:150
void HandleInvalidBindResponse(DnsHandler *handler, dns_flags flags, const DnsItems &ques, DnsItems &ans, DnsItems &auth, DnsItems &add, uint16_t xid)
Definition: dns_handler.cc:637
std::string ipam_name_
Definition: dns_handler.h:114