1 #ifndef NETWORK_ADDRESS_HH |
1 #ifndef NETWORK_ADDRESS_HH |
2 #define NETWORK_ADDRESS_HH |
2 #define NETWORK_ADDRESS_HH |
3 |
3 |
4 #include <ClanLib/Network/Socket/ip_address.h> |
4 #include "../Error.hh" |
|
5 |
|
6 /* |
|
7 * Platform-specific includes |
|
8 */ |
|
9 #ifndef WIN32 |
|
10 // linux |
|
11 #include <sys/types.h> |
|
12 #include <sys/socket.h> |
|
13 #include <netdb.h> |
|
14 #else |
|
15 #error "This network code won't compile on win32 :)" |
|
16 #endif |
|
17 |
|
18 #include <string> |
|
19 |
|
20 // assume... |
|
21 #if INET6_ADDRSTRLEN < INET_ADDRSTRLEN |
|
22 #error INET6_ADDRSTRLEN is smaller than INET_ADDRSTRLEN |
|
23 #endif |
|
24 |
|
25 /** |
|
26 * Length of a network address |
|
27 */ |
|
28 const socklen_t NETWORK_ADDRESS_LENGTH = INET6_ADDRSTRLEN; |
5 |
29 |
6 /** |
30 /** |
7 * We use ClanLib's IPAddress API, but with our own name |
31 * We use ClanLib's IPAddress API, but with our own name |
8 */ |
32 */ |
9 typedef CL_IPAddress NetworkAddress; |
33 class NetworkAddress { |
|
34 private: |
|
35 /** |
|
36 * Our human-readable hostname |
|
37 */ |
|
38 std::string hostname; |
|
39 |
|
40 /** |
|
41 * Our human-readable service |
|
42 */ |
|
43 std::string service; |
|
44 |
|
45 /** |
|
46 * Our machine-readable address and its length |
|
47 */ |
|
48 sockaddr_storage address; |
|
49 socklen_t address_length; |
|
50 |
|
51 public: |
|
52 /** |
|
53 * Construct an empty NetworkAddress |
|
54 */ |
|
55 NetworkAddress (void); |
|
56 |
|
57 /** |
|
58 * Construct a NetworkAddress with a NULL hostname, and a specific service |
|
59 */ |
|
60 NetworkAddress (std::string service); |
|
61 |
|
62 /** |
|
63 * Construct a NetworkAddress on a specific hostname and service |
|
64 */ |
|
65 NetworkAddress (std::string hostname, std::string service); |
|
66 |
|
67 /** |
|
68 * Construct a NetworkAddress from a machine-readable address of the given length |
|
69 */ |
|
70 NetworkAddress (const sockaddr *addr, socklen_t len); |
|
71 |
|
72 public: |
|
73 /** |
|
74 * Get a addrinfo* for this address using the given family/type/protocol/flags. |
|
75 * |
|
76 * Remember to free the returned pointer using freeaddrinfo() after use. |
|
77 * |
|
78 * @param family the socket family for hints.ai_family |
|
79 * @param socktype the socket type for hints.ai_socktype |
|
80 * @param protoocl the socket protocol for hints.ai_protocol |
|
81 * @param flags the flags for hints.ai_flags |
|
82 * @return linked list of addrinfo's |
|
83 * @throw NetworkAddressError if resolving this address fails |
|
84 */ |
|
85 addrinfo* get_addrinfo (int family, int socktype, int protocol = 0, int flags = 0) const; |
|
86 |
|
87 /** |
|
88 * Get a sockaddr* for this address. This is only valid for NetworkAddress's which have had set_sockaddr called |
|
89 * on them. |
|
90 * |
|
91 * @param len_ref updated to the sockaddr length |
|
92 * @return borrowed sockaddr pointer |
|
93 */ |
|
94 const sockaddr* get_sockaddr (socklen_t &len_ref) const; |
|
95 |
|
96 /** |
|
97 * Set a sockaddr for this address |
|
98 * |
|
99 * @param addr the address to copy, of len bytes |
|
100 * @param len the size of the sockaddr |
|
101 */ |
|
102 void set_sockaddr (const sockaddr *addr, socklen_t len); |
|
103 |
|
104 /** |
|
105 * Get the human-readable hostname |
|
106 */ |
|
107 std::string get_hostname (void) const { return hostname; } |
|
108 |
|
109 /** |
|
110 * Get the human-readable service name |
|
111 */ |
|
112 std::string get_service (void) const { return service; } |
|
113 |
|
114 /** |
|
115 * Equal-to comparison operator. This requires that the machine-readable address be available. |
|
116 */ |
|
117 bool operator== (const NetworkAddress &other) const { |
|
118 return (address_length == other.address_length) && memcmp(&address, &other.address, address_length) == 0; |
|
119 } |
|
120 |
|
121 /** |
|
122 * Not-qqual-to comparison operator. This requires that the machine-readable address be available. |
|
123 */ |
|
124 bool operator!= (const NetworkAddress &other) const { |
|
125 return (address_length != other.address_length) || memcmp(&address, &other.address, address_length) != 0; |
|
126 } |
|
127 |
|
128 /** |
|
129 * Less-than comparison operator. Smaller addresses are always lesser. |
|
130 */ |
|
131 bool operator< (const NetworkAddress &other) const { |
|
132 return (address_length < other.address_length) || memcmp(&address, &other.address, other.address_length) < 0; |
|
133 } |
|
134 |
|
135 /** |
|
136 * Greater-than comparison operator. Bigger addresses are always greater. |
|
137 */ |
|
138 bool operator> (const NetworkAddress &other) const { |
|
139 return (address_length > other.address_length) || memcmp(&address, &other.address, address_length) > 0; |
|
140 } |
|
141 }; |
10 |
142 |
11 /** |
143 /** |
12 * Formatted as [<addr>:<port>] |
144 * Formatted as [<addr>:<port>] |
13 */ |
145 */ |
14 std::ostream& operator<< (std::ostream &s, const NetworkAddress &addr); |
146 std::ostream& operator<< (std::ostream &s, const NetworkAddress &addr); |
15 |
147 |
|
148 /** |
|
149 * |
|
150 */ |
|
151 class NetworkAddressError : public Error { |
|
152 protected: |
|
153 static std::string build_str (const NetworkAddress &addr, const char *op, const char *msg); |
|
154 |
|
155 public: |
|
156 NetworkAddressError (const NetworkAddress &addr, const char *op, const char *msg); |
|
157 }; |
|
158 |
16 #endif /* NETWORK_ADDRESS_HH */ |
159 #endif /* NETWORK_ADDRESS_HH */ |