OpenSDN source code
 All Classes Namespaces Files Functions Variables Typedefs Enumerations Enumerator Friends Macros Pages
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 
127 bool
128 DnsAgentXmpp::DnsAgentXmppDecode(const pugi::xml_node dns,
129  XmppType &type, uint32_t &xid,
130  uint16_t &resp_code, DnsUpdateData *data, std::string source_name) {
131  std::stringstream id(dns.attribute("transid").value());
132  id >> xid;
133 
134  pugi::xml_node resp = dns.first_child();
135  if (strcmp(resp.name(), "response") == 0) {
136  std::stringstream code(resp.attribute("code").value());
137  code >> resp_code;
138  return DecodeDns(resp.first_child(), type, true, data, source_name);
139  } else
140  return DecodeDns(resp, type, false, data, source_name);
141 }
142 
143 bool
144 DnsAgentXmpp::DecodeDns(const pugi::xml_node node,
145  XmppType &type,
146  bool is_resp,
147  DnsUpdateData *data, std::string source_name) {
148  if (strcmp(node.name(), "update") == 0) {
149  type = is_resp ? UpdateResponse : Update;
150  return DecodeDnsItems(node, data, source_name);
151  } else if (strcmp(node.name(), "query") == 0) {
152  type = is_resp ? DnsQueryResponse : DnsQuery;
153  return DecodeDnsItems(node, data, source_name);
154  }
155 
156  DNS_XMPP_TRACE(DnsXmppTrace, "Dns XMPP response : unknown tag : " <<
157  node.name());
158  return false;
159 }
160 
161 bool
162 DnsAgentXmpp::DecodeDnsItems(const pugi::xml_node dnsdata,
163  DnsUpdateData *data, std::string source_name) {
164  for (pugi::xml_node node = dnsdata.first_child(); node;
165  node = node.next_sibling()) {
166  if (strcmp(node.name(), "virtual-dns") == 0) {
167  data->virtual_dns = node.child_value();
168  } else if (strcmp(node.name(), "zone") == 0) {
169  data->zone = node.child_value();
170  } else if (strcmp(node.name(), "entry") == 0) {
171  DnsItem item;
172  for (pugi::xml_node entry = node.first_child(); entry;
173  entry = entry.next_sibling()) {
174  if (strcmp(entry.name(), "class") == 0) {
175  std::stringstream cl(entry.child_value());
176  cl >> item.eclass;
177  } else if (strcmp(entry.name(), "type") == 0) {
178  std::stringstream type(entry.child_value());
179  type >> item.type;
180  } else if (strcmp(entry.name(), "name") == 0) {
181  item.name = entry.child_value();
182  } else if (strcmp(entry.name(), "data") == 0) {
183  item.data = entry.child_value();
184  } else if (strcmp(entry.name(), "ttl") == 0) {
185  std::stringstream ttl(entry.child_value());
186  ttl >> item.ttl;
187  } else if (strcmp(entry.name(), "priority") == 0) {
188  std::stringstream prio(entry.child_value());
189  prio >> item.priority;
190  } else {
191  DNS_XMPP_TRACE(DnsXmppTrace,
192  "Dns XMPP response : unknown tag : " <<
193  node.name());
194  return false;
195  }
196  }
197  item.source_name = source_name;
198  data->items.push_back(item);
199  } else {
200  DNS_XMPP_TRACE(DnsXmppTrace, "Dns XMPP response : unknown tag : " <<
201  node.name());
202  return false;
203  }
204  }
205 
206  return true;
207 }
pugi::xml_node FindNode(const std::string &name)
Definition: xml_pugi.cc:51
static bool DecodeDns(const pugi::xml_node node, XmppType &type, bool is_resp, DnsUpdateData *data, std::string source_name)
static void EncodeDnsItem(pugi::xml_node *node, DnsItem &entry)
std::string zone
Definition: bind_util.h:207
static XmlBase * AllocXmppXmlImpl(const char *doc=NULL)
Definition: xmpp_proto.h:167
uint16_t priority
Definition: bind_util.h:152
std::string name
Definition: bind_util.h:158
boost::shared_ptr< TraceBuffer< SandeshTrace > > SandeshTraceBufferPtr
Definition: sandesh_trace.h:18
static int EncodeMessage(const XmppChatMessage *, uint8_t *data, size_t size)
virtual int AddAttribute(const std::string &key, const std::string &value)
Definition: xml_pugi.cc:282
virtual int AddChildNode(const std::string &key, const std::string &value)
Definition: xml_pugi.cc:250
std::string virtual_dns
Definition: bind_util.h:206
uint8_t type
Definition: load_balance.h:109
uint16_t eclass
Definition: bind_util.h:149
static bool DecodeDnsItems(const pugi::xml_node dnsdata, DnsUpdateData *data, std::string source_name)
std::string source_name
Definition: bind_util.h:159
static const char * kDnsPeer
Definition: xmpp_init.h:25
std::string data
Definition: bind_util.h:160
virtual const std::string & ToString() const =0
virtual const std::string & FromString() const =0
virtual int AddNode(const std::string &key, const std::string &value)
Definition: xml_pugi.cc:212
#define DNS_XMPP_TRACE(obj, arg)
Definition: xmpp_dns_agent.h:9
static std::size_t DnsAgentXmppEncode(XmppChannel *channel, XmppType type, uint32_t trans_id, uint32_t resp_code, DnsUpdateData *xmpp_data, uint8_t *data)
SandeshTraceBufferPtr AgentXmppTraceBuf
static bool DnsAgentXmppDecode(const pugi::xml_node dns, XmppType &type, uint32_t &xid, uint16_t &resp_code, DnsUpdateData *data, std::string source_name="")
uint32_t ttl
Definition: bind_util.h:151
static void EncodeDnsData(pugi::xml_node *node, DnsUpdateData *xmpp_data)
DnsItems items
Definition: bind_util.h:208
SandeshTraceBufferPtr SandeshTraceBufferCreate(const std::string &buf_name, size_t buf_size, bool trace_enable=true)
Definition: sandesh_trace.h:46
uint16_t type
Definition: bind_util.h:150