diff options
| author | George Hazan <ghazan@miranda.im> | 2022-09-01 18:23:46 +0300 | 
|---|---|---|
| committer | George Hazan <ghazan@miranda.im> | 2022-09-01 18:23:46 +0300 | 
| commit | 0d54e69d920faef14771c45d75b03bf50824f2bc (patch) | |
| tree | 15c445fa1ea043d4d5a017c285ca3727c567f36d | |
| parent | ab663bfc496f4a47416e2b35d088ac0af8f29204 (diff) | |
Jabber: fix for XEP-0198 processing
| -rw-r--r-- | protocols/JabberG/src/jabber_proto.h | 1 | ||||
| -rw-r--r-- | protocols/JabberG/src/jabber_strm_mgmt.cpp | 5 | ||||
| -rw-r--r-- | protocols/JabberG/src/jabber_strm_mgmt.h | 1 | ||||
| -rw-r--r-- | protocols/JabberG/src/jabber_thread.cpp | 60 | 
4 files changed, 47 insertions, 20 deletions
diff --git a/protocols/JabberG/src/jabber_proto.h b/protocols/JabberG/src/jabber_proto.h index dfd9fb9dcd..daed6fa219 100644 --- a/protocols/JabberG/src/jabber_proto.h +++ b/protocols/JabberG/src/jabber_proto.h @@ -814,6 +814,7 @@ struct CJabberProto : public PROTO<CJabberProto>, public IJabberInterface  	bool       m_isSessionAvailable, m_isAuthAvailable;
  	void       __cdecl ServerThread(JABBER_CONN_DATA *info);
 +	bool       ServerThreadStub(ThreadData &info);
  	void       OnProcessFailure(const TiXmlElement *node, ThreadData *info);
  	void       OnProcessFailed(const TiXmlElement *node, ThreadData *info);
 diff --git a/protocols/JabberG/src/jabber_strm_mgmt.cpp b/protocols/JabberG/src/jabber_strm_mgmt.cpp index 93bacf04de..204aab62c8 100644 --- a/protocols/JabberG/src/jabber_strm_mgmt.cpp +++ b/protocols/JabberG/src/jabber_strm_mgmt.cpp @@ -214,6 +214,11 @@ void strm_mgmt::ResetState()  	m_sStrmMgmtResumeId.clear();
  }
 +void strm_mgmt::HandleConnectionLost()
 +{
 +	m_bStrmMgmtEnabled = false;
 +}
 +
  bool strm_mgmt::HandleIncommingNode(const TiXmlElement *node)
  {
  	if (!m_bStrmMgmtEnabled)
 diff --git a/protocols/JabberG/src/jabber_strm_mgmt.h b/protocols/JabberG/src/jabber_strm_mgmt.h index 0cfa01f1df..d8ad0b63fc 100644 --- a/protocols/JabberG/src/jabber_strm_mgmt.h +++ b/protocols/JabberG/src/jabber_strm_mgmt.h @@ -49,6 +49,7 @@ public:  	void EnableStrmMgmt();
  	void HandleOutgoingNode(TiXmlElement *node);
  	bool HandleIncommingNode(const TiXmlElement *node);
 +	void HandleConnectionLost();
  	void OnProcessEnabled(const TiXmlElement *node, ThreadData *info);
  	void OnProcessResumed(const TiXmlElement *node, ThreadData *info);
  	void OnProcessFailed(const TiXmlElement *node, ThreadData * info);
 diff --git a/protocols/JabberG/src/jabber_thread.cpp b/protocols/JabberG/src/jabber_thread.cpp index f64651169d..18bcb17cb6 100644 --- a/protocols/JabberG/src/jabber_thread.cpp +++ b/protocols/JabberG/src/jabber_thread.cpp @@ -234,11 +234,18 @@ void CJabberProto::xmlStreamInitializeNow(ThreadData *info)  void CJabberProto::ServerThread(JABBER_CONN_DATA *pParam)
  {
 -	ThreadData info(this, pParam);
 -	ptrA tszValue;
 +	Thread_SetName("Jabber: ServerThread");
 +	do {
 +		ThreadData info(this, pParam);
 +		if (!ServerThreadStub(info))
 +			return;
 +	} while (true);
 +}
 +
 +bool CJabberProto::ServerThreadStub(ThreadData &info)
 +{
  	debugLogA("Thread started: type=%d", info.bIsReg);
 -	Thread_SetName("Jabber: ServerThread");
  	if (m_bManualConnect == TRUE) {
  		ptrA szManualHost(getStringA("ManualHost"));
 @@ -256,13 +263,15 @@ void CJabberProto::ServerThread(JABBER_CONN_DATA *pParam)  		// e.g. username, password, etc. from the database.
  		if (m_ThreadInfo != nullptr) {
  			debugLogA("Thread ended, another normal thread is running");
 -			return;
 +			return true;
  		}
  		m_ThreadInfo = &info;
 -		if ((tszValue = getUStringA("LoginName")) != nullptr)
 -			strncpy_s(info.conn.username, tszValue, _TRUNCATE);
 +		if (char *pszValue = getUStringA("LoginName")) {
 +			strncpy_s(info.conn.username, pszValue, _TRUNCATE);
 +			mir_free(pszValue);
 +		}
  		if (*rtrim(info.conn.username) == '\0') {
  			DWORD dwSize = _countof(info.conn.username);
 @@ -281,7 +290,7 @@ LBL_FatalError:  			int oldStatus = m_iStatus;
  			m_iDesiredStatus = m_iStatus = ID_STATUS_OFFLINE;
  			ProtoBroadcastAck(0, ACKTYPE_STATUS, ACKRESULT_SUCCESS, (HANDLE)oldStatus, m_iStatus);
 -			return;
 +			return true;
  		}
  		ptrA szValue(getStringA("LoginServer"));
 @@ -299,7 +308,8 @@ LBL_FatalError:  				strncpy_s(info.resource, "Miranda", _TRUNCATE);
  		}
  		else {
 -			if ((tszValue = getUStringA("Resource")) != nullptr)
 +			ptrA tszValue(getUStringA("Resource"));
 +			if (tszValue != nullptr)
  				strncpy_s(info.resource, tszValue, _TRUNCATE);
  			else
  				mir_strcpy(info.resource, "Miranda");
 @@ -356,7 +366,7 @@ LBL_FatalError:  	}
  	int jabberNetworkBufferSize = 2048;
 -	if ((info.buffer = (char*)mir_alloc(jabberNetworkBufferSize + 1)) == nullptr) {	// +1 is for '\0' when debug logging this buffer
 +	if ((info.buffer = (char *)mir_alloc(jabberNetworkBufferSize + 1)) == nullptr) {	// +1 is for '\0' when debug logging this buffer
  		debugLogA("Cannot allocate network buffer, thread ended");
  		if (info.bIsReg)
  			info.conn.SetProgress(100, TranslateT("Error: Not enough memory"));
 @@ -439,7 +449,7 @@ recvRest:  				if (p) {
  					char *q = strchr(p + 15, '>');
  					if (q) {
 -						CMStringA tmp(info.buffer, int(q - info.buffer)+1);
 +						CMStringA tmp(info.buffer, int(q - info.buffer) + 1);
  						tmp.Append("</stream:stream>");
  						if (0 == root.Parse(tmp)) {
 @@ -451,7 +461,7 @@ recvRest:  					}
  				}
  			}
 -			
 +
  			if (bytesParsed == 0) {
  				if (0 == root.Parse(info.buffer)) {
  					for (auto *n : TiXmlEnum(&root))
 @@ -471,7 +481,7 @@ recvRest:  				//jabberNetworkBufferSize += 65536;
  				jabberNetworkBufferSize *= 2;
  				debugLogA("Increasing network buffer size to %d", jabberNetworkBufferSize);
 -				if ((info.buffer = (char*)mir_realloc(info.buffer, jabberNetworkBufferSize + 1)) == nullptr) {
 +				if ((info.buffer = (char *)mir_realloc(info.buffer, jabberNetworkBufferSize + 1)) == nullptr) {
  					debugLogA("Cannot reallocate more network buffer, go offline now");
  					break;
  				}
 @@ -487,7 +497,6 @@ recvRest:  		if (!info.bIsReg) {
  			m_impl.m_keepAlive.Stop();
 -			m_iqManager.ExpireAll();
  			m_bJabberOnline = false;
  			info.zlibUninit();
  			EnableMenuItems(false);
 @@ -495,6 +504,17 @@ recvRest:  				// Since this is a different thread, simulate the click on the cancel button instead
  				SendMessage(m_hwndJabberChangePassword, WM_COMMAND, MAKEWORD(IDCANCEL, 0), 0);
 +			if (m_StrmMgmt.IsResumeIdPresent()) {
 +				m_StrmMgmt.HandleConnectionLost();
 +				int oldStatus = m_iStatus;
 +				m_iStatus = ID_STATUS_CONNECTING;
 +				ProtoBroadcastAck(0, ACKTYPE_STATUS, ACKRESULT_SUCCESS, (HANDLE)oldStatus, m_iStatus);
 +				return false;
 +			}
 +
 +			m_iqManager.ExpireAll();
 +			m_StrmMgmt.ResetState(); // fully reset strm_mgmt state
 +
  			// Quit all chatrooms (will send quit message)
  			LISTFOREACH(i, this, LIST_CHATROOM)
  				if (JABBER_LIST_ITEM *item = ListGetItemPtrFromIndex(i))
 @@ -513,11 +533,8 @@ recvRest:  			// Set all contacts to offline
  			debugLogA("leaving worker thread");
 -			if (!m_StrmMgmt.IsResumeIdPresent()) {
 -				m_StrmMgmt.ResetState(); // fully reset strm_mgmt state
 -				for (auto &hContact : AccContacts())
 -					SetContactOfflineStatus(hContact);
 -			}
 +			for (auto &hContact : AccContacts())
 +				SetContactOfflineStatus(hContact);
  			mir_free(m_szJabberJID);
  			m_szJabberJID = nullptr;
 @@ -542,6 +559,7 @@ recvRest:  	info.close();
  	debugLogA("Exiting ServerThread");
 +	return true;
  }
  void CJabberProto::PerformRegistration(ThreadData *info)
 @@ -2127,10 +2145,12 @@ int ThreadData::send(TiXmlElement *node)  		node = parent->ToElement();
  	}
 -	if (proto->m_bEnableStreamMgmt)
 +	int res = send_no_strm_mgmt(node);
 +
 +	if (res > 0 && proto->m_bEnableStreamMgmt)
  		proto->m_StrmMgmt.HandleOutgoingNode(node); //TODO: is this a correct place ?, looks like some nodes does not goes here...
 -	return send_no_strm_mgmt(node);
 +	return res;
  }
  // this function required for send <r/>, <a/> and more important, for resend stuck nodes by strm_mgmt (xep-0198)
  | 
