diff options
Diffstat (limited to 'indra')
| -rw-r--r-- | indra/llmessage/llcurl.cpp | 8 | ||||
| -rw-r--r-- | indra/llmessage/llsocks5.cpp | 73 | ||||
| -rw-r--r-- | indra/llmessage/llsocks5.h | 129 | ||||
| -rw-r--r-- | indra/llmessage/net.cpp | 219 | ||||
| -rw-r--r-- | indra/llmessage/net.h | 11 | ||||
| -rw-r--r-- | indra/newview/llstartup.cpp | 6 | ||||
| -rw-r--r-- | indra/newview/llxmlrpctransaction.cpp | 4 | 
7 files changed, 176 insertions, 274 deletions
diff --git a/indra/llmessage/llcurl.cpp b/indra/llmessage/llcurl.cpp index 9c507517c7..32dd438e68 100644 --- a/indra/llmessage/llcurl.cpp +++ b/indra/llmessage/llcurl.cpp @@ -359,13 +359,13 @@ LLCurl::Easy* LLCurl::Easy::getEasy()  	check_curl_code(result);  	//Set the CURL options for either Socks or HTTP proxy -	if (LLSocks::getInstance()->isHttpProxyEnabled()) +	if (LLSocks::getInstance()->isHTTPProxyEnabled())  	{  		std::string address = LLSocks::getInstance()->getHTTPProxy().getIPString();  		U16 port = LLSocks::getInstance()->getHTTPProxy().getPort();  		curl_easy_setopt(easy->mCurlEasyHandle, CURLOPT_PROXY,address.c_str());  		curl_easy_setopt(easy->mCurlEasyHandle, CURLOPT_PROXYPORT,port); -		if (LLSocks::getInstance()->getHttpProxyType() == LLPROXY_SOCKS) +		if (LLSocks::getInstance()->getHTTPProxyType() == LLPROXY_SOCKS)  		{  			curl_easy_setopt(easy->mCurlEasyHandle, CURLOPT_PROXYTYPE, CURLPROXY_SOCKS5);  			if(LLSocks::getInstance()->getSelectedAuthMethod()==METHOD_PASSWORD) @@ -557,13 +557,13 @@ void LLCurl::Easy::prepRequest(const std::string& url,  	//setopt(CURLOPT_VERBOSE, 1); // usefull for debugging  	setopt(CURLOPT_NOSIGNAL, 1); -	if (LLSocks::getInstance()->isHttpProxyEnabled()) +	if (LLSocks::getInstance()->isHTTPProxyEnabled())  	{  		std::string address = LLSocks::getInstance()->getHTTPProxy().getIPString();  		U16 port = LLSocks::getInstance()->getHTTPProxy().getPort();  		setoptString(CURLOPT_PROXY, address.c_str());  		setopt(CURLOPT_PROXYPORT, port); -		if (LLSocks::getInstance()->getHttpProxyType() == LLPROXY_SOCKS) +		if (LLSocks::getInstance()->getHTTPProxyType() == LLPROXY_SOCKS)  		{  			setopt(CURLOPT_PROXYTYPE, CURLPROXY_SOCKS5);  			if(LLSocks::getInstance()->getSelectedAuthMethod()==METHOD_PASSWORD) diff --git a/indra/llmessage/llsocks5.cpp b/indra/llmessage/llsocks5.cpp index 7eac27d4bb..27a31e35b3 100644 --- a/indra/llmessage/llsocks5.cpp +++ b/indra/llmessage/llsocks5.cpp @@ -1,6 +1,6 @@  /**   * @file llsocks5.cpp - * @brief Socks 5 implementation + * @brief SOCKS 5 implementation   *   * $LicenseInfo:firstyear=2011&license=viewerlgpl$   * Second Life Viewer Source Code @@ -37,52 +37,51 @@  // We want this to be static to avoid excessive indirection on every  // incoming packet just to do a simple bool test. The getter for this  // member is also static -bool LLSocks::sUdpProxyEnabled; -bool LLSocks::sHttpProxyEnabled; +bool LLSocks::sUDPProxyEnabled; +bool LLSocks::sHTTPProxyEnabled;  LLSocks::LLSocks()  { -	sUdpProxyEnabled  = false; -	sHttpProxyEnabled = false; -	mProxyControlChannel = 0; +	sUDPProxyEnabled  = false; +	sHTTPProxyEnabled = false; +	mProxyControlChannel.reset();  	mProxyType = LLPROXY_SOCKS;  } -// Perform a Socks5 authentication and UDP association to the proxy +// Perform a SOCKS 5 authentication and UDP association to the proxy  // specified by proxy, and associate UDP port message_port  int LLSocks::proxyHandshake(LLHost proxy, U32 message_port)  {  	int result; -	/* Socks 5 Auth request */ +	/* 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     = mAuthMethodSelected; // 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     = mAuthMethodSelected; // Send only the selected method.  	result = tcp_handshake(mProxyControlChannel, (char*)&socks_auth_request, sizeof(socks_auth_request_t), (char*)&socks_auth_response, sizeof(socks_auth_response_t));  	if (result != 0)  	{ -		llwarns << "Socks authentication request failed, error on TCP control channel : " << result << llendl; +		llwarns << "SOCKS authentication request failed, error on TCP control channel : " << result << llendl;  		stopProxy();  		return SOCKS_CONNECT_ERROR;  	}  	if (socks_auth_response.method == AUTH_NOT_ACCEPTABLE)  	{ -		llwarns << "Socks5 server refused all our authentication methods" << llendl; +		llwarns << "SOCKS 5 server refused all our authentication methods" << llendl;  		stopProxy();  		return SOCKS_NOT_ACCEPTABLE;  	} -	// SOCKS5 USERNAME/PASSWORD authentication +	// SOCKS 5 USERNAME/PASSWORD authentication  	if (socks_auth_response.method == METHOD_PASSWORD)  	{  		// The server has requested a username/password combination  		U32 request_size = mSocksUsername.size() + mSocksPassword.size() + 3; -		// char * password_auth = (char *)malloc(request_size);  		char * password_auth = new char[request_size];  		password_auth[0] = 0x01;  		password_auth[1] = mSocksUsername.size(); @@ -97,14 +96,14 @@ int LLSocks::proxyHandshake(LLHost proxy, U32 message_port)  		if (result != 0)  		{ -			llwarns << "Socks authentication failed, error on TCP control channel : " << result << llendl; +			llwarns << "SOCKS authentication failed, error on TCP control channel : " << result << llendl;  			stopProxy();  			return SOCKS_CONNECT_ERROR;  		}  		if (password_reply.status != AUTH_SUCCESS)  		{ -			llwarns << "Socks authentication failed" << llendl; +			llwarns << "SOCKS authentication failed" << llendl;  			stopProxy();  			return SOCKS_AUTH_FAIL;  		} @@ -115,18 +114,19 @@ int LLSocks::proxyHandshake(LLHost proxy, U32 message_port)  	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.flag    = FIELD_RESERVED; -	connect_request.atype   = ADDRESS_IPV4; -	connect_request.address = 0; // 0.0.0.0 We are not fussy about address -	// UDP is promiscuous receive for our protocol -	connect_request.port    = 0; // Port must be 0 if you ever want to connect via NAT and your router does port rewrite for you +	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 possesion 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(socks_command_request_t), (char*)&connect_reply, sizeof(socks_command_response_t));  	if (result != 0)  	{ -		llwarns << "Socks connect request failed, error on TCP control channel : " << result << llendl; +		llwarns << "SOCKS connect request failed, error on TCP control channel : " << result << llendl;  		stopProxy();  		return SOCKS_CONNECT_ERROR;  	} @@ -134,7 +134,7 @@ int LLSocks::proxyHandshake(LLHost proxy, U32 message_port)  	if (connect_reply.reply != REPLY_REQUEST_GRANTED)  	{  		//Something went wrong -		llwarns << "Connection to SOCKS5 server failed, UDP forward request not granted" << llendl; +		llwarns << "Connection to SOCKS 5 server failed, UDP forward request not granted" << llendl;  		stopProxy();  		return SOCKS_UDP_FWD_NOT_GRANTED;  	} @@ -142,7 +142,7 @@ int LLSocks::proxyHandshake(LLHost proxy, U32 message_port)  	mUDPProxy.setPort(ntohs(connect_reply.port)); // reply port is in network byte order  	mUDPProxy.setAddress(proxy.getAddress());  	// All good now we have been given the UDP port to send requests that need forwarding. -	llinfos << "Socks 5 UDP proxy connected on " << mUDPProxy << llendl; +	llinfos << "SOCKS 5 UDP proxy connected on " << mUDPProxy << llendl;  	return SOCKS_OK;  } @@ -155,19 +155,17 @@ int LLSocks::startProxy(LLHost proxy, U32 message_port)  	if (mProxyControlChannel)  	{  		tcp_close_channel(mProxyControlChannel); -		mProxyControlChannel = 0;  	} -	mProxyControlChannel = tcp_open_channel(proxy); -	if (mProxyControlChannel == -1) +	mProxyControlChannel = tcp_open_channel(mTCPProxy); +	if (!mProxyControlChannel)  	{  		return SOCKS_HOST_CONNECT_FAILED;  	} -  	status = proxyHandshake(proxy, message_port);  	if (status == SOCKS_OK)  	{ -		sUdpProxyEnabled = true; +		sUDPProxyEnabled = true;  	}  	return status;  } @@ -181,21 +179,20 @@ int LLSocks::startProxy(std::string host, U32 port)  void LLSocks::stopProxy()  { -	sUdpProxyEnabled = false; +	sUDPProxyEnabled = false; -	// If the Socks proxy is requested to stop and we are using that for http as well +	// 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 == mProxyType)  	{ -		sHttpProxyEnabled = false; +		sHTTPProxyEnabled = false;  	}  	if (mProxyControlChannel)  	{  		tcp_close_channel(mProxyControlChannel); -		mProxyControlChannel = 0;  	}  } @@ -211,9 +208,9 @@ void LLSocks::setAuthPassword(std::string username, std::string password)  	mSocksPassword      = password;  } -void LLSocks::enableHttpProxy(LLHost httpHost, LLHttpProxyType type) +void LLSocks::enableHTTPProxy(LLHost httpHost, LLHttpProxyType type)  {  -	sHttpProxyEnabled = true; +	sHTTPProxyEnabled = true;  	mHTTPProxy        = httpHost;  	mProxyType        = type;  } diff --git a/indra/llmessage/llsocks5.h b/indra/llmessage/llsocks5.h index 171a933d32..43a7c82fea 100644 --- a/indra/llmessage/llsocks5.h +++ b/indra/llmessage/llsocks5.h @@ -46,9 +46,9 @@  #define	MAXHOSTNAMELEN (255 + 1) /* socks5: 255, +1 for len. */  #endif -#define SOCKS_VERSION 0x05 // we are using socks 5 +#define SOCKS_VERSION 0x05 // we are using SOCKS 5 -// socks 5 address/hostname types +// SOCKS 5 address/hostname types  #define ADDRESS_IPV4     0x01  #define ADDRESS_HOSTNAME 0x03  #define ADDRESS_IPV6     0x04 @@ -56,16 +56,16 @@  // Lets just use our own ipv4 struct rather than dragging in system  // specific headers  union ipv4_address_t { -	unsigned char octets[4]; -	U32 addr32; +	U8		octets[4]; +	U32		addr32;  }; -// Socks 5 control channel commands +// SOCKS 5 control channel commands  #define COMMAND_TCP_STREAM    0x01  #define COMMAND_TCP_BIND      0x02  #define COMMAND_UDP_ASSOCIATE 0x03 -// Socks 5 command replys +// SOCKS 5 command replies  #define REPLY_REQUEST_GRANTED     0x00  #define REPLY_GENERAL_FAIL        0x01  #define REPLY_RULESET_FAIL        0x02 @@ -78,61 +78,61 @@ union ipv4_address_t {  #define FIELD_RESERVED 0x00 -// The standard socks5 request packet +// 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) -// Socks5 command packet +// SOCKS 5 command packet  struct socks_command_request_t { -	unsigned char version; -	unsigned char command; -	unsigned char flag; -	unsigned char atype; -	U32           address; -	U16           port; +	U8		version; +	U8		command; +	U8		reserved; +	U8		atype; +	U32		address; +	U16		port;  }; -// Standard socks5 reply packet +// Standard SOCKS 5 reply packet  struct socks_command_response_t { -	unsigned char version; -	unsigned char reply; -	unsigned char flag; -	unsigned char atype; -	unsigned char add_bytes[4]; -	U16           port; +	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 +// SOCKS 5 authentication request, stating which methods the client supports  struct socks_auth_request_t { -	unsigned char version; -	unsigned char num_methods; -	unsigned char methods; // We are only using a single method currently +	U8		version; +	U8		num_methods; +	U8		methods; // We are only using a single method currently  }; -// socks 5 authentication response packet, stating server prefered method +// SOCKS 5 authentication response packet, stating server preferred method  struct socks_auth_response_t { -	unsigned char version; -	unsigned char method; +	U8		version; +	U8		method;  }; -// socks 5 password reply packet +// SOCKS 5 password reply packet  struct authmethod_password_reply_t { -	unsigned char version; -	unsigned char status; +	U8		version; +	U8		status;  }; -// socks 5 UDP packet header +// SOCKS 5 UDP packet header  struct proxywrap_t { -	U16 rsv; -	U8  frag; -	U8  atype; -	U32 addr; -	U16 port; +	U16		rsv; +	U8		frag; +	U8		atype; +	U32		addr; +	U16		port;  };  #pragma pack(pop) /* restore original alignment from stack */ @@ -158,62 +158,62 @@ class LLSocks: public LLSingleton<LLSocks>  public:  	LLSocks(); -	// Start a connection to the socks 5 proxy -	int startProxy(std::string host,U32 port); -	int startProxy(LLHost proxy,U32 messagePort); +	// Start a connection to the SOCKS 5 proxy +	int startProxy(std::string host, U32 port); +	int startProxy(LLHost proxy, U32 messagePort); -	// Disconnect and clean up any connection to the socks 5 proxy +	// 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(std::string username,std::string password); +	// Set up to use Password auth when connecting to the SOCKS proxy +	void setAuthPassword(std::string username, std::string password); -	// Set up to use No Auth when connecting to the socks proxy +	// 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 bool isEnabled() { return sUDPProxyEnabled; }  	// static check for enabled status for http packets -	static bool isHttpProxyEnabled() { return sHttpProxyEnabled; } +	static bool isHTTPProxyEnabled() { return sHTTPProxyEnabled; } -	// Proxy http packets via httpHost, which can be a Socks5 or a http proxy +	// 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(LLHost httpHost, LLHttpProxyType type); -	// Stop proxying http packets -	void disableHttpProxy() { sHttpProxyEnabled = false; }; +	// 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 +	// Get the SOCKS 5 TCP control channel address and port  	LLHost getTCPProxy() const { return mTCPProxy; } -	// Get the http proxy address and port +	// 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 currently selected HTTP proxy type +	LLHttpProxyType getHTTPProxyType() const { return mProxyType; }  	// Get the username password in a curl compatible format  	std::string getProxyUserPwd() const { return (mSocksUsername + ":" + mSocksPassword); }  private: -	// Open a communication channel to the socks5 proxy proxy, at port messagePort -	int proxyHandshake(LLHost proxy,U32 messagePort); +	// 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 -	S32 mProxyControlChannel; +	// socket handle to proxy TCP control channel +	LLSocket::ptr_t mProxyControlChannel;  	// is the UDP proxy enabled? -	static bool sUdpProxyEnabled; +	static bool sUDPProxyEnabled;  	// is the http proxy enabled? -	static bool sHttpProxyEnabled; +	static bool sHTTPProxyEnabled;  	// currently selected http proxy type  	LLHttpProxyType mProxyType; @@ -225,13 +225,16 @@ private:  	// HTTP proxy address and port  	LLHost mHTTPProxy; -	// socks 5 auth method selected +	// SOCKS 5 auth method selected  	LLSocks5AuthType mAuthMethodSelected; -	// socks 5 username +	// SOCKS 5 username  	std::string mSocksUsername; -	// socks 5 password +	// SOCKS 5 password  	std::string mSocksPassword; + +	// APR pool for the socket +	apr_pool_t* mPool;  };  #endif diff --git a/indra/llmessage/net.cpp b/indra/llmessage/net.cpp index a51d80ff48..366a1835ca 100644 --- a/indra/llmessage/net.cpp +++ b/indra/llmessage/net.cpp @@ -189,93 +189,6 @@ U32 ip_string_to_u32(const char* ip_string)  //////////////////////////////////////////////////////////////////////////////////////////  #if LL_WINDOWS -  -int tcp_handshake(S32 handle, char * dataout, int outlen, char * datain, int maxinlen) -{ -	int result; -	result = send(handle, dataout, outlen, 0); -	if (result != outlen) -	{ -		S32 err = WSAGetLastError(); -		llwarns << "Error sending data to proxy control channel, number of bytes sent were " << result << " error code was " << err << llendl; -		return -1; -	} - -	result = recv(handle, datain, maxinlen, 0); -	if (result != maxinlen) -	{ -		S32 err = WSAGetLastError(); -		llwarns << "Error receiving data from proxy control channel, number of bytes received were " << result << " error code was " << err << llendl; -		return -1; -	} - -	return 0; -} - -S32 tcp_open_channel(LLHost host) -{ -	// Open a TCP channel -	// Jump through some hoops to ensure that if the request hosts is down -	// or not reachable connect() does not block - -	S32 handle; -	handle = socket(AF_INET, SOCK_STREAM, 0); -	if (INVALID_SOCKET == handle) -	{ -		llwarns << "Error opening TCP control socket, socket() returned " -				<< WSAGetLastError() << ", " << DecodeError(WSAGetLastError()) << llendl; -		return -1; -	} - -	struct sockaddr_in address; -	address.sin_port        = htons(host.getPort()); -	address.sin_family      = AF_INET; -	address.sin_addr.s_addr = host.getAddress(); - -	// Non blocking  -	WSAEVENT hEvent = WSACreateEvent(); -	WSAEventSelect(handle, hEvent, FD_CONNECT) ; -	connect(handle, (struct sockaddr*)&address, sizeof(address)) ; -	// Wait for 5 seconds, if we can't get a TCP channel open in this -	// time frame then there is something badly wrong. -	WaitForSingleObject(hEvent, 1000 * 5); // 5 seconds time out - -	WSANETWORKEVENTS netevents; -	WSAEnumNetworkEvents(handle, hEvent, &netevents); - -	// Check the async event status to see if we connected -	if ((netevents.lNetworkEvents & FD_CONNECT) == FD_CONNECT) -	{ -		if (netevents.iErrorCode[FD_CONNECT_BIT] != 0) -		{ -			llwarns << "Unable to open TCP channel, WSA returned an error code of " << netevents.iErrorCode[FD_CONNECT_BIT] << llendl; -			WSACloseEvent(hEvent); -			tcp_close_channel(handle); -			return -1; -		} - -		// Now we are connected disable non blocking -		// we don't need support an async interface as -		// currently our only consumer (socks5) will make one round -		// of packets then just hold the connection open -		WSAEventSelect(handle, hEvent, NULL) ; -		unsigned long NonBlock = 0; -		ioctlsocket(handle, FIONBIO, &NonBlock); - -		return handle; -	} - -	llwarns << "Unable to open TCP channel, Timeout is the host up?" << netevents.iErrorCode[FD_CONNECT_BIT] << llendl; -	tcp_close_channel(handle); -	return -1; -} - -void tcp_close_channel(S32 handle) -{ -	llinfos << "Closing TCP channel" << llendl; -	shutdown(handle, SD_BOTH); -	closesocket(handle); -}  S32 start_net(S32& socket_out, int& nPort)   {			 @@ -473,79 +386,6 @@ BOOL send_packet(int hSocket, const char *sendBuffer, int size, U32 recipient, i  #else - -int tcp_handshake(S32 handle, char * dataout, int outlen, char * datain, int maxinlen) -{ -	if (send(handle, dataout, outlen, 0) != outlen) -	{ -		llwarns << "Error sending data to proxy control channel" << llendl; -		return -1; -	} - -	if (recv(handle, datain, maxinlen, 0) != maxinlen) -	{ -		llwarns << "Error receiving data to proxy control channel" << llendl;		 -		return -1; -	} - -	return 0; -} - -S32 tcp_open_channel(LLHost host) -{ -	S32 handle; -	handle = socket(AF_INET, SOCK_STREAM, IPPROTO_TCP); -	if (-1 == handle) -	{ -		llwarns << "Error opening TCP control socket, socket() returned " << handle << "error code: " << errno << llendl; -		return -1; -	} - -	struct sockaddr_in address; -	address.sin_port        = htons(host.getPort()); -	address.sin_family      = AF_INET; -	address.sin_addr.s_addr = host.getAddress(); - -	// Set the socket to non blocking for the connect() -	int flags = fcntl(handle, F_GETFL, 0); -	fcntl(handle, F_SETFL, flags | O_NONBLOCK); - -	S32 error = connect(handle, (sockaddr*)&address, sizeof(address)); -	if (error && (errno != EINPROGRESS)) -	{ -			llwarns << "Unable to open TCP channel, error code: " << errno << llendl; -			tcp_close_channel(handle); -			return -1; -	} - -	struct timeval timeout; -	timeout.tv_sec  = 5; // Maximum time to wait for the connect() to complete -	timeout.tv_usec = 0; -	fd_set fds; -	FD_ZERO(&fds); -	FD_SET(handle, &fds); - -	// See if we have connected or time out after 5 seconds -	S32 rc = select(sizeof(fds)*8, NULL, &fds, NULL, &timeout); -	 -	if (rc != 1) // we require exactly one descriptor to be set -	{ -			llwarns << "Unable to open TCP channel" << llendl; -			tcp_close_channel(handle); -			return -1; -	} - -	// Return the socket to blocking operations -	fcntl(handle, F_SETFL, flags); - -	return handle; -} - -void tcp_close_channel(S32 handle) -{ -	close(handle); -} -  //  Create socket, make non-blocking  S32 start_net(S32& socket_out, int& nPort)  { @@ -824,4 +664,63 @@ BOOL send_packet(int hSocket, const char * sendBuffer, int size, U32 recipient,  #endif +int tcp_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_size_t expected_len = outlen; + +    apr_socket_opt_set(apr_socket, APR_SO_NONBLOCK, -5); // Blocking connection, 5 second timeout +    apr_socket_timeout_set(apr_socket, (APR_USEC_PER_SEC * 5)); + +	rv = apr_socket_send(apr_socket, dataout, &outlen); +	if (rv != APR_SUCCESS || expected_len != outlen) +	{ +		llwarns << "Error sending data to proxy control channel" << llendl; +		ll_apr_warn_status(rv); +		return -1; +	} + +	expected_len = maxinlen; +	do +	{ +		rv = apr_socket_recv(apr_socket, datain, &maxinlen); +		llinfos << "Receiving packets." << llendl; +		llwarns << "Proxy control channel status: " << rv << llendl; +	} while (APR_STATUS_IS_EAGAIN(rv)); + +	if (rv != APR_SUCCESS) +	{ +		llwarns << "Error receiving data from proxy control channel, status: " << rv << llendl; +		llwarns << "Received " << maxinlen << " bytes." << llendl; +		ll_apr_warn_status(rv); +		return rv; +	} +	else if (expected_len != maxinlen) +	{ +		llwarns << "Incorrect data received length in proxy control channel" << llendl; +		return -1; +	} + +	return 0; +} + +LLSocket::ptr_t tcp_open_channel(LLHost host) +{ +	LLSocket::ptr_t socket = LLSocket::create(gAPRPoolp, LLSocket::STREAM_TCP); +	bool connected = socket->blockingConnect(host); +	if (!connected) +	{ +		tcp_close_channel(socket); +	} + +	return socket; +} + +void tcp_close_channel(LLSocket::ptr_t handle) +{ +	handle.reset(); +} +  //EOF diff --git a/indra/llmessage/net.h b/indra/llmessage/net.h index 047e8ce646..0d91cf2a2f 100644 --- a/indra/llmessage/net.h +++ b/indra/llmessage/net.h @@ -27,6 +27,9 @@  #ifndef LL_NET_H					  #define LL_NET_H +#include "lliosocket.h" +#include "llapr.h" +  class LLTimer;  class LLHost; @@ -52,10 +55,10 @@ U32		get_sender_ip(void);  LLHost	get_receiving_interface();  U32		get_receiving_interface_ip(void); -// Some helpful tcp functions added for the socks 5 proxy support -S32 tcp_open_channel(LLHost host); // Open a tcp channel to a given host -void tcp_close_channel(S32 handle); // Close an open tcp channel -int tcp_handshake(S32 handle, char * dataout, int outlen, char * datain, int maxinlen); // Do a TCP data handshake +// Some helpful TCP functions +LLSocket::ptr_t tcp_open_channel(LLHost host); // Open a TCP channel to a given host +void tcp_close_channel(LLSocket::ptr_t handle); // Close an open TCP channel +int tcp_handshake(LLSocket::ptr_t handle, char * dataout, apr_size_t outlen, char * datain, apr_size_t maxinlen); // Do a TCP data handshake  const char*	u32_to_ip_string(U32 ip);					// Returns pointer to internal string buffer, "(bad IP addr)" on failure, cannot nest calls   char*		u32_to_ip_string(U32 ip, char *ip_string);	// NULL on failure, ip_string on success, you must allocate at least MAXADDRSTR chars diff --git a/indra/newview/llstartup.cpp b/indra/newview/llstartup.cpp index 6d94a5454e..c2f0ca164b 100644 --- a/indra/newview/llstartup.cpp +++ b/indra/newview/llstartup.cpp @@ -2770,18 +2770,18 @@ bool LLStartUp::handleSocksProxy(bool reportOK)  		LLHost httpHost;  		httpHost.setHostByName(gSavedSettings.getString("BrowserProxyAddress"));  		httpHost.setPort(gSavedSettings.getS32("BrowserProxyPort")); -		LLSocks::getInstance()->enableHttpProxy(httpHost,LLPROXY_HTTP); +		LLSocks::getInstance()->enableHTTPProxy(httpHost,LLPROXY_HTTP);  	}  	else if ((httpProxyType.compare("Socks") == 0) && gSavedSettings.getBOOL("Socks5ProxyEnabled"))  	{  		LLHost httpHost;  		httpHost.setHostByName(gSavedSettings.getString("Socks5ProxyHost"));  		httpHost.setPort(gSavedSettings.getU32("Socks5ProxyPort")); -		LLSocks::getInstance()->enableHttpProxy(httpHost,LLPROXY_SOCKS); +		LLSocks::getInstance()->enableHTTPProxy(httpHost,LLPROXY_SOCKS);  	}  	else  	{ -		LLSocks::getInstance()->disableHttpProxy(); +		LLSocks::getInstance()->disableHTTPProxy();  	}  	bool use_socks_proxy = gSavedSettings.getBOOL("Socks5ProxyEnabled"); diff --git a/indra/newview/llxmlrpctransaction.cpp b/indra/newview/llxmlrpctransaction.cpp index 87d2f780be..b9ce7d9fae 100644 --- a/indra/newview/llxmlrpctransaction.cpp +++ b/indra/newview/llxmlrpctransaction.cpp @@ -309,13 +309,13 @@ void LLXMLRPCTransaction::Impl::init(XMLRPC_REQUEST request, bool useGzip)  	}  	mErrorCert = NULL; -	if (LLSocks::getInstance()->isHttpProxyEnabled()) +	if (LLSocks::getInstance()->isHTTPProxyEnabled())  	{  		std::string address = LLSocks::getInstance()->getHTTPProxy().getIPString();  		U16 port = LLSocks::getInstance()->getHTTPProxy().getPort();  		mCurlRequest->setoptString(CURLOPT_PROXY, address.c_str());  		mCurlRequest->setopt(CURLOPT_PROXYPORT, port); -		if (LLSocks::getInstance()->getHttpProxyType() == LLPROXY_SOCKS) +		if (LLSocks::getInstance()->getHTTPProxyType() == LLPROXY_SOCKS)  		{  			mCurlRequest->setopt(CURLOPT_PROXYTYPE, CURLPROXY_SOCKS5);  			if(LLSocks::getInstance()->getSelectedAuthMethod()==METHOD_PASSWORD)  | 
