diff options
author | Logan Dethrow <log@lindenlab.com> | 2011-07-05 16:55:43 -0400 |
---|---|---|
committer | Logan Dethrow <log@lindenlab.com> | 2011-07-05 16:55:43 -0400 |
commit | 975975029d7f248cdf917da670ffd6c6b98d40c1 (patch) | |
tree | 4e7af2d0bf697bf930554d59bd7327fba52e4c69 | |
parent | aec182e3dbc2e4c492167fc250583b9de5ec43f8 (diff) |
STORM-1112 Fixed crash on quit. Other minor fixes:
* Reordered HTTP proxy choices in settings dialog
* Now using setBlocking and setNonBlocking LLSocket methods during TCP handshakes.
* Made those LLSocket methods available outside the class.
-rw-r--r-- | indra/llmessage/lliosocket.cpp | 2 | ||||
-rw-r--r-- | indra/llmessage/lliosocket.h | 16 | ||||
-rw-r--r-- | indra/llmessage/llproxy.cpp | 93 | ||||
-rw-r--r-- | indra/llmessage/llproxy.h | 7 | ||||
-rw-r--r-- | indra/newview/llappviewer.cpp | 3 | ||||
-rw-r--r-- | indra/newview/llstartup.cpp | 16 | ||||
-rw-r--r-- | indra/newview/skins/default/xui/en/floater_preferences_proxy.xml | 17 |
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" |