aboutsummaryrefslogtreecommitdiffstatshomepage
path: root/linden/indra/llmessage/net.cpp
diff options
context:
space:
mode:
authorDavid Seikel2011-04-26 21:30:21 +1000
committerDavid Seikel2011-04-26 21:30:21 +1000
commitda97e24c3b045d16589124496d032ffb9b4ca07f (patch)
tree34d84cf4355f83e1a106d06a10ed2a4bb121fdc4 /linden/indra/llmessage/net.cpp
parentApparently there is a wrong client tag for firestorm out in the wild. (diff)
parentChanged version to Experimental 2011.04.19 (diff)
downloadmeta-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.cpp158
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
184int 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
206S32 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
261void tcp_close_channel(S32 handle)
262{
263 llinfos << "Closing TCP channel" << llendl;
264 shutdown(handle, SD_BOTH);
265 closesocket(handle);
266}
267
183S32 start_net(S32& socket_out, int& nPort) 268S32 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
466int 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
483S32 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
531void tcp_close_channel(S32 handle)
532{
533 close(handle);
534}
535
380// Create socket, make non-blocking 536// Create socket, make non-blocking
381S32 start_net(S32& socket_out, int& nPort) 537S32 start_net(S32& socket_out, int& nPort)
382{ 538{