Commit graph

223 commits

Author SHA1 Message Date
Simon Ser 68463d3e8b Pass-through the BOT ISUPPORT token
References: https://github.com/ircv3/ircv3-specifications/pull/439
2021-05-24 11:41:04 +02:00
Hubert Hirtz 3b41c87a41 Fix CAP LIST listing disabled capabilities 2021-05-21 10:03:39 +02:00
Simon Ser ec26117c08 Relay self-WHO/WHOIS in single-upstream mode
In multi-upstream mode, we can't relay WHO/WHOIS messages for the
current user, because we can't decide which upstream server the
message should be relayed to.

In single-upstream server, we do know which upstream server to use,
so we can just blindly relay the message.

This allows users to send a self-WHO/WHOIS to check their cloak and
other information.
2021-05-20 11:13:14 +02:00
Hubert Hirtz b078ccaf7a Implement CHATHISTORY BETWEEN 2021-05-18 10:44:10 +02:00
Simon Ser bede274f32 Add more context to chathistory errors 2021-05-11 12:42:12 +02:00
Hubert Hirtz 9e04b3899b Don't directly reply to network-specific NICK
The NICK must only apply to the specific network, not to the downstream
connection.
2021-04-30 12:17:23 +02:00
Hubert Hirtz e84fad3eda Handle casemapping on BouncerServ 2021-04-30 12:10:49 +02:00
Simon Ser a2c207d357 Relay detached channel backlog as BouncerServ NOTICE if necessary
Instead of ignoring detached channels wehn replaying backlog,
process them as usual and relay messages as BouncerServ NOTICEs
if necessary. Advance the delivery receipts as if the channel was
attached.

