Fix some bugs when testing opensds ansible
[stor4nfv.git] / src / ceph / src / common / dns_resolve.h
1 // -*- mode:C++; tab-width:8; c-basic-offset:2; indent-tabs-mode:t -*-
2 // vim: ts=8 sw=2 smarttab
3 /*
4  * Ceph - scalable distributed file system
5  *
6  * Copyright (C) 2016 SUSE LINUX GmbH
7  *
8  * This is free software; you can redistribute it and/or
9  * modify it under the terms of the GNU Lesser General Public
10  * License version 2.1, as published by the Free Software
11  * Foundation.  See file COPYING.
12  *
13  */
14 #ifndef CEPH_DNS_RESOLVE_H
15 #define CEPH_DNS_RESOLVE_H
16
17 #include <netinet/in.h>
18 #include <resolv.h>
19
20 #include "common/Mutex.h"
21 #include "msg/msg_types.h"              // for entity_addr_t
22
23 namespace ceph {
24
25 /**
26  * this class is used to facilitate the testing of
27  * resolv.h functions.
28  */
29 class ResolvHWrapper {
30   public:
31     virtual ~ResolvHWrapper() {}
32
33 #ifdef HAVE_RES_NQUERY
34     virtual int res_nquery(res_state s, const char *hostname, int cls, int type, 
35         u_char *buf, int bufsz);
36
37     virtual int res_nsearch(res_state s, const char *hostname, int cls, int type, 
38         u_char *buf, int bufsz);
39 #else
40     virtual int res_query(const char *hostname, int cls, int type,
41         u_char *buf, int bufsz);
42
43     virtual int res_search(const char *hostname, int cls, int type,
44         u_char *buf, int bufsz);
45 #endif
46
47 };
48
49
50 /**
51  * @class DNSResolver
52  *
53  * This is a singleton class that exposes the functionality of DNS querying.
54  */
55 class DNSResolver {
56
57   public:
58     // singleton declaration
59     static DNSResolver *get_instance()
60     {
61       static DNSResolver instance;
62       return &instance;
63     }
64     DNSResolver(DNSResolver const&) = delete;
65     void operator=(DNSResolver const&) = delete;
66
67     // this function is used by the unit test
68     static DNSResolver *get_instance(ResolvHWrapper *resolv_wrapper) {
69       DNSResolver *resolv = DNSResolver::get_instance();
70       delete resolv->resolv_h;
71       resolv->resolv_h = resolv_wrapper;
72       return resolv;
73     }
74
75     enum class SRV_Protocol {
76       TCP, UDP
77     };
78
79
80     struct Record {
81       uint16_t priority;
82       entity_addr_t addr;
83     };
84
85     int resolve_cname(CephContext *cct, const std::string& hostname,
86         std::string *cname, bool *found);
87
88     /**
89      * Resolves the address given a hostname.
90      *
91      * @param hostname the hostname to resolved
92      * @param[out] addr the hostname's address
93      * @returns 0 on success, negative error code on failure
94      */
95     int resolve_ip_addr(CephContext *cct, const std::string& hostname,
96         entity_addr_t *addr);
97
98     /**
99      * Returns the list of hostnames and addresses that provide a given
100      * service configured as DNS SRV records.
101      *
102      * @param service_name the service name
103      * @param trans_protocol the IP protocol used by the service (TCP or UDP)
104      * @param[out] srv_hosts the hostname to address map of available hosts
105      *             providing the service. If no host exists the map is not
106      *             changed.
107      * @returns 0 on success, negative error code on failure
108      */
109     int resolve_srv_hosts(CephContext *cct, const std::string& service_name,
110         const SRV_Protocol trans_protocol, std::map<std::string, Record> *srv_hosts);
111
112     /**
113      * Returns the list of hostnames and addresses that provide a given
114      * service configured as DNS SRV records.
115      *
116      * @param service_name the service name
117      * @param trans_protocol the IP protocol used by the service (TCP or UDP)
118      * @param domain the domain of the service
119      * @param[out] srv_hosts the hostname to address map of available hosts
120      *             providing the service. If no host exists the map is not
121      *             changed.
122      * @returns 0 on success, negative error code on failure
123      */
124     int resolve_srv_hosts(CephContext *cct, const std::string& service_name,
125         const SRV_Protocol trans_protocol, const std::string& domain,
126         std::map<std::string, Record> *srv_hosts);
127
128   private:
129     DNSResolver() : lock("DNSResolver") { resolv_h = new ResolvHWrapper(); }
130     ~DNSResolver();
131
132     Mutex lock;
133     ResolvHWrapper *resolv_h;
134 #ifdef HAVE_RES_NQUERY
135     std::list<res_state> states;
136
137     int get_state(CephContext *cct, res_state *ps);
138     void put_state(res_state s);
139 #endif
140
141     /* this private function allows to reuse the res_state structure used
142      * by other function of this class
143      */
144     int resolve_ip_addr(CephContext *cct, res_state *res,
145         const std::string& hostname, entity_addr_t *addr);
146
147     std::string srv_protocol_to_str(SRV_Protocol proto) {
148       switch (proto) {
149         case SRV_Protocol::TCP:
150           return "tcp";
151         case SRV_Protocol::UDP:
152           return "udp";
153       }
154       return "";
155     }
156
157 };
158
159 }
160
161 #endif
162