Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

MVP for message tags #355

Draft
wants to merge 13 commits into
base: main
Choose a base branch
from
46 changes: 46 additions & 0 deletions include/client_tags.h
Original file line number Diff line number Diff line change
@@ -0,0 +1,46 @@
/*
* Solanum: a slightly advanced ircd
* client_tags.h: client tags (message-tags)
*
* Copyright (C) 2022 Ryan Lahfa
*
* Redistribution and use in source and binary forms, with or without
* modification, are permitted provided that the following conditions are
* met:
*
* 1.Redistributions of source code must retain the above copyright notice,
* this list of conditions and the following disclaimer.
* 2.Redistributions in binary form must reproduce the above copyright
* notice, this list of conditions and the following disclaimer in the
* documentation and/or other materials provided with the distribution.
* 3.The name of the author may not be used to endorse or promote products
* derived from this software without specific prior written permission.
*
* THIS SOFTWARE IS PROVIDED BY THE AUTHOR ``AS IS'' AND ANY EXPRESS OR
* IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED
* WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
* DISCLAIMED. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY DIRECT,
* INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES
* (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR
* SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
* HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT,
* STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING
* IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
* POSSIBILITY OF SUCH DAMAGE.
*/

#ifndef INCLUDED_client_tags_h
#define INCLUDED_client_tags_h

#define MAX_CLIENT_TAGS 100
#define CLIENT_TAG_MAX_LENGTH 100

struct client_tag_support {
char name[CLIENT_TAG_MAX_LENGTH];
};

extern int add_client_tag(const char *);
extern void remove_client_tag(const char *);
extern void format_client_tags(char *, size_t, const char *, const char *);

#endif /* INCLUDED_client_tags_h */
10 changes: 10 additions & 0 deletions include/hook.h
Original file line number Diff line number Diff line change
Expand Up @@ -47,6 +47,7 @@ extern int h_outbound_msgbuf;
extern int h_rehash;
extern int h_priv_change;
extern int h_cap_change;
extern int h_client_tag_accept;

void init_hook(void);
int register_hook(const char *name);
Expand Down Expand Up @@ -156,10 +157,19 @@ typedef struct
int del;
} hook_data_cap_change;

typedef struct
{
struct Client *client;
struct MsgBuf *outgoing_msgbuf;
const struct MsgTag *incoming_tag;
bool drop;
} hook_data_client_tag_accept;

enum message_type {
MESSAGE_TYPE_NOTICE,
MESSAGE_TYPE_PRIVMSG,
MESSAGE_TYPE_PART,
MESSAGE_TYPE_TAGMSG,
MESSAGE_TYPE_COUNT
};

