From d3b4cc34a8d388ab66ef2ca717ee0d814d87ff3d Mon Sep 17 00:00:00 2001
From: Logan Dethrow <log@lindenlab.com>
Date: Tue, 2 Aug 2011 17:18:54 -0400
Subject: [PATCH] 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/llpacketring.cpp |   4 +-
 indra/llmessage/llproxy.cpp      |  12 +--
 indra/llmessage/llproxy.h        |   2 +-
 indra/newview/llstartup.cpp      | 141 +++++++++++++++----------------
 4 files changed, 79 insertions(+), 80 deletions(-)

diff --git a/indra/llmessage/llpacketring.cpp b/indra/llmessage/llpacketring.cpp
index ba82957b472..7628984de4c 100644
--- a/indra/llmessage/llpacketring.cpp
+++ b/indra/llmessage/llpacketring.cpp
@@ -225,7 +225,7 @@ S32 LLPacketRing::receivePacket (S32 socket, char *datap)
 	else
 	{
 		// no delay, pull straight from net
-		if (LLProxy::isEnabled())
+		if (LLProxy::isSOCKSProxyEnabled())
 		{
 			U8 buffer[NET_BUFFER_SIZE + SOCKS_HEADER_SIZE];
 			packet_size = receive_packet(socket, reinterpret_cast<char *>(buffer));
@@ -348,7 +348,7 @@ BOOL LLPacketRing::sendPacket(int h_socket, char * send_buffer, S32 buf_size, LL
 BOOL LLPacketRing::sendPacketImpl(int h_socket, const char * send_buffer, S32 buf_size, LLHost host)
 {
 	
-	if (!LLProxy::isEnabled())
+	if (!LLProxy::isSOCKSProxyEnabled())
 	{
 		return send_packet(h_socket, send_buffer, buf_size, host.getAddress(), host.getPort());
 	}
diff --git a/indra/llmessage/llproxy.cpp b/indra/llmessage/llproxy.cpp
index b2247576738..d2e64e60acc 100644
--- a/indra/llmessage/llproxy.cpp
+++ b/indra/llmessage/llproxy.cpp
@@ -382,14 +382,15 @@ static S32 tcp_handshake(LLSocket::ptr_t handle, char * dataout, apr_size_t outl
 	handle->setBlocking(1000);
 
   	rv = apr_socket_send(apr_socket, dataout, &outlen);
-	if (APR_SUCCESS != rv || expected_len != outlen)
+	if (APR_SUCCESS != rv)
 	{
-		LL_WARNS("Proxy") << "Error sending data to proxy control channel" << LL_ENDL;
+		LL_WARNS("Proxy") << "Error sending data to proxy control channel, status: " << rv << LL_ENDL;
 		ll_apr_warn_status(rv);
 	}
 	else if (expected_len != outlen)
 	{
-		LL_WARNS("Proxy") << "Error sending data to proxy control channel" << LL_ENDL;
+		LL_WARNS("Proxy") << "Incorrect data length sent. Expected: " << expected_len <<
+				" Sent: " << outlen << LL_ENDL;
 		rv = -1;
 	}
 
@@ -402,9 +403,10 @@ static S32 tcp_handshake(LLSocket::ptr_t handle, char * dataout, apr_size_t outl
 			LL_WARNS("Proxy") << "Error receiving data from proxy control channel, status: " << rv << LL_ENDL;
 			ll_apr_warn_status(rv);
 		}
-		else if (expected_len != maxinlen)
+		else if (expected_len < maxinlen)
 		{
-			LL_WARNS("Proxy") << "Received incorrect amount of data in proxy control channel" << LL_ENDL;
+			LL_WARNS("Proxy") << "Incorrect data length received. Expected: " << expected_len <<
+					" Received: " << maxinlen << LL_ENDL;
 			rv = -1;
 		}
 	}
diff --git a/indra/llmessage/llproxy.h b/indra/llmessage/llproxy.h
index 22954f27335..68c40561c84 100644
--- a/indra/llmessage/llproxy.h
+++ b/indra/llmessage/llproxy.h
@@ -191,7 +191,7 @@ class LLProxy: public LLSingleton<LLProxy>
 	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.
diff --git a/indra/newview/llstartup.cpp b/indra/newview/llstartup.cpp
index 3ec5842e3c6..25af63c0d30 100644
--- a/indra/newview/llstartup.cpp
+++ b/indra/newview/llstartup.cpp
@@ -598,6 +598,9 @@ bool idle_startup()
 		// connection if the user is using SOCKS 5
 		// We need to do this early in case the user is using
 		// socks for HTTP so we get the login screen via SOCKS
+		// We don't do anything if proxy setup was
+		// unsuccessful, since the user can configure their
+		// proxy settings before starting to log in.
 		//-------------------------------------------------
 
 		LLStartUp::handleSocksProxy();
@@ -820,23 +823,16 @@ bool idle_startup()
 		// Post login screen, we should see if any settings have changed that may
 		// require us to either start/stop or change the socks proxy. As various communications
 		// past this point may require the proxy to be up.
-		if ( gSavedSettings.getBOOL("Socks5ProxyEnabled") )
+		if (!LLStartUp::handleSocksProxy())
 		{
-			if (!LLStartUp::handleSocksProxy())
-			{
-				// Proxy start up failed, we should now bail the state machine
-				// handleSocksProxy() will have reported an error to the user
-				// already, so we just go back to the login screen. The user
-				// could then change the preferences to fix the issue. 
-				LLStartUp::setStartupState(STATE_LOGIN_SHOW);
-				return FALSE;
-			}
-		}
-		else
-		{
-			LLProxy::getInstance()->stopSOCKSProxy();
+			// Proxy start up failed, we should now bail the state machine
+			// handleSocksProxy() will have reported an error to the user
+			// already, so we just go back to the login screen. The user
+			// could then change the preferences to fix the issue.
+
+			LLStartUp::setStartupState(STATE_LOGIN_SHOW);
+			return FALSE;
 		}
-		
 
 		// reset the values that could have come in from a slurl
 		// DEV-42215: Make sure they're not empty -- gUserCredential
@@ -2771,6 +2767,7 @@ void LLStartUp::setStartSLURL(const LLSLURL& slurl)
 
 bool LLStartUp::handleSocksProxy()
 {
+	bool proxy_ok = true;
 	std::string httpProxyType = gSavedSettings.getString("Socks5HttpProxyType");
 
 	// Determine the HTTP proxy type (if any)
@@ -2785,7 +2782,7 @@ bool LLStartUp::handleSocksProxy()
 			subs["HOST"] = http_host.getIPString();
 			subs["PORT"] = (S32)http_host.getPort();
 			LLNotificationsUtil::add("PROXY_INVALID_HTTP_HOST", subs);
-			return false;
+			proxy_ok = false;
 		}
 	}
 	else if ((httpProxyType.compare("Socks") == 0) && gSavedSettings.getBOOL("Socks5ProxyEnabled"))
@@ -2799,7 +2796,7 @@ bool LLStartUp::handleSocksProxy()
 			subs["HOST"] = socks_host.getIPString();
 			subs["PORT"] = (S32)socks_host.getPort();
 			LLNotificationsUtil::add("PROXY_INVALID_SOCKS_HOST", subs);
-			return false;
+			proxy_ok = false;
 		}
 	}
 	else if (httpProxyType.compare("None") == 0)
@@ -2814,7 +2811,7 @@ bool LLStartUp::handleSocksProxy()
 	}
 
 	// Set up SOCKS proxy (if needed)
