526 Commits

Author SHA1 Message Date
hubert
96082ecef8 Don't forward label tags
We don't want to have the label tag when calling uc.produce, otherwise
downstream will end up with junk labels.

git-svn-id: file:///srv/svn/repo/suika/trunk@526 f0ae65fe-ee39-954e-97ec-027ff2717ef4
2021-05-23 10:32:27 +00:00
contact
acbb420d9c doc/soju.1: document user delete command
git-svn-id: file:///srv/svn/repo/suika/trunk@525 f0ae65fe-ee39-954e-97ec-027ff2717ef4
2021-05-22 08:44:36 +00:00
contact
7225f0f5e9 doc/soju.1: document -connect-command
git-svn-id: file:///srv/svn/repo/suika/trunk@524 f0ae65fe-ee39-954e-97ec-027ff2717ef4
2021-05-22 08:40:36 +00:00
contact
50b5d6c486 readme: add link to IRC channel
git-svn-id: file:///srv/svn/repo/suika/trunk@523 f0ae65fe-ee39-954e-97ec-027ff2717ef4
2021-05-21 22:04:22 +00:00
contact
54f3d31823 readme: move quickstart to dedicated doc page
git-svn-id: file:///srv/svn/repo/suika/trunk@522 f0ae65fe-ee39-954e-97ec-027ff2717ef4
2021-05-21 22:01:06 +00:00
hubert
2b8a6e1a59 Fix CAP LIST listing disabled capabilities
git-svn-id: file:///srv/svn/repo/suika/trunk@521 f0ae65fe-ee39-954e-97ec-027ff2717ef4
2021-05-21 08:03:39 +00:00
contact
de72d133a9 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.

git-svn-id: file:///srv/svn/repo/suika/trunk@520 f0ae65fe-ee39-954e-97ec-027ff2717ef4
2021-05-20 09:13:14 +00:00
contact
692d48de9e Silence net.ErrClosed errors
git-svn-id: file:///srv/svn/repo/suika/trunk@519 f0ae65fe-ee39-954e-97ec-027ff2717ef4
2021-05-19 22:07:44 +00:00
contact
5c822e5b49 contrib/clients: add gamja and senpai
git-svn-id: file:///srv/svn/repo/suika/trunk@518 f0ae65fe-ee39-954e-97ec-027ff2717ef4
2021-05-19 14:42:03 +00:00
contact
b893736c9e Check message stores implement expected interfaces
git-svn-id: file:///srv/svn/repo/suika/trunk@517 f0ae65fe-ee39-954e-97ec-027ff2717ef4
2021-05-18 12:19:34 +00:00
hubert
84c329faff Implement CHATHISTORY BETWEEN
git-svn-id: file:///srv/svn/repo/suika/trunk@516 f0ae65fe-ee39-954e-97ec-027ff2717ef4
2021-05-18 08:44:10 +00:00
contact
0f0bc90e97 Add more context to chathistory errors
git-svn-id: file:///srv/svn/repo/suika/trunk@515 f0ae65fe-ee39-954e-97ec-027ff2717ef4
2021-05-11 10:42:12 +00:00
yyp
547fb73d86 contrib/weechat: fix typo
git-svn-id: file:///srv/svn/repo/suika/trunk@514 f0ae65fe-ee39-954e-97ec-027ff2717ef4
2021-05-03 22:06:02 +00:00
contact
f8965cc888 contrib/weechat: explain how to enable IRCv3 features
git-svn-id: file:///srv/svn/repo/suika/trunk@513 f0ae65fe-ee39-954e-97ec-027ff2717ef4
2021-05-01 16:52:28 +00:00
hubert
fc31a8fa58 Don't directly reply to network-specific NICK
The NICK must only apply to the specific network, not to the downstream
connection.

git-svn-id: file:///srv/svn/repo/suika/trunk@512 f0ae65fe-ee39-954e-97ec-027ff2717ef4
2021-04-30 10:17:23 +00:00
hubert
4c8f7cd0f3 Handle casemapping on BouncerServ
git-svn-id: file:///srv/svn/repo/suika/trunk@511 f0ae65fe-ee39-954e-97ec-027ff2717ef4
2021-04-30 10:10:49 +00:00
yyp
21a44ff840 Makefile: mark soju and sojuctl as .PHONY
Otherwise running `make` didn't do anything on a non-clean state. Go
deals with changed files automatically, and there's no real need to
explicitly specify them.

git-svn-id: file:///srv/svn/repo/suika/trunk@510 f0ae65fe-ee39-954e-97ec-027ff2717ef4
2021-04-27 17:06:16 +00:00
yyp
e92b4b5cdf db: match placeholders with columns
Soju inserts 9 columns but only with 8 placeholders. This causes
channels not being saved properly and also logging errors like this:

    downstream ...: failed to create or update channel ...: 8 values for 9 columns

