summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
-rw-r--r--indra/llmessage/lliosocket.cpp2
-rw-r--r--indra/llmessage/lliosocket.h16
-rw-r--r--indra/llmessage/llproxy.cpp93
-rw-r--r--indra/llmessage/llproxy.h7
-rw-r--r--indra/newview/llappviewer.cpp3
-rw-r--r--indra/newview/llstartup.cpp16
-rw-r--r--indra/newview/skins/default/xui/en/floater_preferences_proxy.xml17
7 files changed, 84 insertions, 70 deletions
diff --git a/indra/llmessage/lliosocket.cpp b/indra/llmessage/lliosocket.cpp
index 8c752fbe30..a349849c30 100644
--- a/indra/llmessage/lliosocket.cpp
+++ b/indra/llmessage/lliosocket.cpp
@@ -251,10 +251,12 @@ LLSocket::~LLSocket()
{
ll_debug_socket("Destroying socket", mSocket);
apr_socket_close(mSocket);
+ mSocket = NULL;
}
if(mPool)
{
apr_pool_destroy(mPool);
+ mPool = NULL;
}
}
diff --git a/indra/llmessage/lliosocket.h b/indra/llmessage/lliosocket.h
index 5a2eaf2d44..be0f7dfcc6 100644
--- a/indra/llmessage/lliosocket.h
+++ b/indra/llmessage/lliosocket.h
@@ -145,13 +145,6 @@ public:
*/
apr_socket_t* getSocket() const { return mSocket; }
-protected:
- /**
- * @brief Protected constructor since should only make sockets
- * with one of the two <code>create()</code> calls.
- */
- LLSocket(apr_socket_t* socket, apr_pool_t* pool);
-
/**
* @brief Set default socket options, with SO_NONBLOCK = 0 and a timeout in us.
* @param timeout Number of microseconds to wait on this socket. Any
@@ -164,9 +157,16 @@ protected:
*/
void setNonBlocking();
+protected:
+ /**
+ * @brief Protected constructor since should only make sockets
+ * with one of the two <code>create()</code> calls.
+ */
+ LLSocket(apr_socket_t* socket, apr_pool_t* pool);
+
public:
/**
- * @brief Do not call this directly. Use LLSocket::ptr_t.reset() instead.
+ * @brief Do not call this directly.
*/
~LLSocket();
diff --git a/indra/llmessage/llproxy.cpp b/indra/llmessage/llproxy.cpp
index 6bc9e8b62b..6278751c31 100644
--- a/indra/llmessage/llproxy.cpp
+++ b/indra/llmessage/llproxy.cpp
@@ -45,9 +45,8 @@ bool LLProxy::sHTTPProxyEnabled = false;
// Some helpful TCP functions
static LLSocket::ptr_t tcp_open_channel(apr_pool_t* pool, LLHost host); // Open a TCP channel to a given host
-static void tcp_close_channel(LLSocket::ptr_t handle); // Close an open TCP channel
-static int tcp_handshake(LLSocket::ptr_t handle, char * dataout, apr_size_t outlen, char * datain, apr_size_t maxinlen); // Do a TCP data handshake
-
+static void tcp_close_channel(LLSocket::ptr_t* handle_ptr); // Close an open TCP channel
+static S32 tcp_handshake(LLSocket::ptr_t handle, char * dataout, apr_size_t outlen, char * datain, apr_size_t maxinlen); // Do a TCP data handshake
LLProxy::LLProxy():
mProxyType(LLPROXY_SOCKS),
@@ -63,16 +62,16 @@ LLProxy::LLProxy():
LLProxy::~LLProxy()
{
- tcp_close_channel(mProxyControlChannel);
+ stopProxy();
sUDPProxyEnabled = false;
sHTTPProxyEnabled = false;
}
// Perform a SOCKS 5 authentication and UDP association to the proxy
// specified by proxy, and associate UDP port message_port
-int LLProxy::proxyHandshake(LLHost proxy, U32 message_port)
+S32 LLProxy::proxyHandshake(LLHost proxy, U32 message_port)
{
- int result;
+ S32 result;
/* SOCKS 5 Auth request */
socks_auth_request_t socks_auth_request;
@@ -153,7 +152,6 @@ int LLProxy::proxyHandshake(LLHost proxy, U32 message_port)
if (connect_reply.reply != REPLY_REQUEST_GRANTED)
{
- //Something went wrong
llwarns << "Connection to SOCKS 5 server failed, UDP forward request not granted" << llendl;
stopProxy();
return SOCKS_UDP_FWD_NOT_GRANTED;
@@ -161,21 +159,21 @@ int LLProxy::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.
+ // The connection was successful. We now have the UDP port to send requests that need forwarding to.
llinfos << "SOCKS 5 UDP proxy connected on " << mUDPProxy << llendl;
return SOCKS_OK;
}
-int LLProxy::startProxy(std::string host, U32 port)
+S32 LLProxy::startProxy(std::string host, U32 port)
{
mTCPProxy.setHostByName(host);
mTCPProxy.setPort(port);
- int status;
+ S32 status;
if (mProxyControlChannel)
{
- tcp_close_channel(mProxyControlChannel);
+ tcp_close_channel(&mProxyControlChannel);
}
mProxyControlChannel = tcp_open_channel(mPool, mTCPProxy);
@@ -200,9 +198,9 @@ void LLProxy::stopProxy()
{
sUDPProxyEnabled = false;
- // 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 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)
{
@@ -211,7 +209,7 @@ void LLProxy::stopProxy()
if (mProxyControlChannel)
{
- tcp_close_channel(mProxyControlChannel);
+ tcp_close_channel(&mProxyControlChannel);
}
}
@@ -234,46 +232,53 @@ void LLProxy::enableHTTPProxy(LLHost httpHost, LLHttpProxyType type)
mProxyType = type;
}
-static int tcp_handshake(LLSocket::ptr_t handle, char * dataout, apr_size_t outlen, char * datain, apr_size_t maxinlen)
+//static
+void LLProxy::cleanupClass()
{
+ LLProxy::getInstance()->stopProxy();
+}
+
+static S32 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_status_t rv = APR_SUCCESS;
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));
+ handle->setBlocking(1000);
- rv = apr_socket_send(apr_socket, dataout, &outlen);
- if (rv != APR_SUCCESS || expected_len != outlen)
+ rv = apr_socket_send(apr_socket, dataout, &outlen);
+ if (APR_SUCCESS != rv || 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)
+ else if (expected_len != outlen)
{
- llwarns << "Error receiving data from proxy control channel, status: " << rv << llendl;
- llwarns << "Received " << maxinlen << " bytes." << llendl;
- ll_apr_warn_status(rv);
- return rv;
+ llwarns << "Error sending data to proxy control channel" << llendl;
+ rv = -1;
}
- else if (expected_len != maxinlen)
+
+ if (APR_SUCCESS == rv)
{
- llwarns << "Incorrect data received length in proxy control channel" << llendl;
- return -1;
+ expected_len = maxinlen;
+ rv = apr_socket_recv(apr_socket, datain, &maxinlen);
+ if (rv != APR_SUCCESS)
+ {
+ llwarns << "Error receiving data from proxy control channel, status: " << rv << llendl;
+ ll_apr_warn_status(rv);
+ }
+ else if (expected_len != maxinlen)
+ {
+ llwarns << "Received incorrect amount of data in proxy control channel" << llendl;
+ rv = -1;
+ }
}
- return 0;
+ handle->setNonBlocking();
+
+ return rv;
}
static LLSocket::ptr_t tcp_open_channel(apr_pool_t* pool, LLHost host)
@@ -282,13 +287,15 @@ static LLSocket::ptr_t tcp_open_channel(apr_pool_t* pool, LLHost host)
bool connected = socket->blockingConnect(host);
if (!connected)
{
- tcp_close_channel(socket);
+ tcp_close_channel(&socket);
}
return socket;
}
-static void tcp_close_channel(LLSocket::ptr_t handle)
+// Pass a pointer-to-pointer to avoid changing use_count().
+static void tcp_close_channel(LLSocket::ptr_t* handle_ptr)
{
- handle.reset();
+ lldebugs << "Resetting proxy LLSocket handle, use_count == " << handle_ptr->use_count() << llendl;
+ handle_ptr->reset();
}
diff --git a/indra/llmessage/llproxy.h b/indra/llmessage/llproxy.h
index 979514a7e0..498ffce24e 100644
--- a/indra/llmessage/llproxy.h
+++ b/indra/llmessage/llproxy.h
@@ -161,11 +161,14 @@ public:
~LLProxy();
// Start a connection to the SOCKS 5 proxy
- int startProxy(std::string host, U32 port);
+ S32 startProxy(std::string host, U32 port);
// Disconnect and clean up any connection to the SOCKS 5 proxy
void stopProxy();
+ // Delete LLProxy singleton, destroying the APR pool used by the control channel.
+ static void cleanupClass();
+
// Set up to use Password auth when connecting to the SOCKS proxy
void setAuthPassword(const std::string &username, const std::string &password);
@@ -209,7 +212,7 @@ public:
private:
// Open a communication channel to the SOCKS 5 proxy proxy, at port messagePort
- int proxyHandshake(LLHost proxy, U32 messagePort);
+ S32 proxyHandshake(LLHost proxy, U32 messagePort);
// socket handle to proxy TCP control channel
LLSocket::ptr_t mProxyControlChannel;
diff --git a/indra/newview/llappviewer.cpp b/indra/newview/llappviewer.cpp
index d2582d524d..57e197a263 100644
--- a/indra/newview/llappviewer.cpp
+++ b/indra/newview/llappviewer.cpp
@@ -136,6 +136,7 @@
#include "lltoolmgr.h"
#include "llassetstorage.h"
#include "llpolymesh.h"
+#include "llproxy.h"
#include "llaudioengine.h"
#include "llstreamingaudio.h"
#include "llviewermenu.h"
@@ -1869,6 +1870,8 @@ bool LLAppViewer::cleanup()
LLWeb::loadURLExternal( gLaunchFileOnQuit, false );
llinfos << "File launched." << llendflush;
}
+ llinfos << "Cleaning up LLProxy." << llendl;
+ LLProxy::cleanupClass();
LLMainLoopRepeater::instance().stop();
diff --git a/indra/newview/llstartup.cpp b/indra/newview/llstartup.cpp
index 7f14e403b0..8b333f265c 100644
--- a/indra/newview/llstartup.cpp
+++ b/indra/newview/llstartup.cpp
@@ -2766,17 +2766,17 @@ bool LLStartUp::handleSocksProxy()
// Determine the HTTP proxy type (if any)
if ((httpProxyType.compare("Web") == 0) && gSavedSettings.getBOOL("BrowserProxyEnabled"))
{
- LLHost httpHost;
- httpHost.setHostByName(gSavedSettings.getString("BrowserProxyAddress"));
- httpHost.setPort(gSavedSettings.getS32("BrowserProxyPort"));
- LLProxy::getInstance()->enableHTTPProxy(httpHost, LLPROXY_HTTP);
+ LLHost http_host;
+ http_host.setHostByName(gSavedSettings.getString("BrowserProxyAddress"));
+ http_host.setPort(gSavedSettings.getS32("BrowserProxyPort"));
+ LLProxy::getInstance()->enableHTTPProxy(http_host, LLPROXY_HTTP);
}
else if ((httpProxyType.compare("Socks") == 0) && gSavedSettings.getBOOL("Socks5ProxyEnabled"))
{
- LLHost httpHost;
- httpHost.setHostByName(gSavedSettings.getString("Socks5ProxyHost"));
- httpHost.setPort(gSavedSettings.getU32("Socks5ProxyPort"));
- LLProxy::getInstance()->enableHTTPProxy(httpHost, LLPROXY_SOCKS);
+ LLHost socks_host;
+ socks_host.setHostByName(gSavedSettings.getString("Socks5ProxyHost"));
+ socks_host.setPort(gSavedSettings.getU32("Socks5ProxyPort"));
+ LLProxy::getInstance()->enableHTTPProxy(socks_host, LLPROXY_SOCKS);
}
else
{
diff --git a/indra/newview/skins/default/xui/en/floater_preferences_proxy.xml b/indra/newview/skins/default/xui/en/floater_preferences_proxy.xml
index 91e85c812c..020ee52c18 100644
--- a/indra/newview/skins/default/xui/en/floater_preferences_proxy.xml
+++ b/indra/newview/skins/default/xui/en/floater_preferences_proxy.xml
@@ -217,7 +217,6 @@
control_name="Socks5HttpProxyType"
height="60"
layout="topleft"
- name="other_http_proxy_selection"
top_pad="9"
width="120"
border="1"
@@ -232,20 +231,20 @@
tool_tip="Non-web HTTP traffic will NOT be sent to any proxy."/>
<radio_item
height="16"
- label="Use SOCKS 5 Proxy"
- layout="topleft"
- value="Socks"
- width="120"
- enabled_control="Socks5ProxyEnabled"
- tool_tip="Non-web HTTP traffic will be sent through the configured Socks 5 proxy."/>
- <radio_item
- height="16"
label="Use HTTP Proxy"
layout="topleft"
value="Web"
width="120"
enabled_control="BrowserProxyEnabled"
tool_tip="Non-web HTTP will be sent through the configured Web proxy." />
+ <radio_item
+ height="16"
+ label="Use SOCKS 5 Proxy"
+ layout="topleft"
+ value="Socks"
+ width="120"
+ enabled_control="Socks5ProxyEnabled"
+ tool_tip="Non-web HTTP traffic will be sent through the configured Socks 5 proxy."/>
</radio_group>
<button
follows="left|top"