-	if (gSavedSettings.getBOOL("Socks5ProxyEnabled"))
+	if (gSavedSettings.getBOOL("Socks5ProxyEnabled") && proxy_ok)
 	{	
 		// Determine and update LLProxy with the saved authentication system
 		std::string auth_type = gSavedSettings.getString("Socks5AuthType");
@@ -2830,7 +2827,7 @@ bool LLStartUp::handleSocksProxy()
 			if (!ok)
 			{
 				LLNotificationsUtil::add("SOCKS_BAD_CREDS");
-				return false;
+				proxy_ok = false;
 			}
 		}
 		else if (auth_type.compare("None") == 0)
@@ -2849,63 +2846,63 @@ bool LLStartUp::handleSocksProxy()
 			LLProxy::getInstance()->setAuthNone();
 		}
 
-		// Start the proxy and check for errors
-		// If status != SOCKS_OK, stopSOCKSProxy() will already have been called when startSOCKSProxy() returns.
-		LLHost socks_host;
-		socks_host.setHostByName(gSavedSettings.getString("Socks5ProxyHost"));
-		socks_host.setPort(gSavedSettings.getU32("Socks5ProxyPort"));
-		int status = LLProxy::getInstance()->startSOCKSProxy(socks_host);
-
-		if (status == SOCKS_OK)
-		{
-			return true;
-		}
-		else
+		if (proxy_ok)
 		{
-			LLSD subs;
-			subs["HOST"] = gSavedSettings.getString("Socks5ProxyHost");
-			subs["PORT"] = (S32)gSavedSettings.getU32("Socks5ProxyPort");
 
-			std::string error_string;
+			// Start the proxy and check for errors
+			// If status != SOCKS_OK, stopSOCKSProxy() will already have been called when startSOCKSProxy() returns.
+			LLHost socks_host;
+			socks_host.setHostByName(gSavedSettings.getString("Socks5ProxyHost"));
+			socks_host.setPort(gSavedSettings.getU32("Socks5ProxyPort"));
+			int status = LLProxy::getInstance()->startSOCKSProxy(socks_host);
 
-			switch(status)
+			if (status != SOCKS_OK)
 			{
-				case SOCKS_CONNECT_ERROR: // TCP Fail
-					error_string = "SOCKS_CONNECT_ERROR";
-					break;
-
-				case SOCKS_NOT_PERMITTED: // SOCKS 5 server rule set refused connection
-					error_string = "SOCKS_NOT_PERMITTED";
-					break;
-
-				case SOCKS_NOT_ACCEPTABLE: // Selected authentication is not acceptable to server
-					error_string = "SOCKS_NOT_ACCEPTABLE";
-					break;
-
-				case SOCKS_AUTH_FAIL: // Authentication failed
-					error_string = "SOCKS_AUTH_FAIL";
-					break;
-
-				case SOCKS_UDP_FWD_NOT_GRANTED: // UDP forward request failed
-					error_string = "SOCKS_UDP_FWD_NOT_GRANTED";
-					break;
-
-				case SOCKS_HOST_CONNECT_FAILED: // Failed to open a TCP channel to the socks server
-					error_string = "SOCKS_HOST_CONNECT_FAILED";
-					break;
-
-				case SOCKS_INVALID_HOST: // Improperly formatted host address or port.
-					error_string = "SOCKS_INVALID_HOST";
-					break;
-
-				default:
-					error_string = "SOCKS_UNKNOWN_STATUS"; // Something strange happened,
-					LL_WARNS("Proxy") << "Unknown return from LLProxy::startProxy(): " << status << LL_ENDL;
-					break;
-			}
+				LLSD subs;
+				subs["HOST"] = gSavedSettings.getString("Socks5ProxyHost");
+				subs["PORT"] = (S32)gSavedSettings.getU32("Socks5ProxyPort");
+
+				std::string error_string;
+
+				switch(status)
+				{
+					case SOCKS_CONNECT_ERROR: // TCP Fail
+						error_string = "SOCKS_CONNECT_ERROR";
+						break;
+
+					case SOCKS_NOT_PERMITTED: // SOCKS 5 server rule set refused connection
+						error_string = "SOCKS_NOT_PERMITTED";
+						break;
+
+					case SOCKS_NOT_ACCEPTABLE: // Selected authentication is not acceptable to server
+						error_string = "SOCKS_NOT_ACCEPTABLE";
+						break;
+
+					case SOCKS_AUTH_FAIL: // Authentication failed
+						error_string = "SOCKS_AUTH_FAIL";
+						break;
+
+					case SOCKS_UDP_FWD_NOT_GRANTED: // UDP forward request failed
+						error_string = "SOCKS_UDP_FWD_NOT_GRANTED";
+						break;
 
-			LLNotificationsUtil::add(error_string, subs);
-			return false;
+					case SOCKS_HOST_CONNECT_FAILED: // Failed to open a TCP channel to the socks server
+						error_string = "SOCKS_HOST_CONNECT_FAILED";
+						break;
+
+					case SOCKS_INVALID_HOST: // Improperly formatted host address or port.
+						error_string = "SOCKS_INVALID_HOST";
+						break;
+
+					default:
+						error_string = "SOCKS_UNKNOWN_STATUS"; // Something strange happened,
+						LL_WARNS("Proxy") << "Unknown return from LLProxy::startProxy(): " << status << LL_ENDL;
+						break;
+				}
+
+				LLNotificationsUtil::add(error_string, subs);
+				proxy_ok = false;
+			}
 		}
 	}
 	else
@@ -2913,7 +2910,7 @@ bool LLStartUp::handleSocksProxy()
 		LLProxy::getInstance()->stopSOCKSProxy(); // ensure no UDP proxy is running and it's all cleaned up
 	}
 
-	return true;
+	return proxy_ok;
 }
 
 bool login_alert_done(const LLSD& notification, const LLSD& response)
-- 
GitLab