[ADD] Proper stanza limits

This commit is contained in:
LDA 2024-10-25 18:03:05 +02:00
commit 7c60ab28cb
18 changed files with 74 additions and 39 deletions

View file

@ -487,7 +487,7 @@ ParseeMessageHandler(ParseeData *data, HashMap *event)
SetStanzaEdit(builder, origin_id);
SetStanzaXParsee(builder, event);
WriteoutStanza(builder, jabber);
WriteoutStanza(builder, jabber, data->config->max_stanza_size);
DestroyStanzaBuilder(builder);
if (direct)
@ -542,8 +542,7 @@ ParseeEventHandler(ParseeData *data, HashMap *event)
return;
}
else if (StrEquals(event_type, "m.room.message") ||
StrEquals(event_type, "m.sticker")) /* TODO: Actual sticker
* support here... */
StrEquals(event_type, "m.sticker"))
{
ParseeMessageHandler(data, event);
Free(parsee);

View file

@ -66,7 +66,7 @@ ParseeConfigLoad(char *conf)
if (!config->max_stanza_size)
{
/* Standard XMPP "minimum" maximum */
config->max_stanza_size = 10 KB;
config->max_stanza_size = 10000;
}
CopyToStr(media_base, "media_base");

View file

@ -228,16 +228,20 @@ ExportStanza(StanzaBuilder *builder)
}
void
WriteoutStanza(StanzaBuilder *builder, XMPPComponent *jabber)
WriteoutStanza(StanzaBuilder *builder, XMPPComponent *jabber, size_t max)
{
XMLElement *elem;
if (!builder || !jabber)
{
return;
}
if (!max)
{
max = 10000; /* XMPP recommended limit */
}
elem = ExportStanza(builder);
XMPPSendStanza(jabber, elem);
XMPPSendStanza(jabber, elem, max);
XMLFreeElement(elem);
}

View file

@ -214,17 +214,34 @@ XMPPEndCompStream(XMPPComponent *comp)
Free(comp);
}
void
XMPPSendStanza(XMPPComponent *comp, XMLElement *stanza)
XMPPSendStanza(XMPPComponent *comp, XMLElement *stanza, size_t max)
{
size_t len;
char *c = NULL;
Stream *stringWriter;
if (!comp || !stanza)
{
return;
}
stringWriter = StrStreamWriter(&c);
XMLEncode(stringWriter, stanza);
StreamFlush(stringWriter);
StreamClose(stringWriter);
if (c && max && (len = strlen(c)) > max)
{
Log(LOG_WARNING,
"Unexceptedly large stanza received (len=%d max=%d).",
(int) len, (int) max
);
Free(c);
return;
}
pthread_mutex_lock(&comp->write_lock);
/* TODO: Find a way to negociate to the server about stanza size
* (beyond the 10KB limit that is REQUIRED by XMPP standards) */
XMLEncode(comp->stream, stanza);
StreamPrintf(comp->stream, c);
StreamFlush(comp->stream);
pthread_mutex_unlock(&comp->write_lock);
Free(c);
}

View file

