Skip to content
Open
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
2 changes: 2 additions & 0 deletions doc/example.conf
Original file line number Diff line number Diff line change
Expand Up @@ -921,6 +921,8 @@ features
# "CAP_ECHOMESSAGE" = "TRUE";
# "CAP_EXTJOIN" = "TRUE";
# "CAP_INVITENOTIFY" = "TRUE";
# "CAP_ACCOUNT_TAG" = "TRUE";
# "CAP_SERVER_TIME" = "TRUE";
# These were introduced by Undernet CFV-165 to add "Head-In-Sand" (HIS)
# behavior to hide most network topology from users.
# "HIS_SNOTICES" = "TRUE";
Expand Down
79 changes: 79 additions & 0 deletions include/batch.h
Original file line number Diff line number Diff line change
@@ -0,0 +1,79 @@
#ifndef INCLUDED_batch_h
#define INCLUDED_batch_h
/*
* IRC - Internet Relay Chat, include/batch.h
* Copyright (C) 2024
*
* This program is free software; you can redistribute it and/or modify
* it under the terms of the GNU General Public License as published by
* the Free Software Foundation; either version 1, or (at your option)
* any later version.
*
* This program is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
* GNU General Public License for more details.
*
* You should have received a copy of the GNU General Public License
* along with this program; if not, write to the Free Software
* Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
*/
/** @file
* @brief IRCv3 batch capability support
* @version $Id$
*/

#ifndef INCLUDED_client_h
#include "client.h"
#endif

/* Batch types - stored as enum for efficiency */
enum BatchType {
BATCH_TYPE_NETSPLIT = 0,
BATCH_TYPE_NETJOIN,
BATCH_TYPE_MAX
};

/* Generate unique batch ID */
char *batch_generate_id(void);

/* Register batch metadata (type and param) for a batch_id.
* This must be called before sending any messages with this batch_id.
* @param[in] batch_id Batch ID to register.
* @param[in] type Batch type.
* @param[in] param Batch parameter (can be NULL).
*/
void batch_register(const char *batch_id, enum BatchType type, const char *param);

/* Unregister batch metadata when batch is complete.
* @param[in] batch_id Batch ID to unregister.
*/
void batch_unregister(const char *batch_id);

/* Get batch metadata for a batch_id (internal use by send_tags).
* @param[in] batch_id Batch ID to look up.
* @param[out] type Batch type (if found).
* @param[out] param Batch parameter (if found, can be NULL).
* @return 1 if found, 0 if not found.
*/
int batch_get_meta(const char *batch_id, enum BatchType *type, const char **param);

/* Send batch start to a client */
void batch_send_start(struct Client *cptr, enum BatchType type,
const char *param, const char *batch_id);

/* Send batch end to a client */
void batch_send_end(struct Client *cptr, const char *batch_id);

/* Complete batch cleanup: send batch end to all affected clients, unregister, and free batch_id.
* @param[in] batch_id Batch ID to complete (will be freed by this function).
*/
void batch_complete(char *batch_id);

/* Remove a client from all batch lists (called on client exit).
* @param[in] cptr Client being removed.
*/
void batch_remove_client(struct Client *cptr);

#endif /* INCLUDED_batch_h */

5 changes: 4 additions & 1 deletion include/capab.h
Original file line number Diff line number Diff line change
Expand Up @@ -39,10 +39,13 @@
#define CAPLIST \
_CAP(ACCOUNTNOTIFY, FEAT_CAP_ACCOUNTNOTIFY, 0, "account-notify"), \
_CAP(AWAYNOTIFY, FEAT_CAP_AWAYNOTIFY, 0 , "away-notify"), \
_CAP(BATCH, FEAT_CAP_BATCH, 0, "batch"), \
_CAP(CHGHOST, FEAT_CAP_CHGHOST, 0, "chghost"), \
_CAP(ECHOMESSAGE, FEAT_CAP_ECHOMESSAGE, 0, "echo-message"), \
_CAP(EXTJOIN, FEAT_CAP_EXTJOIN, 0, "extended-join"), \
_CAP(INVITENOTIFY, FEAT_CAP_INVITENOTIFY, 0, "invite-notify")
_CAP(INVITENOTIFY, FEAT_CAP_INVITENOTIFY, 0, "invite-notify"), \
_CAP(ACCOUNT_TAG, FEAT_CAP_ACCOUNT_TAG, 0, "account-tag"), \
_CAP(SERVER_TIME, FEAT_CAP_SERVER_TIME, 0, "server-time")

