Commit Graph

242 Commits

Author SHA1 Message Date
Simon Ser
76e332b50a Move isHighlight to irc.go 2021-04-13 18:54:58 +02:00
Simon Ser
1e4ff49472 Save delivery receipts in DB
This avoids loosing history on restart for clients that don't
support chathistory.

Closes: https://todo.sr.ht/~emersion/soju/80
2021-03-31 18:04:13 +02:00
Simon Ser
5e11e717f1 Rename user.clients to clientNames
This doesn't contain anything other than just the names. Make this
clearer.
2021-03-30 12:44:56 +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
55274d7213 Move network.clients to user
No need to have this list per-network.
2021-03-29 16:58:56 +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
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
e35a116188 Don't update downstream caps in upstream RPL_WELCOME handler
Prior to being registered, upstreamConn.handleMessage doesn't run
in the user goroutine, it runs in a goroutine specific to the
network. Thus we shouldn't access any user data structure from
there.

downstreamConn.updateSupportedCaps is already called from the
eventUpstreamConnected handler in user.run, the call being removed
was unnecessary.

Closes: https://todo.sr.ht/~emersion/soju/108
2021-03-16 18:25:21 +01:00
Simon Ser
384075a6ed Don't store history for NickServ
Closes: https://todo.sr.ht/~emersion/soju/104
2021-03-16 09:54:29 +01:00
Simon Ser
fa047123b9 Passthrough some ISUPPORT tokens 2021-03-15 23:41:37 +01:00
Simon Ser
3f005d481d Properly handle all ISUPPORT negations 2021-03-15 23:11:42 +01:00
Simon Ser
62d4bf2813 Use upstream ISUPPORT map for NETWORK 2021-03-15 23:08:19 +01:00
Simon Ser
2992ff79c4 Maintain state for upstream ISUPPORT 2021-03-15 23:06:36 +01:00
Simon Ser
ff2cd9423f Simplify if block in ISUPPORT handler 2021-03-15 22:54:32 +01:00
Simon Ser
ffd142f8dd Extract ISUPPORT CHANMODES/PREFIX to separate functions 2021-03-15 22:53:46 +01:00
Simon Ser
d54c8c1122 Add Network.{URL,GetUsername,GetRealname}
Just a bunch of helpers that can be re-used.
2021-03-09 18:55:34 +01:00
Simon Ser
0954c7da79
Add irc to ALPN protocols
The new ALPN token has been approved [1]. We can start using it now.

[1]: https://mailarchive.ietf.org/arch/msg/tls-reg-review/i8YyT82XUtEgR-oXMG3sbyWYT8E/
2021-02-24 19:41:12 +01:00
Hubert Hirtz
6a1a05b1d4 if true return true else return false
Trivial improvement
2021-02-18 09:40:51 +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
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
Hubert Hirtz
a747c732c0
Don't forward batch tags
We don't want to have the batch tag when calling uc.produce, otherwise
downstream will end up with junk batch ids.
2021-01-10 22:48:08 +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
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
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
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
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
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
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
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
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
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
0831dbe6f1
Handle upstream ERROR messages 2020-08-13 15:31:07 +02:00
Simon Ser
9fd69c745e
Handle ERR_NOPERMFORHOST and ERR_YOUREBANNEDCREEP 2020-08-13 15:31:03 +02:00
Simon Ser
7c31c26d86
Don't perform TLS handshake in connectToUpstream
This defers TLS handshake until the first read or write operation. This
allows the upcoming identd server to register the connection before the
TLS handshake is complete, and is necessary because some IRC servers
send an ident request before that.
2020-08-11 10:24:54 +02:00
Simon Ser
b0bf012bbc
Change unix:// to irc+unix://
When Unix socket support will be added for listeners, unix:// will be
ambiguous. It won't be clear whether to setup an IRC server, or some
other kind of server (e.g. identd).