git-svn-id: file:///srv/svn/repo/suika/trunk@509 f0ae65fe-ee39-954e-97ec-027ff2717ef4
2021-04-27 07:22:44 +00:00
ecs
e3c909c007 handleUserDelete: delete the correct user
Prior to this, we deleted the user issuing the deletion rather than the
user which should've been deleted.

git-svn-id: file:///srv/svn/repo/suika/trunk@508 f0ae65fe-ee39-954e-97ec-027ff2717ef4
2021-04-22 08:37:05 +00:00
contact
7bfba6f771 Make db and log config options more future-proof
Rename the "sql" directive to "db". Rename the "log" directive to
"log fs".

In the future, we'll maybe support more databases and more message
stores. Make it so it's easy to integrate these new festures to the
config file format.

git-svn-id: file:///srv/svn/repo/suika/trunk@507 f0ae65fe-ee39-954e-97ec-027ff2717ef4
2021-04-21 16:15:04 +00:00
contact
3922196855 Add default configuration file
git-svn-id: file:///srv/svn/repo/suika/trunk@506 f0ae65fe-ee39-954e-97ec-027ff2717ef4
2021-04-21 14:39:51 +00:00
hubert
9b274dd916 Drop TAGMSG in detached channels
- Do not relay TAGMSG as notices,
- Do not reattach when a TAGMSG is received,
- Do not reset the detach timer when a TAGMSG is received.

git-svn-id: file:///srv/svn/repo/suika/trunk@505 f0ae65fe-ee39-954e-97ec-027ff2717ef4
2021-04-20 14:17:28 +00:00
contact
da3730a850 readme: mention Makefile, assume soju is installed system-wide
git-svn-id: file:///srv/svn/repo/suika/trunk@504 f0ae65fe-ee39-954e-97ec-027ff2717ef4
2021-04-19 14:35:18 +00:00
contact
01b94a7327 sojuctl: don't use log.Fatalf in readPassword
git-svn-id: file:///srv/svn/repo/suika/trunk@503 f0ae65fe-ee39-954e-97ec-027ff2717ef4
2021-04-19 12:11:25 +00:00
contact
edc4b60e04 Add user prefix to upstream logger
git-svn-id: file:///srv/svn/repo/suika/trunk@502 f0ae65fe-ee39-954e-97ec-027ff2717ef4
2021-04-13 18:16:37 +00:00
contact
5472ad31ca Add per-network logger
git-svn-id: file:///srv/svn/repo/suika/trunk@501 f0ae65fe-ee39-954e-97ec-027ff2717ef4
2021-04-13 18:12:49 +00:00
contact
db50fb13e5 Error out on network name conflict
Closes: https://todo.sr.ht/~emersion/soju/29

git-svn-id: file:///srv/svn/repo/suika/trunk@500 f0ae65fe-ee39-954e-97ec-027ff2717ef4
2021-04-13 17:33:06 +00:00
contact
a958ddadee 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

git-svn-id: file:///srv/svn/repo/suika/trunk@499 f0ae65fe-ee39-954e-97ec-027ff2717ef4
2021-04-13 17:11:05 +00:00
contact
ad0b3e4eb1 Move isHighlight to irc.go
git-svn-id: file:///srv/svn/repo/suika/trunk@498 f0ae65fe-ee39-954e-97ec-027ff2717ef4
2021-04-13 16:54:58 +00:00
contact
d36068af4e Store last internal msg ID in DB when detaching
References: https://todo.sr.ht/~emersion/soju/98

git-svn-id: file:///srv/svn/repo/suika/trunk@497 f0ae65fe-ee39-954e-97ec-027ff2717ef4
2021-04-13 16:15:30 +00:00
contact
562beca198 Skip backlog logic in downstreamConn.welcome on chathistory
git-svn-id: file:///srv/svn/repo/suika/trunk@496 f0ae65fe-ee39-954e-97ec-027ff2717ef4
2021-04-13 15:50:03 +00:00
contact
e32cf2acd9 Take msg ID in sendTargetBacklog
git-svn-id: file:///srv/svn/repo/suika/trunk@495 f0ae65fe-ee39-954e-97ec-027ff2717ef4
2021-04-13 15:49:37 +00:00
contact
fec819c48a Panic on unknown user event type
This should never happen. Complain loudly if it does.

git-svn-id: file:///srv/svn/repo/suika/trunk@494 f0ae65fe-ee39-954e-97ec-027ff2717ef4
2021-04-13 11:08:48 +00:00
contact
63c2238407 Introduce per-user logger
Adds the username to log lines.

