xapian-core  1.4.26
resolver.h
Go to the documentation of this file.
1 
4 /* Copyright (C) 2017 Olly Betts
5  *
6  * This program is free software; you can redistribute it and/or modify
7  * it under the terms of the GNU General Public License as published by
8  * the Free Software Foundation; either version 2 of the License, or
9  * (at your option) any later version.
10  *
11  * This program is distributed in the hope that it will be useful,
12  * but WITHOUT ANY WARRANTY; without even the implied warranty of
13  * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
14  * GNU General Public License for more details.
15  *
16  * You should have received a copy of the GNU General Public License
17  * along with this program; if not, write to the Free Software
18  * Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA
19  */
20 
21 #ifndef XAPIAN_INCLUDED_RESOLVER_H
22 #define XAPIAN_INCLUDED_RESOLVER_H
23 
24 #include <cstring>
25 #include "safenetdb.h"
26 #include "safesyssocket.h"
27 #include "str.h"
28 #include "xapian/error.h"
29 
30 using namespace std;
31 
32 class Resolver {
33  struct addrinfo* result = NULL;
34 
35  public:
37  struct addrinfo* p;
38  public:
39  explicit const_iterator(struct addrinfo* p_) : p(p_) { }
40 
41  struct addrinfo& operator*() const {
42  return *p;
43  }
44 
45  void operator++() {
46  p = p->ai_next;
47  }
48 
50  struct addrinfo* old_p = p;
51  operator++();
52  return const_iterator(old_p);
53  }
54 
55  bool operator==(const const_iterator& o) const {
56  return p == o.p;
57  }
58 
59  bool operator!=(const const_iterator& o) const {
60  return !(*this == o);
61  }
62  };
63 
64  Resolver(const std::string& host, int port, int flags = 0) {
65  // RFC 3493 has an extra sentence in its definition of
66  // AI_ADDRCONFIG which POSIX doesn't:
67  //
68  // "The loopback address is not considered for this case as valid
69  // as a configured address."
70  //
71  // Some platforms implement this version rather than POSIX (notably
72  // glibc on Linux). Others implement POSIX (from looking at the
73  // man pages, these include FreeBSD 11.0).
74  //
75  // In most cases, this extra sentence is arguably helpful - e.g. it
76  // means that you won't get IPv6 addresses just because the system
77  // has IPv6 loopback (and similarly for IPv4).
78  //
79  // However, it behaves unhelpfully if the *only* interface
80  // configured is loopback - in this situation, AI_ADDRCONFIG means
81  // that you won't get an IPv4 address (as there's no IPv4 address
82  // configured ignoring loopback) and you won't get an IPv6 address
83  // (as there's no IPv6 address configured ignoring loopback).
84  //
85  // It's generally rare that systems with only loopback would want
86  // to use the remote backend, but a real example is testsuites
87  // (including our own) running on autobuilders which deliberately
88  // close off network access.
89  //
90  // To allow such cases to work on Linux (and other platforms which
91  // follow the RFC rather than POSIX in this detail) we avoid using
92  // AI_ADDRCONFIG for 127.0.0.1, ::1 and localhost. There are
93  // other ways to write these IP addresses and other hostnames may
94  // map onto them, but this just needs to work for the standard
95  // cases which a testsuite might use.
96  if (host != "::1" && host != "127.0.0.1" && host != "localhost") {
97  flags |= AI_ADDRCONFIG;
98  }
99  // Not defined on older macOS (such as 10.5 which Apple no longer
100  // support but newer versions no longer support PowerPC Macs).
101 #ifdef AI_NUMERICSERV
102  flags |= AI_NUMERICSERV;
103 #endif
104 
105  struct addrinfo hints;
106  std::memset(&hints, 0, sizeof(struct addrinfo));
107  hints.ai_family = AF_INET;
108  hints.ai_socktype = SOCK_STREAM;
109  hints.ai_flags = flags;
110  hints.ai_protocol = 0;
111 
112  const char * node = host.empty() ? NULL : host.c_str();
113  int r = getaddrinfo(node, str(port).c_str(), &hints, &result);
114  if (r != 0) {
115  throw Xapian::NetworkError("Couldn't resolve host " + host,
116  eai_to_xapian(r));
117  }
118  }
119 
121  if (result) freeaddrinfo(result);
122  }
123 
125  return const_iterator(result);
126  }
127 
128  const_iterator end() const {
129  return const_iterator(NULL);
130  }
131 };
132 
133 #endif // XAPIAN_INCLUDED_RESOLVER_H
struct addrinfo * p
Definition: resolver.h:37
Definition: header.h:216
bool operator==(const const_iterator &o) const
Definition: resolver.h:55
include <sys/socket.h> with portability workarounds.
int eai_to_xapian(int e)
STL namespace.
Convert types to std::string.
include <netdb.h>, with portability workarounds.
const_iterator operator++(int)
Definition: resolver.h:49
Hierarchy of classes which Xapian can throw as exceptions.
string str(int value)
Convert int to std::string.
Definition: str.cc:90
const_iterator end() const
Definition: resolver.h:128
const_iterator(struct addrinfo *p_)
Definition: resolver.h:39
~Resolver()
Definition: resolver.h:120
Indicates a problem communicating with a remote database.
Definition: error.h:803
const_iterator begin() const
Definition: resolver.h:124
bool operator!=(const const_iterator &o) const
Definition: resolver.h:59
struct addrinfo & operator*() const
Definition: resolver.h:41
Resolver(const std::string &host, int port, int flags=0)
Definition: resolver.h:64