unix:// is still recognized to avoid breaking existing DBs.
2020-07-22 15:44:19 +02:00
Simon Ser
51dc9f0bf9
Broadcast unhandled messages to downstream connections
In case labelled-response isn't supported, broadcast unhandled messages
to all downstream connections. That's better than silently dropping the
messages.
2020-07-08 18:21:52 +02:00
Simon Ser
85fad93a71
Add support for upstream Unix socket connections
References: https://todo.sr.ht/~emersion/soju/51
2020-07-06 17:31:11 +02:00
Simon Ser
7af21d9d81
Parse upstream URLs with net/url
This allows us to ignore the path part of the URL. This is preliminary
work for unix URLs.
2020-07-06 17:18:13 +02:00
Simon Ser
b46a2554e1
Check upstream address with net.SplitHostPort
Looking for a colon is incorrect, IPv6 addresses can contain colons too.
2020-07-06 16:04:56 +02:00
Simon Ser
c490705fee
Sort and split JOIN messages
Sort channels so that channels with a key appear first. Split JOIN
messages so that we don't reach the message size limit.
2020-07-06 11:06:20 +02:00
Simon Ser
90250f5be5
Reply to WHO BouncerServ
Closes: https://todo.sr.ht/~emersion/soju/75
2020-06-29 18:09:48 +02:00
Simon Ser
d26194f62d
Handle registration failures
References: https://todo.sr.ht/~emersion/soju/30
2020-06-29 17:52:49 +02:00
delthas
2232b3128b Fix sending messages from detached channels
Currently, a downstream receives MODE, RPL_CHANNELMODEIS and
RPL_CREATIONTIME messages from soju for detached channels. It should not
be sent any of these messages.

This adds a detach check to the handling of these messages to avoid
receiving these messages.
2020-06-12 14:43:45 +02:00
Simon Ser
d0cf1d2882
Add support for WebSocket connections
WebSocket connections allow web-based clients to connect to IRC. This
commit implements the WebSocket sub-protocol as specified by the pending
IRCv3 proposal [1].

WebSocket listeners can now be set up via a "wss" protocol in the
`listen` directive. The new `http-origin` directive allows the CORS
allowed origins to be configured.

[1]: https://github.com/ircv3/ircv3-specifications/pull/342
2020-06-07 14:13:46 +02:00
fox.cpp
1fa5195b2f
Fix handling of empty response to SASL challenge 2020-06-05 11:35:43 +02:00
Simon Ser
283d4bf14c
Introduce ircConn
This interface will allow a conn to be backed by a websocket.
2020-06-04 17:27:57 +02:00
Simon Ser
07b4de8a1a
Only send JOIN message if we have channels to join
Don't send a JOIN command to upstream server when no channels are configured.
2020-06-03 17:18:57 +02:00
fox.cpp
203dc3df6a
Implement upstream SASL EXTERNAL support
Closes: https://todo.sr.ht/~emersion/soju/47
2020-06-02 11:24:22 +02:00
Eyal Sawady
c547aa0278
Join all channels with a single JOIN message 2020-05-28 16:26:28 +02:00
delthas
b1367a0608 Fix parsing upstream RPL_INVITING messages
Previously, we did not skip the first RPL_INVITING parameter, which is
the user nick (like in all replies), which made the parsing for that
reply incorrect.

This fixes RPL_INVITING parsing by skipping the first parameter.
2020-05-27 23:51:44 +02:00
delthas
f4e0c51366
Add support for TAGMSG and client message tags
Previously we dropped all TAGMSG as well as any client message tag sent
from downstream.

This adds support for properly forwarding TAGMSG and client message tags
from downstreams and upstreams.

TAGMSG messages are intentionally not logged, because they are currently
typically used for +typing, which can generate a lot of traffic and is
only useful for a few seconds after it is sent.
2020-05-27 23:48:08 +02:00
delthas
cdef46d0da
Forward all labeled errors and unknown messages to their downstream
This adds support for forwarding all errors and unknown messages labeled
with a specific downstream to that downstream.

Provided that the upstream supports labeled-response, users will now be
able to receive an error only on their client when making a command that
returns an error, as well as receiving any reply unknown to soju.
2020-05-27 23:47:49 +02:00
delthas
96dad08302
Add support for upstream ban, invite, and exception lists
This does not try to marshal nicks in masks, for simplicity and
consistency with the current behaviour of marshaling MODE messages.
2020-05-27 23:45:13 +02:00
delthas
b3742cc731
Update downstream nicks in single-server mode and after NICK
Previously, the downstream nick was never changed, even when the
downstream sent a NICK message or was in single-server mode with a
different nick.

This adds support for updating the downstream nick in the following
cases:
- when a downstream sends NICK
- additionally, in single-server mode:
  - when a downstream connects and its single network is connected
  - when an upstream connects
  - when an upstream sends NICK
2020-05-27 23:42:38 +02:00
delthas
566986fdd5
Fix sending CAP END twice when SASL is not used
When SASL is not used, we should only send CAP END after we send a CAP
REQ. Previously CAP END was sent both after a CAP REQ and a CAP ACK,
resulting in two CAP END messages.