git-svn-id: file:///srv/svn/repo/suika/trunk@493 f0ae65fe-ee39-954e-97ec-027ff2717ef4
2021-04-13 11:04:23 +00:00
hubert
1cd4279256 Make casemapping work over bytes instead of runes
Fixes a panic in partialCasemap when the input string was invalid UTF-8.

git-svn-id: file:///srv/svn/repo/suika/trunk@492 f0ae65fe-ee39-954e-97ec-027ff2717ef4
2021-04-13 10:48:46 +00:00
contact
04d4691eda cmd/soju: allow specifying -listen multiple times
Closes: https://todo.sr.ht/~emersion/soju/67

git-svn-id: file:///srv/svn/repo/suika/trunk@491 f0ae65fe-ee39-954e-97ec-027ff2717ef4
2021-03-31 17:02:40 +00:00
contact
de665fc884 Update dependencies
git-svn-id: file:///srv/svn/repo/suika/trunk@490 f0ae65fe-ee39-954e-97ec-027ff2717ef4
2021-03-31 16:18:16 +00:00
contact
83a6c849fd 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

git-svn-id: file:///srv/svn/repo/suika/trunk@489 f0ae65fe-ee39-954e-97ec-027ff2717ef4
2021-03-31 16:04:13 +00:00
contact
00fbbb9d0d 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.

git-svn-id: file:///srv/svn/repo/suika/trunk@488 f0ae65fe-ee39-954e-97ec-027ff2717ef4
2021-03-31 15:57:24 +00:00
contact
862be4f5b8 Rename user.clients to clientNames
This doesn't contain anything other than just the names. Make this
clearer.

git-svn-id: file:///srv/svn/repo/suika/trunk@487 f0ae65fe-ee39-954e-97ec-027ff2717ef4
2021-03-30 10:44:56 +00:00
contact
180e314a01 Make NickServ detection casemapping-aware
git-svn-id: file:///srv/svn/repo/suika/trunk@486 f0ae65fe-ee39-954e-97ec-027ff2717ef4
2021-03-30 10:28:45 +00:00
contact
e94da85df6 Introduce deliveredStore
This hides the double-map complexity behind a dedicated type.

git-svn-id: file:///srv/svn/repo/suika/trunk@485 f0ae65fe-ee39-954e-97ec-027ff2717ef4
2021-03-29 15:49:50 +00:00
contact
10a2f92f68 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.

git-svn-id: file:///srv/svn/repo/suika/trunk@484 f0ae65fe-ee39-954e-97ec-027ff2717ef4
2021-03-29 15:07:39 +00:00
contact
84b3a5d057 Move network.clients to user
No need to have this list per-network.

git-svn-id: file:///srv/svn/repo/suika/trunk@483 f0ae65fe-ee39-954e-97ec-027ff2717ef4
2021-03-29 14:58:56 +00:00
contact
a313a3aead Simplify network.offlineClients
Replace it with a list of all clients (online or offline).

git-svn-id: file:///srv/svn/repo/suika/trunk@482 f0ae65fe-ee39-954e-97ec-027ff2717ef4
2021-03-29 14:55:57 +00:00
contact
3f98447c8f contrib/casemap-logs.sh: new utility script
Previous soju versions were storing log without converting the channel
and nick names to their canonical lower-case representation. This could
result in two log directories for the same channel/nick.

This script fixes old log dirs.

git-svn-id: file:///srv/svn/repo/suika/trunk@481 f0ae65fe-ee39-954e-97ec-027ff2717ef4
2021-03-26 14:31:54 +00:00
contact
2cba08b50e Introduce deliveredClientMap
Adds more semantics to map[string]string. Simplifies the complicated
mapStringStringCasemapMap type.

git-svn-id: file:///srv/svn/repo/suika/trunk@480 f0ae65fe-ee39-954e-97ec-027ff2717ef4
2021-03-26 10:21:14 +00:00
hubert
3cad542811 Fix CHATHISTORY target not being casemapped
git-svn-id: file:///srv/svn/repo/suika/trunk@479 f0ae65fe-ee39-954e-97ec-027ff2717ef4
2021-03-26 09:39:52 +00:00
hubert
1b73446cbb 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.

git-svn-id: file:///srv/svn/repo/suika/trunk@478 f0ae65fe-ee39-954e-97ec-027ff2717ef4
2021-03-24 17:15:52 +00:00
delthas
c4cdfba0f2 Increase downstream TCP keepalive interval to 1 hour
The rationale for increasing the TCP keepalive interval from 15 seconds
(default) to 1 hour follows.

- Why increasing TCP keepalives for downstream connections is not an
  issue wrt to detecting connection interruptions

