diff options
Diffstat (limited to 'indra/llmessage/llproxy.cpp')
-rw-r--r-- | indra/llmessage/llproxy.cpp | 588 |
1 files changed, 294 insertions, 294 deletions
diff --git a/indra/llmessage/llproxy.cpp b/indra/llmessage/llproxy.cpp index 749e599c66..3e1e5daa02 100644 --- a/indra/llmessage/llproxy.cpp +++ b/indra/llmessage/llproxy.cpp @@ -5,21 +5,21 @@ * $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$ */ @@ -48,15 +48,15 @@ static LLSocket::ptr_t tcp_open_channel(LLHost host); // Open a TCP channel to a static void tcp_close_channel(LLSocket::ptr_t* handle_ptr); // Close an open TCP channel LLProxy::LLProxy(): - mHTTPProxyEnabled(false), - mProxyMutex(), - mUDPProxy(), - mTCPProxy(), - mHTTPProxy(), - mProxyType(LLPROXY_SOCKS), - mAuthMethodSelected(METHOD_NOAUTH), - mSocksUsername(), - mSocksPassword() + mHTTPProxyEnabled(false), + mProxyMutex(), + mUDPProxy(), + mTCPProxy(), + mHTTPProxy(), + mProxyType(LLPROXY_SOCKS), + mAuthMethodSelected(METHOD_NOAUTH), + mSocksUsername(), + mSocksPassword() {} LLProxy::~LLProxy() @@ -88,112 +88,112 @@ void LLProxy::initSingleton() */ S32 LLProxy::proxyHandshake(LLHost proxy) { - S32 result; - - /* SOCKS 5 Auth request */ - 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. - - 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; - stopSOCKSProxy(); - return SOCKS_CONNECT_ERROR; - } - - if (socks_auth_response.method == AUTH_NOT_ACCEPTABLE) - { - LL_WARNS("Proxy") << "SOCKS 5 server refused all our authentication methods." << LL_ENDL; - stopSOCKSProxy(); - return SOCKS_NOT_ACCEPTABLE; - } - - /* SOCKS 5 USERNAME/PASSWORD authentication */ - if (socks_auth_response.method == METHOD_PASSWORD) - { - // The server has requested a username/password combination - std::string socks_username(getSocksUser()); - std::string socks_password(getSocksPwd()); - U32 request_size = socks_username.size() + socks_password.size() + 3; - char * password_auth = new char[request_size]; - password_auth[0] = 0x01; - password_auth[1] = (char)(socks_username.size()); - memcpy(&password_auth[2], socks_username.c_str(), socks_username.size()); - password_auth[socks_username.size() + 2] = (char)(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_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) - { - LL_WARNS("Proxy") << "SOCKS authentication failed, error on TCP control channel : " << result << LL_ENDL; - stopSOCKSProxy(); - return SOCKS_CONNECT_ERROR; - } - - if (password_reply.status != AUTH_SUCCESS) - { - LL_WARNS("Proxy") << "SOCKS authentication failed" << LL_ENDL; - stopSOCKSProxy(); - return SOCKS_AUTH_FAIL; - } - } - - /* SOCKS5 connect request */ - - socks_command_request_t connect_request; - socks_command_response_t connect_reply; - - connect_request.version = SOCKS_VERSION; // SOCKS V5 - connect_request.command = COMMAND_UDP_ASSOCIATE; // Associate UDP - connect_request.reserved = FIELD_RESERVED; - connect_request.atype = ADDRESS_IPV4; - connect_request.address = htonl(0); // 0.0.0.0 - connect_request.port = htons(0); // 0 - // "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_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; - stopSOCKSProxy(); - return SOCKS_CONNECT_ERROR; - } - - if (connect_reply.reply != REPLY_REQUEST_GRANTED) - { - LL_WARNS("Proxy") << "Connection to SOCKS 5 server failed, UDP forward request not granted" << LL_ENDL; - stopSOCKSProxy(); - return SOCKS_UDP_FWD_NOT_GRANTED; - } - - mUDPProxy.setPort(ntohs(connect_reply.port)); // reply port is in network byte order - 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; + S32 result; + + /* SOCKS 5 Auth request */ + 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. + + 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; + stopSOCKSProxy(); + return SOCKS_CONNECT_ERROR; + } + + if (socks_auth_response.method == AUTH_NOT_ACCEPTABLE) + { + LL_WARNS("Proxy") << "SOCKS 5 server refused all our authentication methods." << LL_ENDL; + stopSOCKSProxy(); + return SOCKS_NOT_ACCEPTABLE; + } + + /* SOCKS 5 USERNAME/PASSWORD authentication */ + if (socks_auth_response.method == METHOD_PASSWORD) + { + // The server has requested a username/password combination + std::string socks_username(getSocksUser()); + std::string socks_password(getSocksPwd()); + U32 request_size = socks_username.size() + socks_password.size() + 3; + char * password_auth = new char[request_size]; + password_auth[0] = 0x01; + password_auth[1] = (char)(socks_username.size()); + memcpy(&password_auth[2], socks_username.c_str(), socks_username.size()); + password_auth[socks_username.size() + 2] = (char)(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_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) + { + LL_WARNS("Proxy") << "SOCKS authentication failed, error on TCP control channel : " << result << LL_ENDL; + stopSOCKSProxy(); + return SOCKS_CONNECT_ERROR; + } + + if (password_reply.status != AUTH_SUCCESS) + { + LL_WARNS("Proxy") << "SOCKS authentication failed" << LL_ENDL; + stopSOCKSProxy(); + return SOCKS_AUTH_FAIL; + } + } + + /* SOCKS5 connect request */ + + socks_command_request_t connect_request; + socks_command_response_t connect_reply; + + connect_request.version = SOCKS_VERSION; // SOCKS V5 + connect_request.command = COMMAND_UDP_ASSOCIATE; // Associate UDP + connect_request.reserved = FIELD_RESERVED; + connect_request.atype = ADDRESS_IPV4; + connect_request.address = htonl(0); // 0.0.0.0 + connect_request.port = htons(0); // 0 + // "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_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; + stopSOCKSProxy(); + return SOCKS_CONNECT_ERROR; + } + + if (connect_reply.reply != REPLY_REQUEST_GRANTED) + { + LL_WARNS("Proxy") << "Connection to SOCKS 5 server failed, UDP forward request not granted" << LL_ENDL; + stopSOCKSProxy(); + return SOCKS_UDP_FWD_NOT_GRANTED; + } + + mUDPProxy.setPort(ntohs(connect_reply.port)); // reply port is in network byte order + 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; } /** @@ -209,38 +209,38 @@ S32 LLProxy::proxyHandshake(LLHost proxy) */ S32 LLProxy::startSOCKSProxy(LLHost host) { - if (host.isOk()) - { - mTCPProxy = host; - } - else - { - return SOCKS_INVALID_HOST; - } - - // Close any running SOCKS connection. - stopSOCKSProxy(); - - mProxyControlChannel = tcp_open_channel(mTCPProxy); - if (!mProxyControlChannel) - { - return SOCKS_HOST_CONNECT_FAILED; - } - - S32 status = proxyHandshake(mTCPProxy); - - if (status != SOCKS_OK) - { - // Shut down the proxy if any of the above steps failed. - stopSOCKSProxy(); - } - else - { - // Connection was successful. - sUDPProxyEnabled = true; - } - - return status; + if (host.isOk()) + { + mTCPProxy = host; + } + else + { + return SOCKS_INVALID_HOST; + } + + // Close any running SOCKS connection. + stopSOCKSProxy(); + + mProxyControlChannel = tcp_open_channel(mTCPProxy); + if (!mProxyControlChannel) + { + return SOCKS_HOST_CONNECT_FAILED; + } + + S32 status = proxyHandshake(mTCPProxy); + + if (status != SOCKS_OK) + { + // Shut down the proxy if any of the above steps failed. + stopSOCKSProxy(); + } + else + { + // Connection was successful. + sUDPProxyEnabled = true; + } + + return status; } /** @@ -252,21 +252,21 @@ S32 LLProxy::startSOCKSProxy(LLHost host) */ void LLProxy::stopSOCKSProxy() { - sUDPProxyEnabled = false; + 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 == getHTTPProxyType()) - { - disableHTTPProxy(); - } + if (LLPROXY_SOCKS == getHTTPProxyType()) + { + disableHTTPProxy(); + } - if (mProxyControlChannel) - { - tcp_close_channel(&mProxyControlChannel); - } + if (mProxyControlChannel) + { + tcp_close_channel(&mProxyControlChannel); + } } /** @@ -274,9 +274,9 @@ void LLProxy::stopSOCKSProxy() */ void LLProxy::setAuthNone() { - LLMutexLock lock(&mProxyMutex); + LLMutexLock lock(&mProxyMutex); - mAuthMethodSelected = METHOD_NOAUTH; + mAuthMethodSelected = METHOD_NOAUTH; } /** @@ -286,27 +286,27 @@ void LLProxy::setAuthNone() * and password conform to the lengths allowed by the * SOCKS protocol. * - * @param username The SOCKS username to send. - * @param password The SOCKS password to send. + * @param username The SOCKS username to send. + * @param password The SOCKS password to send. * @return Return true if applying the settings was successful. No changes are made if false. * */ bool LLProxy::setAuthPassword(const std::string &username, const std::string &password) { - if (username.length() > SOCKSMAXUSERNAMELEN || password.length() > SOCKSMAXPASSWORDLEN || - username.length() < SOCKSMINUSERNAMELEN || password.length() < SOCKSMINPASSWORDLEN) - { - LL_WARNS("Proxy") << "Invalid SOCKS 5 password or username length." << LL_ENDL; - return false; - } + if (username.length() > SOCKSMAXUSERNAMELEN || password.length() > SOCKSMAXPASSWORDLEN || + username.length() < SOCKSMINUSERNAMELEN || password.length() < SOCKSMINPASSWORDLEN) + { + LL_WARNS("Proxy") << "Invalid SOCKS 5 password or username length." << LL_ENDL; + return false; + } - LLMutexLock lock(&mProxyMutex); + LLMutexLock lock(&mProxyMutex); - mAuthMethodSelected = METHOD_PASSWORD; - mSocksUsername = username; - mSocksPassword = password; + mAuthMethodSelected = METHOD_PASSWORD; + mSocksUsername = username; + mSocksPassword = password; - return true; + return true; } /** @@ -320,20 +320,20 @@ bool LLProxy::setAuthPassword(const std::string &username, const std::string &pa */ bool LLProxy::enableHTTPProxy(LLHost httpHost, LLHttpProxyType type) { - if (!httpHost.isOk()) - { - LL_WARNS("Proxy") << "Invalid SOCKS 5 Server" << LL_ENDL; - return false; - } + if (!httpHost.isOk()) + { + LL_WARNS("Proxy") << "Invalid SOCKS 5 Server" << LL_ENDL; + return false; + } - LLMutexLock lock(&mProxyMutex); + LLMutexLock lock(&mProxyMutex); - mHTTPProxy = httpHost; - mProxyType = type; + mHTTPProxy = httpHost; + mProxyType = type; - mHTTPProxyEnabled = true; + mHTTPProxyEnabled = true; - return true; + return true; } /** @@ -345,17 +345,17 @@ bool LLProxy::enableHTTPProxy(LLHost httpHost, LLHttpProxyType type) */ bool LLProxy::enableHTTPProxy() { - bool ok; + bool ok; - LLMutexLock lock(&mProxyMutex); + LLMutexLock lock(&mProxyMutex); - ok = (mHTTPProxy.isOk()); - if (ok) - { - mHTTPProxyEnabled = true; - } + ok = (mHTTPProxy.isOk()); + if (ok) + { + mHTTPProxyEnabled = true; + } - return ok; + return ok; } /** @@ -363,9 +363,9 @@ bool LLProxy::enableHTTPProxy() */ void LLProxy::disableHTTPProxy() { - LLMutexLock lock(&mProxyMutex); + LLMutexLock lock(&mProxyMutex); - mHTTPProxyEnabled = false; + mHTTPProxyEnabled = false; } /** @@ -373,8 +373,8 @@ void LLProxy::disableHTTPProxy() */ LLHttpProxyType LLProxy::getHTTPProxyType() const { - LLMutexLock lock(&mProxyMutex); - return mProxyType; + LLMutexLock lock(&mProxyMutex); + return mProxyType; } /** @@ -382,8 +382,8 @@ LLHttpProxyType LLProxy::getHTTPProxyType() const */ std::string LLProxy::getSocksPwd() const { - LLMutexLock lock(&mProxyMutex); - return mSocksPassword; + LLMutexLock lock(&mProxyMutex); + return mSocksPassword; } /** @@ -391,8 +391,8 @@ std::string LLProxy::getSocksPwd() const */ std::string LLProxy::getSocksUser() const { - LLMutexLock lock(&mProxyMutex); - return mSocksUsername; + LLMutexLock lock(&mProxyMutex); + return mSocksUsername; } /** @@ -402,8 +402,8 @@ std::string LLProxy::getSocksUser() const */ LLSocks5AuthType LLProxy::getSelectedAuthMethod() const { - LLMutexLock lock(&mProxyMutex); - return mAuthMethodSelected; + LLMutexLock lock(&mProxyMutex); + return mAuthMethodSelected; } /** @@ -434,32 +434,32 @@ void LLProxy::cleanupClass() */ void LLProxy::applyProxySettings(CURL* handle) { - // Do a faster unlocked check to see if we are supposed to proxy. - if (sProxyInstance && sProxyInstance->mHTTPProxyEnabled) - { - // We think we should proxy, lock the proxy mutex. sProxyInstance is not protected by mutex - LLMutexLock lock(&sProxyInstance->mProxyMutex); - // Now test again to verify that the proxy wasn't disabled between the first check and the lock. - if (sProxyInstance->mHTTPProxyEnabled) - { - LLCore::LLHttp::check_curl_code(curl_easy_setopt(handle, CURLOPT_PROXY, sProxyInstance->mHTTPProxy.getIPString().c_str()), CURLOPT_PROXY); - LLCore::LLHttp::check_curl_code(curl_easy_setopt(handle, CURLOPT_PROXYPORT, sProxyInstance->mHTTPProxy.getPort()), CURLOPT_PROXYPORT); - - if (sProxyInstance->mProxyType == LLPROXY_SOCKS) - { - LLCore::LLHttp::check_curl_code(curl_easy_setopt(handle, CURLOPT_PROXYTYPE, CURLPROXY_SOCKS5), CURLOPT_PROXYTYPE); - if (sProxyInstance->mAuthMethodSelected == METHOD_PASSWORD) - { - std::string auth_string = sProxyInstance->mSocksUsername + ":" + sProxyInstance->mSocksPassword; - LLCore::LLHttp::check_curl_code(curl_easy_setopt(handle, CURLOPT_PROXYUSERPWD, auth_string.c_str()), CURLOPT_PROXYUSERPWD); - } - } - else - { - LLCore::LLHttp::check_curl_code(curl_easy_setopt(handle, CURLOPT_PROXYTYPE, CURLPROXY_HTTP), CURLOPT_PROXYTYPE); - } - } - } + // Do a faster unlocked check to see if we are supposed to proxy. + if (sProxyInstance && sProxyInstance->mHTTPProxyEnabled) + { + // We think we should proxy, lock the proxy mutex. sProxyInstance is not protected by mutex + LLMutexLock lock(&sProxyInstance->mProxyMutex); + // Now test again to verify that the proxy wasn't disabled between the first check and the lock. + if (sProxyInstance->mHTTPProxyEnabled) + { + LLCore::LLHttp::check_curl_code(curl_easy_setopt(handle, CURLOPT_PROXY, sProxyInstance->mHTTPProxy.getIPString().c_str()), CURLOPT_PROXY); + LLCore::LLHttp::check_curl_code(curl_easy_setopt(handle, CURLOPT_PROXYPORT, sProxyInstance->mHTTPProxy.getPort()), CURLOPT_PROXYPORT); + + if (sProxyInstance->mProxyType == LLPROXY_SOCKS) + { + LLCore::LLHttp::check_curl_code(curl_easy_setopt(handle, CURLOPT_PROXYTYPE, CURLPROXY_SOCKS5), CURLOPT_PROXYTYPE); + if (sProxyInstance->mAuthMethodSelected == METHOD_PASSWORD) + { + std::string auth_string = sProxyInstance->mSocksUsername + ":" + sProxyInstance->mSocksPassword; + LLCore::LLHttp::check_curl_code(curl_easy_setopt(handle, CURLOPT_PROXYUSERPWD, auth_string.c_str()), CURLOPT_PROXYUSERPWD); + } + } + else + { + LLCore::LLHttp::check_curl_code(curl_easy_setopt(handle, CURLOPT_PROXYTYPE, CURLPROXY_HTTP), CURLOPT_PROXYTYPE); + } + } + } } /** @@ -468,59 +468,59 @@ void LLProxy::applyProxySettings(CURL* handle) * This operation is done synchronously with a 1000ms timeout. Therefore, it should not be used when a blocking * operation would impact the operation of the viewer. * - * @param handle_ptr Pointer to a connected LLSocket of type STREAM_TCP. - * @param dataout Data to send. - * @param outlen Length of dataout. - * @param datain Buffer for received data. Undefined if return value is not APR_SUCCESS. - * @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. + * @param handle_ptr Pointer to a connected LLSocket of type STREAM_TCP. + * @param dataout Data to send. + * @param outlen Length of dataout. + * @param datain Buffer for received data. Undefined if return value is not APR_SUCCESS. + * @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 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; - - apr_size_t expected_len = outlen; - - handle->setBlocking(1000); - - rv = apr_socket_send(apr_socket, dataout, &outlen); - if (APR_SUCCESS != rv) - { - char buf[MAX_STRING]; - LL_WARNS("Proxy") << "Error sending data to proxy control channel, status: " << rv << " " << apr_strerror(rv, buf, MAX_STRING) << LL_ENDL; - ll_apr_warn_status(rv); - } - else if (expected_len != outlen) - { - LL_WARNS("Proxy") << "Incorrect data length sent. Expected: " << expected_len << - " Sent: " << outlen << LL_ENDL; - rv = -1; - } - - ms_sleep(1); - - if (APR_SUCCESS == rv) - { - expected_len = maxinlen; - rv = apr_socket_recv(apr_socket, datain, &maxinlen); - if (rv != APR_SUCCESS) - { - char buf[MAX_STRING]; - LL_WARNS("Proxy") << "Error receiving data from proxy control channel, status: " << rv << " " << apr_strerror(rv, buf, MAX_STRING) << LL_ENDL; - ll_apr_warn_status(rv); - } - else if (expected_len < maxinlen) - { - LL_WARNS("Proxy") << "Incorrect data length received. Expected: " << expected_len << - " Received: " << maxinlen << LL_ENDL; - rv = -1; - } - } - - handle->setNonBlocking(); - - return rv; + apr_socket_t* apr_socket = handle->getSocket(); + apr_status_t rv = APR_SUCCESS; + + apr_size_t expected_len = outlen; + + handle->setBlocking(1000); + + rv = apr_socket_send(apr_socket, dataout, &outlen); + if (APR_SUCCESS != rv) + { + char buf[MAX_STRING]; + LL_WARNS("Proxy") << "Error sending data to proxy control channel, status: " << rv << " " << apr_strerror(rv, buf, MAX_STRING) << LL_ENDL; + ll_apr_warn_status(rv); + } + else if (expected_len != outlen) + { + LL_WARNS("Proxy") << "Incorrect data length sent. Expected: " << expected_len << + " Sent: " << outlen << LL_ENDL; + rv = -1; + } + + ms_sleep(1); + + if (APR_SUCCESS == rv) + { + expected_len = maxinlen; + rv = apr_socket_recv(apr_socket, datain, &maxinlen); + if (rv != APR_SUCCESS) + { + char buf[MAX_STRING]; + LL_WARNS("Proxy") << "Error receiving data from proxy control channel, status: " << rv << " " << apr_strerror(rv, buf, MAX_STRING) << LL_ENDL; + ll_apr_warn_status(rv); + } + else if (expected_len < maxinlen) + { + LL_WARNS("Proxy") << "Incorrect data length received. Expected: " << expected_len << + " Received: " << maxinlen << LL_ENDL; + rv = -1; + } + } + + handle->setNonBlocking(); + + return rv; } /** @@ -528,19 +528,19 @@ static apr_status_t tcp_blocking_handshake(LLSocket::ptr_t handle, char * dataou * * Checks for a successful connection, and makes sure the connection is closed if it fails. * - * @param host The host to open the connection to. - * @return The created socket. Will evaluate as NULL if the connection is unsuccessful. + * @param host The host to open the connection to. + * @return The created socket. Will evaluate as NULL if the connection is unsuccessful. */ static LLSocket::ptr_t tcp_open_channel(LLHost host) { - LLSocket::ptr_t socket = LLSocket::create(NULL, LLSocket::STREAM_TCP); - bool connected = socket->blockingConnect(host); - if (!connected) - { - tcp_close_channel(&socket); - } - - return socket; + LLSocket::ptr_t socket = LLSocket::create(NULL, LLSocket::STREAM_TCP); + bool connected = socket->blockingConnect(host); + if (!connected) + { + tcp_close_channel(&socket); + } + + return socket; } /** @@ -550,6 +550,6 @@ static LLSocket::ptr_t tcp_open_channel(LLHost host) */ static void tcp_close_channel(LLSocket::ptr_t* handle_ptr) { - LL_DEBUGS("Proxy") << "Resetting proxy LLSocket handle, use_count == " << handle_ptr->use_count() << LL_ENDL; - handle_ptr->reset(); + LL_DEBUGS("Proxy") << "Resetting proxy LLSocket handle, use_count == " << handle_ptr->use_count() << LL_ENDL; + handle_ptr->reset(); } |