/** Client capabilities, counting by index. */
enum Capab {
Expand Down
5 changes: 5 additions & 0 deletions include/ircd_defs.h
Original file line number Diff line number Diff line change
Expand Up @@ -87,6 +87,11 @@
/** Maximum length for away messages.
*/
#define AWAYLEN 160

/** Maximum length for a batch ID.
*/
#define BATCHLEN 20

/** Exactly long enough to hold one protocol message (RFC 1459)
* including the line termination (\\r\\n). DO NOT CHANGE THIS!!!!
*/
Expand Down
3 changes: 3 additions & 0 deletions include/ircd_features.h
Original file line number Diff line number Diff line change
Expand Up @@ -106,10 +106,13 @@ enum Feature {
/* IRCv3 capabilities */
FEAT_CAP_ACCOUNTNOTIFY,
FEAT_CAP_AWAYNOTIFY,
FEAT_CAP_BATCH,
FEAT_CAP_CHGHOST,
FEAT_CAP_ECHOMESSAGE,
FEAT_CAP_EXTJOIN,
FEAT_CAP_INVITENOTIFY,
FEAT_CAP_ACCOUNT_TAG,
FEAT_CAP_SERVER_TIME,

/* HEAD_IN_SAND Features */
FEAT_HIS_SNOTICES,
Expand Down
7 changes: 7 additions & 0 deletions include/msg.h
Original file line number Diff line number Diff line change
Expand Up @@ -364,6 +364,13 @@ struct Client;
#define TOK_CAP "CAP"
#define CMD_CAP MSG_CAP, TOK_CAP

#ifdef MSG_BATCH
#undef MSG_BATCH
#endif
#define MSG_BATCH "BATCH" /* BATCH */
#define TOK_BATCH "BATCH"
#define CMD_BATCH MSG_BATCH, TOK_BATCH

#define MSG_XQUERY "XQUERY"
#define TOK_XQUERY "XQ"
#define CMD_XQUERY MSG_XQUERY, TOK_XQUERY
Expand Down
70 changes: 70 additions & 0 deletions include/msg_tag.h
Original file line number Diff line number Diff line change
@@ -0,0 +1,70 @@
#ifndef INCLUDED_msg_tag_h
#define INCLUDED_msg_tag_h
/*
* IRC - Internet Relay Chat, include/msg_tag.h
* Copyright (C) 2024
*
* This program is free software; you can redistribute it and/or modify
* it under the terms of the GNU General Public License as published by
* the Free Software Foundation; either version 1, or (at your option)
* any later version.
*
* This program is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
* GNU General Public License for more details.
*
* You should have received a copy of the GNU General Public License
* along with this program; if not, write to the Free Software
* Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
*/
/** @file
* @brief IRCv3 message tag support
* @version $Id$
*/

struct Client;

/** A single message tag (key-value pair). */
struct MsgTag {
struct MsgTag *next; /**< Next tag in the list. */
const char *key; /**< Tag key (e.g., "batch", "account"). */
const char *value; /**< Tag value (e.g., batch ID, account name). */
};

/** Build a tag list with a batch tag.
* @param[in] batch_id Batch ID to add (can be NULL).
* @return Head of tag list, or NULL if batch_id is NULL.
*/
struct MsgTag *msg_tag_build_batch(const char *batch_id);

/** Add a tag to an existing tag list.
* @param[in,out] head Head of tag list (may be NULL).
* @param[in] key Tag key (must not be NULL).
* @param[in] value Tag value (can be NULL for tags without values).
* @return New head of tag list.
*/
struct MsgTag *msg_tag_add(struct MsgTag *head, const char *key, const char *value);

/** Add an account tag to an existing tag list if the client has an account.
* @param[in,out] head Head of tag list (may be NULL).
* @param[in] from Client to get account from (can be NULL).
* @return New head of tag list (unchanged if no account).
*/
struct MsgTag *msg_tag_add_account(struct MsgTag *head, struct Client *from);

/** Build a tag list from a client (for account tag) and batch ID.
* This is a convenience function that combines account and batch tags.
* @param[in] from Client to get account from (can be NULL).
* @param[in] batch_id Batch ID to add (can be NULL).
* @return Head of tag list, or NULL if no tags needed.
*/
struct MsgTag *msg_tag_build(struct Client *from, const char *batch_id);

/** Free a tag list.
* @param[in] head Head of tag list to free.
*/
void msg_tag_free(struct MsgTag *head);

#endif /* INCLUDED_msg_tag_h */

2 changes: 2 additions & 0 deletions include/msgq.h
Original file line number Diff line number Diff line change
Expand Up @@ -77,6 +77,8 @@ extern int msgq_mapiov(const struct MsgQ *mq, struct iovec *iov, int count,
extern struct MsgBuf *msgq_make(struct Client *dest, const char *format, ...);
extern struct MsgBuf *msgq_vmake(struct Client *dest, const char *format,
va_list args);
extern struct MsgBuf *msgq_tags(struct Client *dest, const char *tags_info);

extern void msgq_append(struct Client *dest, struct MsgBuf *mb,
const char *format, ...);
extern void msgq_clean(struct MsgBuf *mb);
Expand Down
1 change: 1 addition & 0 deletions include/s_misc.h
Original file line number Diff line number Diff line change
Expand Up @@ -98,6 +98,7 @@ extern int exit_client_msg(struct Client *cptr, struct Client *bcptr,
struct Client *sptr, const char *pattern, ...);
extern void initstats(void);
extern char *date(time_t clock);
extern char *iso8601_timestamp(char *buffer, size_t buffer_size);
extern int vexit_client_msg(struct Client *cptr, struct Client *bcptr,
struct Client *sptr, const char *pattern, va_list vl);
extern void tstats(struct Client *cptr, const struct StatDesc *sd,
Expand Down
10 changes: 7 additions & 3 deletions include/send.h
Original file line number Diff line number Diff line change
Expand Up @@ -21,13 +21,14 @@ struct Channel;
struct Client;
struct DBuf;
struct MsgBuf;
struct MsgTag;

/*
* Prototypes
*/
extern struct SLink *opsarray[];

extern void send_buffer(struct Client* to, struct MsgBuf* buf, int prio);
extern void send_buffer(struct Client* to, struct MsgBuf* buf, int prio, struct MsgTag *tags);

extern void kill_highest_sendq(int servers_too);
extern void flush_connections(struct Client* cptr);
Expand Down Expand Up @@ -64,6 +65,7 @@ extern void sendcmdto_common_channels_butone(struct Client *from,
const char *cmd,
const char *tok,
struct Client *one,
struct MsgTag *tags,
const char *pattern, ...);

/* Send command to all channels user is on matching or not matching a capability flag */
Expand All @@ -80,6 +82,7 @@ void sendcmdto_capflag_channel_butserv_butone(struct Client *from, const char *c
const char *tok, struct Channel *to,
struct Client *one, unsigned int skip,
capset_t require, capset_t forbid,
struct MsgTag *tags,
const char *pattern, ...);

/* Send command to all channel users on this server */
Expand All @@ -88,7 +91,7 @@ extern void sendcmdto_channel_butserv_butone(struct Client *from,
const char *tok,
struct Channel *to,
struct Client *one,
unsigned int skip,
unsigned int skip,
const char *pattern, ...);

/* Send command to all servers interested in a channel */
Expand All @@ -111,7 +114,8 @@ extern void sendcmdto_channel_butone(struct Client *from, const char *cmd,
extern void sendjointo_channel_butserv(struct Client *from,
struct Channel *chptr,
capset_t require,
capset_t forbid);
capset_t forbid,
struct MsgTag *tags);

/* Send JOIN to a single user */
extern void sendjointo_one(struct Client *from,
Expand Down
1 change: 1 addition & 0 deletions include/struct.h
Original file line number Diff line number Diff line change
Expand Up @@ -65,6 +65,7 @@ struct Server {

char *last_error_msg; /**< Allocated memory with last message receive with an ERROR */
char by[NICKLEN + 1]; /**< Numnick of client who requested the link */
char *batch_id; /**< Batch ID for IRCv3 batching (NULL if none) */
};

/** Describes a user on the network. */
Expand Down
2 changes: 2 additions & 0 deletions ircd/Makefile.in
Original file line number Diff line number Diff line change
Expand Up @@ -86,7 +86,9 @@ UMKPASSWD_SRC = ${CRYPTO_SRC} \

IRCD_SRC = \
IPcheck.c \
batch.c \
channel.c \
msg_tag.c \
class.c \
client.c \
crule.c \
Expand Down
Loading