From 7717b6f647feb250c0b94d038f72a640a7888915 Mon Sep 17 00:00:00 2001 From: Logan Dethrow Date: Tue, 28 Jun 2011 19:54:53 -0400 Subject: STORM-1112 More cleanup of SOCKS 5 proxy code. Renamed llsocks5.cpp to llproxy.cpp. --- indra/llmessage/llproxy.h | 244 ++++++++++++++++++++++++++++++++++++++++++++++ 1 file changed, 244 insertions(+) create mode 100644 indra/llmessage/llproxy.h (limited to 'indra/llmessage/llproxy.h') diff --git a/indra/llmessage/llproxy.h b/indra/llmessage/llproxy.h new file mode 100644 index 0000000000..979514a7e0 --- /dev/null +++ b/indra/llmessage/llproxy.h @@ -0,0 +1,244 @@ +/** + * @file llsocks5.h + * @brief Socks 5 implementation + * + * $LicenseInfo:firstyear=2011&license=viewerlgpl$ + * Second Life Viewer Source Code + * Copyright (C) 2011, Linden Research, Inc. + * + * This library is free software; you can redistribute it and/or + * modify it under the terms of the GNU Lesser General Public + * License as published by the Free Software Foundation; + * version 2.1 of the License only. + * + * This library is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU + * Lesser General Public License for more details. + * + * You should have received a copy of the GNU Lesser General Public + * License along with this library; if not, write to the Free Software + * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA + * + * Linden Research, Inc., 945 Battery Street, San Francisco, CA 94111 USA + * $/LicenseInfo$ + */ + +#ifndef LL_PROXY_H +#define LL_PROXY_H + +#include "llhost.h" +#include "lliosocket.h" +#include "llmemory.h" +#include "llsingleton.h" +#include + +// Error codes returned from the StartProxy method + +#define SOCKS_OK 0 +#define SOCKS_CONNECT_ERROR (-1) +#define SOCKS_NOT_PERMITTED (-2) +#define SOCKS_NOT_ACCEPTABLE (-3) +#define SOCKS_AUTH_FAIL (-4) +#define SOCKS_UDP_FWD_NOT_GRANTED (-5) +#define SOCKS_HOST_CONNECT_FAILED (-6) + +#ifndef MAXHOSTNAMELEN +#define MAXHOSTNAMELEN (255 + 1) /* socks5: 255, +1 for len. */ +#endif + +#define SOCKS_VERSION 0x05 // we are using SOCKS 5 + +// SOCKS 5 address/hostname types +#define ADDRESS_IPV4 0x01 +#define ADDRESS_HOSTNAME 0x03 +#define ADDRESS_IPV6 0x04 + +// Lets just use our own ipv4 struct rather than dragging in system +// specific headers +union ipv4_address_t { + U8 octets[4]; + U32 addr32; +}; + +// SOCKS 5 control channel commands +#define COMMAND_TCP_STREAM 0x01 +#define COMMAND_TCP_BIND 0x02 +#define COMMAND_UDP_ASSOCIATE 0x03 + +// SOCKS 5 command replies +#define REPLY_REQUEST_GRANTED 0x00 +#define REPLY_GENERAL_FAIL 0x01 +#define REPLY_RULESET_FAIL 0x02 +#define REPLY_NETWORK_UNREACHABLE 0x03 +#define REPLY_HOST_UNREACHABLE 0x04 +#define REPLY_CONNECTION_REFUSED 0x05 +#define REPLY_TTL_EXPIRED 0x06 +#define REPLY_PROTOCOL_ERROR 0x07 +#define REPLY_TYPE_NOT_SUPPORTED 0x08 + +#define FIELD_RESERVED 0x00 + +// 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) + +// SOCKS 5 command packet +struct socks_command_request_t { + U8 version; + U8 command; + U8 reserved; + U8 atype; + U32 address; + U16 port; +}; + +// Standard SOCKS 5 reply packet +struct socks_command_response_t { + 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 +struct socks_auth_request_t { + U8 version; + U8 num_methods; + U8 methods; // We are only using a single method currently +}; + +// SOCKS 5 authentication response packet, stating server preferred method +struct socks_auth_response_t { + U8 version; + U8 method; +}; + +// SOCKS 5 password reply packet +struct authmethod_password_reply_t { + U8 version; + U8 status; +}; + +// SOCKS 5 UDP packet header +struct proxywrap_t { + U16 rsv; + U8 frag; + U8 atype; + U32 addr; + U16 port; +}; + +#pragma pack(pop) /* restore original alignment from stack */ + + +// Currently selected http proxy type +enum LLHttpProxyType +{ + LLPROXY_SOCKS = 0, + LLPROXY_HTTP = 1 +}; + +// Auth types +enum LLSocks5AuthType +{ + METHOD_NOAUTH = 0x00, // Client supports no auth + METHOD_GSSAPI = 0x01, // Client supports GSSAPI (Not currently supported) + METHOD_PASSWORD = 0x02 // Client supports username/password +}; + +class LLProxy: public LLSingleton +{ +public: + LLProxy(); + ~LLProxy(); + + // Start a connection to the SOCKS 5 proxy + int startProxy(std::string host, U32 port); + + // 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(const std::string &username, const std::string &password); + + // 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 check for enabled status for http packets + static bool isHTTPProxyEnabled() { return sHTTPProxyEnabled; } + + // 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); + + // 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 + LLHost getTCPProxy() const { return mTCPProxy; } + + // 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 username password in a curl compatible format + std::string getProxyUserPwdCURL() const { return (mSocksUsername + ":" + mSocksPassword); } + + std::string getSocksPwd() const { return mSocksPassword; } + std::string getSocksUser() const { return mSocksUsername; } + +private: + + // 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 + LLSocket::ptr_t mProxyControlChannel; + + // is the UDP proxy enabled? + static bool sUDPProxyEnabled; + // is the http proxy enabled? + static bool sHTTPProxyEnabled; + + // currently selected http proxy type + LLHttpProxyType mProxyType; + + // UDP proxy address and port + LLHost mUDPProxy; + // TCP Proxy control channel address and port + LLHost mTCPProxy; + // HTTP proxy address and port + LLHost mHTTPProxy; + + // SOCKS 5 auth method selected + LLSocks5AuthType mAuthMethodSelected; + + // SOCKS 5 username + std::string mSocksUsername; + // SOCKS 5 password + std::string mSocksPassword; + + // APR pool for the socket + apr_pool_t* mPool; +}; + +#endif -- cgit v1.2.3 From 975975029d7f248cdf917da670ffd6c6b98d40c1 Mon Sep 17 00:00:00 2001 From: Logan Dethrow Date: Tue, 5 Jul 2011 16:55:43 -0400 Subject: 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. --- indra/llmessage/llproxy.h | 7 +++++-- 1 file changed, 5 insertions(+), 2 deletions(-) (limited to 'indra/llmessage/llproxy.h') 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; -- cgit v1.2.3 From cfce3686dea74dfa2a6c92dbd1e8e1ae8518f259 Mon Sep 17 00:00:00 2001 From: Logan Dethrow Date: Wed, 13 Jul 2011 11:40:50 -0400 Subject: STORM-1112 Fixed network buffers that need to have space for the SOCKS proxy header. --- indra/llmessage/llproxy.h | 4 +++- 1 file changed, 3 insertions(+), 1 deletion(-) (limited to 'indra/llmessage/llproxy.h') diff --git a/indra/llmessage/llproxy.h b/indra/llmessage/llproxy.h index 498ffce24e..7893545b9d 100644 --- a/indra/llmessage/llproxy.h +++ b/indra/llmessage/llproxy.h @@ -49,6 +49,8 @@ #define SOCKS_VERSION 0x05 // we are using SOCKS 5 +#define SOCKS_HEADER_SIZE 10 + // SOCKS 5 address/hostname types #define ADDRESS_IPV4 0x01 #define ADDRESS_HOSTNAME 0x03 @@ -139,7 +141,7 @@ struct proxywrap_t { #pragma pack(pop) /* restore original alignment from stack */ -// Currently selected http proxy type +// Currently selected HTTP proxy type enum LLHttpProxyType { LLPROXY_SOCKS = 0, -- cgit v1.2.3 From cb24dff9e36a963af280be1aead9424be8a678b6 Mon Sep 17 00:00:00 2001 From: Logan Dethrow Date: Wed, 13 Jul 2011 16:46:36 -0400 Subject: Code cleanup for the SOCKS 5 proxy viewer. --- indra/llmessage/llproxy.h | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) (limited to 'indra/llmessage/llproxy.h') diff --git a/indra/llmessage/llproxy.h b/indra/llmessage/llproxy.h index 7893545b9d..cf2dfdc60e 100644 --- a/indra/llmessage/llproxy.h +++ b/indra/llmessage/llproxy.h @@ -191,7 +191,7 @@ public: void enableHTTPProxy(LLHost httpHost, LLHttpProxyType type); // Stop proxying HTTP packets - void disableHTTPProxy() { sHTTPProxyEnabled = false; }; + void disableHTTPProxy() { sHTTPProxyEnabled = false; } // Get the UDP proxy address and port LLHost getUDPProxy() const { return mUDPProxy; } -- cgit v1.2.3 From 792667ff8ef13e16823d96b490ea9a4f498425ea Mon Sep 17 00:00:00 2001 From: Logan Dethrow Date: Tue, 19 Jul 2011 14:20:21 -0400 Subject: STORM-1112 Added LLProxy::applyProxySettings() to apply proxy settings to curl handles. Added call to that function everywhere curl handles are created in the viewer. --- indra/llmessage/llproxy.h | 10 ++++++++++ 1 file changed, 10 insertions(+) (limited to 'indra/llmessage/llproxy.h') diff --git a/indra/llmessage/llproxy.h b/indra/llmessage/llproxy.h index cf2dfdc60e..7d1431a4b3 100644 --- a/indra/llmessage/llproxy.h +++ b/indra/llmessage/llproxy.h @@ -27,6 +27,7 @@ #ifndef LL_PROXY_H #define LL_PROXY_H +#include "llcurl.h" #include "llhost.h" #include "lliosocket.h" #include "llmemory.h" @@ -211,6 +212,11 @@ public: std::string getSocksPwd() const { return mSocksPassword; } std::string getSocksUser() const { return mSocksUsername; } + // Apply the current proxy settings to a curl request. Doesn't do anything if sHTTPProxyEnabled is false. + void applyProxySettings(CURL* handle); + void applyProxySettings(LLCurl::Easy* handle); + void applyProxySettings(LLCurlEasyRequest* handle); + private: // Open a communication channel to the SOCKS 5 proxy proxy, at port messagePort @@ -242,6 +248,10 @@ private: // SOCKS 5 password std::string mSocksPassword; + // Vectors to store valid pointers to string options that have been passed to CURL requests. + std::vector mSOCKSAuthStrings; + std::vector mSOCKSAddrStrings; + // APR pool for the socket apr_pool_t* mPool; }; -- cgit v1.2.3 From 859dc52c30a8c750047323399caa4fec18adfb2d Mon Sep 17 00:00:00 2001 From: Logan Dethrow Date: Thu, 21 Jul 2011 15:16:54 -0400 Subject: STORM-1112 Protected LLProxy members during cross-thread calls to LLProxy::applyProxySettings() --- indra/llmessage/llproxy.h | 21 ++++++++++++++------- 1 file changed, 14 insertions(+), 7 deletions(-) (limited to 'indra/llmessage/llproxy.h') diff --git a/indra/llmessage/llproxy.h b/indra/llmessage/llproxy.h index 7d1431a4b3..df1ec9121e 100644 --- a/indra/llmessage/llproxy.h +++ b/indra/llmessage/llproxy.h @@ -32,6 +32,7 @@ #include "lliosocket.h" #include "llmemory.h" #include "llsingleton.h" +#include "llthread.h" #include // Error codes returned from the StartProxy method @@ -190,9 +191,10 @@ public: // 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(); // Stop proxying HTTP packets - void disableHTTPProxy() { sHTTPProxyEnabled = false; } + void disableHTTPProxy(); // Get the UDP proxy address and port LLHost getUDPProxy() const { return mUDPProxy; } @@ -218,16 +220,17 @@ public: void applyProxySettings(LLCurlEasyRequest* handle); private: - // Open a communication channel to the SOCKS 5 proxy proxy, at port messagePort S32 proxyHandshake(LLHost proxy, U32 messagePort); +private: // socket handle to proxy TCP control channel LLSocket::ptr_t mProxyControlChannel; - // is the UDP proxy enabled? + // Is the UDP proxy enabled? static bool sUDPProxyEnabled; - // is the http proxy enabled? + // Is the HTTP proxy enabled? + // Do not toggle directly, use enableHTTPProxy() and disableHTTPProxy() static bool sHTTPProxyEnabled; // currently selected http proxy type @@ -235,7 +238,7 @@ private: // UDP proxy address and port LLHost mUDPProxy; - // TCP Proxy control channel address and port + // TCP proxy control channel address and port LLHost mTCPProxy; // HTTP proxy address and port LLHost mHTTPProxy; @@ -248,9 +251,13 @@ private: // SOCKS 5 password std::string mSocksPassword; - // Vectors to store valid pointers to string options that have been passed to CURL requests. + // Vectors to store valid pointers to string options that might have been set on CURL requests. + // This results in a behavior similar to LLCurl::Easy::setoptstring() std::vector mSOCKSAuthStrings; - std::vector mSOCKSAddrStrings; + std::vector mHTTPProxyAddrStrings; + + // Mutex to protect members in cross-thread calls to applyProxySettings() + LLMutex mProxyMutex; // APR pool for the socket apr_pool_t* mPool; -- cgit v1.2.3 From d2c72cb7e92896cb414e357ef262d91b0498a6b7 Mon Sep 17 00:00:00 2001 From: Logan Dethrow Date: Fri, 29 Jul 2011 15:38:20 -0400 Subject: STORM-1112 Input sanitization of proxy options. --- indra/llmessage/llproxy.h | 18 +++++++++++++----- 1 file changed, 13 insertions(+), 5 deletions(-) (limited to 'indra/llmessage/llproxy.h') diff --git a/indra/llmessage/llproxy.h b/indra/llmessage/llproxy.h index df1ec9121e..ce5bdec5ad 100644 --- a/indra/llmessage/llproxy.h +++ b/indra/llmessage/llproxy.h @@ -44,11 +44,19 @@ #define SOCKS_AUTH_FAIL (-4) #define SOCKS_UDP_FWD_NOT_GRANTED (-5) #define SOCKS_HOST_CONNECT_FAILED (-6) +#define SOCKS_INVALID_HOST (-7) + #ifndef MAXHOSTNAMELEN #define MAXHOSTNAMELEN (255 + 1) /* socks5: 255, +1 for len. */ #endif +#define SOCKSMAXUSERNAMELEN 255 +#define SOCKSMAXPASSWORDLEN 255 + +#define SOCKSMINUSERNAMELEN 1 +#define SOCKSMINPASSWORDLEN 1 + #define SOCKS_VERSION 0x05 // we are using SOCKS 5 #define SOCKS_HEADER_SIZE 10 @@ -165,16 +173,16 @@ public: ~LLProxy(); // Start a connection to the SOCKS 5 proxy - S32 startProxy(std::string host, U32 port); + S32 startSOCKSProxy(LLHost host); // Disconnect and clean up any connection to the SOCKS 5 proxy - void stopProxy(); + void stopSOCKSProxy(); // 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); + bool setAuthPassword(const std::string &username, const std::string &password); // Set up to use No Auth when connecting to the SOCKS proxy void setAuthNone(); @@ -190,8 +198,8 @@ public: // 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(); + bool enableHTTPProxy(LLHost httpHost, LLHttpProxyType type); + bool enableHTTPProxy(); // Stop proxying HTTP packets void disableHTTPProxy(); -- cgit v1.2.3 From 97bedac2a1274f26a6a346afccea7596f1d13923 Mon Sep 17 00:00:00 2001 From: Logan Dethrow Date: Tue, 2 Aug 2011 11:08:07 -0400 Subject: Proxy: Improved mutex usage in LLProxy. Introduced an LLAtomic member to track the status of the http proxy that can be checked without locking a mutex. --- indra/llmessage/llproxy.h | 72 +++++++++++++++++++++++------------------------ 1 file changed, 36 insertions(+), 36 deletions(-) (limited to 'indra/llmessage/llproxy.h') diff --git a/indra/llmessage/llproxy.h b/indra/llmessage/llproxy.h index ce5bdec5ad..22954f2733 100644 --- a/indra/llmessage/llproxy.h +++ b/indra/llmessage/llproxy.h @@ -1,6 +1,6 @@ /** - * @file llsocks5.h - * @brief Socks 5 implementation + * @file llproxy.h + * @brief UDP and HTTP proxy communications * * $LicenseInfo:firstyear=2011&license=viewerlgpl$ * Second Life Viewer Source Code @@ -188,13 +188,14 @@ public: void setAuthNone(); // get the currently selected auth method - LLSocks5AuthType getSelectedAuthMethod() const { return mAuthMethodSelected; } + LLSocks5AuthType getSelectedAuthMethod() const; // static check for enabled status for UDP packets static bool isEnabled() { return sUDPProxyEnabled; } - // static check for enabled status for http packets - static bool isHTTPProxyEnabled() { return sHTTPProxyEnabled; } + // check for enabled status for HTTP packets + // mHTTPProxyEnabled is atomic, so no locking is required for thread safety. + bool isHTTPProxyEnabled() const { return mHTTPProxyEnabled; } // Proxy HTTP packets via httpHost, which can be a SOCKS 5 or a HTTP proxy // as specified in type @@ -204,6 +205,11 @@ public: // Stop proxying HTTP packets void disableHTTPProxy(); + // Apply the current proxy settings to a curl request. Doesn't do anything if mHTTPProxyEnabled is false. + void applyProxySettings(CURL* handle); + void applyProxySettings(LLCurl::Easy* handle); + void applyProxySettings(LLCurlEasyRequest* handle); + // Get the UDP proxy address and port LLHost getUDPProxy() const { return mUDPProxy; } @@ -211,46 +217,51 @@ public: LLHost getTCPProxy() const { return mTCPProxy; } // Get the HTTP proxy address and port - LLHost getHTTPProxy() const { return mHTTPProxy; } + LLHost getHTTPProxy() const; // Get the currently selected HTTP proxy type - LLHttpProxyType getHTTPProxyType() const { return mProxyType; } + LLHttpProxyType getHTTPProxyType() const; - // Get the username password in a curl compatible format - std::string getProxyUserPwdCURL() const { return (mSocksUsername + ":" + mSocksPassword); } - - std::string getSocksPwd() const { return mSocksPassword; } - std::string getSocksUser() const { return mSocksUsername; } - - // Apply the current proxy settings to a curl request. Doesn't do anything if sHTTPProxyEnabled is false. - void applyProxySettings(CURL* handle); - void applyProxySettings(LLCurl::Easy* handle); - void applyProxySettings(LLCurlEasyRequest* handle); + std::string getSocksPwd() const; + std::string getSocksUser() const; private: // Open a communication channel to the SOCKS 5 proxy proxy, at port messagePort S32 proxyHandshake(LLHost proxy, U32 messagePort); private: - // socket handle to proxy TCP control channel - LLSocket::ptr_t mProxyControlChannel; + // Is the HTTP proxy enabled? + // Safe to read in any thread, do not write directly, + // use enableHTTPProxy() and disableHTTPProxy() instead. + mutable LLAtomic32 mHTTPProxyEnabled; + + // Mutex to protect shared members in non-main thread calls to applyProxySettings() + mutable LLMutex mProxyMutex; + + // MEMBERS READ AND WRITTEN ONLY IN THE MAIN THREAD. DO NOT SHARE! // Is the UDP proxy enabled? static bool sUDPProxyEnabled; - // Is the HTTP proxy enabled? - // Do not toggle directly, use enableHTTPProxy() and disableHTTPProxy() - static bool sHTTPProxyEnabled; - - // currently selected http proxy type - LLHttpProxyType mProxyType; // UDP proxy address and port LLHost mUDPProxy; // TCP proxy control channel address and port LLHost mTCPProxy; + + // socket handle to proxy TCP control channel + LLSocket::ptr_t mProxyControlChannel; + + // APR pool for the socket + apr_pool_t* mPool; + + // MEMBERS WRITTEN IN MAIN THREAD AND READ IN ANY THREAD. ONLY READ OR WRITE AFTER LOCKING mProxyMutex! + // HTTP proxy address and port LLHost mHTTPProxy; + // Currently selected HTTP proxy type. Can be web or socks. + LLHttpProxyType mProxyType; + // SOCKS 5 auth method selected LLSocks5AuthType mAuthMethodSelected; @@ -258,17 +269,6 @@ private: std::string mSocksUsername; // SOCKS 5 password std::string mSocksPassword; - - // Vectors to store valid pointers to string options that might have been set on CURL requests. - // This results in a behavior similar to LLCurl::Easy::setoptstring() - std::vector mSOCKSAuthStrings; - std::vector mHTTPProxyAddrStrings; - - // Mutex to protect members in cross-thread calls to applyProxySettings() - LLMutex mProxyMutex; - - // APR pool for the socket - apr_pool_t* mPool; }; #endif -- cgit v1.2.3 From d3b4cc34a8d388ab66ef2ca717ee0d814d87ff3d Mon Sep 17 00:00:00 2001 From: Logan Dethrow Date: Tue, 2 Aug 2011 17:18:54 -0400 Subject: LLProxy cleanup. * Removed early returns in LLStartup::handleSocksProxy * Corrected some cases that would result in handleSocksProxy not being called again during login if settings changed * Allowed for short replies in tcp_handshake in LLProxy.cpp * Renamed LLProxy::isEnabled() to LLProxy::isSocksProxyEnabled() to clarify its use. --- indra/llmessage/llproxy.h | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) (limited to 'indra/llmessage/llproxy.h') diff --git a/indra/llmessage/llproxy.h b/indra/llmessage/llproxy.h index 22954f2733..68c40561c8 100644 --- a/indra/llmessage/llproxy.h +++ b/indra/llmessage/llproxy.h @@ -191,7 +191,7 @@ public: LLSocks5AuthType getSelectedAuthMethod() const; // static check for enabled status for UDP packets - static bool isEnabled() { return sUDPProxyEnabled; } + static bool isSOCKSProxyEnabled() { return sUDPProxyEnabled; } // check for enabled status for HTTP packets // mHTTPProxyEnabled is atomic, so no locking is required for thread safety. -- cgit v1.2.3 From 37f88470850cf572f30b0d1dae2f46a8e3b43977 Mon Sep 17 00:00:00 2001 From: Logan Dethrow Date: Thu, 4 Aug 2011 11:17:03 -0400 Subject: LLProxy: Added another attempt to download gpu and feature tables after successfully setting up a proxy. Other minor changes: Clarified why we are using SOCKS5 as the "grid" argument to store proxy credentials. Added class wide logging to the LLProxy class. --- indra/llmessage/llproxy.h | 1 + 1 file changed, 1 insertion(+) (limited to 'indra/llmessage/llproxy.h') diff --git a/indra/llmessage/llproxy.h b/indra/llmessage/llproxy.h index 68c40561c8..534455a6dd 100644 --- a/indra/llmessage/llproxy.h +++ b/indra/llmessage/llproxy.h @@ -168,6 +168,7 @@ enum LLSocks5AuthType class LLProxy: public LLSingleton { + LOG_CLASS(LLProxy); public: LLProxy(); ~LLProxy(); -- cgit v1.2.3 From 5915da89f06106d0e811c6655144df93d35144f8 Mon Sep 17 00:00:00 2001 From: Logan Dethrow Date: Mon, 8 Aug 2011 15:53:06 -0400 Subject: LLProxy cleanup. Made the socks proxy start first in llstartup.cpp Moved initialization of the proxy to before the HTTP table fetch Added Doxygen comments to LLProxy methods. Removed call to applyProxySettings in llxmlrpctransaction.cpp since the ctor of LLCurlEasyRequest will apply the proxy settings. --- indra/llmessage/llproxy.h | 99 +++++++++++++++++++++++++++++++++++++++-------- 1 file changed, 83 insertions(+), 16 deletions(-) (limited to 'indra/llmessage/llproxy.h') diff --git a/indra/llmessage/llproxy.h b/indra/llmessage/llproxy.h index 534455a6dd..29e7e28567 100644 --- a/indra/llmessage/llproxy.h +++ b/indra/llmessage/llproxy.h @@ -35,7 +35,7 @@ #include "llthread.h" #include -// Error codes returned from the StartProxy method +// SOCKS error codes returned from the StartProxy method #define SOCKS_OK 0 #define SOCKS_CONNECT_ERROR (-1) @@ -166,11 +166,86 @@ enum LLSocks5AuthType METHOD_PASSWORD = 0x02 // Client supports username/password }; +/** + * @brief Manage SOCKS 5 UDP proxy and HTTP proxy. + * + * This class is responsible for managing two interconnected tasks, + * connecting to a SOCKS 5 proxy for use by LLPacketRing to send UDP + * packets and managing proxy settings for HTTP requests. + * + *

