summaryrefslogtreecommitdiff
path: root/indra/llmessage/llproxy.cpp
diff options
context:
space:
mode:
Diffstat (limited to 'indra/llmessage/llproxy.cpp')
-rw-r--r--indra/llmessage/llproxy.cpp102
1 files changed, 49 insertions, 53 deletions
diff --git a/indra/llmessage/llproxy.cpp b/indra/llmessage/llproxy.cpp
index 19f1fc6545..4a7d326c0e 100644
--- a/indra/llmessage/llproxy.cpp
+++ b/indra/llmessage/llproxy.cpp
@@ -43,7 +43,7 @@
bool LLProxy::sUDPProxyEnabled = false;
// Some helpful TCP static functions.
-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
+static apr_status_t tcp_blocking_handshake(LLSocket::ptr_t handle, char * dataout, apr_size_t outlen, char * datain, apr_size_t maxinlen); // Do a TCP data handshake
static LLSocket::ptr_t tcp_open_channel(LLHost host); // Open a TCP channel to a given host
static void tcp_close_channel(LLSocket::ptr_t* handle_ptr); // Close an open TCP channel
@@ -63,14 +63,13 @@ LLProxy::LLProxy():
LLProxy::~LLProxy()
{
stopSOCKSProxy();
- sUDPProxyEnabled = false;
- mHTTPProxyEnabled = false;
+ disableHTTPProxy();
}
/**
* @brief Open the SOCKS 5 TCP control channel.
*
- * Perform a SOCKS 5 authentication and UDP association to the proxy server.
+ * Perform a SOCKS 5 authentication and UDP association with the proxy server.
*
* @param proxy The SOCKS 5 server to connect to.
* @return SOCKS_OK if successful, otherwise a socks error code from llproxy.h.
@@ -83,11 +82,15 @@ S32 LLProxy::proxyHandshake(LLHost proxy)
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 = getSelectedAuthMethod(); // 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 = getSelectedAuthMethod(); // Send only the selected method.
- result = tcp_handshake(mProxyControlChannel, (char*)&socks_auth_request, sizeof(socks_auth_request), (char*)&socks_auth_response, sizeof(socks_auth_response));
+ result = tcp_blocking_handshake(mProxyControlChannel,
+ static_cast<char*>(static_cast<void*>(&socks_auth_request)),
+ sizeof(socks_auth_request),
+ static_cast<char*>(static_cast<void*>(&socks_auth_response)),
+ sizeof(socks_auth_response));
if (result != APR_SUCCESS)
{
LL_WARNS("Proxy") << "SOCKS authentication request failed, error on TCP control channel : " << result << LL_ENDL;
@@ -97,12 +100,12 @@ S32 LLProxy::proxyHandshake(LLHost proxy)
if (socks_auth_response.method == AUTH_NOT_ACCEPTABLE)
{
- LL_WARNS("Proxy") << "SOCKS 5 server refused all our authentication methods" << LL_ENDL;
+ LL_WARNS("Proxy") << "SOCKS 5 server refused all our authentication methods." << LL_ENDL;
stopSOCKSProxy();
return SOCKS_NOT_ACCEPTABLE;
}
- // SOCKS 5 USERNAME/PASSWORD authentication
+ /* SOCKS 5 USERNAME/PASSWORD authentication */
if (socks_auth_response.method == METHOD_PASSWORD)
{
// The server has requested a username/password combination
@@ -114,11 +117,15 @@ S32 LLProxy::proxyHandshake(LLHost proxy)
password_auth[1] = socks_username.size();
memcpy(&password_auth[2], socks_username.c_str(), socks_username.size());
password_auth[socks_username.size() + 2] = socks_password.size();
- memcpy(&password_auth[socks_username.size()+3], socks_password.c_str(), socks_password.size());
+ memcpy(&password_auth[socks_username.size() + 3], socks_password.c_str(), socks_password.size());
authmethod_password_reply_t password_reply;
- result = tcp_handshake(mProxyControlChannel, password_auth, request_size, (char*)&password_reply, sizeof(password_reply));
+ result = tcp_blocking_handshake(mProxyControlChannel,
+ password_auth,
+ request_size,
+ static_cast<char*>(static_cast<void*>(&password_reply)),
+ sizeof(password_reply));
delete[] password_auth;
if (result != APR_SUCCESS)
@@ -150,7 +157,11 @@ S32 LLProxy::proxyHandshake(LLHost proxy)
// "If the client is not in possession 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(connect_request), (char*)&connect_reply, sizeof(connect_reply));
+ result = tcp_blocking_handshake(mProxyControlChannel,
+ static_cast<char*>(static_cast<void*>(&connect_request)),
+ sizeof(connect_request),
+ static_cast<char*>(static_cast<void*>(&connect_reply)),
+ sizeof(connect_reply));
if (result != APR_SUCCESS)
{
LL_WARNS("Proxy") << "SOCKS connect request failed, error on TCP control channel : " << result << LL_ENDL;
@@ -169,6 +180,7 @@ S32 LLProxy::proxyHandshake(LLHost proxy)
mUDPProxy.setAddress(proxy.getAddress());
// The connection was successful. We now have the UDP port to send requests that need forwarding to.
LL_INFOS("Proxy") << "SOCKS 5 UDP proxy connected on " << mUDPProxy << LL_ENDL;
+
return SOCKS_OK;
}
@@ -176,7 +188,8 @@ S32 LLProxy::proxyHandshake(LLHost proxy)
* @brief Initiates a SOCKS 5 proxy session.
*
* Performs basic checks on host to verify that it is a valid address. Opens the control channel
- * and then negotiates the proxy connection with the server.
+ * and then negotiates the proxy connection with the server. Closes any existing SOCKS
+ * connection before proceeding. Also disables an HTTP proxy if it is using SOCKS as the proxy.
*
*
* @param host Socks server to connect to.
@@ -184,43 +197,37 @@ S32 LLProxy::proxyHandshake(LLHost proxy)
*/
S32 LLProxy::startSOCKSProxy(LLHost host)
{
- S32 status = SOCKS_OK;
-
if (host.isOk())
{
mTCPProxy = host;
}
else
{
- status = SOCKS_INVALID_HOST;
+ return SOCKS_INVALID_HOST;
}
- if (mProxyControlChannel && status == SOCKS_OK)
- {
- tcp_close_channel(&mProxyControlChannel);
- }
+ // Close any running SOCKS connection.
+ stopSOCKSProxy();
- if (status == SOCKS_OK)
+ mProxyControlChannel = tcp_open_channel(mTCPProxy);
+ if (!mProxyControlChannel)
{
- mProxyControlChannel = tcp_open_channel(mTCPProxy);
- if (!mProxyControlChannel)
- {
- status = SOCKS_HOST_CONNECT_FAILED;
- }
+ return SOCKS_HOST_CONNECT_FAILED;
}
- if (status == SOCKS_OK)
- {
- status = proxyHandshake(mTCPProxy);
- }
- if (status == SOCKS_OK)
+ S32 status = proxyHandshake(mTCPProxy);
+
+ if (status != SOCKS_OK)
{
- sUDPProxyEnabled = true;
+ // Shut down the proxy if any of the above steps failed.
+ stopSOCKSProxy();
}
else
{
- stopSOCKSProxy();
+ // Connection was successful.
+ sUDPProxyEnabled = true;
}
+
return status;
}
@@ -241,7 +248,7 @@ void LLProxy::stopSOCKSProxy()
if (LLPROXY_SOCKS == getHTTPProxyType())
{
- void disableHTTPProxy();
+ disableHTTPProxy();
}
if (mProxyControlChannel)
@@ -350,16 +357,6 @@ void LLProxy::disableHTTPProxy()
}
/**
- * @brief Get the HTTP proxy address and port
- */
-//
-LLHost LLProxy::getHTTPProxy() const
-{
- LLMutexLock lock(&mProxyMutex);
- return mHTTPProxy;
-}
-
-/**
* @brief Get the currently selected HTTP proxy type
*/
LLHttpProxyType LLProxy::getHTTPProxyType() const
@@ -440,21 +437,21 @@ void LLProxy::applyProxySettings(CURL* handle)
// Now test again to verify that the proxy wasn't disabled between the first check and the lock.
if (mHTTPProxyEnabled)
{
- check_curl_code(curl_easy_setopt(handle, CURLOPT_PROXY, mHTTPProxy.getIPString().c_str()));
- check_curl_code(curl_easy_setopt(handle, CURLOPT_PROXYPORT, mHTTPProxy.getPort()));
+ LLCurlFF::check_easy_code(curl_easy_setopt(handle, CURLOPT_PROXY, mHTTPProxy.getIPString().c_str()));
+ LLCurlFF::check_easy_code(curl_easy_setopt(handle, CURLOPT_PROXYPORT, mHTTPProxy.getPort()));
if (mProxyType == LLPROXY_SOCKS)
{
- check_curl_code(curl_easy_setopt(handle, CURLOPT_PROXYTYPE, CURLPROXY_SOCKS5));
+ LLCurlFF::check_easy_code(curl_easy_setopt(handle, CURLOPT_PROXYTYPE, CURLPROXY_SOCKS5));
if (mAuthMethodSelected == METHOD_PASSWORD)
{
std::string auth_string = mSocksUsername + ":" + mSocksPassword;
- check_curl_code(curl_easy_setopt(handle, CURLOPT_PROXYUSERPWD, auth_string.c_str()));
+ LLCurlFF::check_easy_code(curl_easy_setopt(handle, CURLOPT_PROXYUSERPWD, auth_string.c_str()));
}
}
else
{
- check_curl_code(curl_easy_setopt(handle, CURLOPT_PROXYTYPE, CURLPROXY_HTTP));
+ LLCurlFF::check_easy_code(curl_easy_setopt(handle, CURLOPT_PROXYTYPE, CURLPROXY_HTTP));
}
}
}
@@ -473,7 +470,7 @@ void LLProxy::applyProxySettings(CURL* handle)
* @param maxinlen Maximum possible length of received data. Short reads are allowed.
* @return Indicates APR status code of exchange. APR_SUCCESS if exchange was successful, -1 if invalid data length was received.
*/
-static S32 tcp_handshake(LLSocket::ptr_t handle, char * dataout, apr_size_t outlen, char * datain, apr_size_t maxinlen)
+static apr_status_t tcp_blocking_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_SUCCESS;
@@ -522,7 +519,6 @@ static S32 tcp_handshake(LLSocket::ptr_t handle, char * dataout, apr_size_t outl
*
* Checks for a successful connection, and makes sure the connection is closed if it fails.
*
- * @param pool APR pool to pass into the LLSocket.
* @param host The host to open the connection to.
* @return The created socket. Will evaluate as NULL if the connection is unsuccessful.
*/
@@ -541,7 +537,7 @@ static LLSocket::ptr_t tcp_open_channel(LLHost host)
/**
* @brief Close the socket.
*
- * @param handle_ptr A pointer-to-pointer to avoid increasing the use count.
+ * @param handle_ptr The handle of the socket being closed. A pointer-to-pointer to avoid increasing the use count.
*/
static void tcp_close_channel(LLSocket::ptr_t* handle_ptr)
{