Expand Down
8 changes: 8 additions & 0 deletions include/msgbuf.h
Original file line number Diff line number Diff line change
Expand Up @@ -77,6 +77,12 @@ struct MsgBuf_cache {
*/
int msgbuf_parse(struct MsgBuf *msgbuf, char *line);

/*
* Parse partially a msgbuf without tags
* assuming msgbuf is already initialized.
*/
int msgbuf_partial_parse(struct MsgBuf *msgbuf, const char *line);

/*
* Unparse the tail of a msgbuf perfectly, preserving framing details
* msgbuf->para[n] will reach to the end of the line
Expand All @@ -103,6 +109,8 @@ int msgbuf_vunparse_fmt(char *buf, size_t buflen, const struct MsgBuf *head, uns
int msgbuf_unparse_linebuf_tags(char *buf, size_t buflen, void *data);
int msgbuf_unparse_prefix(char *buf, size_t *buflen, const struct MsgBuf *msgbuf, unsigned int capmask);

const char *msgbuf_get_tag(const struct MsgBuf *buf, const char *name);

void msgbuf_cache_init(struct MsgBuf_cache *cache, const struct MsgBuf *msgbuf, const rb_strf_t *message);
void msgbuf_cache_initf(struct MsgBuf_cache *cache, const struct MsgBuf *msgbuf, const rb_strf_t *message, const char *format, ...) AFP(4, 5);
buf_head_t *msgbuf_cache_get(struct MsgBuf_cache *cache, unsigned int caps);
Expand Down
3 changes: 3 additions & 0 deletions include/parse.h
Original file line number Diff line number Diff line change
Expand Up @@ -42,4 +42,7 @@ extern char *reconstruct_parv(int parc, const char *parv[]);
extern rb_dictionary *alias_dict;
extern rb_dictionary *cmd_dict;

extern const struct MsgBuf *incoming_message;
extern const struct Client *incoming_client;

#endif /* INCLUDED_parse_h_h */
2 changes: 2 additions & 0 deletions include/s_serv.h
Original file line number Diff line number Diff line change
Expand Up @@ -68,6 +68,7 @@ extern unsigned int CLICAP_USERHOST_IN_NAMES;
extern unsigned int CLICAP_CAP_NOTIFY;
extern unsigned int CLICAP_CHGHOST;
extern unsigned int CLICAP_ECHO_MESSAGE;
extern unsigned int CLICAP_MESSAGE_TAGS;

/*
* XXX: this is kind of ugly, but this allows us to have backwards
Expand All @@ -92,6 +93,7 @@ extern unsigned int CAP_EUID; /* supports EUID (ext UID + nonencap CHGHOST) */
extern unsigned int CAP_EOPMOD; /* supports EOPMOD (ext +z + ext topic) */
extern unsigned int CAP_BAN; /* supports propagated bans */
extern unsigned int CAP_MLOCK; /* supports MLOCK messages */
extern unsigned int CAP_STAG; /* supports s2s tags and labeled-response */

/* XXX: added for backwards compatibility. --nenolod */
#define CAP_MASK (capability_index_mask(serv_capindex) & ~(CAP_TS6 | CAP_CAP))
Expand Down
1 change: 1 addition & 0 deletions ircd/Makefile.am
Original file line number Diff line number Diff line change
Expand Up @@ -23,6 +23,7 @@ libircd_la_SOURCES = \
chmode.c \
class.c \
client.c \
client_tags.c \
dns.c \
extban.c \
getopt.c \
Expand Down
84 changes: 84 additions & 0 deletions ircd/client_tags.c
Original file line number Diff line number Diff line change
@@ -0,0 +1,84 @@
/*
* Solanum: a slightly advanced ircd
* client_tags.c: client tags support
*
* Copyright (C) 2022 Ryan Lahfa
*
* Redistribution and use in source and binary forms, with or without
* modification, are permitted provided that the following conditions are
* met:
*
* 1.Redistributions of source code must retain the above copyright notice,
* this list of conditions and the following disclaimer.
* 2.Redistributions in binary form must reproduce the above copyright
* notice, this list of conditions and the following disclaimer in the
* documentation and/or other materials provided with the distribution.
* 3.The name of the author may not be used to endorse or promote products
* derived from this software without specific prior written permission.
*
* THIS SOFTWARE IS PROVIDED BY THE AUTHOR ``AS IS'' AND ANY EXPRESS OR
* IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED
* WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
* DISCLAIMED. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY DIRECT,
* INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES
* (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR
* SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
* HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT,
* STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING
* IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
* POSSIBILITY OF SUCH DAMAGE.
*/

#include "stdinc.h"
#include "client_tags.h"

struct client_tag_support *supported_client_tags;
size_t num_client_tags = 0;
size_t max_client_tags = MAX_CLIENT_TAGS;

void
init_client_tags(void)
{
supported_client_tags = rb_malloc(sizeof(struct client_tag_support) * MAX_CLIENT_TAGS);
}

int
add_client_tag(const char *name)
{
if (num_client_tags >= max_client_tags)
return -1;

strcpy(supported_client_tags[num_client_tags].name, name);
num_client_tags++;

return num_client_tags - 1;
}

void
remove_client_tag(const char *name)
{
for (size_t index = 0 ; index < num_client_tags ; index++)
{
if (strcmp(supported_client_tags[index].name, name)) {
strcpy(supported_client_tags[index].name, supported_client_tags[num_client_tags - 1].name);
num_client_tags--;
break;
}
}
}

void
format_client_tags(char *dst, size_t dst_sz, const char *individual_fmt, const char *join_sep)
{
size_t start = 0;
for (size_t index = 0 ; index < num_client_tags ; index++) {
if (start >= dst_sz)
break;

if (index > 0) {
dst[start] = ',';
start++;
}
start += snprintf((dst + start), dst_sz - start, individual_fmt, supported_client_tags[index].name);
}
}
2 changes: 2 additions & 0 deletions ircd/hook.c
Original file line number Diff line number Diff line change
Expand Up @@ -73,6 +73,7 @@ int h_outbound_msgbuf;
int h_rehash;
int h_priv_change;
int h_cap_change;
int h_client_tag_accept;

void
init_hook(void)
Expand All @@ -99,6 +100,7 @@ init_hook(void)
h_rehash = register_hook("rehash");
h_priv_change = register_hook("priv_change");
h_cap_change = register_hook("cap_change");
h_client_tag_accept = register_hook("client_tag_accept");
}

