1 | #ifndef TCPIP_ENDPOINT_HPP_
|
---|
2 | #define TCPIP_ENDPOINT_HPP_
|
---|
3 |
|
---|
4 | #include<string>
|
---|
5 |
|
---|
6 | #include<boost/tr1/functional.hpp>
|
---|
7 | #include<boost/asio.hpp>
|
---|
8 |
|
---|
9 | #include "detail/address_convenience.hpp"
|
---|
10 | #include "port_address.hpp"
|
---|
11 | #include "ip_address.hpp"
|
---|
12 |
|
---|
13 | namespace ariba {
|
---|
14 | namespace addressing {
|
---|
15 |
|
---|
16 | using boost::asio::ip::tcp;
|
---|
17 | using namespace std;
|
---|
18 |
|
---|
19 | struct tcp_address_info {
|
---|
20 | static const uint16_t type_id;
|
---|
21 | static const std::string type_name;
|
---|
22 | };
|
---|
23 |
|
---|
24 | typedef port_address_tpl<tcp_address_info> tcp_port_address;
|
---|
25 |
|
---|
26 | /**
|
---|
27 | * TODO: Doc
|
---|
28 | *
|
---|
29 | * @author Sebastian Mies <mies@tm.uka.de>
|
---|
30 | */
|
---|
31 | class tcpip_endpoint : public detail::address_convenience<tcpip_endpoint> {
|
---|
32 | private:
|
---|
33 | ip_address ip;
|
---|
34 | tcp_port_address port_;
|
---|
35 | static const std::string protocol_name;
|
---|
36 |
|
---|
37 | public:
|
---|
38 | typedef tcpip_endpoint self;
|
---|
39 |
|
---|
40 | public:
|
---|
41 | tcpip_endpoint() :
|
---|
42 | ip(), port_() {
|
---|
43 | }
|
---|
44 |
|
---|
45 | tcpip_endpoint( const tcpip_endpoint& copy ) {
|
---|
46 | assign(copy);
|
---|
47 | }
|
---|
48 |
|
---|
49 | tcpip_endpoint( uint16_t port ) : ip(address_v6::any()), port_(port) {
|
---|
50 | }
|
---|
51 |
|
---|
52 | tcpip_endpoint( const ip_address& ip, const tcp_port_address& port) :
|
---|
53 | ip(ip), port_(port) {
|
---|
54 | }
|
---|
55 |
|
---|
56 | tcpip_endpoint(const std::string& ip, const std::string& port) :
|
---|
57 | ip(ip), port_(port) {
|
---|
58 | }
|
---|
59 |
|
---|
60 | tcpip_endpoint(const std::string& ip, uint16_t port) :
|
---|
61 | ip(ip), port_(port) {
|
---|
62 | }
|
---|
63 |
|
---|
64 | tcpip_endpoint(const std::string& text) {
|
---|
65 | assign( text );
|
---|
66 | }
|
---|
67 |
|
---|
68 | tcpip_endpoint(const char* text) {
|
---|
69 | assign( std::string(text) );
|
---|
70 | }
|
---|
71 |
|
---|
72 | tcpip_endpoint(const uint8_t* bytes, size_t size) {
|
---|
73 | assign( bytes, size );
|
---|
74 | }
|
---|
75 |
|
---|
76 | bool assign( const self& copy ) {
|
---|
77 | this->ip = copy.ip;
|
---|
78 | this->port_ = copy.port_;
|
---|
79 | return false;
|
---|
80 | }
|
---|
81 |
|
---|
82 | //--- compare operations --------------------------------------------------
|
---|
83 |
|
---|
84 | /// implements comparison operators
|
---|
85 | int compare_to(const self& rhs) const {
|
---|
86 | if (ip.compare_to(rhs.ip)==0 && port_.compare_to(rhs.port_)==0) return 0;
|
---|
87 | return 1;
|
---|
88 | }
|
---|
89 |
|
---|
90 | //--- bytes representation ------------------------------------------------
|
---|
91 |
|
---|
92 | /// returns true, if this address has a fixed size in bytes
|
---|
93 | bool is_bytes_size_static() const {
|
---|
94 | return false;
|
---|
95 | }
|
---|
96 |
|
---|
97 | /// returns the number of bytes used for serialization of this address
|
---|
98 | size_t to_bytes_size() const {
|
---|
99 | return ip.to_bytes_size() + port_.to_bytes_size();
|
---|
100 | }
|
---|
101 |
|
---|
102 | /// converts this address to a binary representation
|
---|
103 | void to_bytes(uint8_t* bytes) const {
|
---|
104 | ip.to_bytes(bytes);
|
---|
105 | port_.to_bytes(bytes+ip.to_bytes_size());
|
---|
106 | }
|
---|
107 |
|
---|
108 | /// Assigns an address using a bunch of bytes
|
---|
109 | bool assign(const uint8_t* bytes, size_t size) {
|
---|
110 | assert(size==6 || size==18);
|
---|
111 | if (size==6) {
|
---|
112 | ip.assign(bytes,4);
|
---|
113 | port_.assign(bytes+4,2);
|
---|
114 | } else {
|
---|
115 | ip.assign(bytes,16);
|
---|
116 | port_.assign(bytes+16,2);
|
---|
117 | }
|
---|
118 | return false;
|
---|
119 | }
|
---|
120 |
|
---|
121 | //--- text representation -------------------------------------------------
|
---|
122 |
|
---|
123 | /// convert address to a string that can be used to reconstruct the address
|
---|
124 | std::string to_string() const {
|
---|
125 | if (ip.asio().is_v4())
|
---|
126 | return ip.to_string()+std::string(":")+port_.to_string();
|
---|
127 | else
|
---|
128 | return std::string("[")+ip.to_string()+std::string("]:")+port_.to_string();
|
---|
129 | }
|
---|
130 |
|
---|
131 | /// Assigns an address using a human-readable
|
---|
132 | bool assign(const std::string& text) {
|
---|
133 | std::string ip_str;
|
---|
134 | std::string port_str;
|
---|
135 | if (text.at(0)=='[') {
|
---|
136 | int i = text.find(']',1);
|
---|
137 | ip_str = text.substr(1,i-1);
|
---|
138 | port_str = text.substr(i+2, text.size()-i-1);
|
---|
139 | } else {
|
---|
140 | int i = text.find(':',1);
|
---|
141 | ip_str = text.substr(0,i);
|
---|
142 | port_str = text.substr(i+1, text.size()-i-1);
|
---|
143 | }
|
---|
144 | return ip.assign(ip_str) || port_.assign(port_str);
|
---|
145 | }
|
---|
146 |
|
---|
147 | //--- address info --------------------------------------------------------
|
---|
148 |
|
---|
149 | /// returns the name of the address
|
---|
150 | const string& type_name() const {
|
---|
151 | return protocol_name;
|
---|
152 | }
|
---|
153 |
|
---|
154 | /// returns the id of the address
|
---|
155 | uint16_t type_id() const {
|
---|
156 | return 6;
|
---|
157 | }
|
---|
158 |
|
---|
159 | //--- endpoint elements ---------------------------------------------------
|
---|
160 |
|
---|
161 | ip_address& address() {
|
---|
162 | return ip;
|
---|
163 | }
|
---|
164 |
|
---|
165 | const ip_address& address() const {
|
---|
166 | return ip;
|
---|
167 | }
|
---|
168 |
|
---|
169 | tcp_port_address& port() {
|
---|
170 | return port_;
|
---|
171 | }
|
---|
172 |
|
---|
173 | const tcp_port_address& port() const {
|
---|
174 | return port_;
|
---|
175 | }
|
---|
176 |
|
---|
177 | //--- conversions ---------------------------------------------------------
|
---|
178 |
|
---|
179 | /// returns the asio endpoint
|
---|
180 | tcp::endpoint asio() const {
|
---|
181 | return tcp::endpoint(ip.asio(), port_.asio());
|
---|
182 | }
|
---|
183 |
|
---|
184 | /// sets the asio endpoint
|
---|
185 | void asio( tcp::endpoint& endp ) {
|
---|
186 | ip.asio(endp.address());
|
---|
187 | port_.asio(endp.port());
|
---|
188 | }
|
---|
189 | };
|
---|
190 |
|
---|
191 | }} // namespace ariba::addressing
|
---|
192 |
|
---|
193 | namespace boost {
|
---|
194 |
|
---|
195 | template<>
|
---|
196 | struct hash<ariba::addressing::tcpip_endpoint>:
|
---|
197 | public std::unary_function<ariba::addressing::tcpip_endpoint, std::size_t> {
|
---|
198 | std::size_t operator()(const ariba::addressing::tcpip_endpoint& ep) const {
|
---|
199 | return hash_value(ep.to_string());
|
---|
200 | }
|
---|
201 | };
|
---|
202 |
|
---|
203 | }
|
---|
204 |
|
---|
205 |
|
---|
206 | #endif /* TCPIP_ENDPOINT_HPP_ */
|
---|