author | terom |
Mon, 15 Dec 2008 23:56:42 +0000 | |
changeset 378 | 5589abf5e61b |
parent 187 | f41f894213ca |
child 380 | d193dd1d8a7e |
permissions | -rw-r--r-- |
187 | 1 |
|
2 |
#include "Socket.hh" |
|
378
5589abf5e61b
break the network code. Too late to set up a branch for this now
terom
parents:
187
diff
changeset
|
3 |
#include "../Engine.hh" |
187 | 4 |
|
5 |
#include <sstream> |
|
6 |
||
378
5589abf5e61b
break the network code. Too late to set up a branch for this now
terom
parents:
187
diff
changeset
|
7 |
NetworkSocket::NetworkSocket (int family, int socktype, int protocol) : |
5589abf5e61b
break the network code. Too late to set up a branch for this now
terom
parents:
187
diff
changeset
|
8 |
fd(-1), family(family), socktype(socktype), protocol(protocol), bound(false) |
5589abf5e61b
break the network code. Too late to set up a branch for this now
terom
parents:
187
diff
changeset
|
9 |
{ |
5589abf5e61b
break the network code. Too late to set up a branch for this now
terom
parents:
187
diff
changeset
|
10 |
|
5589abf5e61b
break the network code. Too late to set up a branch for this now
terom
parents:
187
diff
changeset
|
11 |
} |
5589abf5e61b
break the network code. Too late to set up a branch for this now
terom
parents:
187
diff
changeset
|
12 |
|
5589abf5e61b
break the network code. Too late to set up a branch for this now
terom
parents:
187
diff
changeset
|
13 |
NetworkSocket::NetworkSocket (int fd) : |
5589abf5e61b
break the network code. Too late to set up a branch for this now
terom
parents:
187
diff
changeset
|
14 |
fd(fd), family(0), socktype(0), protocol(0), bound(false) |
5589abf5e61b
break the network code. Too late to set up a branch for this now
terom
parents:
187
diff
changeset
|
15 |
{ |
5589abf5e61b
break the network code. Too late to set up a branch for this now
terom
parents:
187
diff
changeset
|
16 |
|
5589abf5e61b
break the network code. Too late to set up a branch for this now
terom
parents:
187
diff
changeset
|
17 |
} |
5589abf5e61b
break the network code. Too late to set up a branch for this now
terom
parents:
187
diff
changeset
|
18 |
|
5589abf5e61b
break the network code. Too late to set up a branch for this now
terom
parents:
187
diff
changeset
|
19 |
NetworkSocket::~NetworkSocket (void) { |
5589abf5e61b
break the network code. Too late to set up a branch for this now
terom
parents:
187
diff
changeset
|
20 |
// close any remaining socket |
5589abf5e61b
break the network code. Too late to set up a branch for this now
terom
parents:
187
diff
changeset
|
21 |
if (fd >= 0) |
5589abf5e61b
break the network code. Too late to set up a branch for this now
terom
parents:
187
diff
changeset
|
22 |
force_close(); |
5589abf5e61b
break the network code. Too late to set up a branch for this now
terom
parents:
187
diff
changeset
|
23 |
} |
5589abf5e61b
break the network code. Too late to set up a branch for this now
terom
parents:
187
diff
changeset
|
24 |
|
5589abf5e61b
break the network code. Too late to set up a branch for this now
terom
parents:
187
diff
changeset
|
25 |
void NetworkSocket::lazy_socket (int family, int socktype, int protocol) { |
5589abf5e61b
break the network code. Too late to set up a branch for this now
terom
parents:
187
diff
changeset
|
26 |
// if we already have a socket, exit |
5589abf5e61b
break the network code. Too late to set up a branch for this now
terom
parents:
187
diff
changeset
|
27 |
if (fd >= 0) |
5589abf5e61b
break the network code. Too late to set up a branch for this now
terom
parents:
187
diff
changeset
|
28 |
return; |
5589abf5e61b
break the network code. Too late to set up a branch for this now
terom
parents:
187
diff
changeset
|
29 |
|
5589abf5e61b
break the network code. Too late to set up a branch for this now
terom
parents:
187
diff
changeset
|
30 |
// check that we don't have conflicting family/type/protocol |
5589abf5e61b
break the network code. Too late to set up a branch for this now
terom
parents:
187
diff
changeset
|
31 |
if ( |
5589abf5e61b
break the network code. Too late to set up a branch for this now
terom
parents:
187
diff
changeset
|
32 |
(this->family && family != this->family) || |
5589abf5e61b
break the network code. Too late to set up a branch for this now
terom
parents:
187
diff
changeset
|
33 |
(this->socktype && socktype != this->socktype) || |
5589abf5e61b
break the network code. Too late to set up a branch for this now
terom
parents:
187
diff
changeset
|
34 |
(this->protocol && protocol != this->protocol) |
5589abf5e61b
break the network code. Too late to set up a branch for this now
terom
parents:
187
diff
changeset
|
35 |
) |
5589abf5e61b
break the network code. Too late to set up a branch for this now
terom
parents:
187
diff
changeset
|
36 |
throw NetworkSocketError(*this, "socket.create", "family/socktype/protocol mismatch"); |
5589abf5e61b
break the network code. Too late to set up a branch for this now
terom
parents:
187
diff
changeset
|
37 |
|
5589abf5e61b
break the network code. Too late to set up a branch for this now
terom
parents:
187
diff
changeset
|
38 |
// create the socket or fail |
5589abf5e61b
break the network code. Too late to set up a branch for this now
terom
parents:
187
diff
changeset
|
39 |
if ((fd = ::socket(family, socktype, protocol)) < 0) |
5589abf5e61b
break the network code. Too late to set up a branch for this now
terom
parents:
187
diff
changeset
|
40 |
throw NetworkSocketOSError(*this, "socket"); |
5589abf5e61b
break the network code. Too late to set up a branch for this now
terom
parents:
187
diff
changeset
|
41 |
|
5589abf5e61b
break the network code. Too late to set up a branch for this now
terom
parents:
187
diff
changeset
|
42 |
// update our family/type/protocol |
5589abf5e61b
break the network code. Too late to set up a branch for this now
terom
parents:
187
diff
changeset
|
43 |
this->family = family; |
5589abf5e61b
break the network code. Too late to set up a branch for this now
terom
parents:
187
diff
changeset
|
44 |
this->socktype = socktype; |
5589abf5e61b
break the network code. Too late to set up a branch for this now
terom
parents:
187
diff
changeset
|
45 |
this->protocol = protocol; |
5589abf5e61b
break the network code. Too late to set up a branch for this now
terom
parents:
187
diff
changeset
|
46 |
} |
5589abf5e61b
break the network code. Too late to set up a branch for this now
terom
parents:
187
diff
changeset
|
47 |
|
5589abf5e61b
break the network code. Too late to set up a branch for this now
terom
parents:
187
diff
changeset
|
48 |
void NetworkSocket::force_close (void) { |
5589abf5e61b
break the network code. Too late to set up a branch for this now
terom
parents:
187
diff
changeset
|
49 |
// use closesocket |
5589abf5e61b
break the network code. Too late to set up a branch for this now
terom
parents:
187
diff
changeset
|
50 |
if (::closesocket(fd)) |
5589abf5e61b
break the network code. Too late to set up a branch for this now
terom
parents:
187
diff
changeset
|
51 |
Engine::log(WARN, "socket.force_close") << "error closing socket: " /* XXX: errno */; |
5589abf5e61b
break the network code. Too late to set up a branch for this now
terom
parents:
187
diff
changeset
|
52 |
|
5589abf5e61b
break the network code. Too late to set up a branch for this now
terom
parents:
187
diff
changeset
|
53 |
// invalidate fd |
5589abf5e61b
break the network code. Too late to set up a branch for this now
terom
parents:
187
diff
changeset
|
54 |
fd = -1; |
5589abf5e61b
break the network code. Too late to set up a branch for this now
terom
parents:
187
diff
changeset
|
55 |
} |
5589abf5e61b
break the network code. Too late to set up a branch for this now
terom
parents:
187
diff
changeset
|
56 |
|
5589abf5e61b
break the network code. Too late to set up a branch for this now
terom
parents:
187
diff
changeset
|
57 |
void NetworkSocket::bind (const NetworkAddress &addr) { |
5589abf5e61b
break the network code. Too late to set up a branch for this now
terom
parents:
187
diff
changeset
|
58 |
// get our addrinfo |
5589abf5e61b
break the network code. Too late to set up a branch for this now
terom
parents:
187
diff
changeset
|
59 |
addrinfo *r, *results = addr.get_addrinfo(family, socktype, protocol, AI_PASSIVE); |
5589abf5e61b
break the network code. Too late to set up a branch for this now
terom
parents:
187
diff
changeset
|
60 |
|
5589abf5e61b
break the network code. Too late to set up a branch for this now
terom
parents:
187
diff
changeset
|
61 |
// find the right address to bind to |
5589abf5e61b
break the network code. Too late to set up a branch for this now
terom
parents:
187
diff
changeset
|
62 |
for (r = results; r; r = r->ai_next) { |
5589abf5e61b
break the network code. Too late to set up a branch for this now
terom
parents:
187
diff
changeset
|
63 |
// create socket if needed, warn on errors |
5589abf5e61b
break the network code. Too late to set up a branch for this now
terom
parents:
187
diff
changeset
|
64 |
try { |
5589abf5e61b
break the network code. Too late to set up a branch for this now
terom
parents:
187
diff
changeset
|
65 |
lazy_socket(r->ai_family, r->ai_socktype, r->ai_protocol); |
5589abf5e61b
break the network code. Too late to set up a branch for this now
terom
parents:
187
diff
changeset
|
66 |
|
5589abf5e61b
break the network code. Too late to set up a branch for this now
terom
parents:
187
diff
changeset
|
67 |
} catch (NetworkSocketError &e) { |
5589abf5e61b
break the network code. Too late to set up a branch for this now
terom
parents:
187
diff
changeset
|
68 |
Engine::log(WARN, "socket.bind") << "unable to create socket for " << r << ": " << e.what(); |
5589abf5e61b
break the network code. Too late to set up a branch for this now
terom
parents:
187
diff
changeset
|
69 |
continue; |
5589abf5e61b
break the network code. Too late to set up a branch for this now
terom
parents:
187
diff
changeset
|
70 |
} |
5589abf5e61b
break the network code. Too late to set up a branch for this now
terom
parents:
187
diff
changeset
|
71 |
|
5589abf5e61b
break the network code. Too late to set up a branch for this now
terom
parents:
187
diff
changeset
|
72 |
// bind it, warn on errors |
5589abf5e61b
break the network code. Too late to set up a branch for this now
terom
parents:
187
diff
changeset
|
73 |
if (::bind(fd, r->ai_addr, r->ai_addrlen)) { |
5589abf5e61b
break the network code. Too late to set up a branch for this now
terom
parents:
187
diff
changeset
|
74 |
Engine::log(WARN, "socket.bind") << "unable to bind on " << r /* XXX: errno */ ; |
5589abf5e61b
break the network code. Too late to set up a branch for this now
terom
parents:
187
diff
changeset
|
75 |
|
5589abf5e61b
break the network code. Too late to set up a branch for this now
terom
parents:
187
diff
changeset
|
76 |
// close the bad socket |
5589abf5e61b
break the network code. Too late to set up a branch for this now
terom
parents:
187
diff
changeset
|
77 |
force_close(); |
5589abf5e61b
break the network code. Too late to set up a branch for this now
terom
parents:
187
diff
changeset
|
78 |
|
5589abf5e61b
break the network code. Too late to set up a branch for this now
terom
parents:
187
diff
changeset
|
79 |
continue; |
5589abf5e61b
break the network code. Too late to set up a branch for this now
terom
parents:
187
diff
changeset
|
80 |
|
5589abf5e61b
break the network code. Too late to set up a branch for this now
terom
parents:
187
diff
changeset
|
81 |
} else { |
5589abf5e61b
break the network code. Too late to set up a branch for this now
terom
parents:
187
diff
changeset
|
82 |
// we have a bound socket, break |
5589abf5e61b
break the network code. Too late to set up a branch for this now
terom
parents:
187
diff
changeset
|
83 |
break; |
5589abf5e61b
break the network code. Too late to set up a branch for this now
terom
parents:
187
diff
changeset
|
84 |
} |
5589abf5e61b
break the network code. Too late to set up a branch for this now
terom
parents:
187
diff
changeset
|
85 |
} |
5589abf5e61b
break the network code. Too late to set up a branch for this now
terom
parents:
187
diff
changeset
|
86 |
|
5589abf5e61b
break the network code. Too late to set up a branch for this now
terom
parents:
187
diff
changeset
|
87 |
// release our addrinfo |
5589abf5e61b
break the network code. Too late to set up a branch for this now
terom
parents:
187
diff
changeset
|
88 |
freeaddrinfo(results); |
5589abf5e61b
break the network code. Too late to set up a branch for this now
terom
parents:
187
diff
changeset
|
89 |
|
5589abf5e61b
break the network code. Too late to set up a branch for this now
terom
parents:
187
diff
changeset
|
90 |
// if we failed to bind, r is a NULL pointer |
5589abf5e61b
break the network code. Too late to set up a branch for this now
terom
parents:
187
diff
changeset
|
91 |
if (r == NULL) |
5589abf5e61b
break the network code. Too late to set up a branch for this now
terom
parents:
187
diff
changeset
|
92 |
throw NetworkSocketError(*this, "bind", "unable to bind on any addresses"); |
5589abf5e61b
break the network code. Too late to set up a branch for this now
terom
parents:
187
diff
changeset
|
93 |
|
5589abf5e61b
break the network code. Too late to set up a branch for this now
terom
parents:
187
diff
changeset
|
94 |
// mark ourselves as bound |
5589abf5e61b
break the network code. Too late to set up a branch for this now
terom
parents:
187
diff
changeset
|
95 |
bound = true; |
5589abf5e61b
break the network code. Too late to set up a branch for this now
terom
parents:
187
diff
changeset
|
96 |
} |
5589abf5e61b
break the network code. Too late to set up a branch for this now
terom
parents:
187
diff
changeset
|
97 |
|
5589abf5e61b
break the network code. Too late to set up a branch for this now
terom
parents:
187
diff
changeset
|
98 |
void NetworkSocket::listen (int backlog) { |
5589abf5e61b
break the network code. Too late to set up a branch for this now
terom
parents:
187
diff
changeset
|
99 |
// just call listen |
5589abf5e61b
break the network code. Too late to set up a branch for this now
terom
parents:
187
diff
changeset
|
100 |
if (::listen(fd, backlog)) |
5589abf5e61b
break the network code. Too late to set up a branch for this now
terom
parents:
187
diff
changeset
|
101 |
throw NetworkSocketOSError(*this, "listen"); |
5589abf5e61b
break the network code. Too late to set up a branch for this now
terom
parents:
187
diff
changeset
|
102 |
} |
5589abf5e61b
break the network code. Too late to set up a branch for this now
terom
parents:
187
diff
changeset
|
103 |
|
5589abf5e61b
break the network code. Too late to set up a branch for this now
terom
parents:
187
diff
changeset
|
104 |
NetworkAddress NetworkSocket::get_local_address (void) { |
5589abf5e61b
break the network code. Too late to set up a branch for this now
terom
parents:
187
diff
changeset
|
105 |
sockaddr_storage addr; |
5589abf5e61b
break the network code. Too late to set up a branch for this now
terom
parents:
187
diff
changeset
|
106 |
socklen_t addrlen = sizeof(addr); |
5589abf5e61b
break the network code. Too late to set up a branch for this now
terom
parents:
187
diff
changeset
|
107 |
|
5589abf5e61b
break the network code. Too late to set up a branch for this now
terom
parents:
187
diff
changeset
|
108 |
// do getsockname() |
5589abf5e61b
break the network code. Too late to set up a branch for this now
terom
parents:
187
diff
changeset
|
109 |
if (::getsockname(fd, (sockaddr *) &addr, &addrlen)) |
5589abf5e61b
break the network code. Too late to set up a branch for this now
terom
parents:
187
diff
changeset
|
110 |
throw NetworkSocketOSError(*this, "getsockname"); |
5589abf5e61b
break the network code. Too late to set up a branch for this now
terom
parents:
187
diff
changeset
|
111 |
|
5589abf5e61b
break the network code. Too late to set up a branch for this now
terom
parents:
187
diff
changeset
|
112 |
// return addr |
5589abf5e61b
break the network code. Too late to set up a branch for this now
terom
parents:
187
diff
changeset
|
113 |
return NetworkAddress((sockaddr *) &addr, addrlen); |
5589abf5e61b
break the network code. Too late to set up a branch for this now
terom
parents:
187
diff
changeset
|
114 |
} |
5589abf5e61b
break the network code. Too late to set up a branch for this now
terom
parents:
187
diff
changeset
|
115 |
|
5589abf5e61b
break the network code. Too late to set up a branch for this now
terom
parents:
187
diff
changeset
|
116 |
NetworkAddress NetworkSocket::get_remote_address (void) { |
5589abf5e61b
break the network code. Too late to set up a branch for this now
terom
parents:
187
diff
changeset
|
117 |
sockaddr_storage addr; |
5589abf5e61b
break the network code. Too late to set up a branch for this now
terom
parents:
187
diff
changeset
|
118 |
socklen_t addrlen = sizeof(addr); |
5589abf5e61b
break the network code. Too late to set up a branch for this now
terom
parents:
187
diff
changeset
|
119 |
|
5589abf5e61b
break the network code. Too late to set up a branch for this now
terom
parents:
187
diff
changeset
|
120 |
// do getpeername() |
5589abf5e61b
break the network code. Too late to set up a branch for this now
terom
parents:
187
diff
changeset
|
121 |
if (::getpeername(fd, (sockaddr *) &addr, &addrlen)) |
5589abf5e61b
break the network code. Too late to set up a branch for this now
terom
parents:
187
diff
changeset
|
122 |
throw NetworkSocketOSError(*this, "getpeername"); |
5589abf5e61b
break the network code. Too late to set up a branch for this now
terom
parents:
187
diff
changeset
|
123 |
|
5589abf5e61b
break the network code. Too late to set up a branch for this now
terom
parents:
187
diff
changeset
|
124 |
// return addr |
5589abf5e61b
break the network code. Too late to set up a branch for this now
terom
parents:
187
diff
changeset
|
125 |
return NetworkAddress((sockaddr *) &addr, addrlen); |
5589abf5e61b
break the network code. Too late to set up a branch for this now
terom
parents:
187
diff
changeset
|
126 |
} |
5589abf5e61b
break the network code. Too late to set up a branch for this now
terom
parents:
187
diff
changeset
|
127 |
|
5589abf5e61b
break the network code. Too late to set up a branch for this now
terom
parents:
187
diff
changeset
|
128 |
void NetworkSocket::set_nonblocking (bool nonblocking) { |
5589abf5e61b
break the network code. Too late to set up a branch for this now
terom
parents:
187
diff
changeset
|
129 |
// XXX: linux-specific |
5589abf5e61b
break the network code. Too late to set up a branch for this now
terom
parents:
187
diff
changeset
|
130 |
if (fcntl(fd, F_SETFL, O_NONBLOCK, nonblocking ? 1 : 0) == -1) |
5589abf5e61b
break the network code. Too late to set up a branch for this now
terom
parents:
187
diff
changeset
|
131 |
throw NetworkSocketOSError(*this, "fcntl(F_SETFL, O_NONBLOCK)"); |
5589abf5e61b
break the network code. Too late to set up a branch for this now
terom
parents:
187
diff
changeset
|
132 |
} |
5589abf5e61b
break the network code. Too late to set up a branch for this now
terom
parents:
187
diff
changeset
|
133 |
|
5589abf5e61b
break the network code. Too late to set up a branch for this now
terom
parents:
187
diff
changeset
|
134 |
NetworkSocket* NetworkSocket::accept (NetworkAddress *src) { |
5589abf5e61b
break the network code. Too late to set up a branch for this now
terom
parents:
187
diff
changeset
|
135 |
int new_fd; |
5589abf5e61b
break the network code. Too late to set up a branch for this now
terom
parents:
187
diff
changeset
|
136 |
sockaddr_storage addr; |
5589abf5e61b
break the network code. Too late to set up a branch for this now
terom
parents:
187
diff
changeset
|
137 |
socklen_t addrlen = sizeof(addr); |
5589abf5e61b
break the network code. Too late to set up a branch for this now
terom
parents:
187
diff
changeset
|
138 |
|
5589abf5e61b
break the network code. Too late to set up a branch for this now
terom
parents:
187
diff
changeset
|
139 |
// try and get the FD |
5589abf5e61b
break the network code. Too late to set up a branch for this now
terom
parents:
187
diff
changeset
|
140 |
if ((new_fd = ::accept(fd, (sockaddr *) &addr, &addrlen))) |
5589abf5e61b
break the network code. Too late to set up a branch for this now
terom
parents:
187
diff
changeset
|
141 |
throw NetworkSocketOSError(*this, "accept"); |
5589abf5e61b
break the network code. Too late to set up a branch for this now
terom
parents:
187
diff
changeset
|
142 |
|
5589abf5e61b
break the network code. Too late to set up a branch for this now
terom
parents:
187
diff
changeset
|
143 |
// allocate new NetworkSocket for new_fd |
5589abf5e61b
break the network code. Too late to set up a branch for this now
terom
parents:
187
diff
changeset
|
144 |
NetworkSocket *socket = new NetworkSocket(new_fd); |
5589abf5e61b
break the network code. Too late to set up a branch for this now
terom
parents:
187
diff
changeset
|
145 |
|
5589abf5e61b
break the network code. Too late to set up a branch for this now
terom
parents:
187
diff
changeset
|
146 |
// update src |
5589abf5e61b
break the network code. Too late to set up a branch for this now
terom
parents:
187
diff
changeset
|
147 |
if (src) |
5589abf5e61b
break the network code. Too late to set up a branch for this now
terom
parents:
187
diff
changeset
|
148 |
src->set_sockaddr((sockaddr *) &addr, addrlen); |
5589abf5e61b
break the network code. Too late to set up a branch for this now
terom
parents:
187
diff
changeset
|
149 |
|
5589abf5e61b
break the network code. Too late to set up a branch for this now
terom
parents:
187
diff
changeset
|
150 |
// done |
5589abf5e61b
break the network code. Too late to set up a branch for this now
terom
parents:
187
diff
changeset
|
151 |
return socket; |
5589abf5e61b
break the network code. Too late to set up a branch for this now
terom
parents:
187
diff
changeset
|
152 |
} |
5589abf5e61b
break the network code. Too late to set up a branch for this now
terom
parents:
187
diff
changeset
|
153 |
|
5589abf5e61b
break the network code. Too late to set up a branch for this now
terom
parents:
187
diff
changeset
|
154 |
void NetworkSocket::connect (const NetworkAddress &addr) { |
5589abf5e61b
break the network code. Too late to set up a branch for this now
terom
parents:
187
diff
changeset
|
155 |
// get our addrinfo |
5589abf5e61b
break the network code. Too late to set up a branch for this now
terom
parents:
187
diff
changeset
|
156 |
addrinfo *r, *results = addr.get_addrinfo(family, socktype, protocol); |
5589abf5e61b
break the network code. Too late to set up a branch for this now
terom
parents:
187
diff
changeset
|
157 |
|
5589abf5e61b
break the network code. Too late to set up a branch for this now
terom
parents:
187
diff
changeset
|
158 |
// find the right address to bind to |
5589abf5e61b
break the network code. Too late to set up a branch for this now
terom
parents:
187
diff
changeset
|
159 |
for (r = results; r; r = r->ai_next) { |
5589abf5e61b
break the network code. Too late to set up a branch for this now
terom
parents:
187
diff
changeset
|
160 |
// create socket if needed, warn on errors |
5589abf5e61b
break the network code. Too late to set up a branch for this now
terom
parents:
187
diff
changeset
|
161 |
try { |
5589abf5e61b
break the network code. Too late to set up a branch for this now
terom
parents:
187
diff
changeset
|
162 |
lazy_socket(r->ai_family, r->ai_socktype, r->ai_protocol); |
5589abf5e61b
break the network code. Too late to set up a branch for this now
terom
parents:
187
diff
changeset
|
163 |
|
5589abf5e61b
break the network code. Too late to set up a branch for this now
terom
parents:
187
diff
changeset
|
164 |
} catch (NetworkSocketError &e) { |
5589abf5e61b
break the network code. Too late to set up a branch for this now
terom
parents:
187
diff
changeset
|
165 |
Engine::log(WARN, "socket.connect") << "unable to create socket for " << r << ": " << e.what(); |
5589abf5e61b
break the network code. Too late to set up a branch for this now
terom
parents:
187
diff
changeset
|
166 |
continue; |
5589abf5e61b
break the network code. Too late to set up a branch for this now
terom
parents:
187
diff
changeset
|
167 |
} |
5589abf5e61b
break the network code. Too late to set up a branch for this now
terom
parents:
187
diff
changeset
|
168 |
|
5589abf5e61b
break the network code. Too late to set up a branch for this now
terom
parents:
187
diff
changeset
|
169 |
// connect it, warn on errors |
5589abf5e61b
break the network code. Too late to set up a branch for this now
terom
parents:
187
diff
changeset
|
170 |
if (::connect(fd, r->ai_addr, r->ai_addrlen)) { |
5589abf5e61b
break the network code. Too late to set up a branch for this now
terom
parents:
187
diff
changeset
|
171 |
Engine::log(WARN, "socket.connect") << "unable to connect to " << r /* XXX: errno */ ; |
5589abf5e61b
break the network code. Too late to set up a branch for this now
terom
parents:
187
diff
changeset
|
172 |
|
5589abf5e61b
break the network code. Too late to set up a branch for this now
terom
parents:
187
diff
changeset
|
173 |
// close unless bound, to not keep invalid sockets hanging around |
5589abf5e61b
break the network code. Too late to set up a branch for this now
terom
parents:
187
diff
changeset
|
174 |
if (!bound) |
5589abf5e61b
break the network code. Too late to set up a branch for this now
terom
parents:
187
diff
changeset
|
175 |
force_close(); |
5589abf5e61b
break the network code. Too late to set up a branch for this now
terom
parents:
187
diff
changeset
|
176 |
|
5589abf5e61b
break the network code. Too late to set up a branch for this now
terom
parents:
187
diff
changeset
|
177 |
continue; |
5589abf5e61b
break the network code. Too late to set up a branch for this now
terom
parents:
187
diff
changeset
|
178 |
|
5589abf5e61b
break the network code. Too late to set up a branch for this now
terom
parents:
187
diff
changeset
|
179 |
} else { |
5589abf5e61b
break the network code. Too late to set up a branch for this now
terom
parents:
187
diff
changeset
|
180 |
// we have a connected socket, break |
5589abf5e61b
break the network code. Too late to set up a branch for this now
terom
parents:
187
diff
changeset
|
181 |
break; |
5589abf5e61b
break the network code. Too late to set up a branch for this now
terom
parents:
187
diff
changeset
|
182 |
} |
5589abf5e61b
break the network code. Too late to set up a branch for this now
terom
parents:
187
diff
changeset
|
183 |
} |
5589abf5e61b
break the network code. Too late to set up a branch for this now
terom
parents:
187
diff
changeset
|
184 |
|
5589abf5e61b
break the network code. Too late to set up a branch for this now
terom
parents:
187
diff
changeset
|
185 |
// release our addrinfo |
5589abf5e61b
break the network code. Too late to set up a branch for this now
terom
parents:
187
diff
changeset
|
186 |
freeaddrinfo(results); |
5589abf5e61b
break the network code. Too late to set up a branch for this now
terom
parents:
187
diff
changeset
|
187 |
|
5589abf5e61b
break the network code. Too late to set up a branch for this now
terom
parents:
187
diff
changeset
|
188 |
// if we failed to connect, r is a NULL pointer |
5589abf5e61b
break the network code. Too late to set up a branch for this now
terom
parents:
187
diff
changeset
|
189 |
if (r == NULL) |
5589abf5e61b
break the network code. Too late to set up a branch for this now
terom
parents:
187
diff
changeset
|
190 |
throw NetworkSocketError(*this, "connect", "unable to connect to any addresses"); |
5589abf5e61b
break the network code. Too late to set up a branch for this now
terom
parents:
187
diff
changeset
|
191 |
} |
5589abf5e61b
break the network code. Too late to set up a branch for this now
terom
parents:
187
diff
changeset
|
192 |
|
5589abf5e61b
break the network code. Too late to set up a branch for this now
terom
parents:
187
diff
changeset
|
193 |
size_t NetworkSocket::send (const char *buf, size_t size, const NetworkAddress *dest) { |
5589abf5e61b
break the network code. Too late to set up a branch for this now
terom
parents:
187
diff
changeset
|
194 |
ssize_t ret; |
5589abf5e61b
break the network code. Too late to set up a branch for this now
terom
parents:
187
diff
changeset
|
195 |
|
5589abf5e61b
break the network code. Too late to set up a branch for this now
terom
parents:
187
diff
changeset
|
196 |
// use send or sendto? |
5589abf5e61b
break the network code. Too late to set up a branch for this now
terom
parents:
187
diff
changeset
|
197 |
if (dest) { |
5589abf5e61b
break the network code. Too late to set up a branch for this now
terom
parents:
187
diff
changeset
|
198 |
const sockaddr *addr; |
5589abf5e61b
break the network code. Too late to set up a branch for this now
terom
parents:
187
diff
changeset
|
199 |
socklen_t addr_len; |
5589abf5e61b
break the network code. Too late to set up a branch for this now
terom
parents:
187
diff
changeset
|
200 |
|
5589abf5e61b
break the network code. Too late to set up a branch for this now
terom
parents:
187
diff
changeset
|
201 |
// get destination address |
5589abf5e61b
break the network code. Too late to set up a branch for this now
terom
parents:
187
diff
changeset
|
202 |
addr = dest->get_sockaddr(addr_len); |
5589abf5e61b
break the network code. Too late to set up a branch for this now
terom
parents:
187
diff
changeset
|
203 |
|
5589abf5e61b
break the network code. Too late to set up a branch for this now
terom
parents:
187
diff
changeset
|
204 |
// sendto() |
5589abf5e61b
break the network code. Too late to set up a branch for this now
terom
parents:
187
diff
changeset
|
205 |
if ((ret = ::sendto(fd, buf, size, 0, addr, addr_len)) < 0 && errno != EAGAIN) |
5589abf5e61b
break the network code. Too late to set up a branch for this now
terom
parents:
187
diff
changeset
|
206 |
throw NetworkSocketOSError(*this, "sendto"); |
5589abf5e61b
break the network code. Too late to set up a branch for this now
terom
parents:
187
diff
changeset
|
207 |
|
5589abf5e61b
break the network code. Too late to set up a branch for this now
terom
parents:
187
diff
changeset
|
208 |
} else { |
5589abf5e61b
break the network code. Too late to set up a branch for this now
terom
parents:
187
diff
changeset
|
209 |
// send() |
5589abf5e61b
break the network code. Too late to set up a branch for this now
terom
parents:
187
diff
changeset
|
210 |
if ((ret = ::send(fd, buf, size, 0)) < 0 && errno != EAGAIN) |
5589abf5e61b
break the network code. Too late to set up a branch for this now
terom
parents:
187
diff
changeset
|
211 |
throw NetworkSocketOSError(*this, "send"); |
5589abf5e61b
break the network code. Too late to set up a branch for this now
terom
parents:
187
diff
changeset
|
212 |
|
5589abf5e61b
break the network code. Too late to set up a branch for this now
terom
parents:
187
diff
changeset
|
213 |
} |
5589abf5e61b
break the network code. Too late to set up a branch for this now
terom
parents:
187
diff
changeset
|
214 |
|
5589abf5e61b
break the network code. Too late to set up a branch for this now
terom
parents:
187
diff
changeset
|
215 |
// sanity-check |
5589abf5e61b
break the network code. Too late to set up a branch for this now
terom
parents:
187
diff
changeset
|
216 |
if (ret == 0) { |
5589abf5e61b
break the network code. Too late to set up a branch for this now
terom
parents:
187
diff
changeset
|
217 |
// XXX: not sure what this means... |
5589abf5e61b
break the network code. Too late to set up a branch for this now
terom
parents:
187
diff
changeset
|
218 |
Engine::log(ERROR, "socket.send") << "send[to] returned zero, trying again..."; |
5589abf5e61b
break the network code. Too late to set up a branch for this now
terom
parents:
187
diff
changeset
|
219 |
return 0; |
5589abf5e61b
break the network code. Too late to set up a branch for this now
terom
parents:
187
diff
changeset
|
220 |
} |
5589abf5e61b
break the network code. Too late to set up a branch for this now
terom
parents:
187
diff
changeset
|
221 |
|
5589abf5e61b
break the network code. Too late to set up a branch for this now
terom
parents:
187
diff
changeset
|
222 |
// EAGAIN? |
5589abf5e61b
break the network code. Too late to set up a branch for this now
terom
parents:
187
diff
changeset
|
223 |
if (ret < 0) |
5589abf5e61b
break the network code. Too late to set up a branch for this now
terom
parents:
187
diff
changeset
|
224 |
return 0; |
5589abf5e61b
break the network code. Too late to set up a branch for this now
terom
parents:
187
diff
changeset
|
225 |
|
5589abf5e61b
break the network code. Too late to set up a branch for this now
terom
parents:
187
diff
changeset
|
226 |
// return number of bytes sent |
5589abf5e61b
break the network code. Too late to set up a branch for this now
terom
parents:
187
diff
changeset
|
227 |
return ret; |
5589abf5e61b
break the network code. Too late to set up a branch for this now
terom
parents:
187
diff
changeset
|
228 |
} |
5589abf5e61b
break the network code. Too late to set up a branch for this now
terom
parents:
187
diff
changeset
|
229 |
|
5589abf5e61b
break the network code. Too late to set up a branch for this now
terom
parents:
187
diff
changeset
|
230 |
size_t NetworkSocket::recv (char *buf, size_t size, NetworkAddress *src) { |
5589abf5e61b
break the network code. Too late to set up a branch for this now
terom
parents:
187
diff
changeset
|
231 |
ssize_t ret; |
5589abf5e61b
break the network code. Too late to set up a branch for this now
terom
parents:
187
diff
changeset
|
232 |
|
5589abf5e61b
break the network code. Too late to set up a branch for this now
terom
parents:
187
diff
changeset
|
233 |
// use recv or recvfrom? |
5589abf5e61b
break the network code. Too late to set up a branch for this now
terom
parents:
187
diff
changeset
|
234 |
if (src) { |
5589abf5e61b
break the network code. Too late to set up a branch for this now
terom
parents:
187
diff
changeset
|
235 |
sockaddr_storage addr; |
5589abf5e61b
break the network code. Too late to set up a branch for this now
terom
parents:
187
diff
changeset
|
236 |
socklen_t addr_len = sizeof(addr); |
5589abf5e61b
break the network code. Too late to set up a branch for this now
terom
parents:
187
diff
changeset
|
237 |
|
5589abf5e61b
break the network code. Too late to set up a branch for this now
terom
parents:
187
diff
changeset
|
238 |
// recvfrom() |
5589abf5e61b
break the network code. Too late to set up a branch for this now
terom
parents:
187
diff
changeset
|
239 |
if ((ret = ::recvfrom(fd, buf, size, 0, (sockaddr *) &addr, &addr_len)) < 0 && errno != EAGAIN) |
5589abf5e61b
break the network code. Too late to set up a branch for this now
terom
parents:
187
diff
changeset
|
240 |
throw NetworkSocketOSError(*this, "recvfrom"); |
5589abf5e61b
break the network code. Too late to set up a branch for this now
terom
parents:
187
diff
changeset
|
241 |
|
5589abf5e61b
break the network code. Too late to set up a branch for this now
terom
parents:
187
diff
changeset
|
242 |
// modify src... |
5589abf5e61b
break the network code. Too late to set up a branch for this now
terom
parents:
187
diff
changeset
|
243 |
src->set_sockaddr((sockaddr *) &addr, addr_len); |
5589abf5e61b
break the network code. Too late to set up a branch for this now
terom
parents:
187
diff
changeset
|
244 |
|
5589abf5e61b
break the network code. Too late to set up a branch for this now
terom
parents:
187
diff
changeset
|
245 |
} else { |
5589abf5e61b
break the network code. Too late to set up a branch for this now
terom
parents:
187
diff
changeset
|
246 |
// recv |
5589abf5e61b
break the network code. Too late to set up a branch for this now
terom
parents:
187
diff
changeset
|
247 |
if ((ret = ::recv(fd, buf, size, 0)) < 0 && errno != EAGAIN) |
5589abf5e61b
break the network code. Too late to set up a branch for this now
terom
parents:
187
diff
changeset
|
248 |
throw NetworkSocketOSError(*this, "recv"); |
5589abf5e61b
break the network code. Too late to set up a branch for this now
terom
parents:
187
diff
changeset
|
249 |
|
5589abf5e61b
break the network code. Too late to set up a branch for this now
terom
parents:
187
diff
changeset
|
250 |
} |
5589abf5e61b
break the network code. Too late to set up a branch for this now
terom
parents:
187
diff
changeset
|
251 |
|
5589abf5e61b
break the network code. Too late to set up a branch for this now
terom
parents:
187
diff
changeset
|
252 |
// EOF? |
5589abf5e61b
break the network code. Too late to set up a branch for this now
terom
parents:
187
diff
changeset
|
253 |
if (ret == 0) |
5589abf5e61b
break the network code. Too late to set up a branch for this now
terom
parents:
187
diff
changeset
|
254 |
throw NetworkSocketEOFError(*this, "recv"); |
5589abf5e61b
break the network code. Too late to set up a branch for this now
terom
parents:
187
diff
changeset
|
255 |
|
5589abf5e61b
break the network code. Too late to set up a branch for this now
terom
parents:
187
diff
changeset
|
256 |
// EAGAIN? |
5589abf5e61b
break the network code. Too late to set up a branch for this now
terom
parents:
187
diff
changeset
|
257 |
if (ret < 0) |
5589abf5e61b
break the network code. Too late to set up a branch for this now
terom
parents:
187
diff
changeset
|
258 |
return 0; |
5589abf5e61b
break the network code. Too late to set up a branch for this now
terom
parents:
187
diff
changeset
|
259 |
|
5589abf5e61b
break the network code. Too late to set up a branch for this now
terom
parents:
187
diff
changeset
|
260 |
// return number of bytes received |
5589abf5e61b
break the network code. Too late to set up a branch for this now
terom
parents:
187
diff
changeset
|
261 |
return ret; |
5589abf5e61b
break the network code. Too late to set up a branch for this now
terom
parents:
187
diff
changeset
|
262 |
} |
5589abf5e61b
break the network code. Too late to set up a branch for this now
terom
parents:
187
diff
changeset
|
263 |
|
5589abf5e61b
break the network code. Too late to set up a branch for this now
terom
parents:
187
diff
changeset
|
264 |
void NetworkSocket::close (void) { |
5589abf5e61b
break the network code. Too late to set up a branch for this now
terom
parents:
187
diff
changeset
|
265 |
// use closesocket |
5589abf5e61b
break the network code. Too late to set up a branch for this now
terom
parents:
187
diff
changeset
|
266 |
if (::closesocket(fd)) |
5589abf5e61b
break the network code. Too late to set up a branch for this now
terom
parents:
187
diff
changeset
|
267 |
throw NetworkSocketOSError(*this, "close"); |
5589abf5e61b
break the network code. Too late to set up a branch for this now
terom
parents:
187
diff
changeset
|
268 |
|
5589abf5e61b
break the network code. Too late to set up a branch for this now
terom
parents:
187
diff
changeset
|
269 |
// invalidate fd |
5589abf5e61b
break the network code. Too late to set up a branch for this now
terom
parents:
187
diff
changeset
|
270 |
fd = -1; |
5589abf5e61b
break the network code. Too late to set up a branch for this now
terom
parents:
187
diff
changeset
|
271 |
} |
5589abf5e61b
break the network code. Too late to set up a branch for this now
terom
parents:
187
diff
changeset
|
272 |
|
187 | 273 |
std::string NetworkSocketError::build_str (const NetworkSocket &socket, const char *op, const char *err) { |
274 |
std::stringstream ss; |
|
275 |
||
276 |
ss << "socket #" << socket.get_socket() << " " << op << ": " << err; |
|
277 |
||
278 |
return ss.str(); |
|
279 |
} |
|
280 |
||
281 |
NetworkSocketError::NetworkSocketError (const NetworkSocket &socket, const char *op, const char *err) : |
|
282 |
Error(build_str(socket, op, err)) { |
|
283 |
||
284 |
// nothing |
|
285 |
} |
|
286 |