@ -33,7 +33,7 @@ XMPPQueryMUC(XMPPComponent *jabber, char *muc, MUCInfo *out)
{
XMLElement *identity;
XMPPSendStanza(jabber, iq_query);
XMPPSendStanza(jabber, iq_query, 10000);
XMLFreeElement(iq_query);
/* Except an IQ reply. 10 seconds of timeout is pretty
@ -153,7 +153,7 @@ XMPPRequestVoice(XMPPComponent *jabber, char *from, char *muc)
}
XMLAddChild(stanza, x);
}
XMPPSendStanza(jabber, stanza);
XMPPSendStanza(jabber, stanza, 10000);
XMLFreeElement(stanza);
Free(identifier);
@ -201,7 +201,7 @@ XMPPJoinMUC(XMPPComponent *comp, char *fr, char *muc, char *hash, int time, bool
XMLAddChild(presence, x);
}
XMPPSendStanza(comp, presence);
XMPPSendStanza(comp, presence, 10000);
XMLFreeElement(presence);
Free(from);
@ -248,7 +248,7 @@ XMPPLeaveMUC(XMPPComponent *comp, char *fr, char *muc, char *reason)
XMPPAnnotatePresence(presence);
XMPPSendStanza(comp, presence);
XMPPSendStanza(comp, presence, 10000);
XMLFreeElement(presence);
Free(from);

View file

@ -66,7 +66,7 @@ XMPPRetract(XMPPComponent *comp, char *fr, char *to, char *type, char *redact)
}
XMPPSendStanza(comp, message);
XMPPSendStanza(comp, message, 10000);
XMLFreeElement(message);
Free(from);
@ -264,7 +264,7 @@ XMPPSendDisco(ParseeData *data, char *from, char *to)
XMLAddChild(iq, query);
}
XMPPSendStanza(jabber, iq);
XMPPSendStanza(jabber, iq, 10000);
XMLFreeElement(iq);
ret = ParseeAwaitStanza(identifier, 1.25 SECONDS);

View file

@ -274,7 +274,7 @@ XMPPManageCommand(XMPPCommandManager *m, XMLElement *stanza, ParseeData *data)
x = XMPPFormifyCommand(m, cmd, from);
XMLAddChild(command_xml, x);
XMPPSendStanza(jabber, iq);
XMPPSendStanza(jabber, iq, data->config->max_stanza_size);
XMLFreeElement(iq);
goto end;
@ -302,7 +302,7 @@ XMPPManageCommand(XMPPCommandManager *m, XMLElement *stanza, ParseeData *data)
XMPPExecuteCommand(m, cmd, from, command_xml, NULL);
XMLAddChild(iq, command_xml);
XMPPSendStanza(jabber, iq);
XMPPSendStanza(jabber, iq, data->config->max_stanza_size);
XMLFreeElement(iq);
InvalidateSession(m, session_id);
@ -342,7 +342,7 @@ XMPPManageCommand(XMPPCommandManager *m, XMLElement *stanza, ParseeData *data)
XMPPExecuteCommand(m, cmd, from, command_xml, x_form);
XMLAddChild(iq, command_xml);
XMPPSendStanza(jabber, iq);
XMPPSendStanza(jabber, iq, data->config->max_stanza_size);
XMLFreeElement(iq);
InvalidateSession(m, session_given);

View file

@ -72,7 +72,7 @@ PEPAvatarEvent(PEPManager *m, XMLElement *stanza, XMLElement *item)
char *url = HashMapGet(item->attrs, "url");
XMLElement *request = CreateAvatarRequest(from, to, id);
XMPPSendStanza(jabber, request);
XMPPSendStanza(jabber, request, args->config->max_stanza_size);
XMLFreeElement(request);
(void) url; /* TODO */

View file

@ -113,7 +113,7 @@ PEPVCardEvent(PEPManager *m, XMLElement *stanza, XMLElement *item)
}
}
XMPPSendStanza(jabber, reply);
XMPPSendStanza(jabber, reply, data->config->max_stanza_size);
XMLFreeElement(reply);
(void) item;
}

View file

@ -131,7 +131,7 @@ ParseeBroadcastStanza(ParseeData *data, char *from, XMLElement *stanza)
/* TODO: Should we store IDs somewhere? */
XMLAddAttr(sub, "id", (storm_id = StrRandom(16)));
XMPPSendStanza(jabber, sub);
XMPPSendStanza(jabber, sub, data->config->max_stanza_size);
XMLFreeElement(sub);
Free(storm_id);
end:

View file

