summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorGluzskiy Alexandr <sss@sss.chaoslab.ru>2018-03-28 10:03:13 +0300
committerGluzskiy Alexandr <sss@sss.chaoslab.ru>2018-03-28 10:03:13 +0300
commit37a61502be9d19eb89efd2c8c0cbe0debe968333 (patch)
tree6e5f26386831d6f45f99ae35ded6e2b7a39d21e5
parent5e65ecbf7c7e008ac23adc0f29bc000f7fd27019 (diff)
prootcols: jabber: xep-0198
- send ack on disconnect as suggested by xep - bugfixes (outgoing messages tracking still does not work properly)
-rwxr-xr-xprotocols/JabberG/src/jabber_proto.cpp2
-rwxr-xr-xprotocols/JabberG/src/jabber_strm_mgmt.cpp82
-rwxr-xr-xprotocols/JabberG/src/jabber_strm_mgmt.h1
-rwxr-xr-xprotocols/JabberG/src/jabber_thread.cpp24
-rwxr-xr-x[-rw-r--r--]protocols/JabberG/src/stdafx.h1
5 files changed, 70 insertions, 40 deletions
diff --git a/protocols/JabberG/src/jabber_proto.cpp b/protocols/JabberG/src/jabber_proto.cpp
index 84310548fe..f2c0e992d7 100755
--- a/protocols/JabberG/src/jabber_proto.cpp
+++ b/protocols/JabberG/src/jabber_proto.cpp
@@ -1134,6 +1134,8 @@ int __cdecl CJabberProto::SetStatus(int iNewStatus)
if (iNewStatus == ID_STATUS_OFFLINE) {
if (m_ThreadInfo) {
+ if(m_bEnableStreamMgmt)
+ m_StrmMgmt.SendAck();
m_ThreadInfo->send("</stream:stream>");
m_ThreadInfo->shutdown();
RebuildInfoFrame();
diff --git a/protocols/JabberG/src/jabber_strm_mgmt.cpp b/protocols/JabberG/src/jabber_strm_mgmt.cpp
index 293e4783ad..aff05bf828 100755
--- a/protocols/JabberG/src/jabber_strm_mgmt.cpp
+++ b/protocols/JabberG/src/jabber_strm_mgmt.cpp
@@ -54,46 +54,54 @@ void strm_mgmt::OnProcessSMa(HXML node)
int size = m_nStrmMgmtLocalSCount - m_nStrmMgmtSrvHCount;
if (size < 0)
{
- //TODO: this should never happen, indicate server side bug
- //TODO: once our side implementation good enough abort strem in this case, noop for now
+ //TODO: this should never happen, indicates server side bug
+ //TODO: once our client side implementation good enough, abort stream in this case, noop for now
}
- else if (size > 0)
+ else if (size > 0 && !NodeCache.empty()) //TODO: NodeCache cannot be empty if size >0, it's a bug
{
- const size_t diff = NodeCache.size() - size;
- if (diff)
+ if (size <= NodeCache.size()) //TODO: size should not be larger than NodeCache.size(), another bug
{
- size_t diff_tmp = diff;
- for (auto i : NodeCache)
+ const size_t diff = NodeCache.size() - size;
+ if (diff)
{
- if (diff_tmp > 0)
+ size_t diff_tmp = diff;
+ for (auto i : NodeCache)
{
- xmlFree(i);
+ if (diff_tmp > 0)
+ {
+ xmlFree(i);
+ diff_tmp--;
+ }
+ }
+ diff_tmp = diff;
+ while (diff_tmp)
+ {
+ NodeCache.pop_front();
diff_tmp--;
}
}
- diff_tmp = diff;
- while (diff_tmp)
- {
- NodeCache.pop_front();
- diff_tmp--;
- }
}
+ std::list<HXML> tmp_list = NodeCache;
+ NodeCache.clear();
+ for (auto i : tmp_list)
+ {
+ proto->m_ThreadInfo->send_no_strm_mgmt(i); //freed by send ?
+ //xmlFree(i);
+ }
+ }
+ else
+ {
for (auto i : NodeCache)
- proto->m_ThreadInfo->send(i);
+ xmlFree(i);
+ NodeCache.clear();
}
- NodeCache.clear();
}
}
void strm_mgmt::OnProcessSMr(HXML node)
{
if (!mir_wstrcmp(XmlGetAttrValue(node, L"xmlns"), L"urn:xmpp:sm:3"))
- {
- XmlNode enable_sm(L"a");
- XmlAddAttr(enable_sm, L"xmlns", L"urn:xmpp:sm:3");
- xmlAddAttrInt(enable_sm, L"h", m_nStrmMgmtLocalHCount);
- proto->m_ThreadInfo->send(enable_sm);
- }
+ SendAck();
}
void strm_mgmt::OnProcessFailed(HXML node, ThreadData * /*info*/) //used failed instead of failure, notes: https://xmpp.org/extensions/xep-0198.html#errors
@@ -129,16 +137,13 @@ void strm_mgmt::HandleOutgoingNode(HXML node)
{
if (!m_bStrmMgmtEnabled)
return;
- auto name = XmlGetName(node);
- if (mir_wstrcmp(name, L"a") && mir_wstrcmp(name, L"r"))
+ m_nStrmMgmtLocalSCount++;
+ NodeCache.push_back(xmlCopyNode(node));
+ if ((m_nStrmMgmtLocalSCount - m_nStrmMgmtSrvHCount) >= m_nStrmMgmtCacheSize)
{
- m_nStrmMgmtLocalSCount++;
- if ((m_nStrmMgmtLocalSCount - m_nStrmMgmtSrvHCount) >= m_nStrmMgmtCacheSize)
- {
- XmlNode enable_sm(L"r");
- XmlAddAttr(enable_sm, L"xmlns", L"urn:xmpp:sm:3");
- proto->m_ThreadInfo->send(enable_sm);
- }
+ XmlNode enable_sm(L"r");
+ XmlAddAttr(enable_sm, L"xmlns", L"urn:xmpp:sm:3");
+ proto->m_ThreadInfo->send_no_strm_mgmt(enable_sm);
}
}
@@ -155,10 +160,7 @@ void strm_mgmt::OnDisconnect()
void strm_mgmt::HandleIncommingNode(HXML node)
{
if (m_bStrmMgmtEnabled && mir_wstrcmp(XmlGetName(node), L"r") && mir_wstrcmp(XmlGetName(node), L"a")) //TODO: something better
- {
- NodeCache.push_back(xmlCopyNode(node));
m_nStrmMgmtLocalHCount++;
- }
else if (!mir_wstrcmp(XmlGetName(node), L"r"))
OnProcessSMr(node);
else if (!mir_wstrcmp(XmlGetName(node), L"a"))
@@ -172,4 +174,14 @@ void strm_mgmt::EnableStrmMgmt()
XmlAddAttr(enable_sm, L"resume", L"true"); //enable resumption (most useful part of this xep)
proto->m_ThreadInfo->send(enable_sm);
m_nStrmMgmtLocalSCount = 1; //TODO: this MUST be 0, i have bug somewhere.
+}
+
+void strm_mgmt::SendAck()
+{
+ if (!m_bStrmMgmtEnabled)
+ return;
+ XmlNode enable_sm(L"a");
+ XmlAddAttr(enable_sm, L"xmlns", L"urn:xmpp:sm:3");
+ xmlAddAttrInt(enable_sm, L"h", m_nStrmMgmtLocalHCount);
+ proto->m_ThreadInfo->send_no_strm_mgmt(enable_sm);
} \ No newline at end of file
diff --git a/protocols/JabberG/src/jabber_strm_mgmt.h b/protocols/JabberG/src/jabber_strm_mgmt.h
index 178727e2c0..2bb770df77 100755
--- a/protocols/JabberG/src/jabber_strm_mgmt.h
+++ b/protocols/JabberG/src/jabber_strm_mgmt.h
@@ -50,6 +50,7 @@ public:
void CheckStreamFeatures(HXML node);
void CheckState();
void OnDisconnect();
+ void SendAck();
};
#endif //JABBER_STRM_MGMT_H \ No newline at end of file
diff --git a/protocols/JabberG/src/jabber_thread.cpp b/protocols/JabberG/src/jabber_thread.cpp
index aee0373064..d79a2d72e0 100755
--- a/protocols/JabberG/src/jabber_thread.cpp
+++ b/protocols/JabberG/src/jabber_thread.cpp
@@ -128,6 +128,8 @@ void CJabberProto::OnPingReply(HXML, CJabberIqInfo *pInfo)
return;
if (pInfo->GetIqType() == JABBER_IQ_TYPE_FAIL) {
// disconnect because of timeout
+ if (m_bEnableStreamMgmt)
+ m_StrmMgmt.SendAck();
m_ThreadInfo->send("</stream:stream>");
m_ThreadInfo->shutdown();
}
@@ -820,6 +822,8 @@ void CJabberProto::OnProcessError(HXML node, ThreadData *info)
if (!skipMsg)
MsgPopup(0, buff, TranslateT("Jabber Error"));
+ if (m_bEnableStreamMgmt) //TODO: check if needed/work here
+ m_StrmMgmt.SendAck();
info->send("</stream:stream>");
}
@@ -2113,6 +2117,18 @@ int ThreadData::send(HXML node)
while (HXML parent = xmlGetParent(node))
node = parent;
+ int result = send_no_strm_mgmt(node);
+
+ if (proto->m_bEnableStreamMgmt)
+ proto->m_StrmMgmt.HandleOutgoingNode(node); //TODO: is this a correct place ?, looks like some nodes does not goes here...
+
+ return result;
+}
+
+// this function required for send <r/>, <a/> and more important, for resend stuck nodes by strm_mgmt (xep-0198)
+int ThreadData::send_no_strm_mgmt(HXML node)
+{
+
if (proto->m_sendManager.HandleSendPermanent(node, this))
return 0;
@@ -2132,12 +2148,10 @@ int ThreadData::send(HXML node)
}
*q = 0;
-
T2Utf utfStr(str);
int result = send(utfStr, (int)mir_strlen(utfStr));
-
xmlFree(str);
- if (proto->m_bEnableStreamMgmt)
- proto->m_StrmMgmt.HandleOutgoingNode(node); //TODO: is this a correct place ?
+
return result;
-}
+
+} \ No newline at end of file
diff --git a/protocols/JabberG/src/stdafx.h b/protocols/JabberG/src/stdafx.h
index ca39578fe3..41e02d9b85 100644..100755
--- a/protocols/JabberG/src/stdafx.h
+++ b/protocols/JabberG/src/stdafx.h
@@ -403,6 +403,7 @@ struct ThreadData
int recv(char* buf, size_t len);
int send(char* buffer, int bufsize = -1);
int send(HXML node);
+ int send_no_strm_mgmt(HXML node);
int recvws(char* buffer, size_t bufsize, int flags);
int sendws(char* buffer, size_t bufsize, int flags);