/* grow_hooktable()
Expand Down
21 changes: 21 additions & 0 deletions ircd/msgbuf.c
Original file line number Diff line number Diff line change
Expand Up @@ -133,6 +133,14 @@ msgbuf_parse(struct MsgBuf *msgbuf, char *line)
return 1;
}
}

return msgbuf_partial_parse(msgbuf, ch);
}

int
msgbuf_partial_parse(struct MsgBuf *msgbuf, const char *line)
{
char *ch = strdup(line);

/* truncate message if it's too long */
if (strlen(ch) > DATALEN) {
Expand Down Expand Up @@ -404,6 +412,19 @@ msgbuf_unparse_fmt(char *buf, size_t buflen, const struct MsgBuf *head, unsigned
return res;
}

const char *
msgbuf_get_tag(const struct MsgBuf *buf, const char *name)
{
for (size_t i = 0; i < buf->n_tags; i++)
{
if (strcmp(name, buf->tags[i].key))
continue;
const char *v = buf->tags[i].value;
return v != NULL ? v : "";
}
return NULL;
}

void
msgbuf_cache_init(struct MsgBuf_cache *cache, const struct MsgBuf *msgbuf, const rb_strf_t *message)
{
Expand Down
8 changes: 8 additions & 0 deletions ircd/parse.c
Original file line number Diff line number Diff line change
Expand Up @@ -44,6 +44,9 @@
rb_dictionary *cmd_dict = NULL;
rb_dictionary *alias_dict = NULL;

const struct MsgBuf *incoming_message = NULL;
const struct Client *incoming_client = NULL;

static void cancel_clients(struct Client *, struct Client *);
static void remove_unknown(struct Client *, const char *, char *);

Expand Down Expand Up @@ -153,6 +156,9 @@ parse(struct Client *client_p, char *pbuffer, char *bufend)
return;
}

incoming_message = &msgbuf;
incoming_client = client_p;

if(handle_command(mptr, &msgbuf, client_p, from) < -1)
{
char *p;
Expand All @@ -177,6 +183,8 @@ parse(struct Client *client_p, char *pbuffer, char *bufend)
}
}

incoming_message = NULL;
incoming_client = NULL;
}

/*
Expand Down
4 changes: 4 additions & 0 deletions ircd/s_serv.c
Original file line number Diff line number Diff line change
Expand Up @@ -86,6 +86,7 @@ unsigned int CAP_EUID;
unsigned int CAP_EOPMOD;
unsigned int CAP_BAN;
unsigned int CAP_MLOCK;
unsigned int CAP_STAG;

unsigned int CLICAP_MULTI_PREFIX;
unsigned int CLICAP_ACCOUNT_NOTIFY;
Expand All @@ -95,6 +96,7 @@ unsigned int CLICAP_USERHOST_IN_NAMES;
unsigned int CLICAP_CAP_NOTIFY;
unsigned int CLICAP_CHGHOST;
unsigned int CLICAP_ECHO_MESSAGE;
unsigned int CLICAP_MESSAGE_TAGS;

/*
* initialize our builtin capability table. --nenolod
Expand Down Expand Up @@ -126,6 +128,7 @@ init_builtin_capabs(void)
CAP_EOPMOD = capability_put(serv_capindex, "EOPMOD", NULL);
CAP_BAN = capability_put(serv_capindex, "BAN", NULL);
CAP_MLOCK = capability_put(serv_capindex, "MLOCK", NULL);
CAP_STAG = capability_put(serv_capindex, "STAG", NULL);

capability_require(serv_capindex, "QS");
capability_require(serv_capindex, "EX");
Expand All @@ -142,6 +145,7 @@ init_builtin_capabs(void)
CLICAP_CAP_NOTIFY = capability_put(cli_capindex, "cap-notify", NULL);
CLICAP_CHGHOST = capability_put(cli_capindex, "chghost", &high_priority);
CLICAP_ECHO_MESSAGE = capability_put(cli_capindex, "echo-message", NULL);
CLICAP_MESSAGE_TAGS = capability_put(cli_capindex, "message-tags", NULL);
}

static CNCB serv_connect_callback;
Expand Down
Loading