@ -175,7 +175,7 @@ IQDiscoGet(ParseeData *args, XMPPComponent *jabber, XMLElement *stanza)
}
XMLAddChild(iq_reply, query);
XMPPSendStanza(jabber, iq_reply);
XMPPSendStanza(jabber, iq_reply, args->config->max_stanza_size);
XMLFreeElement(iq_reply);
(void) args;
@ -412,7 +412,7 @@ IQGet(ParseeData *args, XMLElement *stanza, XMPPThread *thr)
XMPPShoveCommandList(thr->info->m, to, q);
XMLAddChild(iq_reply, q);
}
XMPPSendStanza(jabber, iq_reply);
XMPPSendStanza(jabber, iq_reply, args->config->max_stanza_size);
XMLFreeElement(iq_reply);
}
else if (XMLookForTKV(stanza, "vCard", "xmlns", "vcard-temp"))
@ -450,7 +450,7 @@ IQGet(ParseeData *args, XMLElement *stanza, XMPPThread *thr)
XMLAddChild(iqVCard, vCard);
}
XMPPSendStanza(jabber, iqVCard);
XMPPSendStanza(jabber, iqVCard, args->config->max_stanza_size);
XMLFreeElement(iqVCard);
Free(to_matrix);
Free(name);
@ -477,7 +477,7 @@ IQGet(ParseeData *args, XMLElement *stanza, XMPPThread *thr)
XMLAddChild(iqVCard, vCard);
}
XMPPSendStanza(jabber, iqVCard);
XMPPSendStanza(jabber, iqVCard, args->config->max_stanza_size);
XMLFreeElement(iqVCard);
Free(to_matrix);
Free(name);
@ -531,7 +531,7 @@ IQGet(ParseeData *args, XMLElement *stanza, XMPPThread *thr)
XMLAddChild(reply, ps);
}
XMPPSendStanza(jabber, reply);
XMPPSendStanza(jabber, reply, args->config->max_stanza_size);
XMLFreeElement(reply);
Free(to_matrix);
@ -569,7 +569,7 @@ IQGet(ParseeData *args, XMLElement *stanza, XMPPThread *thr)
XMLAddChild(query, version);
XMLAddChild(iq_reply, query);
XMPPSendStanza(jabber, iq_reply);
XMPPSendStanza(jabber, iq_reply, args->config->max_stanza_size);
XMLFreeElement(iq_reply);
}
else

View file

@ -370,13 +370,13 @@ end_error:
ps = CreatePubsubRequest(
parsee, decode_from, "urn:xmpp:avatar:metadata"
);
XMPPSendStanza(jabber, ps);
XMPPSendStanza(jabber, ps, args->config->max_stanza_size);
XMLFreeElement(ps);
ps = CreatePubsubRequest(
parsee, trim, "urn:xmpp:avatar:metadata"
);
XMPPSendStanza(jabber, ps);
XMPPSendStanza(jabber, ps, args->config->max_stanza_size);
XMLFreeElement(ps);
if (args->verbosity >= PARSEE_VERBOSE_TIMINGS)
{

View file

@ -381,7 +381,7 @@ end_item:
from, HashMapGet(stanza->attrs, "from")
);
XMPPSendStanza(jabber, vcard_request);
XMPPSendStanza(jabber, vcard_request, args->config->max_stanza_size);
XMLFreeElement(vcard_request);
Free(from);
}

View file

@ -16,7 +16,7 @@ extern StanzaBuilder * SetStanzaID(StanzaBuilder *builder, char *id);
extern StanzaBuilder * SetStanzaXParsee(StanzaBuilder *builder, HashMap *e);
extern StanzaBuilder * AddStanzaElem(StanzaBuilder *builder, XMLElement *item);
extern XMLElement * ExportStanza(StanzaBuilder *builder);
extern void WriteoutStanza(StanzaBuilder *builder, XMPPComponent *jabber);
extern void WriteoutStanza(StanzaBuilder *builder, XMPPComponent *jabber, size_t max);
extern void DestroyStanzaBuilder(StanzaBuilder *builder);
#endif

View file

@ -30,11 +30,12 @@ extern XMPPComponent * XMPPInitialiseCompStream(char *host, int port);
extern bool XMPPAuthenticateCompStream(XMPPComponent *comp, char *shared);
/** Writes an XML stanza through a component, while making sure any locking
* work is done.
* work is done. If {max} is non-zero, then this function will not send
* stanzas beyond {max} bytes.
* -----------------------
* Modifies: {comp}, the XMPP stream
* See-Also: XMPPInitialiseCompStream, XMPPAuthenticateCompStream, XMPP-core RFC */
extern void XMPPSendStanza(XMPPComponent *comp, XMLElement *stanza);
extern void XMPPSendStanza(XMPPComponent *comp, XMLElement *stanza, size_t max);
/* Makes a user join/leave a MUC */
extern bool XMPPJoinMUC(XMPPComponent *comp, char *fr, char *muc, char *hash, int secs, bool ret);