1
0
mirror of https://github.com/unrealircd/unrealircd.git synced 2026-06-12 17:14:46 +02:00

* Server to server lines can now be 16384 bytes in size when

`PROTOCTL BIGLINES` is set. This will allow us to do things more
  efficiently and possibly raise some other limits in the future.
  This 16k is the size of the complete line, including sender,
  message tags, content and \r\n. Also, in server-to-server traffic
  we now allow 30 parameters (MAXPARA*2).
  The original input size limits for non-servers remain the same: the
  complete line can be 4k+512, with the non-mtag portion limit set
  at 512 bytes (including \r\n), and MAXPARA is still 15 as well.
* I chose 16k because I don't want to first raise it to like 8k
  and then realize later that 16k would be better and raise it again.
* To receive BIGLINES in a command, you need to `CommandAdd()` with
  flags `CMD_BIGLINES`, without it you still get regular 512 max.
  This is so, because a lot of the code does not expect longer than
  512 bytes lines or in parameters, so we can gradually change that
  (where needed).
This commit is contained in:
Bram Matthys
2023-05-28 15:01:10 +02:00
parent 5e64991296
commit 2fcb5b4669
8 changed files with 96 additions and 19 deletions
+16
View File
@@ -107,6 +107,22 @@ in progress and may not be a stable version.
* The [`require module` block](https://www.unrealircd.org/docs/Require_module_block)
was only checked of one side of the link, thus partially not working.
### Developers and protocol:
* Server to server lines can now be 16384 bytes in size when
`PROTOCTL BIGLINES` is set. This will allow us to do things more
efficiently and possibly raise some other limits in the future.
This 16k is the size of the complete line, including sender,
message tags, content and \r\n. Also, in server-to-server traffic
we now allow 30 parameters (MAXPARA*2).
The original input size limits for non-servers remain the same: the
complete line can be 4k+512, with the non-mtag portion limit set
at 512 bytes (including \r\n), and MAXPARA is still 15 as well.
* To receive BIGLINES in a command, you need to `CommandAdd()` with
flags `CMD_BIGLINES`, without it you still get regular 512 max.
This is so, because a lot of the code does not expect longer than
512 bytes lines or in parameters, so we can gradually change that
(where needed).
UnrealIRCd 6.1.0
-----------------
This is UnrealIRCd 6.1.0 stable. It is the direct successor to 6.0.7, there
+1 -3
View File
@@ -33,8 +33,6 @@
* before Dreamforge aren't safe with more than six. -Donwulff
*/
#include "msg.h"
#define MAXMODEPARAMS (MAXPARA-3) /* Maximum modes processed */
#define RESYNCMODES 12 /* Max modes per MODE in resync */
#define MODEPARAMS 6 /* Max modes from user */
#define MAXMODEPARAMS (MAXPARA_USER-3) /* Maximum modes processed */
#endif
+2 -1
View File
@@ -167,6 +167,7 @@
#define MSG_MLOCK "MLOCK"
#define MAXPARA 15
#define MAXPARA 30
#define MAXPARA_USER 15
#endif
+8 -2
View File
@@ -183,8 +183,9 @@ typedef OperPermission (*OperClassEntryEvalCallback)(OperClassACLEntryVar* varia
#define LINKLEN 32
#define BUFSIZE 512 /* WARNING: *DONT* CHANGE THIS!!!! */
#define MAXTAGSIZE 8192 /**< Maximum length of message tags (4K user + 4K server) */
#define MAXLINELENGTH (MAXTAGSIZE+BUFSIZE) /**< Maximum length of a line on IRC: 4k client tags + 4k server tags + 512 bytes (IRCv3) */
#define READBUFSIZE MAXLINELENGTH /* for the read buffer */
#define MAXLINELENGTH_USER (MAXTAGSIZE+BUFSIZE) /**< Maximum length of a line on IRC (for non-servers): 4k client tags + 4k server tags + 512 bytes (IRCv3) */
#define MAXLINELENGTH 16384 /**< Maximum length of a line on IRC: from servers is 16k */
#define READBUFSIZE MAXLINELENGTH /**< for the read buffer */
#define MAXRECIPIENTS 20
#define MAXSILELENGTH NICKLEN+USERLEN+HOSTLEN+10
#define IDLEN 12
@@ -449,6 +450,7 @@ typedef enum ClientStatus {
#define PROTO_SJSBY 0x000020 /* SJOIN setby information (TS and nick) */
#define PROTO_MTAGS 0x000040 /* Support message tags and big buffers */
#define PROTO_NEXTBANS 0x000080 /* Server supports named extended bans */
#define PROTO_BIGLINES 0x000100 /* BIGLINES support */
/* For client capabilities: */
#define CAP_INVERT 1L
@@ -614,6 +616,7 @@ typedef enum ClientStatus {
#define SupportCLK(x) (CHECKSERVERPROTO(x, PROTO_CLK))
#define SupportMTAGS(x) (CHECKSERVERPROTO(x, PROTO_MTAGS))
#define SupportNEXTBANS(x) (CHECKSERVERPROTO(x, PROTO_NEXTBANS))
#define SupportBIGLINES(x) (CHECKSERVERPROTO(x, PROTO_BIGLINES))
#define SetVL(x) ((x)->local->proto |= PROTO_VL)
#define SetSJSBY(x) ((x)->local->proto |= PROTO_SJSBY)
@@ -621,6 +624,7 @@ typedef enum ClientStatus {
#define SetCLK(x) ((x)->local->proto |= PROTO_CLK)
#define SetMTAGS(x) ((x)->local->proto |= PROTO_MTAGS)
#define SetNEXTBANS(x) ((x)->local->proto |= PROTO_NEXTBANS)
#define SetBIGLINES(x) ((x)->local->proto |= PROTO_BIGLINES)
/* Dcc deny types (see src/s_extra.c) */
#define DCCDENY_HARD 0
@@ -917,6 +921,8 @@ struct SWhois {
#define CMD_OPER 0x0200
/** Command is for control channel only (unrealircd.ctl socket) */
#define CMD_CONTROL 0x0400
/** Command is able to receive BIG lines */
#define CMD_BIGLINES 0x0800
/** Command function - used by all command handlers.
* This is used in the code like <pre>CMD_FUNC(cmd_yourcmd)</pre> as a function definition.
+4
View File
@@ -122,6 +122,10 @@ CMD_FUNC(cmd_protoctl)
{
SetNEXTBANS(client);
}
else if (!strcmp(name, "BIGLINES"))
{
SetBIGLINES(client);
}
else if (!strcmp(name, "NICKCHARS") && value)
{
if (!IsServer(client) && !IsEAuth(client) && !IsHandshake(client))
+37 -7
View File
@@ -251,12 +251,13 @@ void parse(Client *cptr, char *buffer, int length)
* the message has a sender, eg :xyz PRIVMSG ..
* @param mtags Message tags received for this message.
* @param mtags_bytes The length of all message tags.
* @param ch The incoming line received (buffer), excluding message tags.
* @param line The incoming line received (buffer), excluding message tags.
*/
static void parse2(Client *cptr, Client **fromptr, MessageTag *mtags, int mtags_bytes, char *ch)
static void parse2(Client *cptr, Client **fromptr, MessageTag *mtags, int mtags_bytes, char *line)
{
Client *from = cptr;
char *s;
char *ch = line;
int len, i, numeric = 0, paramcount;
#ifdef DEBUGMODE
time_t then, ticks;
@@ -267,14 +268,14 @@ static void parse2(Client *cptr, Client **fromptr, MessageTag *mtags, int mtags_
*fromptr = cptr; /* The default, unless a source is specified (and permitted) */
/* The remaining part should never be more than 510 bytes
* (that is 512 minus CR LF, as specified in RFC1459 section 2.3).
/* In client-to-server traffic, the remaining part should
* never be more than 510 bytes (that is 512 minus CR LF,
* as specified in RFC1459 section 2.3).
* If it is too long, then we cut it off here.
* Note that there is a second check later for the IsServer() case.
*/
if (strlen(ch) > 510)
{
if (!IsServer(cptr) && (strlen(ch) > 510))
ch[510] = '\0';
}
para[0] = (char *)DEADBEEF_ADDR; /* helps us catch bugs :) */
@@ -355,6 +356,20 @@ static void parse2(Client *cptr, Client **fromptr, MessageTag *mtags, int mtags_
s = strchr(ch, ' '); /* s -> End of the command code */
len = (s) ? (s - ch) : 0;
/* An early "guard": check for oversized command name
* (not parameters, the actual command name being 512+ chars),
* just in case... especially for BIGLINES.
*/
if (len > 512)
{
ch[510] = '\0';
sendto_one(from, NULL, ":%s %d %s %s :Unknown command",
me.name, ERR_UNKNOWNCOMMAND,
from->name, ch);
ircstats.is_unco++;
return;
}
if (len == 3 && isdigit(*ch) && isdigit(*(ch + 1)) && isdigit(*(ch + 2)))
{
/* Numeric (eg: 311) */
@@ -462,11 +477,26 @@ static void parse2(Client *cptr, Client **fromptr, MessageTag *mtags, int mtags_
** (about same effect as ":" has...) --msa
*/
/* The high MAXPARA is only for servers, so readjust here for clients... */
if (!IsServer(from) && (paramcount > MAXPARA_USER))
paramcount = MAXPARA_USER;
/* Note initially true: s==NULL || *(s-1) == '\0' !! */
i = 0;
if (s)
{
if (IsServer(cptr) && (!cmptr || !(cmptr->flags & CMD_BIGLINES)))
{
int slen = strlen(s);
if ((s-line)+slen > 510)
{
ch[510] = '\0'; /* same as check at beginning of this function */
if (slen > 510)
s[510] = '\0'; /* just in case the earlier cut was like mid-sender instead of in parameters */
}
}
/*
if (paramcount > MAXPARA)
paramcount = MAXPARA;
+27 -5
View File
@@ -253,11 +253,33 @@ static int sendbufto_one_prepare_line(Client *to, char *msg)
len = strlen(p);
if (!len || (p[len - 1] != '\n'))
{
if (len > 510)
len = 510;
p[len++] = '\r';
p[len++] = '\n';
p[len] = '\0';
if (!IsServer(to) || !SupportBIGLINES(to->direction))
{
/* Normal case */
if (len > 510)
len = 510;
p[len++] = '\r';
p[len++] = '\n';
p[len] = '\0';
} else {
/* BIGLINES case:
* - first 'if' is about the total line length,
* this is basically an optimized strlen(msg)
* - the 'else' applies to non-mtags part,
* like in the 'Normal case' from above.
*/
if ((p - msg) + len > MAXLINELENGTH-3)
{
len = MAXLINELENGTH-3;
msg[len++] = '\r';
msg[len++] = '\n';
msg[len] = '\0';
} else {
p[len++] = '\r';
p[len++] = '\n';
p[len] = '\0';
}
}
}
/* Return length, that is:
+1 -1
View File
@@ -264,7 +264,7 @@ void send_proto(Client *client, ConfigItem_link *aconf)
me.id, (long long)TStime());
/* Third line */
sendto_one(client, NULL, "PROTOCTL NICKCHARS=%s CHANNELCHARS=%s",
sendto_one(client, NULL, "PROTOCTL NICKCHARS=%s CHANNELCHARS=%s BIGLINES",
charsys_get_current_languages(),
allowed_channelchars_valtostr(iConf.allowed_channelchars));
}