summaryrefslogtreecommitdiff
path: root/indra
diff options
context:
space:
mode:
authorLogan Dethrow <log@lindenlab.com>2011-06-21 17:09:12 -0400
committerLogan Dethrow <log@lindenlab.com>2011-06-21 17:09:12 -0400
commit20100ba38c6d3fa16ab11be2ed326ab0964c4c21 (patch)
tree6f249a693990463fc7e057f29a106db6e20bb691 /indra
parent6ce2c20a06e32825f4e4260575059a9867510ecd (diff)
Refactored SOCKS 5 handshake to use existing LLSocket class.
Diffstat (limited to 'indra')
-rw-r--r--indra/llmessage/llcurl.cpp8
-rw-r--r--indra/llmessage/llsocks5.cpp73
-rw-r--r--indra/llmessage/llsocks5.h129
-rw-r--r--indra/llmessage/net.cpp219
-rw-r--r--indra/llmessage/net.h11
-rw-r--r--indra/newview/llstartup.cpp6
-rw-r--r--indra/newview/llxmlrpctransaction.cpp4
7 files changed, 176 insertions, 274 deletions
diff --git a/indra/llmessage/llcurl.cpp b/indra/llmessage/llcurl.cpp
index 9c507517c7..32dd438e68 100644
--- a/indra/llmessage/llcurl.cpp
+++ b/indra/llmessage/llcurl.cpp
@@ -359,13 +359,13 @@ LLCurl::Easy* LLCurl::Easy::getEasy()
check_curl_code(result);
//Set the CURL options for either Socks or HTTP proxy
- if (LLSocks::getInstance()->isHttpProxyEnabled())
+ if (LLSocks::getInstance()->isHTTPProxyEnabled())
{
std::string address = LLSocks::getInstance()->getHTTPProxy().getIPString();
U16 port = LLSocks::getInstance()->getHTTPProxy().getPort();
curl_easy_setopt(easy->mCurlEasyHandle, CURLOPT_PROXY,address.c_str());
curl_easy_setopt(easy->mCurlEasyHandle, CURLOPT_PROXYPORT,port);
- if (LLSocks::getInstance()->getHttpProxyType() == LLPROXY_SOCKS)
+ if (LLSocks::getInstance()->getHTTPProxyType() == LLPROXY_SOCKS)
{
curl_easy_setopt(easy->mCurlEasyHandle, CURLOPT_PROXYTYPE, CURLPROXY_SOCKS5);
if(LLSocks::getInstance()->getSelectedAuthMethod()==METHOD_PASSWORD)
@@ -557,13 +557,13 @@ void LLCurl::Easy::prepRequest(const std::string& url,
//setopt(CURLOPT_VERBOSE, 1); // usefull for debugging
setopt(CURLOPT_NOSIGNAL, 1);
- if (LLSocks::getInstance()->isHttpProxyEnabled())
+ if (LLSocks::getInstance()->isHTTPProxyEnabled())
{
std::string address = LLSocks::getInstance()->getHTTPProxy().getIPString();
U16 port = LLSocks::getInstance()->getHTTPProxy().getPort();
setoptString(CURLOPT_PROXY, address.c_str());
setopt(CURLOPT_PROXYPORT, port);
- if (LLSocks::getInstance()->getHttpProxyType() == LLPROXY_SOCKS)
+ if (LLSocks::getInstance()->getHTTPProxyType() == LLPROXY_SOCKS)
{
setopt(CURLOPT_PROXYTYPE, CURLPROXY_SOCKS5);
if(LLSocks::getInstance()->getSelectedAuthMethod()==METHOD_PASSWORD)
diff --git a/indra/llmessage/llsocks5.cpp b/indra/llmessage/llsocks5.cpp
index 7eac27d4bb..27a31e35b3 100644
--- a/indra/llmessage/llsocks5.cpp
+++ b/indra/llmessage/llsocks5.cpp
@@ -1,6 +1,6 @@
/**
* @file llsocks5.cpp
- * @brief Socks 5 implementation
+ * @brief SOCKS 5 implementation
*
* $LicenseInfo:firstyear=2011&license=viewerlgpl$
* Second Life Viewer Source Code
@@ -37,52 +37,51 @@
// We want this to be static to avoid excessive indirection on every
// incoming packet just to do a simple bool test. The getter for this
// member is also static
-bool LLSocks::sUdpProxyEnabled;
-bool LLSocks::sHttpProxyEnabled;
+bool LLSocks::sUDPProxyEnabled;
+bool LLSocks::sHTTPProxyEnabled;
LLSocks::LLSocks()
{
- sUdpProxyEnabled = false;
- sHttpProxyEnabled = false;
- mProxyControlChannel = 0;
+ sUDPProxyEnabled = false;
+ sHTTPProxyEnabled = false;
+ mProxyControlChannel.reset();
mProxyType = LLPROXY_SOCKS;
}
-// Perform a Socks5 authentication and UDP association to the proxy
+// Perform a SOCKS 5 authentication and UDP association to the proxy
// specified by proxy, and associate UDP port message_port
int LLSocks::proxyHandshake(LLHost proxy, U32 message_port)
{
int result;
- /* Socks 5 Auth request */
+ /* SOCKS 5 Auth request */
socks_auth_request_t socks_auth_request;
socks_auth_response_t socks_auth_response;
- socks_auth_request.version = SOCKS_VERSION; // Socks version 5
- socks_auth_request.num_methods = 1; // Sending 1 method
- socks_auth_request.methods = mAuthMethodSelected; // send only the selected method
+ socks_auth_request.version = SOCKS_VERSION; // SOCKS version 5
+ socks_auth_request.num_methods = 1; // Sending 1 method.
+ socks_auth_request.methods = mAuthMethodSelected; // Send only the selected method.
result = tcp_handshake(mProxyControlChannel, (char*)&socks_auth_request, sizeof(socks_auth_request_t), (char*)&socks_auth_response, sizeof(socks_auth_response_t));
if (result != 0)
{
- llwarns << "Socks authentication request failed, error on TCP control channel : " << result << llendl;
+ llwarns << "SOCKS authentication request failed, error on TCP control channel : " << result << llendl;
stopProxy();
return SOCKS_CONNECT_ERROR;
}
if (socks_auth_response.method == AUTH_NOT_ACCEPTABLE)
{
- llwarns << "Socks5 server refused all our authentication methods" << llendl;
+ llwarns << "SOCKS 5 server refused all our authentication methods" << llendl;
stopProxy();
return SOCKS_NOT_ACCEPTABLE;
}
- // SOCKS5 USERNAME/PASSWORD authentication
+ // SOCKS 5 USERNAME/PASSWORD authentication
if (socks_auth_response.method == METHOD_PASSWORD)
{
// The server has requested a username/password combination
U32 request_size = mSocksUsername.size() + mSocksPassword.size() + 3;
- // char * password_auth = (char *)malloc(request_size);
char * password_auth = new char[request_size];
password_auth[0] = 0x01;
password_auth[1] = mSocksUsername.size();
@@ -97,14 +96,14 @@ int LLSocks::proxyHandshake(LLHost proxy, U32 message_port)
if (result != 0)
{
- llwarns << "Socks authentication failed, error on TCP control channel : " << result << llendl;
+ llwarns << "SOCKS authentication failed, error on TCP control channel : " << result << llendl;
stopProxy();
return SOCKS_CONNECT_ERROR;
}
if (password_reply.status != AUTH_SUCCESS)
{
- llwarns << "Socks authentication failed" << llendl;
+ llwarns << "SOCKS authentication failed" << llendl;
stopProxy();
return SOCKS_AUTH_FAIL;
}
@@ -115,18 +114,19 @@ int LLSocks::proxyHandshake(LLHost proxy, U32 message_port)
socks_command_request_t connect_request;
socks_command_response_t connect_reply;
- connect_request.version = SOCKS_VERSION; //Socks V5
- connect_request.command = COMMAND_UDP_ASSOCIATE; // Associate UDP
- connect_request.flag = FIELD_RESERVED;
- connect_request.atype = ADDRESS_IPV4;
- connect_request.address = 0; // 0.0.0.0 We are not fussy about address
- // UDP is promiscuous receive for our protocol
- connect_request.port = 0; // Port must be 0 if you ever want to connect via NAT and your router does port rewrite for you
+ connect_request.version = SOCKS_VERSION; // SOCKS V5
+ connect_request.command = COMMAND_UDP_ASSOCIATE; // Associate UDP
+ connect_request.reserved = FIELD_RESERVED;
+ connect_request.atype = ADDRESS_IPV4;
+ connect_request.address = htonl(0); // 0.0.0.0
+ connect_request.port = htons(0); // 0
+ // "If the client is not in possesion of the information at the time of the UDP ASSOCIATE,
+ // the client MUST use a port number and address of all zeros. RFC 1928"
result = tcp_handshake(mProxyControlChannel, (char*)&connect_request, sizeof(socks_command_request_t), (char*)&connect_reply, sizeof(socks_command_response_t));
if (result != 0)
{
- llwarns << "Socks connect request failed, error on TCP control channel : " << result << llendl;
+ llwarns << "SOCKS connect request failed, error on TCP control channel : " << result << llendl;
stopProxy();
return SOCKS_CONNECT_ERROR;
}
@@ -134,7 +134,7 @@ int LLSocks::proxyHandshake(LLHost proxy, U32 message_port)
if (connect_reply.reply != REPLY_REQUEST_GRANTED)
{
//Something went wrong
- llwarns << "Connection to SOCKS5 server failed, UDP forward request not granted" << llendl;
+ llwarns << "Connection to SOCKS 5 server failed, UDP forward request not granted" << llendl;
stopProxy();
return SOCKS_UDP_FWD_NOT_GRANTED;
}
@@ -142,7 +142,7 @@ int LLSocks::proxyHandshake(LLHost proxy, U32 message_port)
mUDPProxy.setPort(ntohs(connect_reply.port)); // reply port is in network byte order
mUDPProxy.setAddress(proxy.getAddress());
// All good now we have been given the UDP port to send requests that need forwarding.
- llinfos << "Socks 5 UDP proxy connected on " << mUDPProxy << llendl;
+ llinfos << "SOCKS 5 UDP proxy connected on " << mUDPProxy << llendl;
return SOCKS_OK;
}
@@ -155,19 +155,17 @@ int LLSocks::startProxy(LLHost proxy, U32 message_port)
if (mProxyControlChannel)
{
tcp_close_channel(mProxyControlChannel);
- mProxyControlChannel = 0;
}
- mProxyControlChannel = tcp_open_channel(proxy);
- if (mProxyControlChannel == -1)
+ mProxyControlChannel = tcp_open_channel(mTCPProxy);
+ if (!mProxyControlChannel)
{
return SOCKS_HOST_CONNECT_FAILED;
}
-
status = proxyHandshake(proxy, message_port);
if (status == SOCKS_OK)
{
- sUdpProxyEnabled = true;
+ sUDPProxyEnabled = true;
}
return status;
}
@@ -181,21 +179,20 @@ int LLSocks::startProxy(std::string host, U32 port)
void LLSocks::stopProxy()
{
- sUdpProxyEnabled = false;
+ sUDPProxyEnabled = false;
- // If the Socks proxy is requested to stop and we are using that for http as well
+ // If the SOCKS proxy is requested to stop and we are using that for http as well
// then we must shut down any http proxy operations. But it is allowable if web
// proxy is being used to continue proxying http.
if(LLPROXY_SOCKS == mProxyType)
{
- sHttpProxyEnabled = false;
+ sHTTPProxyEnabled = false;
}
if (mProxyControlChannel)
{
tcp_close_channel(mProxyControlChannel);
- mProxyControlChannel = 0;
}
}
@@ -211,9 +208,9 @@ void LLSocks::setAuthPassword(std::string username, std::string password)
mSocksPassword = password;
}
-void LLSocks::enableHttpProxy(LLHost httpHost, LLHttpProxyType type)
+void LLSocks::enableHTTPProxy(LLHost httpHost, LLHttpProxyType type)
{
- sHttpProxyEnabled = true;
+ sHTTPProxyEnabled = true;
mHTTPProxy = httpHost;
mProxyType = type;
}
diff --git a/indra/llmessage/llsocks5.h b/indra/llmessage/llsocks5.h
index 171a933d32..43a7c82fea 100644
--- a/indra/llmessage/llsocks5.h
+++ b/indra/llmessage/llsocks5.h
@@ -46,9 +46,9 @@
#define MAXHOSTNAMELEN (255 + 1) /* socks5: 255, +1 for len. */
#endif
-#define SOCKS_VERSION 0x05 // we are using socks 5
+#define SOCKS_VERSION 0x05 // we are using SOCKS 5
-// socks 5 address/hostname types
+// SOCKS 5 address/hostname types
#define ADDRESS_IPV4 0x01
#define ADDRESS_HOSTNAME 0x03
#define ADDRESS_IPV6 0x04
@@ -56,16 +56,16 @@
// Lets just use our own ipv4 struct rather than dragging in system
// specific headers
union ipv4_address_t {
- unsigned char octets[4];
- U32 addr32;
+ U8 octets[4];
+ U32 addr32;
};
-// Socks 5 control channel commands
+// SOCKS 5 control channel commands
#define COMMAND_TCP_STREAM 0x01
#define COMMAND_TCP_BIND 0x02
#define COMMAND_UDP_ASSOCIATE 0x03
-// Socks 5 command replys
+// SOCKS 5 command replies
#define REPLY_REQUEST_GRANTED 0x00
#define REPLY_GENERAL_FAIL 0x01
#define REPLY_RULESET_FAIL 0x02
@@ -78,61 +78,61 @@ union ipv4_address_t {
#define FIELD_RESERVED 0x00
-// The standard socks5 request packet
+// The standard SOCKS 5 request packet
// Push current alignment to stack and set alignment to 1 byte boundary
// This enabled us to use structs directly to set up and receive network packets
// into the correct fields, without fear of boundary alignment causing issues
#pragma pack(push,1)
-// Socks5 command packet
+// SOCKS 5 command packet
struct socks_command_request_t {
- unsigned char version;
- unsigned char command;
- unsigned char flag;
- unsigned char atype;
- U32 address;
- U16 port;
+ U8 version;
+ U8 command;
+ U8 reserved;
+ U8 atype;
+ U32 address;
+ U16 port;
};
-// Standard socks5 reply packet
+// Standard SOCKS 5 reply packet
struct socks_command_response_t {
- unsigned char version;
- unsigned char reply;
- unsigned char flag;
- unsigned char atype;
- unsigned char add_bytes[4];
- U16 port;
+ U8 version;
+ U8 reply;
+ U8 reserved;
+ U8 atype;
+ U8 add_bytes[4];
+ U16 port;
};
#define AUTH_NOT_ACCEPTABLE 0xFF // reply if preferred methods are not available
#define AUTH_SUCCESS 0x00 // reply if authentication successful
-// socks 5 authentication request, stating which methods the client supports
+// SOCKS 5 authentication request, stating which methods the client supports
struct socks_auth_request_t {
- unsigned char version;
- unsigned char num_methods;
- unsigned char methods; // We are only using a single method currently
+ U8 version;
+ U8 num_methods;
+ U8 methods; // We are only using a single method currently
};
-// socks 5 authentication response packet, stating server prefered method
+// SOCKS 5 authentication response packet, stating server preferred method
struct socks_auth_response_t {
- unsigned char version;
- unsigned char method;
+ U8 version;
+ U8 method;
};
-// socks 5 password reply packet
+// SOCKS 5 password reply packet
struct authmethod_password_reply_t {
- unsigned char version;
- unsigned char status;
+ U8 version;
+ U8 status;
};
-// socks 5 UDP packet header
+// SOCKS 5 UDP packet header
struct proxywrap_t {
- U16 rsv;
- U8 frag;
- U8 atype;
- U32 addr;
- U16 port;
+ U16 rsv;
+ U8 frag;
+ U8 atype;
+ U32 addr;
+ U16 port;
};
#pragma pack(pop) /* restore original alignment from stack */
@@ -158,62 +158,62 @@ class LLSocks: public LLSingleton<LLSocks>
public:
LLSocks();
- // Start a connection to the socks 5 proxy
- int startProxy(std::string host,U32 port);
- int startProxy(LLHost proxy,U32 messagePort);
+ // Start a connection to the SOCKS 5 proxy
+ int startProxy(std::string host, U32 port);
+ int startProxy(LLHost proxy, U32 messagePort);
- // Disconnect and clean up any connection to the socks 5 proxy
+ // Disconnect and clean up any connection to the SOCKS 5 proxy
void stopProxy();
- // Set up to use Password auth when connecting to the socks proxy
- void setAuthPassword(std::string username,std::string password);
+ // Set up to use Password auth when connecting to the SOCKS proxy
+ void setAuthPassword(std::string username, std::string password);
- // Set up to use No Auth when connecting to the socks proxy
+ // Set up to use No Auth when connecting to the SOCKS proxy
void setAuthNone();
// get the currently selected auth method
LLSocks5AuthType getSelectedAuthMethod() const { return mAuthMethodSelected; }
// static check for enabled status for UDP packets
- static bool isEnabled() { return sUdpProxyEnabled; }
+ static bool isEnabled() { return sUDPProxyEnabled; }
// static check for enabled status for http packets
- static bool isHttpProxyEnabled() { return sHttpProxyEnabled; }
+ static bool isHTTPProxyEnabled() { return sHTTPProxyEnabled; }
- // Proxy http packets via httpHost, which can be a Socks5 or a http proxy
+ // Proxy HTTP packets via httpHost, which can be a SOCKS 5 or a HTTP proxy
// as specified in type
- void enableHttpProxy(LLHost httpHost, LLHttpProxyType type);
+ void enableHTTPProxy(LLHost httpHost, LLHttpProxyType type);
- // Stop proxying http packets
- void disableHttpProxy() { sHttpProxyEnabled = false; };
+ // Stop proxying HTTP packets
+ void disableHTTPProxy() { sHTTPProxyEnabled = false; };
// Get the UDP proxy address and port
LLHost getUDPProxy() const { return mUDPProxy; }
- // Get the socks 5 TCP control channel address and port
+ // Get the SOCKS 5 TCP control channel address and port
LLHost getTCPProxy() const { return mTCPProxy; }
- // Get the http proxy address and port
+ // Get the HTTP proxy address and port
LLHost getHTTPProxy() const { return mHTTPProxy; }
- // Get the currently selected http proxy type
- LLHttpProxyType getHttpProxyType() const { return mProxyType; }
+ // Get the currently selected HTTP proxy type
+ LLHttpProxyType getHTTPProxyType() const { return mProxyType; }
// Get the username password in a curl compatible format
std::string getProxyUserPwd() const { return (mSocksUsername + ":" + mSocksPassword); }
private:
- // Open a communication channel to the socks5 proxy proxy, at port messagePort
- int proxyHandshake(LLHost proxy,U32 messagePort);
+ // Open a communication channel to the SOCKS 5 proxy proxy, at port messagePort
+ int proxyHandshake(LLHost proxy, U32 messagePort);
- // socket handle to proxy tcp control channel
- S32 mProxyControlChannel;
+ // socket handle to proxy TCP control channel
+ LLSocket::ptr_t mProxyControlChannel;
// is the UDP proxy enabled?
- static bool sUdpProxyEnabled;
+ static bool sUDPProxyEnabled;
// is the http proxy enabled?
- static bool sHttpProxyEnabled;
+ static bool sHTTPProxyEnabled;
// currently selected http proxy type
LLHttpProxyType mProxyType;
@@ -225,13 +225,16 @@ private:
// HTTP proxy address and port
LLHost mHTTPProxy;
- // socks 5 auth method selected
+ // SOCKS 5 auth method selected
LLSocks5AuthType mAuthMethodSelected;
- // socks 5 username
+ // SOCKS 5 username
std::string mSocksUsername;
- // socks 5 password
+ // SOCKS 5 password
std::string mSocksPassword;
+
+ // APR pool for the socket
+ apr_pool_t* mPool;
};
#endif
diff --git a/indra/llmessage/net.cpp b/indra/llmessage/net.cpp
index a51d80ff48..366a1835ca 100644
--- a/indra/llmessage/net.cpp
+++ b/indra/llmessage/net.cpp
@@ -189,93 +189,6 @@ U32 ip_string_to_u32(const char* ip_string)
//////////////////////////////////////////////////////////////////////////////////////////
#if LL_WINDOWS
-
-int tcp_handshake(S32 handle, char * dataout, int outlen, char * datain, int maxinlen)
-{
- int result;
- result = send(handle, dataout, outlen, 0);
- if (result != outlen)
- {
- S32 err = WSAGetLastError();
- llwarns << "Error sending data to proxy control channel, number of bytes sent were " << result << " error code was " << err << llendl;
- return -1;
- }
-
- result = recv(handle, datain, maxinlen, 0);
- if (result != maxinlen)
- {
- S32 err = WSAGetLastError();
- llwarns << "Error receiving data from proxy control channel, number of bytes received were " << result << " error code was " << err << llendl;
- return -1;
- }
-
- return 0;
-}
-
-S32 tcp_open_channel(LLHost host)
-{
- // Open a TCP channel
- // Jump through some hoops to ensure that if the request hosts is down
- // or not reachable connect() does not block
-
- S32 handle;
- handle = socket(AF_INET, SOCK_STREAM, 0);
- if (INVALID_SOCKET == handle)
- {
- llwarns << "Error opening TCP control socket, socket() returned "
- << WSAGetLastError() << ", " << DecodeError(WSAGetLastError()) << llendl;
- return -1;
- }
-
- struct sockaddr_in address;
- address.sin_port = htons(host.getPort());
- address.sin_family = AF_INET;
- address.sin_addr.s_addr = host.getAddress();
-
- // Non blocking
- WSAEVENT hEvent = WSACreateEvent();
- WSAEventSelect(handle, hEvent, FD_CONNECT) ;
- connect(handle, (struct sockaddr*)&address, sizeof(address)) ;
- // Wait for 5 seconds, if we can't get a TCP channel open in this
- // time frame then there is something badly wrong.
- WaitForSingleObject(hEvent, 1000 * 5); // 5 seconds time out
-
- WSANETWORKEVENTS netevents;
- WSAEnumNetworkEvents(handle, hEvent, &netevents);
-
- // Check the async event status to see if we connected
- if ((netevents.lNetworkEvents & FD_CONNECT) == FD_CONNECT)
- {
- if (netevents.iErrorCode[FD_CONNECT_BIT] != 0)
- {
- llwarns << "Unable to open TCP channel, WSA returned an error code of " << netevents.iErrorCode[FD_CONNECT_BIT] << llendl;
- WSACloseEvent(hEvent);
- tcp_close_channel(handle);
- return -1;
- }
-
- // Now we are connected disable non blocking
- // we don't need support an async interface as
- // currently our only consumer (socks5) will make one round
- // of packets then just hold the connection open
- WSAEventSelect(handle, hEvent, NULL) ;
- unsigned long NonBlock = 0;
- ioctlsocket(handle, FIONBIO, &NonBlock);
-
- return handle;
- }
-
- llwarns << "Unable to open TCP channel, Timeout is the host up?" << netevents.iErrorCode[FD_CONNECT_BIT] << llendl;
- tcp_close_channel(handle);
- return -1;
-}
-
-void tcp_close_channel(S32 handle)
-{
- llinfos << "Closing TCP channel" << llendl;
- shutdown(handle, SD_BOTH);
- closesocket(handle);
-}
S32 start_net(S32& socket_out, int& nPort)
{
@@ -473,79 +386,6 @@ BOOL send_packet(int hSocket, const char *sendBuffer, int size, U32 recipient, i
#else
-
-int tcp_handshake(S32 handle, char * dataout, int outlen, char * datain, int maxinlen)
-{
- if (send(handle, dataout, outlen, 0) != outlen)
- {
- llwarns << "Error sending data to proxy control channel" << llendl;
- return -1;
- }
-
- if (recv(handle, datain, maxinlen, 0) != maxinlen)
- {
- llwarns << "Error receiving data to proxy control channel" << llendl;
- return -1;
- }
-
- return 0;
-}
-
-S32 tcp_open_channel(LLHost host)
-{
- S32 handle;
- handle = socket(AF_INET, SOCK_STREAM, IPPROTO_TCP);
- if (-1 == handle)
- {
- llwarns << "Error opening TCP control socket, socket() returned " << handle << "error code: " << errno << llendl;
- return -1;
- }
-
- struct sockaddr_in address;
- address.sin_port = htons(host.getPort());
- address.sin_family = AF_INET;
- address.sin_addr.s_addr = host.getAddress();
-
- // Set the socket to non blocking for the connect()
- int flags = fcntl(handle, F_GETFL, 0);
- fcntl(handle, F_SETFL, flags | O_NONBLOCK);
-
- S32 error = connect(handle, (sockaddr*)&address, sizeof(address));
- if (error && (errno != EINPROGRESS))
- {
- llwarns << "Unable to open TCP channel, error code: " << errno << llendl;
- tcp_close_channel(handle);
- return -1;
- }
-
- struct timeval timeout;
- timeout.tv_sec = 5; // Maximum time to wait for the connect() to complete
- timeout.tv_usec = 0;
- fd_set fds;
- FD_ZERO(&fds);
- FD_SET(handle, &fds);
-
- // See if we have connected or time out after 5 seconds
- S32 rc = select(sizeof(fds)*8, NULL, &fds, NULL, &timeout);
-
- if (rc != 1) // we require exactly one descriptor to be set
- {
- llwarns << "Unable to open TCP channel" << llendl;
- tcp_close_channel(handle);
- return -1;
- }
-
- // Return the socket to blocking operations
- fcntl(handle, F_SETFL, flags);
-
- return handle;
-}
-
-void tcp_close_channel(S32 handle)
-{
- close(handle);
-}
-
// Create socket, make non-blocking
S32 start_net(S32& socket_out, int& nPort)
{
@@ -824,4 +664,63 @@ BOOL send_packet(int hSocket, const char * sendBuffer, int size, U32 recipient,
#endif
+int tcp_handshake(LLSocket::ptr_t handle, char * dataout, apr_size_t outlen, char * datain, apr_size_t maxinlen)
+{
+ apr_socket_t* apr_socket = handle->getSocket();
+ apr_status_t rv;
+
+ apr_size_t expected_len = outlen;
+
+ apr_socket_opt_set(apr_socket, APR_SO_NONBLOCK, -5); // Blocking connection, 5 second timeout
+ apr_socket_timeout_set(apr_socket, (APR_USEC_PER_SEC * 5));
+
+ rv = apr_socket_send(apr_socket, dataout, &outlen);
+ if (rv != APR_SUCCESS || expected_len != outlen)
+ {
+ llwarns << "Error sending data to proxy control channel" << llendl;
+ ll_apr_warn_status(rv);
+ return -1;
+ }
+
+ expected_len = maxinlen;
+ do
+ {
+ rv = apr_socket_recv(apr_socket, datain, &maxinlen);
+ llinfos << "Receiving packets." << llendl;
+ llwarns << "Proxy control channel status: " << rv << llendl;
+ } while (APR_STATUS_IS_EAGAIN(rv));
+
+ if (rv != APR_SUCCESS)
+ {
+ llwarns << "Error receiving data from proxy control channel, status: " << rv << llendl;
+ llwarns << "Received " << maxinlen << " bytes." << llendl;
+ ll_apr_warn_status(rv);
+ return rv;
+ }
+ else if (expected_len != maxinlen)
+ {
+ llwarns << "Incorrect data received length in proxy control channel" << llendl;
+ return -1;
+ }
+
+ return 0;
+}
+
+LLSocket::ptr_t tcp_open_channel(LLHost host)
+{
+ LLSocket::ptr_t socket = LLSocket::create(gAPRPoolp, LLSocket::STREAM_TCP);
+ bool connected = socket->blockingConnect(host);
+ if (!connected)
+ {
+ tcp_close_channel(socket);
+ }
+
+ return socket;
+}
+
+void tcp_close_channel(LLSocket::ptr_t handle)
+{
+ handle.reset();
+}
+
//EOF
diff --git a/indra/llmessage/net.h b/indra/llmessage/net.h
index 047e8ce646..0d91cf2a2f 100644
--- a/indra/llmessage/net.h
+++ b/indra/llmessage/net.h
@@ -27,6 +27,9 @@
#ifndef LL_NET_H
#define LL_NET_H
+#include "lliosocket.h"
+#include "llapr.h"
+
class LLTimer;
class LLHost;
@@ -52,10 +55,10 @@ U32 get_sender_ip(void);
LLHost get_receiving_interface();
U32 get_receiving_interface_ip(void);
-// Some helpful tcp functions added for the socks 5 proxy support
-S32 tcp_open_channel(LLHost host); // Open a tcp channel to a given host
-void tcp_close_channel(S32 handle); // Close an open tcp channel
-int tcp_handshake(S32 handle, char * dataout, int outlen, char * datain, int maxinlen); // Do a TCP data handshake
+// Some helpful TCP functions
+LLSocket::ptr_t tcp_open_channel(LLHost host); // Open a TCP channel to a given host
+void tcp_close_channel(LLSocket::ptr_t handle); // Close an open TCP channel
+int tcp_handshake(LLSocket::ptr_t handle, char * dataout, apr_size_t outlen, char * datain, apr_size_t maxinlen); // Do a TCP data handshake
const char* u32_to_ip_string(U32 ip); // Returns pointer to internal string buffer, "(bad IP addr)" on failure, cannot nest calls
char* u32_to_ip_string(U32 ip, char *ip_string); // NULL on failure, ip_string on success, you must allocate at least MAXADDRSTR chars
diff --git a/indra/newview/llstartup.cpp b/indra/newview/llstartup.cpp
index 6d94a5454e..c2f0ca164b 100644
--- a/indra/newview/llstartup.cpp
+++ b/indra/newview/llstartup.cpp
@@ -2770,18 +2770,18 @@ bool LLStartUp::handleSocksProxy(bool reportOK)
LLHost httpHost;
httpHost.setHostByName(gSavedSettings.getString("BrowserProxyAddress"));
httpHost.setPort(gSavedSettings.getS32("BrowserProxyPort"));
- LLSocks::getInstance()->enableHttpProxy(httpHost,LLPROXY_HTTP);
+ LLSocks::getInstance()->enableHTTPProxy(httpHost,LLPROXY_HTTP);
}
else if ((httpProxyType.compare("Socks") == 0) && gSavedSettings.getBOOL("Socks5ProxyEnabled"))
{
LLHost httpHost;
httpHost.setHostByName(gSavedSettings.getString("Socks5ProxyHost"));
httpHost.setPort(gSavedSettings.getU32("Socks5ProxyPort"));
- LLSocks::getInstance()->enableHttpProxy(httpHost,LLPROXY_SOCKS);
+ LLSocks::getInstance()->enableHTTPProxy(httpHost,LLPROXY_SOCKS);
}
else
{
- LLSocks::getInstance()->disableHttpProxy();
+ LLSocks::getInstance()->disableHTTPProxy();
}
bool use_socks_proxy = gSavedSettings.getBOOL("Socks5ProxyEnabled");
diff --git a/indra/newview/llxmlrpctransaction.cpp b/indra/newview/llxmlrpctransaction.cpp
index 87d2f780be..b9ce7d9fae 100644
--- a/indra/newview/llxmlrpctransaction.cpp
+++ b/indra/newview/llxmlrpctransaction.cpp
@@ -309,13 +309,13 @@ void LLXMLRPCTransaction::Impl::init(XMLRPC_REQUEST request, bool useGzip)
}
mErrorCert = NULL;
- if (LLSocks::getInstance()->isHttpProxyEnabled())
+ if (LLSocks::getInstance()->isHTTPProxyEnabled())
{
std::string address = LLSocks::getInstance()->getHTTPProxy().getIPString();
U16 port = LLSocks::getInstance()->getHTTPProxy().getPort();
mCurlRequest->setoptString(CURLOPT_PROXY, address.c_str());
mCurlRequest->setopt(CURLOPT_PROXYPORT, port);
- if (LLSocks::getInstance()->getHttpProxyType() == LLPROXY_SOCKS)
+ if (LLSocks::getInstance()->getHTTPProxyType() == LLPROXY_SOCKS)
{
mCurlRequest->setopt(CURLOPT_PROXYTYPE, CURLPROXY_SOCKS5);
if(LLSocks::getInstance()->getSelectedAuthMethod()==METHOD_PASSWORD)