OpenSDN source code
xmpp_dns_agent.cc
Go to the documentation of this file.
1 /*
2  * Copyright (c) 2013 Juniper Networks, Inc. All rights reserved.
3  */
4 
5 #include "base/util.h"
6 #include "base/logging.h"
7 #include "xmpp/xmpp_init.h"
8 #include <pugixml/pugixml.hpp>
9 #include "xml/xml_pugi.h"
10 #include "bind/bind_util.h"
11 #include "bind/xmpp_dns_agent.h"
12 
14 
15 std::size_t
17  XmppType type,
18  uint32_t trans_id,
19  uint32_t response_code,
20  DnsUpdateData *xmpp_data,
21  uint8_t *data) {
22  if (!channel)
23  return 0;
24 
25  std::unique_ptr<XmlBase> impl(XmppStanza::AllocXmppXmlImpl());
26  XmlPugi *pugi = reinterpret_cast<XmlPugi *>(impl.get());
27  std::string iq_type =
28  (type == DnsQuery) ? "get" :
29  (type == Update) ? "set" : "result";
30 
31  pugi->AddNode("iq", "");
32  pugi->AddAttribute("type", iq_type);
33  pugi->AddAttribute("from", channel->FromString());
34  std::string to(channel->ToString());
35  to += "/";
36  to += XmppInit::kDnsPeer;
37  pugi->AddAttribute("to", to);
38  std::stringstream id;
39  id << trans_id;
40  pugi->AddAttribute("id", id.str());
41 
42  pugi->AddChildNode("dns", "");
43  pugi->AddAttribute("transid", id.str());
44 
45  std::stringstream code;
46  code << response_code;
47  pugi::xml_node node;
48  switch (type) {
49  case Update:
50  pugi->AddChildNode("update", "");
51  node = pugi->FindNode("update");
52  break;
53 
54  case UpdateResponse:
55  pugi->AddChildNode("response", "");
56  pugi->AddAttribute("code", code.str());
57  pugi->AddChildNode("update", "");
58  node = pugi->FindNode("update");
59  break;
60 
61  case DnsQuery:
62  pugi->AddChildNode("query", "");
63  node = pugi->FindNode("query");
64  break;
65 
66  case DnsQueryResponse:
67  pugi->AddChildNode("response", "");
68  pugi->AddAttribute("code", code.str());
69  pugi->AddChildNode("query", "");
70  node = pugi->FindNode("query");
71  break;
72 
73  default:
74  assert(0);
75  }
76 
77  EncodeDnsData(&node, xmpp_data);
78  return XmppProto::EncodeMessage(impl.get(), data, sizeof(data));
79 }
80 
81 void
82 DnsAgentXmpp::EncodeDnsData(pugi::xml_node *node, DnsUpdateData *xmpp_data) {
83  pugi::xml_node node_c;
84 
85  node_c = node->append_child("virtual-dns");
86  node_c.text().set(xmpp_data->virtual_dns.c_str());
87 
88  node_c = node->append_child("zone");
89  node_c.text().set(xmpp_data->zone.c_str());
90 
91  for (DnsItems::iterator item = xmpp_data->items.begin();
92  item != xmpp_data->items.end(); ++item) {
93  node_c = node->append_child("entry");
94  EncodeDnsItem(&node_c, *item);
95  }
96 }
97 
98 void
99 DnsAgentXmpp::EncodeDnsItem(pugi::xml_node *node, DnsItem &item) {
100  pugi::xml_node node_c;
101 
102  node_c = node->append_child("class");
103  node_c.text().set(item.eclass);
104 
105  node_c = node->append_child("type");
106  node_c.text().set(item.type);
107 
108  node_c = node->append_child("name");
109  node_c.text().set(item.name.c_str());
110 
111  if (item.data != "") {
112  node_c = node->append_child("data");
113  node_c.text().set(item.data.c_str());
114  }
115 
116  if (item.ttl != (uint32_t) -1) {
117  node_c = node->append_child("ttl");
118  node_c.text().set(item.ttl);
119  }
120 
121  if (item.priority != (uint16_t) -1) {
122  node_c = node->append_child("priority");
123  node_c.text().set(item.priority);
124  }
125 
126  if (!item.vm_uuid.empty()) {
127  node_c = node->append_child("vm-uuid");
128  node_c.text().set(item.vm_uuid.c_str());
129  }
130 }
131 
132 bool
133 DnsAgentXmpp::DnsAgentXmppDecode(const pugi::xml_node dns,
134  XmppType &type, uint32_t &xid,
135  uint16_t &resp_code, DnsUpdateData *data, std::string source_name) {
136  std::stringstream id(dns.attribute("transid").value());
137  id >> xid;
138 
139  pugi::xml_node resp = dns.first_child();
140  if (strcmp(resp.name(), "response") == 0) {
141  std::stringstream code(resp.attribute("code").value());
142  code >> resp_code;
143  return DecodeDns(resp.first_child(), type, true, data, source_name);
144  } else
145  return DecodeDns(resp, type, false, data, source_name);
146 }
147 
148 bool
149 DnsAgentXmpp::DecodeDns(const pugi::xml_node node,
150  XmppType &type,
151  bool is_resp,
152  DnsUpdateData *data, std::string source_name) {
153  if (strcmp(node.name(), "update") == 0) {
154  type = is_resp ? UpdateResponse : Update;
155  return DecodeDnsItems(node, data, source_name);
156  } else if (strcmp(node.name(), "query") == 0) {
157  type = is_resp ? DnsQueryResponse : DnsQuery;
158  return DecodeDnsItems(node, data, source_name);
159  }
160 
161  DNS_XMPP_TRACE(DnsXmppTrace, "Dns XMPP response : unknown tag : " <<
162  node.name());
163  return false;
164 }
165 
166 bool
167 DnsAgentXmpp::DecodeDnsItems(const pugi::xml_node dnsdata,
168  DnsUpdateData *data, std::string source_name) {
169  for (pugi::xml_node node = dnsdata.first_child(); node;
170  node = node.next_sibling()) {
171  if (strcmp(node.name(), "virtual-dns") == 0) {
172  data->virtual_dns = node.child_value();
173  } else if (strcmp(node.name(), "zone") == 0) {
174  data->zone = node.child_value();
175  } else if (strcmp(node.name(), "entry") == 0) {
176  DnsItem item;
177  for (pugi::xml_node entry = node.first_child(); entry;
178  entry = entry.next_sibling()) {
179  if (strcmp(entry.name(), "class") == 0) {
180  std::stringstream cl(entry.child_value());
181  cl >> item.eclass;
182  } else if (strcmp(entry.name(), "type") == 0) {
183  std::stringstream type(entry.child_value());
184  type >> item.type;
185  } else if (strcmp(entry.name(), "name") == 0) {
186  item.name = entry.child_value();
187  } else if (strcmp(entry.name(), "data") == 0) {
188  item.data = entry.child_value();
189  } else if (strcmp(entry.name(), "ttl") == 0) {
190  std::stringstream ttl(entry.child_value());
191  ttl >> item.ttl;
192  } else if (strcmp(entry.name(), "priority") == 0) {
193  std::stringstream prio(entry.child_value());
194  prio >> item.priority;
195  } else if (strcmp(entry.name(), "vm-uuid") == 0) {
196  item.vm_uuid = entry.child_value();
197  } else {
198  DNS_XMPP_TRACE(DnsXmppTrace,
199  "Dns XMPP response : unknown tag : " <<
200  node.name());
201  return false;
202  }
203  }
204  item.source_name = source_name;
205  data->items.push_back(item);
206  } else {
207  DNS_XMPP_TRACE(DnsXmppTrace, "Dns XMPP response : unknown tag : " <<
208  node.name());
209  return false;
210  }
211  }
212 
213  return true;
214 }
static bool DnsAgentXmppDecode(const pugi::xml_node dns, XmppType &type, uint32_t &xid, uint16_t &resp_code, DnsUpdateData *data, std::string source_name="")
static void EncodeDnsItem(pugi::xml_node *node, DnsItem &entry)
static void EncodeDnsData(pugi::xml_node *node, DnsUpdateData *xmpp_data)
static std::size_t DnsAgentXmppEncode(XmppChannel *channel, XmppType type, uint32_t trans_id, uint32_t resp_code, DnsUpdateData *xmpp_data, uint8_t *data)
static bool DecodeDns(const pugi::xml_node node, XmppType &type, bool is_resp, DnsUpdateData *data, std::string source_name)
static bool DecodeDnsItems(const pugi::xml_node dnsdata, DnsUpdateData *data, std::string source_name)
virtual const std::string & ToString() const =0
virtual const std::string & FromString() const =0
static const char * kDnsPeer
Definition: xmpp_init.h:25
static int EncodeMessage(const XmppChatMessage *, uint8_t *data, size_t size)
static XmlBase * AllocXmppXmlImpl(const char *doc=NULL)
Definition: xmpp_proto.h:167
uint8_t type
Definition: load_balance.h:2
boost::shared_ptr< TraceBuffer< SandeshTrace > > SandeshTraceBufferPtr
Definition: sandesh_trace.h:18
SandeshTraceBufferPtr SandeshTraceBufferCreate(const std::string &buf_name, size_t buf_size, bool trace_enable=true)
Definition: sandesh_trace.h:46
std::string source_name
Definition: bind_util.h:159
uint16_t priority
Definition: bind_util.h:152
std::string name
Definition: bind_util.h:158
uint16_t eclass
Definition: bind_util.h:149
std::string vm_uuid
Definition: bind_util.h:160
uint16_t type
Definition: bind_util.h:150
uint32_t ttl
Definition: bind_util.h:151
std::string data
Definition: bind_util.h:161
DnsItems items
Definition: bind_util.h:216
std::string virtual_dns
Definition: bind_util.h:214
std::string zone
Definition: bind_util.h:215
SandeshTraceBufferPtr AgentXmppTraceBuf(SandeshTraceBufferCreate("Xmpp", 500))
#define DNS_XMPP_TRACE(obj, arg)
Definition: xmpp_dns_agent.h:9