Closes: https://todo.sr.ht/~emersion/soju/98
2021-04-13 19:11:05 +02:00
Simon Ser 45e2c0023a Skip backlog logic in downstreamConn.welcome on chathistory 2021-04-13 17:50:03 +02:00
Simon Ser 65c58adbd9 Take msg ID in sendTargetBacklog 2021-04-13 17:49:37 +02:00
Simon Ser 5b4469fcb7 Use BARE for internal message IDs
This allows to have shorter and more future-proof IDs. This also
guarantees the IDs will only use reasonable ASCII characters (no
spaces), removing the need to encode them for PING/PONG tokens.
2021-03-31 17:57:24 +02:00
Simon Ser ecf35187fa Make NickServ detection casemapping-aware 2021-03-30 12:28:45 +02:00
Simon Ser 3237bde9f3 Introduce deliveredStore
This hides the double-map complexity behind a dedicated type.
2021-03-29 17:49:50 +02:00
Simon Ser 07519da768 Ensure targets are case-mapped before being passed to messageStore
messageStore isn't aware of the network's case-mapping. We need
to canonicalize the names before passing them to messageStore.
2021-03-29 17:07:39 +02:00
Simon Ser 5a899abaab Simplify network.offlineClients
Replace it with a list of all clients (online or offline).
2021-03-29 16:55:57 +02:00
Simon Ser 6e5a307dc7 Introduce deliveredClientMap
Adds more semantics to map[string]string. Simplifies the complicated
mapStringStringCasemapMap type.
2021-03-26 11:21:14 +01:00
Hubert Hirtz 5014673aae Fix CHATHISTORY target not being casemapped 2021-03-26 10:39:52 +01:00
Hubert Hirtz bdd0c7bc06
Implement casemapping
TL;DR: supports for casemapping, now logs are saved in
casemapped/canonical/tolower form
(eg. in the #channel directory instead of #Channel... or something)

== What is casemapping? ==

see <https://modern.ircdocs.horse/#casemapping-parameter>

== Casemapping and multi-upstream ==

Since each upstream does not necessarily use the same casemapping, and
since casemappings cannot coexist [0],

1. soju must also update the database accordingly to upstreams'
   casemapping, otherwise it will end up inconsistent,
2. soju must "normalize" entity names and expose only one casemapping
   that is a subset of all supported casemappings (here, ascii).

[0] On some upstreams, "emersion[m]" and "emersion{m}" refer to the same
user (upstreams that advertise rfc1459 for example), while on others
(upstreams that advertise ascii) they don't.

Once upstream's casemapping is known (default to rfc1459), entity names
in map keys are made into casemapped form, for upstreamConn,
upstreamChannel and network.

downstreamConn advertises "CASEMAPPING=ascii", and always casemap map
keys with ascii.

Some functions require the caller to casemap their argument (to avoid
needless calls to casemapping functions).

== Message forwarding and casemapping ==

downstream message handling (joins and parts basically):
When relaying entity names from downstreams to upstreams, soju uses the
upstream casemapping, in order to not get in the way of the user.  This
does not brings any issue, as long as soju replies with the ascii
casemapping in mind (solves point 1.).

marshalEntity/marshalUserPrefix:
When relaying entity names from upstreams with non-ascii casemappings,
soju *partially* casemap them: it only change the case of characters
which are not ascii letters.  ASCII case is thus kept intact, while
special symbols like []{} are the same every time soju sends them to
downstreams (solves point 2.).

== Casemapping changes ==

Casemapping changes are not fully supported by this patch and will
result in loss of history.  This is a limitation of the protocol and
should be solved by the RENAME spec.
2021-03-24 18:15:52 +01:00
Simon Ser 26c5c11caf Improve ERR_NOSUCHCHANNEL error messages
References: https://todo.sr.ht/~emersion/soju/63
2021-03-16 09:13:46 +01:00
Simon Ser fa047123b9 Passthrough some ISUPPORT tokens 2021-03-15 23:41:37 +01:00
Simon Ser 62d4bf2813 Use upstream ISUPPORT map for NETWORK 2021-03-15 23:08:19 +01:00
Hubert Hirtz 1645371276 Send correct CHATHISTORY error messages 2021-03-05 09:53:59 +01:00
Simon Ser 26473ed60d Introduce downstreamConn.sendTargetBacklog 2021-02-10 13:48:41 +01:00
Simon Ser 7e39f6d663 Rename network.history to network.delivered
"History" is over-loaded with e.g. CHATHISTORY support.
2021-02-10 11:31:34 +01:00
Simon Ser c14118f7f9 Rename sendNetworkHistory to sendNetworkBacklog
"History" is a little bit over-loaded with CHATHISTORY support.
2021-02-10 10:23:51 +01:00
Hubert Hirtz 5aa15d5628 Request invite-notify to upstreams
... and do not forward INVITEs to downstreams that do not support the
capability.

The downstream capability can be permanent because there is no way for a
client to get the list of people invited to a channel, thus no state can
be corrupted.
2021-01-31 22:18:51 +01:00
Simon Ser 62f1207437 Forward ISUPPORT NETWORK token 2021-01-22 12:00:38 +01:00
Simon Ser c4d9e6822d Send RPL_ISUPPORT CHATHISTORY token 2021-01-22 11:55:06 +01:00
Simon Ser ac3431ef76
Make chat history operations optional in messageStore
Some stores may want not to implement chat history operations.
2021-01-04 17:17:35 +01:00
Simon Ser 83a4590acc
Add store-agnostic message ID format
Allow to query the network ID and entity from the message ID regardless
of the underlying store used.
2021-01-04 16:26:30 +01:00
Hubert Hirtz 943182de2f
Improve dc.authenticate()'s error messages 2020-12-25 13:37:15 +01:00
Hubert Hirtz 7bfa4dafef
Advertise all caps, CAP DEL them on registration
... so that the JOIN/history batch takes into account all capabilities.
Without this commit for example, enabling multi-prefix after the batch
makes the client send NAMES requests for all channels, which generate
needless traffic.
2020-12-25 13:35:20 +01:00
delthas a76b22bf29 Add customizable auto-detaching, auto-reattaching, relaying.
This uses the fields added previously to the Channel struct to implement
the actual detaching/reattaching/relaying logic.

The `FilterDefault` values of the messages filters are currently
hardcoded.

The values of the message filters are not currently user-settable.

This introduces a new user event, eventChannelDetach, which stores an
upstreamConn (which might become invalid at the time of processing), and
a channel name, used for auto-detaching. Every time the channel detach
timer is refreshed (by receveing a message, etc.), a new timer is
created on the upstreamChannel, which will dispatch this event after the
duration (and discards the previous timer, if any).
2020-12-14 20:54:02 +01:00
Hubert Hirtz cab0fc2b7d
Uphold echo-message even with BouncerServ
Fixes <https://todo.sr.ht/~emersion/soju/74>
2020-11-24 14:25:19 +01:00
Simon Ser 473a0f018b
Fix nickname in ERR_ERRONEOUSNICKNAME 2020-11-24 14:22:39 +01:00
Hubert Hirtz 16c68b21b5
Prevent downstreams from changing their nick to service's
This commit prevents downstream from sending those commands:
- NICK BouncerServ
- NICK BouncerServ/<network>

The later is necessary because soju would otherwise save the nick change
and, in the event that the downstream connects in single-upstream mode
to <network>, it will end up with the nickname "BouncerServ".
2020-11-24 14:22:18 +01:00
Simon Ser e797d90c59
Implement delivery receipts via PING messages
This patch implements basic message delivery receipts via PING and PONG.

When a PRIVMSG or NOTICE message is sent, a PING message with a token is
also sent. The history cursor isn't immediately advanced, instead the
bouncer will wait for a PONG message before doing so.

Self-messages trigger a PING for simplicity's sake. We can't immediately
advance the history cursor in this case, because a prior message might
still have an outstanding PING.

Future work may include optimizations such as removing the need to send
a PING after a self-message, or groupping multiple PING messages
together.

Closes: https://todo.sr.ht/~emersion/soju/11
2020-11-24 14:13:24 +01:00
Hubert Hirtz e4d2ddb377
Don't send TAGMSG to upstreams that don't support it
TAGMSG are (in current specs and drafts from IRCv3) only used for
client tags. These are optional information by design (since they are
not distributed to all users), therefore it is preferable to discard
them accordingly to upstream, instead of waiting for all upstreams to
support the capability to advertise it.
2020-11-20 11:37:43 +01:00
Simon Ser 05aafb5edf
Add message store abstraction
Introduce a messageStore type, which will allow for multiple
implementations (e.g. in the DB or in-memory instead of on-disk).

The message store is per-user so that we don't need to deal with locking
and it's easier to implement per-user limits.
2020-10-25 17:47:38 +01:00
Simon Ser fa16337d97
Switch DB API to user IDs
This commit changes the Network schema to use user IDs instead of
usernames. While at it, a new UNIQUE(user, name) constraint ensures
there is no conflict with custom network names.

Closes: https://todo.sr.ht/~emersion/soju/86
References: https://todo.sr.ht/~emersion/soju/29
2020-10-24 15:14:23 +02:00
delthas 28cf1147e8 Add support for the extended-join capability
This simple implementation only advertises extended-join to downstreams
when all upstreams support it.

In the future, it could be modified so that soju buffers incoming
upstream JOINs, sends a WHO, waits for the reply, and sends an extended
join to the downstream; so that soju could advertise that capability
even when some or all upstreams do not support it. This is not the case
in this commit.
2020-09-11 00:10:58 +02:00
Simon Ser 480d771a67
Fix panic in downstreamConn.sendNetworkHistory
This panic happens when sending history to a multi-upstream client.
sendNetworkHistory is called on each network, but dc.network is nil.

Closes: https://todo.sr.ht/~emersion/soju/93
2020-08-26 15:28:10 +02:00
Simon Ser 43aa3e5529
Fix downstream PING argument handling
The PONG message should have these arguments:

- Our server name
- The PING message's source name

Closes: https://todo.sr.ht/~emersion/soju/92
2020-08-26 15:18:57 +02:00
Simon Ser fb8c6340c8
Allow '/' in nickname
This allows to specify a network name in the nickname.

Closes: https://todo.sr.ht/~emersion/soju/91
2020-08-25 11:49:22 +02:00
Simon Ser 92fece5cd4
Nuke in-memory ring buffer
Instead, always read chat history from logs. Unify the implicit chat
history (pushing history to clients) and explicit chat history
(via the CHATHISTORY command).

Instead of keeping track of ring buffer cursors for each client, use
message IDs.

If necessary, the ring buffer could be re-introduced behind a
common MessageStore interface (could be useful when on-disk logs are
disabled).

References: https://todo.sr.ht/~emersion/soju/80
2020-08-20 20:05:01 +02:00
Simon Ser 4dae0da59f
Replace networkHistory.offlineClients with clients
Keep the ring buffer alive even if all clients are connected. Keep the
ID of the latest delivered message even for online clients.

As-is, this is a net downgrade: memory usage increases because ring
buffers aren't free'd anymore. However upcoming commits will replace the
ring buffer with log files. This change makes reading from log files
easier.
2020-08-20 17:38:57 +02:00
Hubert Hirtz e740d952ad
Reject downstream NICK with illegal characters
This should avoid confusion when mixing up nickname and user name.
Also it avoid breaking downstreams (since '@' and '!' are used for host
masks).
2020-08-20 10:00:58 +02:00
Hubert Hirtz a27e5ea92e
More explicit error message on INVITE with the wrong network 2020-08-20 09:13:38 +02:00
Hubert Hirtz a636b92a95
More explicit error message on KICK with the wrong network 2020-08-19 23:57:25 +02:00
Simon Ser bdb132ad98
Implement rate limiting for upstream messages
Allow up to 10 outgoing messages in a burst, then throttle to 1 message
each 2 seconds.

Closes: https://todo.sr.ht/~emersion/soju/87
2020-08-19 19:42:33 +02:00