diff options
Diffstat (limited to 'indra/llmessage')
| -rw-r--r-- | indra/llmessage/llassetstorage.cpp | 2 | ||||
| -rw-r--r-- | indra/llmessage/llcurl.cpp | 208 | ||||
| -rw-r--r-- | indra/llmessage/llcurl.h | 3 | ||||
| -rw-r--r-- | indra/llmessage/llhttpassetstorage.cpp | 8 | ||||
| -rw-r--r-- | indra/llmessage/llsdmessagebuilder.cpp | 1 | ||||
| -rw-r--r-- | indra/llmessage/lltemplatemessagebuilder.cpp | 1 | ||||
| -rw-r--r-- | indra/llmessage/lltemplatemessagereader.cpp | 1 | ||||
| -rw-r--r-- | indra/llmessage/lltransfermanager.cpp | 2 | ||||
| -rw-r--r-- | indra/llmessage/lltransfersourceasset.cpp | 1 | 
9 files changed, 197 insertions, 30 deletions
| diff --git a/indra/llmessage/llassetstorage.cpp b/indra/llmessage/llassetstorage.cpp index b26d412e9f..c5864b30c7 100644 --- a/indra/llmessage/llassetstorage.cpp +++ b/indra/llmessage/llassetstorage.cpp @@ -540,7 +540,7 @@ void LLAssetStorage::_queueDataRequest(const LLUUID& uuid, LLAssetType::EType at  			tpvf.setAsset(uuid, atype);  			tpvf.setCallback(downloadCompleteCallback, req); -			llinfos << "Starting transfer for " << uuid << llendl; +			//llinfos << "Starting transfer for " << uuid << llendl;  			LLTransferTargetChannel *ttcp = gTransferManager.getTargetChannel(mUpstreamHost, LLTCT_ASSET);  			ttcp->requestTransfer(spa, tpvf, 100.f + (is_priority ? 1.f : 0.f));  		} diff --git a/indra/llmessage/llcurl.cpp b/indra/llmessage/llcurl.cpp index a485fa0160..6473b23e80 100644 --- a/indra/llmessage/llcurl.cpp +++ b/indra/llmessage/llcurl.cpp @@ -49,6 +49,7 @@  #include "llstl.h"  #include "llsdserialize.h"  #include "llthread.h" +#include "lltimer.h"  //////////////////////////////////////////////////////////////////////////////  /* @@ -84,6 +85,36 @@ std::vector<LLMutex*> LLCurl::sSSLMutex;  std::string LLCurl::sCAPath;  std::string LLCurl::sCAFile; +void check_curl_code(CURLcode code) +{ +	if (code != CURLE_OK) +	{ +		// linux appears to throw a curl error once per session for a bad initialization +		// at a pretty random time (when enabling cookies). Making curl errors non-asserts +		// for non-windows platforms for now. - Nyx +		#if LL_WINDOWS +			llerrs << "curl error detected: " << curl_easy_strerror(code) << llendl; +		#else +			llinfos << "curl error detected: " << curl_easy_strerror(code) << llendl; +		#endif +	} +} + +void check_curl_multi_code(CURLMcode code)  +{ +	if (code != CURLM_OK) +	{ +		// linux appears to throw a curl error once per session for a bad initialization +		// at a pretty random time (when enabling cookies). Making curl errors non-asserts +		// for non-windows platforms for now. - Nyx +		#if LL_WINDOWS +			llerrs << "curl multi error detected: " << curl_multi_strerror(code) << llendl; +		#else  +			llinfos << "curl multi error detected: " << curl_multi_strerror(code) << llendl; +		#endif +	} +} +  //static  void LLCurl::setCAPath(const std::string& path)  { @@ -234,7 +265,12 @@ public:  	void resetState(); +	static CURL* allocEasyHandle(); +	static void releaseEasyHandle(CURL* handle); +  private:	 +	friend class LLCurl; +  	CURL*				mCurlEasyHandle;  	struct curl_slist*	mHeaders; @@ -249,8 +285,62 @@ private:  	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; + + +//static +CURL* LLCurl::Easy::allocEasyHandle() +{ +	CURL* ret = NULL; +	LLMutexLock lock(sHandleMutex); +	if (sFreeHandles.empty()) +	{ +		ret = curl_easy_init(); +	} +	else +	{ +		ret = *(sFreeHandles.begin()); +		sFreeHandles.erase(ret); +		curl_easy_reset(ret); +	} + +	if (ret) +	{ +		sActiveHandles.insert(ret); +	} + +	return ret; +} + +//static +void LLCurl::Easy::releaseEasyHandle(CURL* handle) +{ +	if (!handle) +	{ +		llerrs << "handle cannot be NULL!" << llendl; +	} + +	LLMutexLock lock(sHandleMutex); +	 +	if (sActiveHandles.find(handle) != sActiveHandles.end()) +	{ +		sActiveHandles.erase(handle); +		sFreeHandles.insert(handle); +	} +	else +	{ +		llerrs << "Invalid handle." << llendl; +	} +} +  LLCurl::Easy::Easy()  	: mHeaders(NULL),  	  mCurlEasyHandle(NULL) @@ -261,25 +351,28 @@ LLCurl::Easy::Easy()  LLCurl::Easy* LLCurl::Easy::getEasy()  {  	Easy* easy = new Easy(); -	easy->mCurlEasyHandle = curl_easy_init(); +	easy->mCurlEasyHandle = allocEasyHandle();  +	  	if (!easy->mCurlEasyHandle)  	{  		// this can happen if we have too many open files (fails in c-ares/ares_init.c) -		llwarns << "curl_multi_init() returned NULL! Easy handles: " << gCurlEasyCount << " Multi handles: " << gCurlMultiCount << llendl; +		llwarns << "allocEasyHandle() returned NULL! Easy handles: " << gCurlEasyCount << " Multi handles: " << gCurlMultiCount << llendl;  		delete easy;  		return NULL;  	} -	// set no DMS caching as default for all easy handles. This prevents them adopting a +	// set no DNS caching as default for all easy handles. This prevents them adopting a  	// multi handles cache if they are added to one. -	curl_easy_setopt(easy->mCurlEasyHandle, CURLOPT_DNS_CACHE_TIMEOUT, 0); +	CURLcode result = curl_easy_setopt(easy->mCurlEasyHandle, CURLOPT_DNS_CACHE_TIMEOUT, 0); +	check_curl_code(result); +	  	++gCurlEasyCount;  	return easy;  }  LLCurl::Easy::~Easy()  { -	curl_easy_cleanup(mCurlEasyHandle); +	releaseEasyHandle(mCurlEasyHandle);  	--gCurlEasyCount;  	curl_slist_free_all(mHeaders);  	for_each(mStrings.begin(), mStrings.end(), DeletePointerArray()); @@ -338,9 +431,9 @@ void LLCurl::Easy::setHeaders()  void LLCurl::Easy::getTransferInfo(LLCurl::TransferInfo* info)  { -	curl_easy_getinfo(mCurlEasyHandle, CURLINFO_SIZE_DOWNLOAD, &info->mSizeDownload); -	curl_easy_getinfo(mCurlEasyHandle, CURLINFO_TOTAL_TIME, &info->mTotalTime); -	curl_easy_getinfo(mCurlEasyHandle, CURLINFO_SPEED_DOWNLOAD, &info->mSpeedDownload); +	check_curl_code(curl_easy_getinfo(mCurlEasyHandle, CURLINFO_SIZE_DOWNLOAD, &info->mSizeDownload)); +	check_curl_code(curl_easy_getinfo(mCurlEasyHandle, CURLINFO_TOTAL_TIME, &info->mTotalTime)); +	check_curl_code(curl_easy_getinfo(mCurlEasyHandle, CURLINFO_SPEED_DOWNLOAD, &info->mSpeedDownload));  }  U32 LLCurl::Easy::report(CURLcode code) @@ -350,13 +443,14 @@ U32 LLCurl::Easy::report(CURLcode code)  	if (code == CURLE_OK)  	{ -		curl_easy_getinfo(mCurlEasyHandle, CURLINFO_RESPONSE_CODE, &responseCode); +		check_curl_code(curl_easy_getinfo(mCurlEasyHandle, CURLINFO_RESPONSE_CODE, &responseCode));  		//*TODO: get reason from first line of mHeaderOutput  	}  	else  	{  		responseCode = 499;  		responseReason = strerror(code) + " : " + mErrorBuffer; +		setopt(CURLOPT_FRESH_CONNECT, TRUE);  	}  	if (mResponder) @@ -372,17 +466,20 @@ U32 LLCurl::Easy::report(CURLcode code)  // Note: these all assume the caller tracks the value (i.e. keeps it persistant)  void LLCurl::Easy::setopt(CURLoption option, S32 value)  { -	curl_easy_setopt(mCurlEasyHandle, option, value); +	CURLcode result = curl_easy_setopt(mCurlEasyHandle, option, value); +	check_curl_code(result);  }  void LLCurl::Easy::setopt(CURLoption option, void* value)  { -	curl_easy_setopt(mCurlEasyHandle, option, value); +	CURLcode result = curl_easy_setopt(mCurlEasyHandle, option, value); +	check_curl_code(result);  }  void LLCurl::Easy::setopt(CURLoption option, char* value)  { -	curl_easy_setopt(mCurlEasyHandle, option, value); +	CURLcode result = curl_easy_setopt(mCurlEasyHandle, option, value); +	check_curl_code(result);  }  // Note: this copies the string so that the caller does not have to keep it around @@ -391,7 +488,8 @@ void LLCurl::Easy::setoptString(CURLoption option, const std::string& value)  	char* tstring = new char[value.length()+1];  	strcpy(tstring, value.c_str());  	mStrings.push_back(tstring); -	curl_easy_setopt(mCurlEasyHandle, option, tstring); +	CURLcode result = curl_easy_setopt(mCurlEasyHandle, option, tstring); +	check_curl_code(result);  }  void LLCurl::Easy::slist_append(const char* str) @@ -443,7 +541,7 @@ void LLCurl::Easy::prepRequest(const std::string& url,  	if (post) setoptString(CURLOPT_ENCODING, ""); -//	setopt(CURLOPT_VERBOSE, 1); // usefull for debugging +	//setopt(CURLOPT_VERBOSE, 1); // usefull for debugging  	setopt(CURLOPT_NOSIGNAL, 1);  	mOutput.reset(new LLBufferArray); @@ -467,6 +565,9 @@ void LLCurl::Easy::prepRequest(const std::string& url,  	setCA();  	setopt(CURLOPT_SSL_VERIFYPEER, true); +	 +	//don't verify host name so urls with scrubbed host names will work (improves DNS performance) +	setopt(CURLOPT_SSL_VERIFYHOST, 0);  	setopt(CURLOPT_TIMEOUT, CURL_REQUEST_TIMEOUT);  	setoptString(CURLOPT_URL, url); @@ -532,6 +633,7 @@ LLCurl::Multi::Multi()  		llwarns << "curl_multi_init() returned NULL! Easy handles: " << gCurlEasyCount << " Multi handles: " << gCurlMultiCount << llendl;  		mCurlMultiHandle = curl_multi_init();  	} +	  	llassert_always(mCurlMultiHandle);  	++gCurlMultiCount;  } @@ -543,7 +645,7 @@ LLCurl::Multi::~Multi()  		iter != mEasyActiveList.end(); ++iter)  	{  		Easy* easy = *iter; -		curl_multi_remove_handle(mCurlMultiHandle, easy->getCurlHandle()); +		check_curl_multi_code(curl_multi_remove_handle(mCurlMultiHandle, easy->getCurlHandle()));  		delete easy;  	}  	mEasyActiveList.clear(); @@ -553,7 +655,7 @@ LLCurl::Multi::~Multi()  	for_each(mEasyFreeList.begin(), mEasyFreeList.end(), DeletePointer());	  	mEasyFreeList.clear(); -	curl_multi_cleanup(mCurlMultiHandle); +	check_curl_multi_code(curl_multi_cleanup(mCurlMultiHandle));  	--gCurlMultiCount;  } @@ -574,8 +676,10 @@ S32 LLCurl::Multi::perform()  		CURLMcode code = curl_multi_perform(mCurlMultiHandle, &q);  		if (CURLM_CALL_MULTI_PERFORM != code || q == 0)  		{ +			check_curl_multi_code(code);  			break;  		} +	  	}  	mQueued = q;  	return q; @@ -642,11 +746,12 @@ LLCurl::Easy* LLCurl::Multi::allocEasy()  bool LLCurl::Multi::addEasy(Easy* easy)  {  	CURLMcode mcode = curl_multi_add_handle(mCurlMultiHandle, easy->getCurlHandle()); -	if (mcode != CURLM_OK) -	{ -		llwarns << "Curl Error: " << curl_multi_strerror(mcode) << llendl; -		return false; -	} +	check_curl_multi_code(mcode); +	//if (mcode != CURLM_OK) +	//{ +	//	llwarns << "Curl Error: " << curl_multi_strerror(mcode) << llendl; +	//	return false; +	//}  	return true;  } @@ -667,7 +772,7 @@ void LLCurl::Multi::easyFree(Easy* easy)  void LLCurl::Multi::removeEasy(Easy* easy)  { -	curl_multi_remove_handle(mCurlMultiHandle, easy->getCurlHandle()); +	check_curl_multi_code(curl_multi_remove_handle(mCurlMultiHandle, easy->getCurlHandle()));  	easyFree(easy);  } @@ -694,6 +799,7 @@ LLCurlRequest::LLCurlRequest() :  	mActiveRequestCount(0)  {  	mThreadID = LLThread::currentID(); +	mProcessing = FALSE;  }  LLCurlRequest::~LLCurlRequest() @@ -728,6 +834,11 @@ LLCurl::Easy* LLCurlRequest::allocEasy()  bool LLCurlRequest::addEasy(LLCurl::Easy* easy)  {  	llassert_always(mActiveMulti); +	 +	if (mProcessing) +	{ +		llerrs << "Posting to a LLCurlRequest instance from within a responder is not allowed (causes DNS timeouts)." << llendl; +	}  	bool res = mActiveMulti->addEasy(easy);  	return res;  } @@ -785,12 +896,41 @@ bool LLCurlRequest::post(const std::string& url,  	bool res = addEasy(easy);  	return res;  } + +bool LLCurlRequest::post(const std::string& url, +						 const headers_t& headers, +						 const std::string& data, +						 LLCurl::ResponderPtr responder) +{ +	LLCurl::Easy* easy = allocEasy(); +	if (!easy) +	{ +		return false; +	} +	easy->prepRequest(url, headers, responder); + +	easy->getInput().write(data.data(), data.size()); +	S32 bytes = easy->getInput().str().length(); +	easy->setopt(CURLOPT_POST, 1); +	easy->setopt(CURLOPT_POSTFIELDS, (void*)NULL); +	easy->setopt(CURLOPT_POSTFIELDSIZE, bytes); + +	easy->slist_append("Content-Type: application/octet-stream"); +	easy->setHeaders(); + +	lldebugs << "POSTING: " << bytes << " bytes." << llendl; +	bool res = addEasy(easy); +	return res; +} +  // Note: call once per frame  S32 LLCurlRequest::process()  {  	llassert_always(mThreadID == LLThread::currentID());  	S32 res = 0; + +	mProcessing = TRUE;  	for (curlmulti_set_t::iterator iter = mMultiSet.begin();  		 iter != mMultiSet.end(); )  	{ @@ -804,6 +944,7 @@ S32 LLCurlRequest::process()  			delete multi;  		}  	} +	mProcessing = FALSE;  	return res;  } @@ -1033,8 +1174,12 @@ void LLCurl::initClass()  	// Do not change this "unless you are familiar with and mean to control   	// internal operations of libcurl"  	// - http://curl.haxx.se/libcurl/c/curl_global_init.html -	curl_global_init(CURL_GLOBAL_ALL); +	CURLcode code = curl_global_init(CURL_GLOBAL_ALL); + +	check_curl_code(code); +	Easy::sHandleMutex = new LLMutex(NULL); +  #if SAFE_SSL  	S32 mutex_count = CRYPTO_num_locks();  	for (S32 i=0; i<mutex_count; i++) @@ -1052,7 +1197,22 @@ void LLCurl::cleanupClass()  	CRYPTO_set_locking_callback(NULL);  	for_each(sSSLMutex.begin(), sSSLMutex.end(), DeletePointer());  #endif -	curl_global_cleanup(); + +	delete Easy::sHandleMutex; +	Easy::sHandleMutex = NULL; + +	for (std::set<CURL*>::iterator iter = Easy::sFreeHandles.begin(); iter != Easy::sFreeHandles.end(); ++iter) +	{ +		CURL* curl = *iter; +		curl_easy_cleanup(curl); +	} + +	Easy::sFreeHandles.clear(); + +	if (!Easy::sActiveHandles.empty()) +	{ +		llerrs << "CURL easy handles not cleaned up on shutdown!" << llendl; +	}  }  const unsigned int LLCurl::MAX_REDIRECTS = 5; diff --git a/indra/llmessage/llcurl.h b/indra/llmessage/llcurl.h index 64dadd6640..4ce3fa1078 100644 --- a/indra/llmessage/llcurl.h +++ b/indra/llmessage/llcurl.h @@ -202,6 +202,8 @@ public:  	void get(const std::string& url, LLCurl::ResponderPtr responder);  	bool getByteRange(const std::string& url, const headers_t& headers, S32 offset, S32 length, LLCurl::ResponderPtr responder);  	bool post(const std::string& url, const headers_t& headers, const LLSD& data, LLCurl::ResponderPtr responder); +	bool post(const std::string& url, const headers_t& headers, const std::string& data, LLCurl::ResponderPtr responder); +	  	S32  process();  	S32  getQueued(); @@ -215,6 +217,7 @@ private:  	curlmulti_set_t mMultiSet;  	LLCurl::Multi* mActiveMulti;  	S32 mActiveRequestCount; +	BOOL mProcessing;  	U32 mThreadID; // debug  }; diff --git a/indra/llmessage/llhttpassetstorage.cpp b/indra/llmessage/llhttpassetstorage.cpp index 9ea2ff4153..5a38b7fd9f 100644 --- a/indra/llmessage/llhttpassetstorage.cpp +++ b/indra/llmessage/llhttpassetstorage.cpp @@ -174,8 +174,8 @@ LLSD LLHTTPAssetRequest::getFullDetails() const  		double curl_total_time = -1.0f;  		double curl_size_upload = -1.0f;  		double curl_size_download = -1.0f; -		long curl_content_length_upload = -1; -		long curl_content_length_download = -1; +		double curl_content_length_upload = -1.0f; +		double curl_content_length_download = -1.0f;  		long curl_request_size = -1;  		const char* curl_content_type = NULL; @@ -194,8 +194,8 @@ LLSD LLHTTPAssetRequest::getFullDetails() const  		sd["curl_total_time"] = curl_total_time;  		sd["curl_size_upload"]   = curl_size_upload;  		sd["curl_size_download"] = curl_size_download; -		sd["curl_content_length_upload"]   = (int) curl_content_length_upload; -		sd["curl_content_length_download"] = (int) curl_content_length_download; +		sd["curl_content_length_upload"]   =  curl_content_length_upload; +		sd["curl_content_length_download"] =  curl_content_length_download;  		sd["curl_request_size"] = (int) curl_request_size;  		if (curl_content_type)  		{ diff --git a/indra/llmessage/llsdmessagebuilder.cpp b/indra/llmessage/llsdmessagebuilder.cpp index 42c179782f..2698a271ee 100644 --- a/indra/llmessage/llsdmessagebuilder.cpp +++ b/indra/llmessage/llsdmessagebuilder.cpp @@ -29,6 +29,7 @@  #include "llsdmessagebuilder.h"  #include "llmessagetemplate.h" +#include "llmath.h"  #include "llquaternion.h"  #include "llsdutil.h"  #include "llsdutil_math.h" diff --git a/indra/llmessage/lltemplatemessagebuilder.cpp b/indra/llmessage/lltemplatemessagebuilder.cpp index 6611d704e6..9e8eb48460 100644 --- a/indra/llmessage/lltemplatemessagebuilder.cpp +++ b/indra/llmessage/lltemplatemessagebuilder.cpp @@ -29,6 +29,7 @@  #include "lltemplatemessagebuilder.h"  #include "llmessagetemplate.h" +#include "llmath.h"  #include "llquaternion.h"  #include "u64.h"  #include "v3dmath.h" diff --git a/indra/llmessage/lltemplatemessagereader.cpp b/indra/llmessage/lltemplatemessagereader.cpp index 3bfcd58c69..f470e1b2a5 100644 --- a/indra/llmessage/lltemplatemessagereader.cpp +++ b/indra/llmessage/lltemplatemessagereader.cpp @@ -30,6 +30,7 @@  #include "llfasttimer.h"  #include "llmessagebuilder.h"  #include "llmessagetemplate.h" +#include "llmath.h"  #include "llquaternion.h"  #include "message.h"  #include "u64.h" diff --git a/indra/llmessage/lltransfermanager.cpp b/indra/llmessage/lltransfermanager.cpp index 754eb99cbd..034680caf8 100644 --- a/indra/llmessage/lltransfermanager.cpp +++ b/indra/llmessage/lltransfermanager.cpp @@ -338,7 +338,7 @@ void LLTransferManager::processTransferInfo(LLMessageSystem *msgp, void **)  		}  	} -	llinfos << "Receiving " << transfer_id << ", size " << size << " bytes" << llendl; +	//llinfos << "Receiving " << transfer_id << ", size " << size << " bytes" << llendl;  	ttp->setSize(size);  	ttp->setGotInfo(TRUE); diff --git a/indra/llmessage/lltransfersourceasset.cpp b/indra/llmessage/lltransfersourceasset.cpp index 7e57841580..8537773a3f 100644 --- a/indra/llmessage/lltransfersourceasset.cpp +++ b/indra/llmessage/lltransfersourceasset.cpp @@ -251,3 +251,4 @@ BOOL LLTransferSourceParamsAsset::unpackParams(LLDataPacker &dp)  	return TRUE;  } + | 
