Commit Graph

692 Commits

Author SHA1 Message Date
Simon Ser
1110f39227
Add in-memory message store
Uses an in-memory ring buffer.

Closes: https://todo.sr.ht/~emersion/soju/96
2021-01-04 17:18:30 +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
Simon Ser
021a4c9474
Turn messageStore into an interface
This allows for other implementations that aren't based on a filesystem.
2021-01-04 14:24:00 +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
0ddc0de7e5 service: Introduce channel update
This adds the `channel update` service command, which is used to set the
auto-detach, auto-reattach, and message relaying settings of a channel.

Of note is that currently the parser parses `#` as a comment, which
means any `channel update #foo ...` will actually need to be escaped to
`channel update "#foo" ...`
2020-12-14 20:54:02 +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
delthas
939c087754 Introduce Channel.{RelayDetached,ReattachOn,DetachAfter,DetachOn}
This adds several fields to the channel database schema and struct.
These fields will be used to add support for customizable message
relaying through BouncerServ, auto-reattaching, auto-detaching.

- RelayDetached is a filter for which notices to relay through
  BouncerServ for detached channels.
- ReattachOn is a filter for which messages to trigger a channel
  reattach on.
- DetachAfter is the duration after which to automatically detach a
  channel if no matching messages are received.
- DetachOn is a filter for which messages will reset the auto-detach
  timer.
2020-12-14 20:54:02 +01:00
Simon Ser
ddcaf558c0
Add .editorconfig 2020-11-30 11:39:41 +01:00
Kalyan Sriram
586c7ee336
sojuctl: change-password: check if user exists
When changing the password, checks if the user exists *before* prompting
for a password change, instead of after.
2020-11-26 19:27:08 +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
88d241fd1d
Don't accept any IP as a proxy by default
It's too easy to setup a reverse proxy which doesn't support the PROXY
protocol, or lets the X-Forwarded-For header fields pass through.
Disable this by default.

To restore the previous behaviour, add `accept-proxy-ip localhost` to
the config file.
2020-10-25 18:22:12 +01:00
Simon Ser
24d8f2167b
Upgrade dependencies 2020-10-25 18:15:54 +01:00
Simon Ser
0709ac143f
Switch to go-scfg
We don't use child directives yet, but likely will in the future.
2020-10-25 18:10:50 +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
af1e578936
Switch to sql.NullString
Not really better than what we had before, however new contributors will
maybe be familiar with it.
2020-10-24 15:47:53 +02: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
Simon Ser
b3e136e3b7
Add id column to User table
We used rowid before, but an explicit ID column is cleaner.
2020-10-24 14:52:55 +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
bbe67adf1e
Add support for the PROXY protocol
IPs whitelisted in accept-proxy-ip can now use the PROXY protocol to
indicate the original source/destination addresses.

Closes: https://todo.sr.ht/~emersion/soju/81
2020-09-07 21:28:24 +02:00
Simon Ser
2c723823b0
Set Server.AcceptProxyIPs 2020-09-07 20:58:49 +02:00
Hubert Hirtz
7310f67fc7
Make DB.DeleteChannel take the channel ID
... to allow the caller to correctly do any necessary casemapping.
2020-09-07 11:40:18 +02:00
Hubert Hirtz
42828d68e9
Make sure that WebSocket messages are valid UTF-8
... by replacing invalid bytes with the REPLACEMENT CHARACTER U+FFFD

This is better than:
- discarding the whole message, since the user would not see it...
- removing invalid bytes, since the user would not see their presence,
- converting the encoding (this is actually not possible).

Contrary to its documentation, strings.ToValidUTF8 doesn't copy the
string if it's valid UTF-8:
<https://golang.org/src/strings/strings.go?s=15815:15861#L623>
2020-09-02 17:09:32 +02:00
Simon Ser
046175f564
Don't update history when msgID is empty in appendLog
Log files don't record all message types. If the message isn't inserted
in the log file, don't update the history cursors for downstream
connections.
2020-08-28 13:35:55 +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
ae3e4262b9
Update dependencies 2020-08-24 19:05:56 +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
b6f15c3e3c
Introduce loadHistoryLatestID
This loads latest messages from logs up to a given message ID. This is
similar to the IRCv3 CHATHISTORY LATEST command [1].

[1]: 0c271a5f1d/extensions/chathistory.md (latest)
2020-08-20 20:05:01 +02:00
Simon Ser
8f29ae41a2
Introduce internal message IDs
For now, these can be used as cursors in the logs. Future patches will
introduce functions that perform log queries with message IDs.

The IDs are state-less tokens containing all the required information to
refer to an on-disk log line: network name, entity name, date and byte
offset. The byte offset doesn't need to point to the first byte of the
line, any byte will do (note, this makes it so message IDs aren't
necessarily unique, we may want to change that in the future).

These internal message IDs are not exposed to clients because we don't
support upstream message IDs yet.
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
81c7e80e0f
Forward RPL_TOPICWHOTIME to downstreams 2020-08-20 11:12:54 +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
d957493348
Fix marshalling of channel name in RPL_CREATIONTIME 2020-08-20 09:15:47 +02:00
Simon Ser
e523deb15c
go fmt 2020-08-20 09:13:56 +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
385825d010
Improve registration error messages
- Don't print the raw IRC message, since we already show the original
  error message
- Avoid double-printing "registration failed"
2020-08-19 23:35:12 +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
Simon Ser
9f26422592
Escape user/network/entity characters in log file path
ZNC replaces slashes and backslashes with a dashes.
2020-08-19 12:22:32 +02:00
Simon Ser
ee32329a14
Strip message tags in error message
The time tag was causing the registration error messages to be
continuously sent to downstream connections.
2020-08-19 11:50:19 +02:00
Simon Ser
78361f0b1e
Encode idents to hex instead of base64
base64 strings may contain characters rejected by ident clients such
as "+". Use hex encoding and shorten the string a little.
2020-08-19 11:24:25 +02:00
Simon Ser
ca40e79855
ident: remove leftover debug log 2020-08-18 17:57:12 +02:00
Dan Shick
54efb1cab4
Fix store user query values 2020-08-18 00:26:59 +02:00