Sending a CAP END right after the CAP REQ rather than waiting for the
CAP ACK/NAK saves 1 RTT.
2020-05-21 22:38:07 +02:00
delthas
de7b4c8588
Fix a null access due to assigning nil to the member memberships map
Even though the memberships map has type map[string]*memberships
(with memberships being defined as []membership), the default value for
that map should not be `nil` but a pointer to a nil slice.

This fixes a segfault on some servers before user channel prefixes are
sent.
2020-05-21 22:37:37 +02:00
delthas
c88700ef18
Fix parsing MODE messages by updating channel memberships
Previously, we only considered channel modes in the modes of a MODE
messages, which means channel membership changes were ignored. This
resulted in bugs where users channel memberships would not be properly
updated and cached with wrong values. Further, mode arguments
representing entities were not properly marshaled.

This adds support for correctly parsing and updating channel memberships
when processing MODE messages. Mode arguments corresponding to channel
memberships updates are now also properly marshaled.

MODE messages can't be easily sent from history because marshaling these
messages require knowing about the upstream available channel types and
channel membership types, which is currently only possible when
connected. For now this is not an issue since we do not send MODE
messages in history.
2020-05-21 22:36:54 +02:00
delthas
732b581eb2
Add support for multiple user channel memberships
User channel memberships are actually a set of memberships, not a single
value. This introduces memberships, a type representing a set of
memberships, stored as an array of memberships ordered by descending
rank.

This also adds multi-prefix to the permanent downstream and upstream
capabilities, so that we try to get all possible channel memberships.
2020-05-11 12:25:49 +02:00
Simon Ser
1363a5c27e
Improve highlight matching
Detect word boundaries instead of just doing a sub-string check.
2020-05-01 19:51:22 +02:00
Simon Ser
bd8ab7230d
Send service NOTICE on highlight in detached channel 2020-05-01 19:05:20 +02:00
Simon Ser
70f26a1a5a
Unify upstream NOTICE and PRIVMSG handling 2020-05-01 18:12:47 +02:00
Simon Ser
d9186e994d
Add support for detached channels
Channels can now be detached by leaving them with the reason "detach",
and re-attached by joining them again. Upon detaching the channel is
no longer forwarded to downstream connections. Upon re-attaching the
history buffer is sent.
2020-05-01 15:18:14 +02:00
Simon Ser
bbb5e79f59
Introduce permanentUpstreamCaps 2020-04-30 16:10:39 +02:00
Simon Ser
2a569c3b27
Add upstream cap-notify support 2020-04-30 15:27:41 +02:00
Simon Ser
c4655f1492
Add upstreamConn.caps
Instead of adding one field per capability, let's just have a map, just
like downstreamConn.
2020-04-29 19:45:37 +02:00
Simon Ser
8445979956
Rename upstreamConn.caps to supportedCaps
For consistency with downstreamConn.
2020-04-29 19:40:31 +02:00
Simon Ser
0c549d68c4
Add support for away-notify
This makes use of cap-notify to dynamically advertise support for
away-notify. away-notify is advertised to downstream connections if all
upstreams support it.
2020-04-29 19:34:44 +02:00
Simon Ser
70131f5b31
Don't use forEachDownstreamByID when forwarding RPL_AWAY
We should broadcast the message, not send it to a specific downstream
connection.
2020-04-29 15:32:22 +02:00
Simon Ser
2236142681
Check upstream NOTICE prefix is non-nil 2020-04-29 15:00:17 +02:00
Simon Ser
976ae2e649
Forward RPL_AWAY messages 2020-04-29 14:53:48 +02:00
delthas
7b35757bac Add support for the irc+insecure address scheme
Some servers do not support TLS, or have invalid, expired or self-signed
TLS certificates. While the right fix would be toi contact each server
owner to add support for valid TLS, supporting plaintext upstream
connections is sometimes necessary.

This adds support for the irc+insecure address scheme, which connects to
a network in plain-text over TCP.
2020-04-28 11:41:13 +02:00
delthas
19795a2321 Add support for IRC address schemes
This is preparatory work for adding other connection types to upstream
servers. The service command `network create` now accepts a scheme in
the address flag, which specifies how to connect to the upstream server.

The only supported scheme for now is ircs, which is also the default if
no scheme is specified. ircs connects to a network over a TLS TCP
connection.
2020-04-28 11:41:13 +02:00
Simon Ser
276ce12e7c
Add network.channels, remove DB.GetChannel
Store the list of configured channels in the network data structure.
This removes the need for a database lookup and will be useful for
detached channels.
2020-04-23 16:36:20 +02:00
delthas
7f74055380 Add support for custom network on-connect commands
Some servers use custom IRC bots with custom commands for registering to
specific services after connection.