The use case of TCP keepalives is detecting whether a TCP connection was
forcefully shut down without receiving any TCP FIN or RST frame, when no
data are sent from that endpoint to the other peer.

If any data is sent from the peer and is not ACKed because the
connection was interrupted, the socket will be closed after the TCP RTO
(usually a few seconds) anyway, without the need for TCP keepalives.

Therefore the only use of TCP keepalives is making sure that a peer that
is not writing anything to the socket, and is actively reading and
waiting for new stream data to be received, can, - instead of waiting
forever to receive packets that will never arrive because the connection
was interrupted -, detect this disconnection, close the connection
locally, then try to connect again to its peer.

This only makes sense from a client point-of-view. When an IRC client is
not write(2)ing anything to the socket but is simply waiting for new
messages to arrive, ie read(2)ing on the socket, it must ensure that the
connection is still alive so that any new messages will indeed be sent
to him. So that IRC client should probably enable TCP keepalives.

However, when an IRC server is not writing anything to its downstream
socket, it doesn't care if it misses any messages from its downstream
client: in any case, the downstream client will instantly detect when
its messages are not reaching its server, because of the TCP RTO
(keepalives are not even needed in the client in that specific case),
and will try to reconnect to the server.

Thus TCP keepalives should be enabled for upstream connections, in
order to make sure that soju does not miss any messages coming from
upstream servers, but TCP keepalives are not needed for downstream
connections.

- Why increasing TCP keepalives for downstream connections is not an
  issue wrt security, performance, and server socket resources
  exhaustion

TCP keepalives are orthogonal to security. Malicious clients can open
thousands of TCP connections and keep them open with minimal
bookkeeping, and TCP keepalives will not prevent attacks planning to
use up all available sockets to soju.

It is also unlikely that soju will keep many connections open, and in
the event that thousands of dead, disconnected connections are active in
soju, any upstream message that needs to be sent to downstreams will
disconnect all disconnected downstreams after the TCP RTO (a few
seconds). Performance could only be slightly affected in the few seconds
before a TCP RTO if many messages were sent to a very large number of
disconnected connections, which is extremely unlikely and not a large
impact to performance either.

- Why increasing TCP keepalives could be helpful to some clients running
  on mobile devices

In the current state of IRC, most clients running on mobile devices
(mostly running Android and iOS) will probably need to stay connected
at all times, even when the application is in background, in order to
receive private messages and highlight notifications, complete chat
history (and possibly reduced connection traffic due to avoiding all the
initial messages traffic, including all NAMES and WHO replies which
are quite large).

This means most IRC clients on mobile devices will keep a socket open at
all times, in background. When a mobile device runs on a cellular data
connection, it uses the phone wireless radio to transmit all TCP
packets, including TCP packets without user data, for example TCP
keepalives.

On a typical mobile device, a wireless radio consumes significant power
when full active, so it switches between several energy states in order
to conserve power when not in use. It typically has 3 energy states,
from Standby, when no messages are sent, to Low Power, to Full Power;
and switches modes on an average time scale of 15s. This means that any
time any TCP packet is sent from any socket on the device, the radio
switches to a high-power energy state, sends the packet, then stays on
that energy state for around 15s, then goes back to Standby. This
does include TCP keepalives.

If a TCP keepalive of 15s was used, this means that the IRC server would
force all clients running on mobile devices to send a TCP keepalive
packet at least once every 15s, which means that the radio would stay
in its high-power energy state at all times. This would consume a
very significant amount of power and use up battery much faster.

Even though it would seem at first that a mobile device would have many
different sockets open at any time; actually, a typical Android device
typically has at one background socket open, with Firebase Cloud
Messaging, for receiving instant push notifications (for example, for
the equivalent of IRC highlights on other messaging platforms), and
perhaps a socket open for the current foreground app. When the current
foreground app does not use the network, or when no app is currently
used and the phone is in sleep mode, and no notifications are sent, then
the device can effectively have no wireless radio usage at all. This
makes removing TCP keepalives extremely significant with regard to the
mobile device battery usage.

Increasing the TCP keepalive from soju lets downstream clients choose
their own keepalive interval and therefore possibly save battery for
mobile devices. Most modern mobile devices have complex heuristics for
when to sleep the CPU and wireless radio, and have specific rules for
TCP keepalives depending on the current internet connection, sleep
state, etc.

By increasing the downstream TCP keepalive to such a high period, soju
lets clients choose their most optimal TCP keepalive period, which means
that in turn clients can possibly let their mobile device platform
choose best that keepalive for them, thus letting them save battery in
those cases.

git-svn-id: file:///srv/svn/repo/suika/trunk@477 f0ae65fe-ee39-954e-97ec-027ff2717ef4
2021-03-24 17:04:44 +00:00