xapian-core  1.4.27
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 <cerrno>
25 #include <cstring>
26 #include "safenetdb.h"
27 #include "safesyssocket.h"
28 #include "str.h"
29 #include "xapian/error.h"
30 
31 using namespace std;
32 
33 class Resolver {
34  struct addrinfo* result = NULL;
35 
36  public:
38  struct addrinfo* p;
39  public:
40  explicit const_iterator(struct addrinfo* p_) : p(p_) { }
41 
42  struct addrinfo& operator*() const {
43  return *p;
44  }
45 
46  void operator++() {
47  p = p->ai_next;
48  }
49 
51  struct addrinfo* old_p = p;
52  operator++();
53  return const_iterator(old_p);
54  }
55 
56  bool operator==(const const_iterator& o) const {
57  return p == o.p;
58  }
59 
60  bool operator!=(const const_iterator& o) const {
61  return !(*this == o);
62  }
63  };
64 
65  Resolver(const std::string& host, int port, int flags = 0) {
66  // RFC 3493 has an extra sentence in its definition of
67  // AI_ADDRCONFIG which POSIX doesn't:
68  //
69  // "The loopback address is not considered for this case as valid
70  // as a configured address."
71  //
72  // Some platforms implement this version rather than POSIX (notably
73  // glibc on Linux). Others implement POSIX (from looking at the
74  // man pages, these include FreeBSD 11.0).
75  //
76  // In most cases, this extra sentence is arguably helpful - e.g. it
77  // means that you won't get IPv6 addresses just because the system
78  // has IPv6 loopback (and similarly for IPv4).
79  //
80  // However, it behaves unhelpfully if the *only* interface
81  // configured is loopback - in this situation, AI_ADDRCONFIG means
82  // that you won't get an IPv4 address (as there's no IPv4 address
83  // configured ignoring loopback) and you won't get an IPv6 address
84  // (as there's no IPv6 address configured ignoring loopback).
85  //
86  // It's generally rare that systems with only loopback would want
87  // to use the remote backend, but a real example is testsuites
88  // (including our own) running on autobuilders which deliberately
89  // close off network access.
90  //
91  // To allow such cases to work on Linux (and other platforms which
92  // follow the RFC rather than POSIX in this detail) we avoid using
93  // AI_ADDRCONFIG for 127.0.0.1, ::1 and localhost. There are
94  // other ways to write these IP addresses and other hostnames may
95  // map onto them, but this just needs to work for the standard
96  // cases which a testsuite might use.
97  if (host != "::1" && host != "127.0.0.1" && host != "localhost") {
98  flags |= AI_ADDRCONFIG;
99  }
100  // Not defined on older macOS (such as 10.5 which Apple no longer
101  // support but newer versions no longer support PowerPC Macs).
102 #ifdef AI_NUMERICSERV
103  flags |= AI_NUMERICSERV;
104 #endif
105 
106  struct addrinfo hints;
107  std::memset(&hints, 0, sizeof(struct addrinfo));
108  hints.ai_family = AF_INET;
109  hints.ai_socktype = SOCK_STREAM;
110  hints.ai_flags = flags;
111  hints.ai_protocol = 0;
112 
113  const char * node = host.empty() ? NULL : host.c_str();
114  int r = getaddrinfo(node, str(port).c_str(), &hints, &result);
115  if (r != 0) {
116  throw Xapian::NetworkError("Couldn't resolve host " + host,
117  eai_to_xapian(r));
118  }
119  }
120 
122  if (result) freeaddrinfo(result);
123  }
124 
126  return const_iterator(result);
127  }
128 
129  const_iterator end() const {
130  return const_iterator(NULL);
131  }
132 };
133 
134 #endif // XAPIAN_INCLUDED_RESOLVER_H
struct addrinfo * p
Definition: resolver.h:38
Definition: header.h:216
bool operator==(const const_iterator &o) const
Definition: resolver.h:56
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:50
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:129
const_iterator(struct addrinfo *p_)
Definition: resolver.h:40
~Resolver()
Definition: resolver.h:121
Indicates a problem communicating with a remote database.
Definition: error.h:803
const_iterator begin() const
Definition: resolver.h:125
bool operator!=(const const_iterator &o) const
Definition: resolver.h:60
struct addrinfo & operator*() const
Definition: resolver.h:42
Resolver(const std::string &host, int port, int flags=0)
Definition: resolver.h:65