comparison src/network/core/address.cpp @ 17148:848eb1ffb17d draft

(svn r21886) -Codechange: move documentation towards the code to make it more likely to be updated [n].
author rubidium <rubidium@openttd.org>
date Sat, 22 Jan 2011 09:53:15 +0000
parents dd6d2c758c96
children b76a26d921f1
comparison
equal deleted inserted replaced
17147:5ffc4ae6944d 17148:848eb1ffb17d
14 #ifdef ENABLE_NETWORK 14 #ifdef ENABLE_NETWORK
15 15
16 #include "address.h" 16 #include "address.h"
17 #include "../../debug.h" 17 #include "../../debug.h"
18 18
19 /**
20 * Get the hostname; in case it wasn't given the
21 * IPv4 dotted representation is given.
22 * @return the hostname
23 */
19 const char *NetworkAddress::GetHostname() 24 const char *NetworkAddress::GetHostname()
20 { 25 {
21 if (StrEmpty(this->hostname) && this->address.ss_family != AF_UNSPEC) { 26 if (StrEmpty(this->hostname) && this->address.ss_family != AF_UNSPEC) {
22 assert(this->address_length != 0); 27 assert(this->address_length != 0);
23 getnameinfo((struct sockaddr *)&this->address, this->address_length, this->hostname, sizeof(this->hostname), NULL, 0, NI_NUMERICHOST); 28 getnameinfo((struct sockaddr *)&this->address, this->address_length, this->hostname, sizeof(this->hostname), NULL, 0, NI_NUMERICHOST);
24 } 29 }
25 return this->hostname; 30 return this->hostname;
26 } 31 }
27 32
33 /**
34 * Get the port.
35 * @return the port.
36 */
28 uint16 NetworkAddress::GetPort() const 37 uint16 NetworkAddress::GetPort() const
29 { 38 {
30 switch (this->address.ss_family) { 39 switch (this->address.ss_family) {
31 case AF_UNSPEC: 40 case AF_UNSPEC:
32 case AF_INET: 41 case AF_INET:
38 default: 47 default:
39 NOT_REACHED(); 48 NOT_REACHED();
40 } 49 }
41 } 50 }
42 51
52 /**
53 * Set the port.
54 * @param port set the port number.
55 */
43 void NetworkAddress::SetPort(uint16 port) 56 void NetworkAddress::SetPort(uint16 port)
44 { 57 {
45 switch (this->address.ss_family) { 58 switch (this->address.ss_family) {
46 case AF_UNSPEC: 59 case AF_UNSPEC:
47 case AF_INET: 60 case AF_INET:
55 default: 68 default:
56 NOT_REACHED(); 69 NOT_REACHED();
57 } 70 }
58 } 71 }
59 72
73 /**
74 * Get the address as a string, e.g. 127.0.0.1:12345.
75 * @param buffer the buffer to write to
76 * @param last the last element in the buffer
77 * @param with_family whether to add the family (e.g. IPvX).
78 */
60 void NetworkAddress::GetAddressAsString(char *buffer, const char *last, bool with_family) 79 void NetworkAddress::GetAddressAsString(char *buffer, const char *last, bool with_family)
61 { 80 {
62 if (this->GetAddress()->ss_family == AF_INET6) buffer = strecpy(buffer, "[", last); 81 if (this->GetAddress()->ss_family == AF_INET6) buffer = strecpy(buffer, "[", last);
63 buffer = strecpy(buffer, this->GetHostname(), last); 82 buffer = strecpy(buffer, this->GetHostname(), last);
64 if (this->GetAddress()->ss_family == AF_INET6) buffer = strecpy(buffer, "]", last); 83 if (this->GetAddress()->ss_family == AF_INET6) buffer = strecpy(buffer, "]", last);
73 } 92 }
74 seprintf(buffer, last, " (IPv%c)", family); 93 seprintf(buffer, last, " (IPv%c)", family);
75 } 94 }
76 } 95 }
77 96
97 /**
98 * Get the address as a string, e.g. 127.0.0.1:12345.
99 * @param with_family whether to add the family (e.g. IPvX).
100 * @return the address
101 * @note NOT thread safe
102 */
78 const char *NetworkAddress::GetAddressAsString(bool with_family) 103 const char *NetworkAddress::GetAddressAsString(bool with_family)
79 { 104 {
80 /* 6 = for the : and 5 for the decimal port number */ 105 /* 6 = for the : and 5 for the decimal port number */
81 static char buf[NETWORK_HOSTNAME_LENGTH + 6 + 7]; 106 static char buf[NETWORK_HOSTNAME_LENGTH + 6 + 7];
82 this->GetAddressAsString(buf, lastof(buf), with_family); 107 this->GetAddressAsString(buf, lastof(buf), with_family);
92 { 117 {
93 /* We just want the first 'entry', so return a valid socket. */ 118 /* We just want the first 'entry', so return a valid socket. */
94 return !INVALID_SOCKET; 119 return !INVALID_SOCKET;
95 } 120 }
96 121
122 /**
123 * Get the address in its internal representation.
124 * @return the address
125 */
97 const sockaddr_storage *NetworkAddress::GetAddress() 126 const sockaddr_storage *NetworkAddress::GetAddress()
98 { 127 {
99 if (!this->IsResolved()) { 128 if (!this->IsResolved()) {
100 /* Here we try to resolve a network address. We use SOCK_STREAM as 129 /* Here we try to resolve a network address. We use SOCK_STREAM as
101 * socket type because some stupid OSes, like Solaris, cannot be 130 * socket type because some stupid OSes, like Solaris, cannot be
105 this->Resolve(this->address.ss_family, SOCK_STREAM, AI_ADDRCONFIG, NULL, ResolveLoopProc); 134 this->Resolve(this->address.ss_family, SOCK_STREAM, AI_ADDRCONFIG, NULL, ResolveLoopProc);
106 } 135 }
107 return &this->address; 136 return &this->address;
108 } 137 }
109 138
139 /**
140 * Checks of this address is of the given family.
141 * @param family the family to check against
142 * @return true if it is of the given family
143 */
110 bool NetworkAddress::IsFamily(int family) 144 bool NetworkAddress::IsFamily(int family)
111 { 145 {
112 if (!this->IsResolved()) { 146 if (!this->IsResolved()) {
113 this->Resolve(family, SOCK_STREAM, AI_ADDRCONFIG, NULL, ResolveLoopProc); 147 this->Resolve(family, SOCK_STREAM, AI_ADDRCONFIG, NULL, ResolveLoopProc);
114 } 148 }
115 return this->address.ss_family == family; 149 return this->address.ss_family == family;
116 } 150 }
117 151
152 /**
153 * Checks whether this IP address is contained by the given netmask.
154 * @param netmask the netmask in CIDR notation to test against.
155 * @note netmask without /n assumes all bits need to match.
156 * @return true if this IP is within the netmask.
157 */
118 bool NetworkAddress::IsInNetmask(char *netmask) 158 bool NetworkAddress::IsInNetmask(char *netmask)
119 { 159 {
120 /* Resolve it if we didn't do it already */ 160 /* Resolve it if we didn't do it already */
121 if (!this->IsResolved()) this->GetAddress(); 161 if (!this->IsResolved()) this->GetAddress();
122 162
167 } 207 }
168 208
169 return true; 209 return true;
170 } 210 }
171 211
212 /**
213 * Resolve this address into a socket
214 * @param family the type of 'protocol' (IPv4, IPv6)
215 * @param socktype the type of socket (TCP, UDP, etc)
216 * @param flags the flags to send to getaddrinfo
217 * @param sockets the list of sockets to add the sockets to
218 * @param func the inner working while looping over the address info
219 * @return the resolved socket or INVALID_SOCKET.
220 */
172 SOCKET NetworkAddress::Resolve(int family, int socktype, int flags, SocketList *sockets, LoopProc func) 221 SOCKET NetworkAddress::Resolve(int family, int socktype, int flags, SocketList *sockets, LoopProc func)
173 { 222 {
174 struct addrinfo *ai; 223 struct addrinfo *ai;
175 struct addrinfo hints; 224 struct addrinfo hints;
176 memset(&hints, 0, sizeof (hints)); 225 memset(&hints, 0, sizeof (hints));
264 DEBUG(net, 1, "[%s] connected to %s", type, address); 313 DEBUG(net, 1, "[%s] connected to %s", type, address);
265 314
266 return sock; 315 return sock;
267 } 316 }
268 317
318 /**
319 * Connect to the given address.
320 * @return the connected socket or INVALID_SOCKET.
321 */
269 SOCKET NetworkAddress::Connect() 322 SOCKET NetworkAddress::Connect()
270 { 323 {
271 DEBUG(net, 1, "Connecting to %s", this->GetAddressAsString()); 324 DEBUG(net, 1, "Connecting to %s", this->GetAddressAsString());
272 325
273 return this->Resolve(AF_UNSPEC, SOCK_STREAM, AI_ADDRCONFIG, NULL, ConnectLoopProc); 326 return this->Resolve(AF_UNSPEC, SOCK_STREAM, AI_ADDRCONFIG, NULL, ConnectLoopProc);
322 375
323 DEBUG(net, 1, "[%s] listening on %s port %s", type, family, address); 376 DEBUG(net, 1, "[%s] listening on %s port %s", type, family, address);
324 return sock; 377 return sock;
325 } 378 }
326 379
380 /**
381 * Make the given socket listen.
382 * @param socktype the type of socket (TCP, UDP, etc)
383 * @param sockets the list of sockets to add the sockets to
384 */
327 void NetworkAddress::Listen(int socktype, SocketList *sockets) 385 void NetworkAddress::Listen(int socktype, SocketList *sockets)
328 { 386 {
329 assert(sockets != NULL); 387 assert(sockets != NULL);
330 388
331 /* Setting both hostname to NULL and port to 0 is not allowed. 389 /* Setting both hostname to NULL and port to 0 is not allowed.
338 } else { 396 } else {
339 this->Resolve(AF_UNSPEC, socktype, AI_ADDRCONFIG | AI_PASSIVE, sockets, ListenLoopProc); 397 this->Resolve(AF_UNSPEC, socktype, AI_ADDRCONFIG | AI_PASSIVE, sockets, ListenLoopProc);
340 } 398 }
341 } 399 }
342 400
401 /**
402 * Convert the socket type into a string
403 * @param socktype the socket type to convert
404 * @return the string representation
405 * @note only works for SOCK_STREAM and SOCK_DGRAM
406 */
343 /* static */ const char *NetworkAddress::SocketTypeAsString(int socktype) 407 /* static */ const char *NetworkAddress::SocketTypeAsString(int socktype)
344 { 408 {
345 switch (socktype) { 409 switch (socktype) {
346 case SOCK_STREAM: return "tcp"; 410 case SOCK_STREAM: return "tcp";
347 case SOCK_DGRAM: return "udp"; 411 case SOCK_DGRAM: return "udp";
348 default: return "unsupported"; 412 default: return "unsupported";
349 } 413 }
350 } 414 }
351 415
416 /**
417 * Convert the address family into a string
418 * @param family the family to convert
419 * @return the string representation
420 * @note only works for AF_INET, AF_INET6 and AF_UNSPEC
421 */
352 /* static */ const char *NetworkAddress::AddressFamilyAsString(int family) 422 /* static */ const char *NetworkAddress::AddressFamilyAsString(int family)
353 { 423 {
354 switch (family) { 424 switch (family) {
355 case AF_UNSPEC: return "either IPv4 or IPv6"; 425 case AF_UNSPEC: return "either IPv4 or IPv6";
356 case AF_INET: return "IPv4"; 426 case AF_INET: return "IPv4";