Line data Source code
1 : /*
2 : * Copyright (c) 2013 Juniper Networks, Inc. All rights reserved.
3 : * Copyright Contributors to the OpenSDN project
4 : */
5 :
6 : #ifndef vnsw_agent_dns_proto_hpp
7 : #define vnsw_agent_dns_proto_hpp
8 :
9 : #include "pkt/proto.h"
10 : #include "services/dns_handler.h"
11 : #include "vnc_cfg_types.h"
12 :
13 : class VmInterface;
14 : class IFMapNode;
15 :
16 : class DnsProto : public Proto {
17 :
18 : static const Ip4Address ip4_unspec_;
19 : static const Ip6Address ip6_unspec_;
20 :
21 : public:
22 : static const uint32_t kDnsDefaultTtl = 84600;
23 : static const uint32_t kDnsDefaultSlistInterval =
24 : 10 * 60 * 1000; //10 minutes
25 :
26 : enum InterTaskMessage {
27 : DNS_NONE,
28 : DNS_DEFAULT_RESPONSE,
29 : DNS_BIND_RESPONSE,
30 : DNS_TIMER_EXPIRED,
31 : DNS_XMPP_SEND_UPDATE,
32 : DNS_XMPP_SEND_UPDATE_ALL,
33 : DNS_XMPP_UPDATE_RESPONSE,
34 : DNS_XMPP_MODIFY_VDNS,
35 : };
36 :
37 : struct DnsIpc : InterTaskMsg {
38 0 : DnsIpc(uint8_t *msg, std::size_t len, uint16_t id,
39 : DnsHandler *h, InterTaskMessage cmd)
40 0 : : InterTaskMsg(cmd), resp(msg), length(len), xid(id), handler(h) {}
41 :
42 0 : virtual ~DnsIpc() {
43 0 : if (resp)
44 0 : delete [] resp;
45 0 : if (handler)
46 0 : delete handler;
47 0 : }
48 :
49 : uint8_t *resp;
50 : std::size_t length;
51 : uint16_t xid;
52 : DnsHandler *handler;
53 : };
54 :
55 : struct DnsUpdateIpc : InterTaskMsg {
56 0 : DnsUpdateIpc(const VmInterface *vm, const std::string &nvdns,
57 : const std::string &ovdns, const std::string &dom,
58 : uint32_t ttl_value, bool is_floating)
59 0 : : InterTaskMsg(DNS_XMPP_MODIFY_VDNS), xmpp_data(NULL),
60 0 : itf(vm), floatingIp(is_floating), ttl(ttl_value),
61 0 : new_vdns(nvdns), old_vdns(ovdns), new_domain(dom) {}
62 :
63 338 : DnsUpdateIpc(DnsAgentXmpp::XmppType type, DnsUpdateData *data,
64 : const VmInterface *vm, bool floating)
65 676 : : InterTaskMsg(DNS_NONE), xmpp_data(data), itf(vm),
66 338 : floatingIp(floating), ttl(0) {
67 338 : if (type == DnsAgentXmpp::Update)
68 338 : cmd = DNS_XMPP_SEND_UPDATE;
69 0 : else if (type == DnsAgentXmpp::UpdateResponse)
70 0 : cmd = DNS_XMPP_UPDATE_RESPONSE;
71 338 : }
72 :
73 676 : virtual ~DnsUpdateIpc() {
74 338 : if (xmpp_data)
75 0 : delete xmpp_data;
76 676 : }
77 :
78 : DnsUpdateData *xmpp_data;
79 : const VmInterface *itf;
80 : bool floatingIp;
81 : uint32_t ttl;
82 : std::string new_vdns;
83 : std::string old_vdns;
84 : std::string new_domain;
85 : };
86 :
87 : struct UpdateCompare {
88 0 : bool operator() (DnsUpdateIpc *const &lhs, DnsUpdateIpc *const &rhs) const {
89 0 : if (!lhs || !rhs)
90 0 : return lhs < rhs;
91 0 : if (lhs->itf != rhs->itf)
92 0 : return lhs->itf < rhs->itf;
93 0 : if (lhs->floatingIp != rhs->floatingIp)
94 0 : return lhs->floatingIp < rhs->floatingIp;
95 : DnsUpdateData::Compare tmp;
96 0 : return tmp(lhs->xmpp_data, rhs->xmpp_data);
97 : }
98 : };
99 :
100 : struct DnsUpdateAllIpc : InterTaskMsg {
101 0 : DnsUpdateAllIpc(AgentDnsXmppChannel *ch)
102 0 : : InterTaskMsg(DNS_XMPP_SEND_UPDATE_ALL), channel(ch) {}
103 :
104 : AgentDnsXmppChannel *channel;
105 : };
106 :
107 : struct DnsStats {
108 17 : DnsStats() { Reset(); }
109 42 : void Reset() {
110 42 : requests = resolved = retransmit_reqs = unsupported = fail = drop = 0;
111 42 : }
112 :
113 : uint32_t requests;
114 : uint32_t resolved;
115 : uint32_t retransmit_reqs;
116 : uint32_t unsupported;
117 : uint32_t fail;
118 : uint32_t drop;
119 : };
120 :
121 : struct DnsFipEntry {
122 : DnsFipEntry(const VnEntry *vn, const IpAddress &fip,
123 : const VmInterface *itf);
124 : virtual ~DnsFipEntry();
125 : bool IsLess(const DnsFipEntry *rhs) const;
126 : const VnEntry *vn_;
127 : IpAddress floating_ip_;
128 : const VmInterface *interface_;
129 : std::string vdns_name_;
130 : std::string fip_name_;
131 : };
132 :
133 : typedef boost::shared_ptr<DnsFipEntry> DnsFipEntryPtr;
134 :
135 : class DnsFipEntryCmp {
136 : public:
137 : bool operator()(const DnsFipEntryPtr &lhs, const DnsFipEntryPtr &rhs) const;
138 : };
139 : typedef std::set<DnsFipEntryPtr, DnsFipEntryCmp> DnsFipSet;
140 : typedef std::map<uint32_t, DnsHandler *> DnsBindQueryMap;
141 : typedef std::pair<uint32_t, DnsHandler *> DnsBindQueryPair;
142 : typedef std::set<DnsHandler::QueryKey> DnsVmRequestSet;
143 : typedef std::set<DnsUpdateIpc *, UpdateCompare> DnsUpdateSet;
144 : typedef std::map<uint32_t, std::string> IpVdnsMap;
145 : typedef std::pair<uint32_t, std::string> IpVdnsPair;
146 : typedef std::map<const VmInterface *, IpVdnsMap> VmDataMap;
147 : typedef std::pair<const VmInterface *, IpVdnsMap> VmDataPair;
148 : // Map of transaction id and BindServer Index
149 : typedef std::map<uint32_t, int16_t> DnsBindQueryIndexMap;
150 : typedef std::pair<uint32_t, int16_t> DnsBindQueryIndexPair;
151 : typedef std::vector<IpAddress> DefaultServerList;
152 :
153 : void ConfigInit();
154 : void Shutdown();
155 : void IoShutdown();
156 : DnsProto(Agent *agent, boost::asio::io_context &io);
157 : virtual ~DnsProto();
158 : ProtoHandler *AllocProtoHandler(boost::shared_ptr<PktInfo> info,
159 : boost::asio::io_context &io);
160 : bool SendUpdateDnsEntry(const VmInterface *vmitf, const std::string &name,
161 : const Ip4Address &ip, uint32_t plen,
162 : const Ip6Address &ip6, uint32_t plen6,
163 : const std::string &vdns_name,
164 : const autogen::VirtualDnsType &vdns_type,
165 : bool is_floating, bool is_delete);
166 : bool UpdateFloatingIp(const VmInterface *vmitf, const VnEntry *vn,
167 : const IpAddress &ip, bool is_deleted);
168 : void IpamNotify(IFMapNode *node);
169 : void VdnsNotify(IFMapNode *node);
170 : uint16_t GetTransId();
171 :
172 : void SendDnsIpc(uint8_t *pkt, std::size_t length);
173 : void SendDnsIpc(InterTaskMessage cmd, uint16_t xid,
174 : uint8_t *msg, DnsHandler *handler);
175 : void SendDnsUpdateIpc(DnsUpdateData *data, DnsAgentXmpp::XmppType type,
176 : const VmInterface *vm, bool floating);
177 : void SendDnsUpdateIpc(const VmInterface *vm, const std::string &new_vdns,
178 : const std::string &old_vdns,
179 : const std::string &new_dom,
180 : uint32_t ttl, bool is_floating);
181 : void SendDnsUpdateIpc(AgentDnsXmppChannel *channel);
182 :
183 0 : const DnsUpdateSet &update_set() const { return update_set_; }
184 0 : void AddUpdateRequest(DnsUpdateIpc *ipc) { update_set_.insert(ipc); }
185 0 : void DelUpdateRequest(DnsUpdateIpc *ipc) { update_set_.erase(ipc); }
186 338 : DnsUpdateIpc *FindUpdateRequest(DnsUpdateIpc *ipc) {
187 338 : DnsUpdateSet::iterator it = update_set_.find(ipc);
188 338 : if (it != update_set_.end())
189 0 : return *it;
190 338 : return NULL;
191 : }
192 :
193 : void AddDnsQuery(uint16_t xid, DnsHandler *handler);
194 : void DelDnsQuery(uint16_t xid);
195 : void DelDnsQueryHandler(DnsHandler *handler);
196 : bool IsDnsQueryInProgress(uint16_t xid);
197 : bool IsDnsHandlerInUse(DnsHandler *handler);
198 : DnsHandler *GetDnsQueryHandler(uint16_t xid);
199 : bool BuildDefaultServerList();
200 : DefaultServerList BuildDefaultServerListImpl();
201 : DefaultServerList GetDefaultServerList();
202 :
203 : void AddDnsQueryIndex(uint16_t xid, int16_t srv_idx);
204 : void DelDnsQueryIndex(uint16_t xid);
205 : int16_t GetDnsQueryServerIndex(uint16_t xid);
206 :
207 : void AddVmRequest(DnsHandler::QueryKey *key);
208 : void DelVmRequest(DnsHandler::QueryKey *key);
209 : bool IsVmRequestDuplicate(DnsHandler::QueryKey *key);
210 :
211 0 : uint32_t timeout() const { return timeout_; }
212 6 : void set_timeout(uint32_t timeout) { timeout_ = timeout; }
213 0 : uint32_t max_retries() const { return max_retries_; }
214 6 : void set_max_retries(uint32_t retries) { max_retries_ = retries; }
215 :
216 0 : void IncrStatsReq() { stats_.requests++; }
217 0 : void IncrStatsRetransmitReq() { stats_.retransmit_reqs++; }
218 0 : void IncrStatsRes() { stats_.resolved++; }
219 0 : void IncrStatsUnsupp() { stats_.unsupported++; }
220 0 : void IncrStatsFail() { stats_.fail++; }
221 0 : void IncrStatsDrop() { stats_.drop++; }
222 61 : const DnsStats &GetStats() const { return stats_; }
223 25 : void ClearStats() { stats_.Reset(); }
224 0 : const VmDataMap& all_vms() const { return all_vms_; }
225 16 : const DnsFipSet& fip_list() const { return fip_list_; }
226 :
227 : private:
228 : void InterfaceNotify(DBEntryBase *entry);
229 : void VnNotify(DBEntryBase *entry);
230 : void VrfNotify(DBEntryBase *entry);
231 : void ProcessNotify(std::string name, bool is_deleted, bool is_ipam);
232 : void CheckForUpdate(IpVdnsMap &ipvdns, const VmInterface *vmitf,
233 : const VnEntry *vn, const Ip4Address &ip,
234 : const Ip6Address &ip6, std::string &vdns_name,
235 : const autogen::VirtualDnsType &vdns_type);
236 : void CheckForFipUpdate(DnsFipEntry *entry, std::string &vdns_name,
237 : const autogen::VirtualDnsType &vdns_type);
238 : bool UpdateDnsEntry(const VmInterface *vmitf, const VnEntry *vn,
239 : const std::string &vm_name,
240 : const std::string &vdns_name,
241 : const Ip4Address &ip,
242 : const Ip6Address &ip6,
243 : bool is_floating, bool is_deleted);
244 : bool MoveVDnsEntry(const VmInterface *vmitf,
245 : std::string &new_vdns_name,
246 : std::string &old_vdns_name,
247 : const autogen::VirtualDnsType &vdns_type,
248 : bool is_floating);
249 : bool GetVdnsData(const VnEntry *vn, const Ip4Address &v4_addr,
250 : const Ip6Address &v6_addr, std::string &vdns_name,
251 : autogen::VirtualDnsType &vdns_type);
252 : bool GetFipName(const VmInterface *vmitf,
253 : const autogen::VirtualDnsType &vdns_type,
254 : const IpAddress &ip, std::string &fip_name) const;
255 :
256 : uint16_t xid_;
257 : DnsUpdateSet update_set_;
258 : DnsBindQueryMap dns_query_map_;
259 : DnsVmRequestSet curr_vm_requests_;
260 : DnsBindQueryIndexMap dns_query_index_map_;
261 : DefaultServerList def_server_list_;
262 : DnsStats stats_;
263 : uint32_t timeout_; // milli seconds
264 : uint32_t max_retries_;
265 : Timer *default_slist_timer_;
266 :
267 : VmDataMap all_vms_;
268 : DnsFipSet fip_list_;
269 : DBTableBase::ListenerId lid_;
270 : DBTableBase::ListenerId Vnlid_;
271 : DBTableBase::ListenerId vrf_table_listener_id_;
272 :
273 : DISALLOW_COPY_AND_ASSIGN(DnsProto);
274 : };
275 :
276 : #endif // vnsw_agent_dns_proto_hpp
|