summaryrefslogtreecommitdiff
path: root/indra/llmessage
diff options
context:
space:
mode:
Diffstat (limited to 'indra/llmessage')
-rw-r--r--indra/llmessage/CMakeLists.txt2
-rw-r--r--indra/llmessage/llcurl.cpp133
-rw-r--r--indra/llmessage/llcurl.h118
-rw-r--r--indra/llmessage/llhttpassetstorage.cpp5
-rw-r--r--indra/llmessage/llhttpclient.cpp5
-rw-r--r--indra/llmessage/lliosocket.cpp2
-rw-r--r--indra/llmessage/lliosocket.h14
-rw-r--r--indra/llmessage/llpacketring.cpp65
-rw-r--r--indra/llmessage/llpacketring.h12
-rw-r--r--indra/llmessage/llproxy.cpp411
-rw-r--r--indra/llmessage/llproxy.h266
-rw-r--r--indra/llmessage/llurlrequest.cpp5
-rw-r--r--indra/llmessage/net.cpp39
-rw-r--r--indra/llmessage/net.h4
14 files changed, 919 insertions, 162 deletions
diff --git a/indra/llmessage/CMakeLists.txt b/indra/llmessage/CMakeLists.txt
index c5f82cf052..0f40a670fa 100644
--- a/indra/llmessage/CMakeLists.txt
+++ b/indra/llmessage/CMakeLists.txt
@@ -65,6 +65,7 @@ set(llmessage_SOURCE_FILES
llpacketbuffer.cpp
llpacketring.cpp
llpartdata.cpp
+ llproxy.cpp
llpumpio.cpp
llregionpresenceverifier.cpp
llsdappservices.cpp
@@ -161,6 +162,7 @@ set(llmessage_HEADER_FILES
llpacketring.h
llpartdata.h
llpumpio.h
+ llproxy.h
llqueryflags.h
llregionflags.h
llregionhandle.h
diff --git a/indra/llmessage/llcurl.cpp b/indra/llmessage/llcurl.cpp
index 0735842dcd..7a041239bc 100644
--- a/indra/llmessage/llcurl.cpp
+++ b/indra/llmessage/llcurl.cpp
@@ -46,8 +46,9 @@
#endif
#include "llbufferstream.h"
-#include "llstl.h"
+#include "llproxy.h"
#include "llsdserialize.h"
+#include "llstl.h"
#include "llthread.h"
#include "lltimer.h"
@@ -204,7 +205,7 @@ namespace boost
void intrusive_ptr_release(LLCurl::Responder* p)
{
- if(p && 0 == --p->mReferenceCount)
+ if (p && 0 == --p->mReferenceCount)
{
delete p;
}
@@ -214,73 +215,6 @@ namespace boost
//////////////////////////////////////////////////////////////////////////////
-
-class LLCurl::Easy
-{
- LOG_CLASS(Easy);
-
-private:
- Easy();
-
-public:
- static Easy* getEasy();
- ~Easy();
-
- CURL* getCurlHandle() const { return mCurlEasyHandle; }
-
- void setErrorBuffer();
- void setCA();
-
- void setopt(CURLoption option, S32 value);
- // These assume the setter does not free value!
- void setopt(CURLoption option, void* value);
- void setopt(CURLoption option, char* value);
- // Copies the string so that it is gauranteed to stick around
- void setoptString(CURLoption option, const std::string& value);
-
- void slist_append(const char* str);
- void setHeaders();
-
- U32 report(CURLcode);
- void getTransferInfo(LLCurl::TransferInfo* info);
-
- void prepRequest(const std::string& url, const std::vector<std::string>& headers, ResponderPtr, bool post = false);
-
- const char* getErrorBuffer();
-
- std::stringstream& getInput() { return mInput; }
- std::stringstream& getHeaderOutput() { return mHeaderOutput; }
- LLIOPipe::buffer_ptr_t& getOutput() { return mOutput; }
- const LLChannelDescriptors& getChannels() { return mChannels; }
-
- void resetState();
-
- static CURL* allocEasyHandle();
- static void releaseEasyHandle(CURL* handle);
-
-private:
- friend class LLCurl;
-
- CURL* mCurlEasyHandle;
- struct curl_slist* mHeaders;
-
- std::stringstream mRequest;
- LLChannelDescriptors mChannels;
- LLIOPipe::buffer_ptr_t mOutput;
- std::stringstream mInput;
- std::stringstream mHeaderOutput;
- char mErrorBuffer[CURL_ERROR_SIZE];
-
- // Note: char*'s not strings since we pass pointers to curl
- std::vector<char*> mStrings;
-
- ResponderPtr mResponder;
-
- static std::set<CURL*> sFreeHandles;
- static std::set<CURL*> sActiveHandles;
- static LLMutex* sHandleMutex;
-};
-
std::set<CURL*> LLCurl::Easy::sFreeHandles;
std::set<CURL*> LLCurl::Easy::sActiveHandles;
LLMutex* LLCurl::Easy::sHandleMutex = NULL;
@@ -404,11 +338,11 @@ const char* LLCurl::Easy::getErrorBuffer()
void LLCurl::Easy::setCA()
{
- if(!sCAPath.empty())
+ if (!sCAPath.empty())
{
setoptString(CURLOPT_CAPATH, sCAPath);
}
- if(!sCAFile.empty())
+ if (!sCAFile.empty())
{
setoptString(CURLOPT_CAINFO, sCAFile);
}
@@ -531,9 +465,12 @@ void LLCurl::Easy::prepRequest(const std::string& url,
if (post) setoptString(CURLOPT_ENCODING, "");
- //setopt(CURLOPT_VERBOSE, 1); // usefull for debugging
+ //setopt(CURLOPT_VERBOSE, 1); // useful for debugging
setopt(CURLOPT_NOSIGNAL, 1);
+ // Set the CURL options for either Socks or HTTP proxy
+ LLProxy::getInstance()->applyProxySettings(this);
+
mOutput.reset(new LLBufferArray);
setopt(CURLOPT_WRITEFUNCTION, (void*)&curlWriteCallback);
setopt(CURLOPT_WRITEDATA, (void*)this);
@@ -545,7 +482,7 @@ void LLCurl::Easy::prepRequest(const std::string& url,
setopt(CURLOPT_HEADERDATA, (void*)this);
// Allow up to five redirects
- if(responder && responder->followRedir())
+ if (responder && responder->followRedir())
{
setopt(CURLOPT_FOLLOWLOCATION, 1);
setopt(CURLOPT_MAXREDIRS, MAX_REDIRECTS);
@@ -579,54 +516,6 @@ void LLCurl::Easy::prepRequest(const std::string& url,
////////////////////////////////////////////////////////////////////////////
-class LLCurl::Multi : public LLThread
-{
- LOG_CLASS(Multi);
-public:
-
- typedef enum
- {
- PERFORM_STATE_READY=0,
- PERFORM_STATE_PERFORMING=1,
- PERFORM_STATE_COMPLETED=2
- } ePerformState;
-
- Multi();
- ~Multi();
-
- Easy* allocEasy();
- bool addEasy(Easy* easy);
-
- void removeEasy(Easy* easy);
-
- S32 process();
- void perform();
-
- virtual void run();
-
- CURLMsg* info_read(S32* msgs_in_queue);
-
- S32 mQueued;
- S32 mErrorCount;
-
- S32 mPerformState;
-
- LLCondition* mSignal;
- bool mQuitting;
-
-private:
- void easyFree(Easy*);
-
- CURLM* mCurlMultiHandle;
-
- typedef std::set<Easy*> easy_active_list_t;
- easy_active_list_t mEasyActiveList;
- typedef std::map<CURL*, Easy*> easy_active_map_t;
- easy_active_map_t mEasyActiveMap;
- typedef std::set<Easy*> easy_free_list_t;
- easy_free_list_t mEasyFreeList;
-};
-
LLCurl::Multi::Multi()
: LLThread("Curl Multi"),
mQueued(0),
@@ -1025,6 +914,8 @@ LLCurlEasyRequest::LLCurlEasyRequest()
{
mEasy->setErrorBuffer();
mEasy->setCA();
+ // Set proxy settings if configured to do so.
+ LLProxy::getInstance()->applyProxySettings(mEasy);
}
}
diff --git a/indra/llmessage/llcurl.h b/indra/llmessage/llcurl.h
index 2f951d6ab8..79f5eeb927 100644
--- a/indra/llmessage/llcurl.h
+++ b/indra/llmessage/llcurl.h
@@ -41,6 +41,7 @@
#include "llbuffer.h"
#include "lliopipe.h"
#include "llsd.h"
+#include "llthread.h"
class LLMutex;
@@ -184,6 +185,120 @@ private:
static const unsigned int MAX_REDIRECTS;
};
+class LLCurl::Easy
+{
+ LOG_CLASS(Easy);
+
+private:
+ Easy();
+
+public:
+ static Easy* getEasy();
+ ~Easy();
+
+ CURL* getCurlHandle() const { return mCurlEasyHandle; }
+
+ void setErrorBuffer();
+ void setCA();
+
+ void setopt(CURLoption option, S32 value);
+ // These assume the setter does not free value!
+ void setopt(CURLoption option, void* value);
+ void setopt(CURLoption option, char* value);
+ // Copies the string so that it is guaranteed to stick around
+ void setoptString(CURLoption option, const std::string& value);
+
+ void slist_append(const char* str);
+ void setHeaders();
+
+ U32 report(CURLcode);
+ void getTransferInfo(LLCurl::TransferInfo* info);
+
+ void prepRequest(const std::string& url, const std::vector<std::string>& headers, ResponderPtr, bool post = false);
+
+ const char* getErrorBuffer();
+
+ std::stringstream& getInput() { return mInput; }
+ std::stringstream& getHeaderOutput() { return mHeaderOutput; }
+ LLIOPipe::buffer_ptr_t& getOutput() { return mOutput; }
+ const LLChannelDescriptors& getChannels() { return mChannels; }
+
+ void resetState();
+
+ static CURL* allocEasyHandle();
+ static void releaseEasyHandle(CURL* handle);
+
+private:
+ friend class LLCurl;
+
+ CURL* mCurlEasyHandle;
+ struct curl_slist* mHeaders;
+
+ std::stringstream mRequest;
+ LLChannelDescriptors mChannels;
+ LLIOPipe::buffer_ptr_t mOutput;
+ std::stringstream mInput;
+ std::stringstream mHeaderOutput;
+ char mErrorBuffer[CURL_ERROR_SIZE];
+
+ // Note: char*'s not strings since we pass pointers to curl
+ std::vector<char*> mStrings;
+
+ ResponderPtr mResponder;
+
+ static std::set<CURL*> sFreeHandles;
+ static std::set<CURL*> sActiveHandles;
+ static LLMutex* sHandleMutex;
+};
+
+class LLCurl::Multi : public LLThread
+{
+ LOG_CLASS(Multi);
+public:
+
+ typedef enum
+ {
+ PERFORM_STATE_READY=0,
+ PERFORM_STATE_PERFORMING=1,
+ PERFORM_STATE_COMPLETED=2
+ } ePerformState;
+
+ Multi();
+ ~Multi();
+
+ Easy* allocEasy();
+ bool addEasy(Easy* easy);
+
+ void removeEasy(Easy* easy);
+
+ S32 process();
+ void perform();
+
+ virtual void run();
+
+ CURLMsg* info_read(S32* msgs_in_queue);
+
+ S32 mQueued;
+ S32 mErrorCount;
+
+ S32 mPerformState;
+
+ LLCondition* mSignal;
+ bool mQuitting;
+
+private:
+ void easyFree(Easy*);
+
+ CURLM* mCurlMultiHandle;
+
+ typedef std::set<Easy*> easy_active_list_t;
+ easy_active_list_t mEasyActiveList;
+ typedef std::map<CURL*, Easy*> easy_active_map_t;
+ easy_active_map_t mEasyActiveMap;
+ typedef std::set<Easy*> easy_free_list_t;
+ easy_free_list_t mEasyFreeList;
+};
+
namespace boost
{
void intrusive_ptr_add_ref(LLCurl::Responder* p);
@@ -250,4 +365,7 @@ private:
bool mResultReturned;
};
+void check_curl_code(CURLcode code);
+void check_curl_multi_code(CURLMcode code);
+
#endif // LL_LLCURL_H
diff --git a/indra/llmessage/llhttpassetstorage.cpp b/indra/llmessage/llhttpassetstorage.cpp
index 5a38b7fd9f..2bca517e97 100644
--- a/indra/llmessage/llhttpassetstorage.cpp
+++ b/indra/llmessage/llhttpassetstorage.cpp
@@ -33,6 +33,7 @@
#include "indra_constants.h"
#include "message.h"
+#include "llproxy.h"
#include "llvfile.h"
#include "llvfs.h"
@@ -232,6 +233,10 @@ void LLHTTPAssetRequest::setupCurlHandle()
{
// *NOTE: Similar code exists in mapserver/llcurlutil.cpp JC
mCurlHandle = curl_easy_init();
+
+ // Apply proxy settings if configured to do so
+ LLProxy::getInstance()->applyProxySettings(mCurlHandle);
+
curl_easy_setopt(mCurlHandle, CURLOPT_NOSIGNAL, 1);
curl_easy_setopt(mCurlHandle, CURLOPT_NOPROGRESS, 1);
curl_easy_setopt(mCurlHandle, CURLOPT_URL, mURLBuffer.c_str());
diff --git a/indra/llmessage/llhttpclient.cpp b/indra/llmessage/llhttpclient.cpp
index 0e5206a520..dd4e3a6300 100644
--- a/indra/llmessage/llhttpclient.cpp
+++ b/indra/llmessage/llhttpclient.cpp
@@ -428,6 +428,9 @@ static LLSD blocking_request(
std::string body_str;
// other request method checks root cert first, we skip?
+
+ // Apply configured proxy settings
+ LLProxy::getInstance()->applyProxySettings(curlp);
// * Set curl handle options
curl_easy_setopt(curlp, CURLOPT_NOSIGNAL, 1); // don't use SIGALRM for timeouts
@@ -436,7 +439,7 @@ static LLSD blocking_request(
curl_easy_setopt(curlp, CURLOPT_WRITEDATA, &http_buffer);
curl_easy_setopt(curlp, CURLOPT_URL, url.c_str());
curl_easy_setopt(curlp, CURLOPT_ERRORBUFFER, curl_error_buffer);
-
+
// * Setup headers (don't forget to free them after the call!)
curl_slist* headers_list = NULL;
if (headers.isMap())
diff --git a/indra/llmessage/lliosocket.cpp b/indra/llmessage/lliosocket.cpp
index b717e321bf..ee9379f205 100644
--- a/indra/llmessage/lliosocket.cpp
+++ b/indra/llmessage/lliosocket.cpp
@@ -251,10 +251,12 @@ LLSocket::~LLSocket()
{
ll_debug_socket("Destroying socket", mSocket);
apr_socket_close(mSocket);
+ mSocket = NULL;
}
if(mPool)
{
apr_pool_destroy(mPool);
+ mPool = NULL;
}
}
diff --git a/indra/llmessage/lliosocket.h b/indra/llmessage/lliosocket.h
index e0f6c1e34d..be0f7dfcc6 100644
--- a/indra/llmessage/lliosocket.h
+++ b/indra/llmessage/lliosocket.h
@@ -145,13 +145,6 @@ public:
*/
apr_socket_t* getSocket() const { return mSocket; }
-protected:
- /**
- * @brief Protected constructor since should only make sockets
- * with one of the two <code>create()</code> calls.
- */
- LLSocket(apr_socket_t* socket, apr_pool_t* pool);
-
/**
* @brief Set default socket options, with SO_NONBLOCK = 0 and a timeout in us.
* @param timeout Number of microseconds to wait on this socket. Any
@@ -164,6 +157,13 @@ protected:
*/
void setNonBlocking();
+protected:
+ /**
+ * @brief Protected constructor since should only make sockets
+ * with one of the two <code>create()</code> calls.
+ */
+ LLSocket(apr_socket_t* socket, apr_pool_t* pool);
+
public:
/**
* @brief Do not call this directly.
diff --git a/indra/llmessage/llpacketring.cpp b/indra/llmessage/llpacketring.cpp
index 8999dec64a..ba82957b47 100644
--- a/indra/llmessage/llpacketring.cpp
+++ b/indra/llmessage/llpacketring.cpp
@@ -28,11 +28,20 @@
#include "llpacketring.h"
+#if LL_WINDOWS
+ #include <winsock2.h>
+#else
+ #include <sys/socket.h>
+ #include <netinet/in.h>
+#endif
+
// linden library includes
#include "llerror.h"
#include "lltimer.h"
-#include "timing.h"
+#include "llproxy.h"
#include "llrand.h"
+#include "message.h"
+#include "timing.h"
#include "u64.h"
///////////////////////////////////////////////////////////
@@ -216,8 +225,32 @@ S32 LLPacketRing::receivePacket (S32 socket, char *datap)
else
{
// no delay, pull straight from net
- packet_size = receive_packet(socket, datap);
- mLastSender = ::get_sender();
+ if (LLProxy::isEnabled())
+ {
+ U8 buffer[NET_BUFFER_SIZE + SOCKS_HEADER_SIZE];
+ packet_size = receive_packet(socket, reinterpret_cast<char *>(buffer));
+
+ if (packet_size > SOCKS_HEADER_SIZE)
+ {
+ // *FIX We are assuming ATYP is 0x01 (IPv4), not 0x03 (hostname) or 0x04 (IPv6)
+ memcpy(datap, buffer + SOCKS_HEADER_SIZE, packet_size - SOCKS_HEADER_SIZE);
+ proxywrap_t * header = reinterpret_cast<proxywrap_t *>(buffer);
+ mLastSender.setAddress(header->addr);
+ mLastSender.setPort(ntohs(header->port));
+
+ packet_size -= SOCKS_HEADER_SIZE; // The unwrapped packet size
+ }
+ else
+ {
+ packet_size = 0;
+ }
+ }
+ else
+ {
+ packet_size = receive_packet(socket, datap);
+ mLastSender = ::get_sender();
+ }
+
mLastReceivingIF = ::get_receiving_interface();
if (packet_size) // did we actually get a packet?
@@ -243,7 +276,7 @@ BOOL LLPacketRing::sendPacket(int h_socket, char * send_buffer, S32 buf_size, LL
BOOL status = TRUE;
if (!mUseOutThrottle)
{
- return send_packet(h_socket, send_buffer, buf_size, host.getAddress(), host.getPort() );
+ return sendPacketImpl(h_socket, send_buffer, buf_size, host );
}
else
{
@@ -264,7 +297,7 @@ BOOL LLPacketRing::sendPacket(int h_socket, char * send_buffer, S32 buf_size, LL
mOutBufferLength -= packetp->getSize();
packet_size = packetp->getSize();
- status = send_packet(h_socket, packetp->getData(), packet_size, packetp->getHost().getAddress(), packetp->getHost().getPort());
+ status = sendPacketImpl(h_socket, packetp->getData(), packet_size, packetp->getHost());
delete packetp;
// Update the throttle
@@ -273,7 +306,7 @@ BOOL LLPacketRing::sendPacket(int h_socket, char * send_buffer, S32 buf_size, LL
else
{
// If the queue's empty, we can just send this packet right away.
- status = send_packet(h_socket, send_buffer, buf_size, host.getAddress(), host.getPort() );
+ status = sendPacketImpl(h_socket, send_buffer, buf_size, host );
packet_size = buf_size;
// Update the throttle
@@ -311,3 +344,23 @@ BOOL LLPacketRing::sendPacket(int h_socket, char * send_buffer, S32 buf_size, LL
return status;
}
+
+BOOL LLPacketRing::sendPacketImpl(int h_socket, const char * send_buffer, S32 buf_size, LLHost host)
+{
+
+ if (!LLProxy::isEnabled())
+ {
+ return send_packet(h_socket, send_buffer, buf_size, host.getAddress(), host.getPort());
+ }
+
+ proxywrap_t *socks_header = reinterpret_cast<proxywrap_t *>(&mProxyWrappedSendBuffer);
+ socks_header->rsv = 0;
+ socks_header->addr = host.getAddress();
+ socks_header->port = htons(host.getPort());
+ socks_header->atype = ADDRESS_IPV4;
+ socks_header->frag = 0;
+
+ memcpy(mProxyWrappedSendBuffer + SOCKS_HEADER_SIZE, send_buffer, buf_size);
+
+ return send_packet(h_socket, (const char*) mProxyWrappedSendBuffer, buf_size + 10, LLProxy::getInstance()->getUDPProxy().getAddress(), LLProxy::getInstance()->getUDPProxy().getPort());
+}
diff --git a/indra/llmessage/llpacketring.h b/indra/llmessage/llpacketring.h
index e6409d2048..7edcc834db 100644
--- a/indra/llmessage/llpacketring.h
+++ b/indra/llmessage/llpacketring.h
@@ -30,11 +30,11 @@
#include <queue>
-#include "llpacketbuffer.h"
#include "llhost.h"
-#include "net.h"
+#include "llpacketbuffer.h"
+#include "llproxy.h"
#include "llthrottle.h"
-
+#include "net.h"
class LLPacketRing
{
@@ -82,6 +82,12 @@ protected:
LLHost mLastSender;
LLHost mLastReceivingIF;
+
+
+ U8 mProxyWrappedSendBuffer[NET_BUFFER_SIZE + SOCKS_HEADER_SIZE];
+
+private:
+ BOOL sendPacketImpl(int h_socket, const char * send_buffer, S32 buf_size, LLHost host);
};
diff --git a/indra/llmessage/llproxy.cpp b/indra/llmessage/llproxy.cpp
new file mode 100644
index 0000000000..d34ad1a811
--- /dev/null
+++ b/indra/llmessage/llproxy.cpp
@@ -0,0 +1,411 @@
+/**
+ * @file llsocks5.cpp
+ * @brief SOCKS 5 implementation
+ *
+ * $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$
+ */
+
+#include "linden_common.h"
+
+#include "llproxy.h"
+
+#include <algorithm>
+#include <string>
+#include <curl/curl.h>
+
+#include "llapr.h"
+#include "llcurl.h"
+#include "llhost.h"
+#include "message.h"
+#include "net.h"
+
+// Static class variable instances
+
+// 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 LLProxy::sUDPProxyEnabled = false;
+bool LLProxy::sHTTPProxyEnabled = false;
+
+// Some helpful TCP functions
+static LLSocket::ptr_t tcp_open_channel(apr_pool_t* pool, 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
+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
+
+LLProxy::LLProxy():
+ mProxyType(LLPROXY_SOCKS),
+ mUDPProxy(),
+ mTCPProxy(),
+ mHTTPProxy(),
+ mAuthMethodSelected(METHOD_NOAUTH),
+ mSocksUsername(),
+ mSocksPassword(),
+ mPool(gAPRPoolp),
+ mSOCKSAuthStrings(),
+ mHTTPProxyAddrStrings(),
+ mProxyMutex(0)
+{
+}
+
+LLProxy::~LLProxy()
+{
+ stopProxy();
+ sUDPProxyEnabled = false;
+ sHTTPProxyEnabled = false;
+
+ // Delete c_str versions of the addresses and credentials.
+ for_each(mSOCKSAuthStrings.begin(), mSOCKSAuthStrings.end(), DeletePointerArray());
+ for_each(mHTTPProxyAddrStrings.begin(), mHTTPProxyAddrStrings.end(), DeletePointerArray());
+}
+
+// Perform a SOCKS 5 authentication and UDP association to the proxy
+// specified by proxy, and associate UDP port message_port
+S32 LLProxy::proxyHandshake(LLHost proxy, U32 message_port)
+{
+ 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 = mAuthMethodSelected; // 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));
+ if (result != 0)
+ {
+ LL_WARNS("Proxy") << "SOCKS authentication request failed, error on TCP control channel : " << result << LL_ENDL;
+ stopProxy();
+ 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;
+ stopProxy();
+ return SOCKS_NOT_ACCEPTABLE;
+ }
+
+ // 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 = new char[request_size];
+ password_auth[0] = 0x01;
+ password_auth[1] = mSocksUsername.size();
+ memcpy(&password_auth[2], mSocksUsername.c_str(), mSocksUsername.size());
+ password_auth[mSocksUsername.size() + 2] = mSocksPassword.size();
+ memcpy(&password_auth[mSocksUsername.size()+3], mSocksPassword.c_str(), mSocksPassword.size());
+
+ authmethod_password_reply_t password_reply;
+
+ result = tcp_handshake(mProxyControlChannel, password_auth, request_size, (char*)&password_reply, sizeof(password_reply));
+ delete[] password_auth;
+
+ if (result != 0)
+ {
+ LL_WARNS("Proxy") << "SOCKS authentication failed, error on TCP control channel : " << result << LL_ENDL;
+ stopProxy();
+ return SOCKS_CONNECT_ERROR;
+ }
+
+ if (password_reply.status != AUTH_SUCCESS)
+ {
+ LL_WARNS("Proxy") << "SOCKS authentication failed" << LL_ENDL;
+ stopProxy();
+ 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_handshake(mProxyControlChannel, (char*)&connect_request, sizeof(connect_request), (char*)&connect_reply, sizeof(connect_reply));
+ if (result != 0)
+ {
+ LL_WARNS("Proxy") << "SOCKS connect request failed, error on TCP control channel : " << result << LL_ENDL;
+ stopProxy();
+ 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;
+ stopProxy();
+ 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 LLProxy::startProxy(std::string host, U32 port)
+{
+ mTCPProxy.setHostByName(host);
+ mTCPProxy.setPort(port);
+
+ S32 status;
+
+ if (mProxyControlChannel)
+ {
+ tcp_close_channel(&mProxyControlChannel);
+ }
+
+ mProxyControlChannel = tcp_open_channel(mPool, mTCPProxy);
+ if (!mProxyControlChannel)
+ {
+ return SOCKS_HOST_CONNECT_FAILED;
+ }
+ status = proxyHandshake(mTCPProxy, (U32)gMessageSystem->mPort);
+ if (status == SOCKS_OK)
+ {
+ sUDPProxyEnabled = true;
+ }
+ else
+ {
+ stopProxy();
+ }
+ return status;
+
+}
+
+void LLProxy::stopProxy()
+{
+ 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 (LLPROXY_SOCKS == mProxyType)
+ {
+ void disableHTTPProxy();
+ }
+
+ if (mProxyControlChannel)
+ {
+ tcp_close_channel(&mProxyControlChannel);
+ }
+}
+
+void LLProxy::setAuthNone()
+{
+ mAuthMethodSelected = METHOD_NOAUTH;
+}
+
+void LLProxy::setAuthPassword(const std::string &username, const std::string &password)
+{
+ mAuthMethodSelected = METHOD_PASSWORD;
+ mSocksUsername = username;
+ mSocksPassword = password;
+
+ U32 size = username.length() + password.length() + 2;
+ char* curl_auth_string = new char[size];
+ snprintf(curl_auth_string, size, "%s:%s", username.c_str(), password.c_str());
+
+ LLMutexLock lock(&mProxyMutex);
+ mSOCKSAuthStrings.push_back(curl_auth_string);
+}
+
+void LLProxy::enableHTTPProxy(LLHost httpHost, LLHttpProxyType type)
+{
+ LLMutexLock lock(&mProxyMutex);
+
+ sHTTPProxyEnabled = true;
+ mHTTPProxy = httpHost;
+ mProxyType = type;
+
+ U32 size = httpHost.getIPString().length() + 1;
+ char* http_addr_string = new char[size];
+ strncpy(http_addr_string, httpHost.getIPString().c_str(), size);
+ mHTTPProxyAddrStrings.push_back(http_addr_string);
+}
+
+void LLProxy::enableHTTPProxy()
+{
+ LLMutexLock lock(&mProxyMutex);
+
+ sHTTPProxyEnabled = true;
+}
+
+void LLProxy::disableHTTPProxy()
+{
+ LLMutexLock lock(&mProxyMutex);
+
+ sHTTPProxyEnabled = false;
+}
+
+//static
+void LLProxy::cleanupClass()
+{
+ getInstance()->stopProxy();
+ deleteSingleton();
+}
+
+// Apply proxy settings to CuRL request if either type of HTTP proxy is enabled.
+void LLProxy::applyProxySettings(LLCurl::Easy* handle)
+{
+ if (sHTTPProxyEnabled)
+ {
+ std::string address = mHTTPProxy.getIPString();
+ U16 port = mHTTPProxy.getPort();
+ handle->setoptString(CURLOPT_PROXY, address.c_str());
+ handle->setopt(CURLOPT_PROXYPORT, port);
+ if (mProxyType == LLPROXY_SOCKS)
+ {
+ handle->setopt(CURLOPT_PROXYTYPE, CURLPROXY_SOCKS5);
+ if (mAuthMethodSelected == METHOD_PASSWORD)
+ {
+ handle->setoptString(CURLOPT_PROXYUSERPWD, getProxyUserPwdCURL());
+ }
+ }
+ else
+ {
+ handle->setopt(CURLOPT_PROXYTYPE, CURLPROXY_HTTP);
+ }
+ }
+}
+
+void LLProxy::applyProxySettings(LLCurlEasyRequest* handle)
+{
+ if (sHTTPProxyEnabled)
+ {
+ std::string address = mHTTPProxy.getIPString();
+ U16 port = mHTTPProxy.getPort();
+ handle->setoptString(CURLOPT_PROXY, address.c_str());
+ handle->setopt(CURLOPT_PROXYPORT, port);
+ if (mProxyType == LLPROXY_SOCKS)
+ {
+ handle->setopt(CURLOPT_PROXYTYPE, CURLPROXY_SOCKS5);
+ if (mAuthMethodSelected == METHOD_PASSWORD)
+ {
+ handle->setoptString(CURLOPT_PROXYUSERPWD, getProxyUserPwdCURL());
+ }
+ }
+ else
+ {
+ handle->setopt(CURLOPT_PROXYTYPE, CURLPROXY_HTTP);
+ }
+ }
+}
+
+void LLProxy::applyProxySettings(CURL* handle)
+{
+ LLMutexLock lock(&mProxyMutex);
+ if (sHTTPProxyEnabled)
+ {
+ check_curl_code(curl_easy_setopt(handle, CURLOPT_PROXY, mHTTPProxyAddrStrings.back()));
+ U16 port = mHTTPProxy.getPort();
+ check_curl_code(curl_easy_setopt(handle, CURLOPT_PROXYPORT, port));
+
+ if (mProxyType == LLPROXY_SOCKS)
+ {
+ check_curl_code(curl_easy_setopt(handle, CURLOPT_PROXYTYPE, CURLPROXY_SOCKS5));
+ if (mAuthMethodSelected == METHOD_PASSWORD)
+ {
+ check_curl_code(curl_easy_setopt(handle, CURLOPT_PROXYUSERPWD, mSOCKSAuthStrings.back()));
+ }
+ }
+ else
+ {
+ check_curl_code(curl_easy_setopt(handle, CURLOPT_PROXYTYPE, CURLPROXY_HTTP));
+ }
+ }
+}
+
+static S32 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_SUCCESS;
+
+ apr_size_t expected_len = outlen;
+
+ handle->setBlocking(1000);
+
+ rv = apr_socket_send(apr_socket, dataout, &outlen);
+ if (APR_SUCCESS != rv || expected_len != outlen)
+ {
+ LL_WARNS("Proxy") << "Error sending data to proxy control channel" << LL_ENDL;
+ ll_apr_warn_status(rv);
+ }
+ else if (expected_len != outlen)
+ {
+ LL_WARNS("Proxy") << "Error sending data to proxy control channel" << LL_ENDL;
+ rv = -1;
+ }
+
+ if (APR_SUCCESS == rv)
+ {
+ expected_len = maxinlen;
+ rv = apr_socket_recv(apr_socket, datain, &maxinlen);
+ if (rv != APR_SUCCESS)
+ {
+ LL_WARNS("Proxy") << "Error receiving data from proxy control channel, status: " << rv << LL_ENDL;
+ ll_apr_warn_status(rv);
+ }
+ else if (expected_len != maxinlen)
+ {
+ LL_WARNS("Proxy") << "Received incorrect amount of data in proxy control channel" << LL_ENDL;
+ rv = -1;
+ }
+ }
+
+ handle->setNonBlocking();
+
+ return rv;
+}
+
+static LLSocket::ptr_t tcp_open_channel(apr_pool_t* pool, 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;
+}
+
+// Pass a pointer-to-pointer to avoid changing use_count().
+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();
+}
diff --git a/indra/llmessage/llproxy.h b/indra/llmessage/llproxy.h
new file mode 100644
index 0000000000..df1ec9121e
--- /dev/null
+++ b/indra/llmessage/llproxy.h
@@ -0,0 +1,266 @@
+/**
+ * @file llsocks5.h
+ * @brief Socks 5 implementation
+ *
+ * $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$
+ */
+
+#ifndef LL_PROXY_H
+#define LL_PROXY_H
+
+#include "llcurl.h"
+#include "llhost.h"
+#include "lliosocket.h"
+#include "llmemory.h"
+#include "llsingleton.h"
+#include "llthread.h"
+#include <string>
+
+// Error codes returned from the StartProxy method
+
+#define SOCKS_OK 0
+#define SOCKS_CONNECT_ERROR (-1)
+#define SOCKS_NOT_PERMITTED (-2)
+#define SOCKS_NOT_ACCEPTABLE (-3)
+#define SOCKS_AUTH_FAIL (-4)
+#define SOCKS_UDP_FWD_NOT_GRANTED (-5)
+#define SOCKS_HOST_CONNECT_FAILED (-6)
+
+#ifndef MAXHOSTNAMELEN
+#define MAXHOSTNAMELEN (255 + 1) /* socks5: 255, +1 for len. */
+#endif
+
+#define SOCKS_VERSION 0x05 // we are using SOCKS 5
+
+#define SOCKS_HEADER_SIZE 10
+
+// SOCKS 5 address/hostname types
+#define ADDRESS_IPV4 0x01
+#define ADDRESS_HOSTNAME 0x03
+#define ADDRESS_IPV6 0x04
+
+// Lets just use our own ipv4 struct rather than dragging in system
+// specific headers
+union ipv4_address_t {
+ U8 octets[4];
+ U32 addr32;
+};
+
+// SOCKS 5 control channel commands
+#define COMMAND_TCP_STREAM 0x01
+#define COMMAND_TCP_BIND 0x02
+#define COMMAND_UDP_ASSOCIATE 0x03
+
+// SOCKS 5 command replies
+#define REPLY_REQUEST_GRANTED 0x00
+#define REPLY_GENERAL_FAIL 0x01
+#define REPLY_RULESET_FAIL 0x02
+#define REPLY_NETWORK_UNREACHABLE 0x03
+#define REPLY_HOST_UNREACHABLE 0x04
+#define REPLY_CONNECTION_REFUSED 0x05
+#define REPLY_TTL_EXPIRED 0x06
+#define REPLY_PROTOCOL_ERROR 0x07
+#define REPLY_TYPE_NOT_SUPPORTED 0x08
+
+#define FIELD_RESERVED 0x00
+
+// 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)
+
+// SOCKS 5 command packet
+struct socks_command_request_t {
+ U8 version;
+ U8 command;
+ U8 reserved;
+ U8 atype;
+ U32 address;
+ U16 port;
+};
+
+// Standard SOCKS 5 reply packet
+struct socks_command_response_t {
+ 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
+struct socks_auth_request_t {
+ U8 version;
+ U8 num_methods;
+ U8 methods; // We are only using a single method currently
+};
+
+// SOCKS 5 authentication response packet, stating server preferred method
+struct socks_auth_response_t {
+ U8 version;
+ U8 method;
+};
+
+// SOCKS 5 password reply packet
+struct authmethod_password_reply_t {
+ U8 version;
+ U8 status;
+};
+
+// SOCKS 5 UDP packet header
+struct proxywrap_t {
+ U16 rsv;
+ U8 frag;
+ U8 atype;
+ U32 addr;
+ U16 port;
+};
+
+#pragma pack(pop) /* restore original alignment from stack */
+
+
+// Currently selected HTTP proxy type
+enum LLHttpProxyType
+{
+ LLPROXY_SOCKS = 0,
+ LLPROXY_HTTP = 1
+};
+
+// Auth types
+enum LLSocks5AuthType
+{
+ METHOD_NOAUTH = 0x00, // Client supports no auth
+ METHOD_GSSAPI = 0x01, // Client supports GSSAPI (Not currently supported)
+ METHOD_PASSWORD = 0x02 // Client supports username/password
+};
+
+class LLProxy: public LLSingleton<LLProxy>
+{
+public:
+ LLProxy();
+ ~LLProxy();
+
+ // Start a connection to the SOCKS 5 proxy
+ S32 startProxy(std::string host, U32 port);
+
+ // Disconnect and clean up any connection to the SOCKS 5 proxy
+ void stopProxy();
+
+ // Delete LLProxy singleton, destroying the APR pool used by the control channel.
+ static void cleanupClass();
+
+ // Set up to use Password auth when connecting to the SOCKS proxy
+ void setAuthPassword(const std::string &username, const std::string &password);
+
+ // 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 check for enabled status for http packets
+ static bool isHTTPProxyEnabled() { return sHTTPProxyEnabled; }
+
+ // 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();
+
+ // Stop proxying HTTP packets
+ void disableHTTPProxy();
+
+ // Get the UDP proxy address and port
+ LLHost getUDPProxy() const { return mUDPProxy; }
+
+ // Get the SOCKS 5 TCP control channel address and port
+ LLHost getTCPProxy() const { return mTCPProxy; }
+
+ // 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 username password in a curl compatible format
+ std::string getProxyUserPwdCURL() const { return (mSocksUsername + ":" + mSocksPassword); }
+
+ std::string getSocksPwd() const { return mSocksPassword; }
+ std::string getSocksUser() const { return mSocksUsername; }
+
+ // Apply the current proxy settings to a curl request. Doesn't do anything if sHTTPProxyEnabled is false.
+ void applyProxySettings(CURL* handle);
+ void applyProxySettings(LLCurl::Easy* handle);
+ void applyProxySettings(LLCurlEasyRequest* handle);
+
+private:
+ // Open a communication channel to the SOCKS 5 proxy proxy, at port messagePort
+ S32 proxyHandshake(LLHost proxy, U32 messagePort);
+
+private:
+ // socket handle to proxy TCP control channel
+ LLSocket::ptr_t mProxyControlChannel;
+
+ // Is the UDP proxy enabled?
+ static bool sUDPProxyEnabled;
+ // Is the HTTP proxy enabled?
+ // Do not toggle directly, use enableHTTPProxy() and disableHTTPProxy()
+ static bool sHTTPProxyEnabled;
+
+ // currently selected http proxy type
+ LLHttpProxyType mProxyType;
+
+ // UDP proxy address and port
+ LLHost mUDPProxy;
+ // TCP proxy control channel address and port
+ LLHost mTCPProxy;
+ // HTTP proxy address and port
+ LLHost mHTTPProxy;
+
+ // SOCKS 5 auth method selected
+ LLSocks5AuthType mAuthMethodSelected;
+
+ // SOCKS 5 username
+ std::string mSocksUsername;
+ // SOCKS 5 password
+ std::string mSocksPassword;
+
+ // Vectors to store valid pointers to string options that might have been set on CURL requests.
+ // This results in a behavior similar to LLCurl::Easy::setoptstring()
+ std::vector<char*> mSOCKSAuthStrings;
+ std::vector<char*> mHTTPProxyAddrStrings;
+
+ // Mutex to protect members in cross-thread calls to applyProxySettings()
+ LLMutex mProxyMutex;
+
+ // APR pool for the socket
+ apr_pool_t* mPool;
+};
+
+#endif
diff --git a/indra/llmessage/llurlrequest.cpp b/indra/llmessage/llurlrequest.cpp
index e8e35d00a2..a186596582 100644
--- a/indra/llmessage/llurlrequest.cpp
+++ b/indra/llmessage/llurlrequest.cpp
@@ -35,6 +35,7 @@
#include "llcurl.h"
#include "llioutil.h"
#include "llmemtype.h"
+#include "llproxy.h"
#include "llpumpio.h"
#include "llsd.h"
#include "llstring.h"
@@ -227,8 +228,7 @@ void LLURLRequest::useProxy(bool use_proxy)
}
}
-
- lldebugs << "use_proxy = " << (use_proxy?'Y':'N') << ", env_proxy = " << (env_proxy ? env_proxy : "(null)") << llendl;
+ LL_DEBUGS("Proxy") << "use_proxy = " << (use_proxy?'Y':'N') << ", env_proxy = " << (env_proxy ? env_proxy : "(null)") << LL_ENDL;
if (env_proxy && use_proxy)
{
@@ -438,6 +438,7 @@ void LLURLRequest::initialize()
LLMemType m1(LLMemType::MTYPE_IO_URL_REQUEST);
mState = STATE_INITIALIZED;
mDetail = new LLURLRequestDetail;
+ LLProxy::getInstance()->applyProxySettings(mDetail->mCurlRequest);
mDetail->mCurlRequest->setopt(CURLOPT_NOSIGNAL, 1);
mDetail->mCurlRequest->setWriteCallback(&downCallback, (void*)this);
mDetail->mCurlRequest->setReadCallback(&upCallback, (void*)this);
diff --git a/indra/llmessage/net.cpp b/indra/llmessage/net.cpp
index 97611c3b51..85aef5da00 100644
--- a/indra/llmessage/net.cpp
+++ b/indra/llmessage/net.cpp
@@ -50,7 +50,6 @@
#include "lltimer.h"
#include "indra_constants.h"
-
// Globals
#if LL_WINDOWS
@@ -174,7 +173,7 @@ U32 ip_string_to_u32(const char* ip_string)
// use wildcard addresses. -Ambroff
U32 ip = inet_addr(ip_string);
if (ip == INADDR_NONE
- && strncmp(ip_string, BROADCAST_ADDRESS_STRING, MAXADDRSTR) != 0)
+ && strncmp(ip_string, BROADCAST_ADDRESS_STRING, MAXADDRSTR) != 0)
{
llwarns << "ip_string_to_u32() failed, Error: Invalid IP string '" << ip_string << "'" << llendl;
return INVALID_HOST_IP_ADDRESS;
@@ -188,11 +187,11 @@ U32 ip_string_to_u32(const char* ip_string)
//////////////////////////////////////////////////////////////////////////////////////////
#if LL_WINDOWS
-
+
S32 start_net(S32& socket_out, int& nPort)
{
// Create socket, make non-blocking
- // Init WinSock
+ // Init WinSock
int nRet;
int hSocket;
@@ -201,7 +200,7 @@ S32 start_net(S32& socket_out, int& nPort)
int buff_size = 4;
// Initialize windows specific stuff
- if(WSAStartup(0x0202, &stWSAData))
+ if (WSAStartup(0x0202, &stWSAData))
{
S32 err = WSAGetLastError();
WSACleanup();
@@ -210,8 +209,8 @@ S32 start_net(S32& socket_out, int& nPort)
}
// Get a datagram socket
- hSocket = (int)socket(AF_INET, SOCK_DGRAM, 0);
- if (hSocket == INVALID_SOCKET)
+ hSocket = (int)socket(AF_INET, SOCK_DGRAM, 0);
+ if (hSocket == INVALID_SOCKET)
{
S32 err = WSAGetLastError();
WSACleanup();
@@ -304,7 +303,7 @@ S32 start_net(S32& socket_out, int& nPort)
// Setup a destination address
stDstAddr.sin_family = AF_INET;
stDstAddr.sin_addr.s_addr = INVALID_HOST_IP_ADDRESS;
- stDstAddr.sin_port = htons(nPort);
+ stDstAddr.sin_port = htons(nPort);
socket_out = hSocket;
return 0;
@@ -393,10 +392,10 @@ S32 start_net(S32& socket_out, int& nPort)
int rec_size = RECEIVE_BUFFER_SIZE;
socklen_t buff_size = 4;
-
+
// Create socket
- hSocket = socket(AF_INET, SOCK_DGRAM, 0);
- if (hSocket < 0)
+ hSocket = socket(AF_INET, SOCK_DGRAM, 0);
+ if (hSocket < 0)
{
llwarns << "socket() failed" << llendl;
return 1;
@@ -429,7 +428,7 @@ S32 start_net(S32& socket_out, int& nPort)
}
else
{
- // Name the socket (assign the local port number to receive on)
+ // Name the socket (assign the local port number to receive on)
stLclAddr.sin_family = AF_INET;
stLclAddr.sin_addr.s_addr = htonl(INADDR_ANY);
stLclAddr.sin_port = htons(nPort);
@@ -474,7 +473,7 @@ S32 start_net(S32& socket_out, int& nPort)
nPort = attempt_port;
}
// Set socket to be non-blocking
- fcntl(hSocket, F_SETFL, O_NONBLOCK);
+ fcntl(hSocket, F_SETFL, O_NONBLOCK);
// set a large receive buffer
nRet = setsockopt(hSocket, SOL_SOCKET, SO_RCVBUF, (char *)&rec_size, buff_size);
if (nRet)
@@ -510,8 +509,8 @@ S32 start_net(S32& socket_out, int& nPort)
// Setup a destination address
char achMCAddr[MAXADDRSTR] = "127.0.0.1"; /* Flawfinder: ignore */
stDstAddr.sin_family = AF_INET;
- stDstAddr.sin_addr.s_addr = ip_string_to_u32(achMCAddr);
- stDstAddr.sin_port = htons(nPort);
+ stDstAddr.sin_addr.s_addr = ip_string_to_u32(achMCAddr);
+ stDstAddr.sin_port = htons(nPort);
socket_out = hSocket;
return 0;
@@ -537,7 +536,7 @@ static int recvfrom_destip( int socket, void *buf, int len, struct sockaddr *fro
iov[0].iov_base = buf;
iov[0].iov_len = len;
- memset( &msg, 0, sizeof msg );
+ memset(&msg, 0, sizeof msg);
msg.msg_name = from;
msg.msg_namelen = *fromlen;
msg.msg_iov = iov;
@@ -545,14 +544,14 @@ static int recvfrom_destip( int socket, void *buf, int len, struct sockaddr *fro
msg.msg_control = &cmsg;
msg.msg_controllen = sizeof(cmsg);
- size = recvmsg( socket, &msg, 0 );
+ size = recvmsg(socket, &msg, 0);
- if( size == -1 )
+ if (size == -1)
{
return -1;
}
- for( cmsgptr = CMSG_FIRSTHDR(&msg); cmsgptr != NULL; cmsgptr = CMSG_NXTHDR( &msg, cmsgptr ) )
+ for (cmsgptr = CMSG_FIRSTHDR(&msg); cmsgptr != NULL; cmsgptr = CMSG_NXTHDR( &msg, cmsgptr))
{
if( cmsgptr->cmsg_level == SOL_IP && cmsgptr->cmsg_type == IP_PKTINFO )
{
@@ -650,7 +649,7 @@ BOOL send_packet(int hSocket, const char * sendBuffer, int size, U32 recipient,
}
}
}
- while ( resend && send_attempts < 3);
+ while (resend && send_attempts < 3);
if (send_attempts >= 3)
{
diff --git a/indra/llmessage/net.h b/indra/llmessage/net.h
index 9f4f5c5821..0f2437479d 100644
--- a/indra/llmessage/net.h
+++ b/indra/llmessage/net.h
@@ -46,10 +46,10 @@ S32 receive_packet(int hSocket, char * receiveBuffer);
BOOL send_packet(int hSocket, const char *sendBuffer, int size, U32 recipient, int nPort); // Returns TRUE on success.
//void get_sender(char * tmp);
-LLHost get_sender();
+LLHost get_sender();
U32 get_sender_port();
U32 get_sender_ip(void);
-LLHost get_receiving_interface();
+LLHost get_receiving_interface();
U32 get_receiving_interface_ip(void);
const char* u32_to_ip_string(U32 ip); // Returns pointer to internal string buffer, "(bad IP addr)" on failure, cannot nest calls