Mercurial > hg > openttd
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"; |