diff options
Diffstat (limited to 'indra/llmessage/llproxy.cpp')
-rw-r--r-- | indra/llmessage/llproxy.cpp | 102 |
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) { |