This adds support for setting custom raw IRC messages, that will be
sent after registering to a network.

It also adds support for a custom flag.Value type for string
slice flags (flags taking several string values).
2020-04-16 17:38:47 +02:00
Simon Ser
3e80573765
Support sending history when upstream is disconnected
Previously, we were dropping the history.
2020-04-16 17:23:35 +02:00
Simon Ser
45e897c1c1
Make downstreamConn.marshal{Entity,UserPrefix} take a network
This will be used when sending history while upstream is disconnected.
2020-04-16 17:19:00 +02:00
Simon Ser
5cf876cb89
Kill downstreamConn.marshal{Nick,Channel}
We can just use downstreamConn.marshalEntity instead.
2020-04-16 16:57:33 +02:00
Simon Ser
db198335aa
Per-entity ring buffers
Instead of having one ring buffer per network, each network has one ring
buffer per entity (channel or nick). This allows history to be more
fair: if there's a lot of activity in a channel, it won't prune activity
in other channels.

We now track history sequence numbers per client and per network in
networkHistory. The overall list of offline clients is still tracked in
network.offlineClients.

When all clients have received history, the ring buffer can be released.

In the future, we should get rid of too-old offline clients to avoid
having to maintain history for them forever. We should also add a
per-user limit on the number of ring buffers.
2020-04-10 19:22:47 +02:00
Simon Ser
f2037c5d52
Make newMessageLogger take a *network instead of an *upstreamConn
There's no reason why messgeLogger needs access to the whole connection,
the network is enough.
2020-04-07 21:54:24 +02:00
Simon Ser
0a895b591e
Remove outdated comment
Locks are gone for good.
2020-04-07 19:57:36 +02:00
Simon Ser
3195809c30
Centralize logged messages marshaling
This allows messages added to logs to be handled just like messages
added to the ring buffer.
2020-04-07 19:45:29 +02:00
Simon Ser
37cd9e4d89
Fix upstream NICK handling
- uc.nicl was compared to msg.Prefix.Name after being updated to the new
  nick
- The new nick wasn't marshaled
2020-04-07 15:02:44 +02:00
Simon Ser
13635747c4
Fix server-time tags timezone
We need to use UTC time.
2020-04-06 22:05:49 +02:00
Simon Ser
9692114f37
Make upstreamConn.produce log messages 2020-04-06 21:42:55 +02:00
Simon Ser
baadb964bc
Add origin argument to upstreamConn.produce 2020-04-06 21:34:45 +02:00
Simon Ser
78b123be72
Log TOPIC messages
See [1].

[1]: 82c4ad8362/modules/log.cpp (L486)
2020-04-06 18:49:39 +02:00
Simon Ser
f0bc919885
Remove downstreamConn.ringConsumers
We no longer need long-lived ring buffer consumers now that
upstreamConn.produce dispatches messages to downstream connections.
2020-04-06 18:31:48 +02:00
Simon Ser
ad2c142c36
Remove per-network ring buffer goroutines
Just dispatch from the user goroutine. This allows removes a lot of complexity.
2020-04-06 18:05:36 +02:00
Simon Ser
0c06142ae9
Introduce upstreamConn.produce
The logic in this function is about to get more complicated. It'll soon
also dispatch messages in connected downstreams.
2020-04-06 17:28:49 +02:00
delthas
93c96d6c21
Remove unused entityLog struct
Since the logging refactoring in 27e090, entityLog is not used anymore
and can be removed.
2020-04-04 17:34:37 +02:00
delthas
eb941d2d2b
Send one NOTICE on new upstream disconnect/connect errors
In order to notify the user when we are disconnected from a network
(either due to an error, or due a QUIT), and when we fail reconnecting,
this commit adds support for sending a short NOTICE message from the
service user to all relevant downstreams.

The last error is stored, and cleared on successful connection, to
ensure that the user is *not* flooded with identical connection error
messages, which can often happen when a server is down.

No lock is needed on lastError because it is only read and modified from
the user goroutine.

Closes: https://todo.sr.ht/~emersion/soju/27
2020-04-04 17:33:09 +02:00
Simon Ser
ee8aae7a96
Add NOTICE messages to ring buffer
References: https://todo.sr.ht/~emersion/soju/33
2020-04-03 21:00:19 +02:00
Simon Ser
3d142cae9f
Add time tag to all messages 2020-04-03 20:48:23 +02:00