IBR-DTNSuite  0.10
vaddress.cpp
Go to the documentation of this file.
1 /*
2  * vaddress.cpp
3  *
4  * Copyright (C) 2011 IBR, TU Braunschweig
5  *
6  * Written-by: Johannes Morgenroth <morgenroth@ibr.cs.tu-bs.de>
7  *
8  * Licensed under the Apache License, Version 2.0 (the "License");
9  * you may not use this file except in compliance with the License.
10  * You may obtain a copy of the License at
11  *
12  * http://www.apache.org/licenses/LICENSE-2.0
13  *
14  * Unless required by applicable law or agreed to in writing, software
15  * distributed under the License is distributed on an "AS IS" BASIS,
16  * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
17  * See the License for the specific language governing permissions and
18  * limitations under the License.
19  *
20  */
21 
22 #include "ibrcommon/config.h"
23 #include "ibrcommon/net/vaddress.h"
24 #include "ibrcommon/net/socket.h"
25 #include <arpa/inet.h>
26 #include <string.h>
27 #include <netdb.h>
28 
29 namespace ibrcommon
30 {
31 #if (defined HAVE_LIBNL3) || (defined HAVE_LIBNL)
32  const std::string vaddress::SCOPE_GLOBAL = "global";
33 #else
34  const std::string vaddress::SCOPE_GLOBAL = "universe";
35 #endif
36  const std::string vaddress::SCOPE_LINKLOCAL = "link";
37 
38  const std::string vaddress::VADDR_LOCALHOST = "localhost";
39  const std::string vaddress::VADDR_ANY = "any";
40 
42  : _address(VADDR_ANY), _service(), _scope(), _family(AF_UNSPEC)
43  {
44  }
45 
46  vaddress::vaddress(const int port, sa_family_t family)
47  : _address(VADDR_ANY), _service(), _scope(), _family(family)
48  {
49  std::stringstream ss;
50  ss << port;
51  _service = ss.str();
52  }
53 
54  vaddress::vaddress(const std::string &address, const int port, sa_family_t family)
55  : _address(address), _service(), _scope(), _family(family)
56  {
57  std::stringstream ss;
58  ss << port;
59  _service = ss.str();
60  }
61 
62  vaddress::vaddress(const std::string &address, const std::string &service, sa_family_t family)
63  : _address(address), _service(service), _scope(), _family(family)
64  {
65  }
66 
67  vaddress::vaddress(const std::string &address, const std::string &service, const std::string &scope, sa_family_t family)
68  : _address(address), _service(service), _scope(scope), _family(family)
69  {
70  }
71 
73  {
74  }
75 
77  {
78  if (_address < dhs._address) return true;
79  if (_scope < dhs._scope) return true;
80  return false;
81  }
82 
83 
84  bool vaddress::operator!=(const vaddress &obj) const
85  {
86  if (_address != obj._address) return true;
87  if (_scope != obj._scope) return true;
88  return false;
89  }
90 
91  bool vaddress::operator==(const vaddress &obj) const
92  {
93  if (_address != obj._address) return false;
94  if (_scope != obj._scope) return false;
95  return true;
96  }
97 
98  bool vaddress::isLocal() const
99  {
100  return (_address == VADDR_LOCALHOST);
101  }
102 
103  bool vaddress::isAny() const
104  {
105  return (_address == VADDR_ANY);
106  }
107 
108  sa_family_t vaddress::family() const throw (address_exception)
109  {
110  if (_family != AF_UNSPEC)
111  return _family;
112 
113  struct addrinfo hints;
114  memset(&hints, 0, sizeof(struct addrinfo));
115  hints.ai_family = PF_UNSPEC;
116  hints.ai_socktype = SOCK_DGRAM;
117 
118  struct addrinfo *res;
119  int ret = 0;
120 
121  const char *address = NULL;
122  const char *service = NULL;
123 
124  // throw exception if the address is not set.
125  // without an address we can not determine the address family
126  address = this->address().c_str();
127 
128  try {
129  service = this->service().c_str();
130  } catch (const vaddress::service_not_set&) { };
131 
132  if ((ret = ::getaddrinfo(address, service, &hints, &res)) != 0)
133  {
134  throw address_exception("getaddrinfo(): " + std::string(gai_strerror(ret)));
135  }
136 
137  sa_family_t fam = static_cast<sa_family_t>(res->ai_family);
138  freeaddrinfo(res);
139 
140  return fam;
141  }
142 
143  std::string vaddress::scope() const throw (scope_not_set)
144  {
145  if (_scope.length() == 0) throw scope_not_set();
146  return _scope;
147  }
148 
149  const std::string vaddress::address() const throw (address_not_set)
150  {
151  if (_address.length() == 0) throw address_not_set();
152  if (isAny()) throw address_not_set();
153  return _address;
154  }
155 
156  const std::string vaddress::service() const throw (service_not_set)
157  {
158  if (_service.length() == 0) throw service_not_set();
159  return _service;
160  }
161 
162  void vaddress::setService(const std::string &service)
163  {
164  _service = service;
165  }
166 
167  const std::string vaddress::toString() const
168  {
169  std::stringstream ss;
170 
171  try {
172  try {
173  std::string service = this->service();
174  ss << "[" << this->address() << "]:" + service;
175  } catch (const service_not_set&) {
176  ss << this->address();
177  }
178 
179  try {
180  std::string scope = this->scope();
181  ss << " (" << scope << ")";
182  } catch (const scope_not_set&) { }
183  } catch (const address_not_set&) {
184  ss << "<any>";
185  try {
186  std::string service = this->service();
187  ss << ":" + service;
188  } catch (const service_not_set&) { }
189  }
190 
191  return ss.str();
192  }
193 }