diff options
author | David Seikel | 2011-04-26 21:30:21 +1000 |
---|---|---|
committer | David Seikel | 2011-04-26 21:30:21 +1000 |
commit | da97e24c3b045d16589124496d032ffb9b4ca07f (patch) | |
tree | 34d84cf4355f83e1a106d06a10ed2a4bb121fdc4 /linden/indra/llmessage/net.cpp | |
parent | Apparently there is a wrong client tag for firestorm out in the wild. (diff) | |
parent | Changed version to Experimental 2011.04.19 (diff) | |
download | meta-impy-da97e24c3b045d16589124496d032ffb9b4ca07f.zip meta-impy-da97e24c3b045d16589124496d032ffb9b4ca07f.tar.gz meta-impy-da97e24c3b045d16589124496d032ffb9b4ca07f.tar.bz2 meta-impy-da97e24c3b045d16589124496d032ffb9b4ca07f.tar.xz |
Merge remote-tracking branch 'imprudence/exp' into exp
Conflicts (for future reference):
linden/indra/llcommon/llstring.cpp
linden/indra/newview/llpanelnetwork.cpp
linden/indra/newview/llselectmgr.cpp
linden/indra/newview/llstartup.cpp
linden/indra/newview/lltoolmgr.cpp
linden/indra/newview/llvoavatar.cpp
Diffstat (limited to 'linden/indra/llmessage/net.cpp')
-rw-r--r-- | linden/indra/llmessage/net.cpp | 158 |
1 files changed, 157 insertions, 1 deletions
diff --git a/linden/indra/llmessage/net.cpp b/linden/indra/llmessage/net.cpp index 7166271..fa51645 100644 --- a/linden/indra/llmessage/net.cpp +++ b/linden/indra/llmessage/net.cpp | |||
@@ -56,6 +56,7 @@ | |||
56 | #include "lltimer.h" | 56 | #include "lltimer.h" |
57 | #include "indra_constants.h" | 57 | #include "indra_constants.h" |
58 | 58 | ||
59 | #include "llsocks5.h" | ||
59 | 60 | ||
60 | // Globals | 61 | // Globals |
61 | #if LL_WINDOWS | 62 | #if LL_WINDOWS |
@@ -179,7 +180,91 @@ U32 ip_string_to_u32(const char* ip_string) | |||
179 | ////////////////////////////////////////////////////////////////////////////////////////// | 180 | ////////////////////////////////////////////////////////////////////////////////////////// |
180 | 181 | ||
181 | #if LL_WINDOWS | 182 | #if LL_WINDOWS |
182 | 183 | ||
184 | int tcp_handshake(S32 handle, char * dataout, int outlen, char * datain, int maxinlen) | ||
185 | { | ||
186 | int result; | ||
187 | result = send(handle, dataout, outlen, 0); | ||
188 | if (result != outlen) | ||
189 | { | ||
190 | S32 err = WSAGetLastError(); | ||
191 | llwarns << "Error sending data to proxy control channel, number of bytes sent were " << result << " error code was " << err << llendl; | ||
192 | return -1; | ||
193 | } | ||
194 | |||
195 | result = recv(handle, datain, maxinlen, 0); | ||
196 | if (result != maxinlen) | ||
197 | { | ||
198 | S32 err = WSAGetLastError(); | ||
199 | llwarns << "Error receiving data from proxy control channel, number of bytes received were " << result << " error code was " << err << llendl; | ||
200 | return -1; | ||
201 | } | ||
202 | |||
203 | return 0; | ||
204 | } | ||
205 | |||
206 | S32 tcp_open_channel(LLHost host) | ||
207 | { | ||
208 | // Open a TCP channel | ||
209 | // Jump through some hoops to ensure that if the request hosts is down | ||
210 | // or not reachable connect() does not block | ||
211 | |||
212 | S32 handle; | ||
213 | handle = socket(AF_INET, SOCK_STREAM, 0); | ||
214 | if (!handle) | ||
215 | { | ||
216 | llwarns << "Error opening TCP control socket, socket() returned " << handle << llendl; | ||
217 | return -1; | ||
218 | } | ||
219 | |||
220 | struct sockaddr_in address; | ||
221 | address.sin_port = htons(host.getPort()); | ||
222 | address.sin_family = AF_INET; | ||
223 | address.sin_addr.s_addr = host.getAddress(); | ||
224 | |||
225 | // Non blocking | ||
226 | WSAEVENT hEvent=WSACreateEvent(); | ||
227 | WSAEventSelect(handle, hEvent, FD_CONNECT) ; | ||
228 | connect(handle, (struct sockaddr*)&address, sizeof(address)) ; | ||
229 | // Wait fot 5 seconds, if we can't get a TCP channel open in this | ||
230 | // time frame then there is something badly wrong. | ||
231 | WaitForSingleObject(hEvent, 1000*5); // 5 seconds time out | ||
232 | |||
233 | WSANETWORKEVENTS netevents; | ||
234 | WSAEnumNetworkEvents(handle,hEvent,&netevents); | ||
235 | |||
236 | // Check the async event status to see if we connected | ||
237 | if ((netevents.lNetworkEvents & FD_CONNECT) == FD_CONNECT) | ||
238 | { | ||
239 | if (netevents.iErrorCode[FD_CONNECT_BIT] != 0) | ||
240 | { | ||
241 | llwarns << "Unable to open TCP channel, WSA returned an error code of " << netevents.iErrorCode[FD_CONNECT_BIT] << llendl; | ||
242 | WSACloseEvent(hEvent); | ||
243 | return -1; | ||
244 | } | ||
245 | |||
246 | // Now we are connected disable non blocking | ||
247 | // we don't need support an async interface as | ||
248 | // currently our only consumer (socks5) will make one round | ||
249 | // of packets then just hold the connection open | ||
250 | WSAEventSelect(handle, hEvent, NULL) ; | ||
251 | unsigned long NonBlock = 0; | ||
252 | ioctlsocket(handle, FIONBIO, &NonBlock); | ||
253 | |||
254 | return handle; | ||
255 | } | ||
256 | |||
257 | llwarns << "Unable to open TCP channel, Timeout is the host up?" << netevents.iErrorCode[FD_CONNECT_BIT] << llendl; | ||
258 | return -1; | ||
259 | } | ||
260 | |||
261 | void tcp_close_channel(S32 handle) | ||
262 | { | ||
263 | llinfos << "Closing TCP channel" << llendl; | ||
264 | shutdown(handle, SD_BOTH); | ||
265 | closesocket(handle); | ||
266 | } | ||
267 | |||
183 | S32 start_net(S32& socket_out, int& nPort) | 268 | S32 start_net(S32& socket_out, int& nPort) |
184 | { | 269 | { |
185 | // Create socket, make non-blocking | 270 | // Create socket, make non-blocking |
@@ -377,6 +462,77 @@ BOOL send_packet(int hSocket, const char *sendBuffer, int size, U32 recipient, i | |||
377 | 462 | ||
378 | #else | 463 | #else |
379 | 464 | ||
465 | |||
466 | int tcp_handshake(S32 handle, char * dataout, int outlen, char * datain, int maxinlen) | ||
467 | { | ||
468 | if (send(handle, dataout, outlen, 0) != outlen) | ||
469 | { | ||
470 | llwarns << "Error sending data to proxy control channel" << llendl; | ||
471 | return -1; | ||
472 | } | ||
473 | |||
474 | if (recv(handle, datain, maxinlen, 0) != maxinlen) | ||
475 | { | ||
476 | llwarns << "Error receiving data to proxy control channel" << llendl; | ||
477 | return -1; | ||
478 | } | ||
479 | |||
480 | return 0; | ||
481 | } | ||
482 | |||
483 | S32 tcp_open_channel(LLHost host) | ||
484 | { | ||
485 | S32 handle; | ||
486 | handle = socket(AF_INET, SOCK_STREAM, IPPROTO_TCP); | ||
487 | if (!handle) | ||
488 | { | ||
489 | llwarns << "Error opening TCP control socket, socket() returned " << handle << llendl; | ||
490 | return -1; | ||
491 | } | ||
492 | |||
493 | struct sockaddr_in address; | ||
494 | address.sin_port = htons(host.getPort()); | ||
495 | address.sin_family = AF_INET; | ||
496 | address.sin_addr.s_addr = host.getAddress(); | ||
497 | |||
498 | // Set the socket to non blocking for the connect() | ||
499 | int flags = fcntl(handle, F_GETFL, 0); | ||
500 | fcntl(handle, F_SETFL, flags | O_NONBLOCK); | ||
501 | |||
502 | S32 error = connect(handle, (sockaddr*)&address, sizeof(address)); | ||
503 | if (error && (errno != EINPROGRESS)) | ||
504 | { | ||
505 | llwarns << "Unable to open TCP channel, error code: " << errno << llendl; | ||
506 | return -1; | ||
507 | } | ||
508 | |||
509 | struct timeval timeout; | ||
510 | timeout.tv_sec = 5; // Maximum time to wait for the connect() to complete | ||
511 | timeout.tv_usec = 0; | ||
512 | fd_set fds; | ||
513 | FD_ZERO(&fds); | ||
514 | FD_SET(handle, &fds); | ||
515 | |||
516 | // See if we have connectde or time out after 5 seconds | ||
517 | U32 rc = select(sizeof(fds)*8, NULL, &fds, NULL, &timeout); | ||
518 | |||
519 | if (rc != 1) // we require exactly one descriptor to be set | ||
520 | { | ||
521 | llwarns << "Unable to open TCP channel" << llendl; | ||
522 | return -1; | ||
523 | } | ||
524 | |||
525 | // Return the socket to blocking operations | ||
526 | fcntl(handle, F_SETFL, flags); | ||
527 | |||
528 | return handle; | ||
529 | } | ||
530 | |||
531 | void tcp_close_channel(S32 handle) | ||
532 | { | ||
533 | close(handle); | ||
534 | } | ||
535 | |||
380 | // Create socket, make non-blocking | 536 | // Create socket, make non-blocking |
381 | S32 start_net(S32& socket_out, int& nPort) | 537 | S32 start_net(S32& socket_out, int& nPort) |
382 | { | 538 | { |