Threading:

+ * Because HTTP requests can be generated in threads outside the + * main thread, it is necessary for some of the information stored + * by this class to be available to other threads. The members that + * need to be read across threads are in a labeled section below. + * To protect those members, a mutex, mProxyMutex should be locked + * before reading or writing those members. Methods that can lock + * mProxyMutex are in a labeled section below. Those methods should + * not be called while the mutex is already locked. + * + * There is also a LLAtomic type flag (mHTTPProxyEnabled) that is used + * to track whether the HTTP proxy is currently enabled. This allows + * for faster unlocked checks to see if the proxy is enabled. This + * allows us to cut down on the performance hit when the proxy is + * disabled compared to before this class was introduced. + * + *

UDP Proxying:

+ * UDP datagrams are proxied via a SOCKS 5 proxy with the UDP associate + * command. To initiate the proxy, a TCP socket connection is opened + * to the SOCKS 5 host, and after a handshake exchange, the server + * returns a port and address to send the UDP traffic that is to be + * proxied to. The LLProxy class tracks this address and port after the + * exchange and provides it to LLPacketRing when required to. All UDP + * proxy management occurs in the main thread. + * + *

HTTP Proxying:

+ * This class allows all viewer HTTP packets to be sent through a proxy. + * The user can select whether to send HTTP packets through a standard + * "web" HTTP proxy, through a SOCKS 5 proxy, or to not proxy HTTP + * communication. This class does not manage the integrated web browser + * proxy, which is handled in llviewermedia.cpp. + * + * The implementation of HTTP proxying is handled by libcurl. LLProxy + * is responsible for managing the HTTP proxy options and provides a + * thread-safe method to apply those options to a curl request + * (LLProxy::applyProxySettings()). This method is overloaded + * to accommodate the various abstraction libcurl layers that exist + * throughout the viewer (LLCurlEasyRequest, LLCurl::Easy, and CURL). + * + * If you are working with LLCurl or LLCurlEasyRequest objects, + * the configured proxy settings will be applied in the constructors + * of those request handles. If you are working with CURL objects + * directly, you will need to pass the handle of the request to + * applyProxySettings() before issuing the request. + * + * To ensure thread safety, all LLProxy members that relate to the HTTP + * proxy require the LLProxyMutex to be locked before accessing. + */ class LLProxy: public LLSingleton { LOG_CLASS(LLProxy); public: + // METHODS THAT DO NOT LOCK mProxyMutex! + LLProxy(); + + // static check for enabled status for UDP packets + static bool isSOCKSProxyEnabled() { return sUDPProxyEnabled; } + + // check for enabled status for HTTP packets + // mHTTPProxyEnabled is atomic, so no locking is required for thread safety. + bool isHTTPProxyEnabled() const { return mHTTPProxyEnabled; } + + // Get the UDP proxy address and port + LLHost getUDPProxy() const { return mUDPProxy; } + + // Get the SOCKS 5 TCP control channel address and port + LLHost getTCPProxy() const { return mTCPProxy; } + + // END OF NON-LOCKING METHODS + + // METHODS THAT DO LOCK mProxyMutex! DO NOT CALL WHILE mProxyMutex IS LOCKED! + ~LLProxy(); // Start a connection to the SOCKS 5 proxy @@ -188,16 +263,9 @@ public: // Set up to use No Auth when connecting to the SOCKS proxy void setAuthNone(); - // get the currently selected auth method + // Get the currently selected auth method. LLSocks5AuthType getSelectedAuthMethod() const; - // static check for enabled status for UDP packets - static bool isSOCKSProxyEnabled() { return sUDPProxyEnabled; } - - // check for enabled status for HTTP packets - // mHTTPProxyEnabled is atomic, so no locking is required for thread safety. - bool isHTTPProxyEnabled() const { return mHTTPProxyEnabled; } - // Proxy HTTP packets via httpHost, which can be a SOCKS 5 or a HTTP proxy // as specified in type bool enableHTTPProxy(LLHost httpHost, LLHttpProxyType type); @@ -211,12 +279,6 @@ public: void applyProxySettings(LLCurl::Easy* handle); void applyProxySettings(LLCurlEasyRequest* handle); - // Get the UDP proxy address and port - LLHost getUDPProxy() const { return mUDPProxy; } - - // Get the SOCKS 5 TCP control channel address and port - LLHost getTCPProxy() const { return mTCPProxy; } - // Get the HTTP proxy address and port LLHost getHTTPProxy() const; @@ -226,9 +288,10 @@ public: std::string getSocksPwd() const; std::string getSocksUser() const; + // END OF LOCKING METHODS private: // Open a communication channel to the SOCKS 5 proxy proxy, at port messagePort - S32 proxyHandshake(LLHost proxy, U32 messagePort); + S32 proxyHandshake(LLHost proxy); private: // Is the HTTP proxy enabled? @@ -255,6 +318,8 @@ private: // APR pool for the socket apr_pool_t* mPool; + // END OF UNSHARED MEMBERS + // MEMBERS WRITTEN IN MAIN THREAD AND READ IN ANY THREAD. ONLY READ OR WRITE AFTER LOCKING mProxyMutex! // HTTP proxy address and port @@ -270,6 +335,8 @@ private: std::string mSocksUsername; // SOCKS 5 password std::string mSocksPassword; + + // END OF SHARED MEMBERS }; #endif -- cgit v1.2.3