Building an IRC Server 1

2021-04-21
3 min read

by Arthur

[proxy, server, client, parser]

init 1

Disclaimer: this blog post was written 4-5 week after the project has started.
Initially we were like, yea that sh*t easy, but then came an avalanche of problem like mode, multiserver etc.

First what you MUST have to simplify the project by a LOT is a proxy, in our case we used a modified version of this proxy:
https://github.com/LiveOverflow/PwnAdventure3/blob/master/tools/proxy/proxy_part9.py
But if you feel like, you can use wireshark netcat etc, but quite annoying to set up / use in my opinion.
Having a proxy allows you to easily debug your server and also gives you the ability to check how already existing one behaves.

In our case, our server is 90% of the time built according to oragono irc server.
https://oragono.io/

As for the client the one that we choose almost every time is irrsi. A CLI irc client.
We also went for revolutionIRC, hexchat and kiwirc for testing purposes.

We started off by building a small server in C to understand what every function was doing (accept, listen, bind etc.)

Then came the first strange function we had to use, select(). Ngl this fuction is really bad, it takes an array like structure and an int, it will then check for an update on any of the FD you gave him. But the fact that it overwrites the array of FD you gave him in this first place + the way you have to check what happened on what FD is just so annoying (+ according to stackoverflow, it can handle at most 1024 FD which is quite bad when you see that a lot of public IRC server have ~2k client connected).
I may do a ticket soon to replace it with poll().

Not gonna talk about the parser since it’s just a basic split on whitespaces.

First “parameter” in irc packets comming from client is the command, other ones are arguments.

We started off with basic commands, we handled which commands to call with a map of string and pointer to function. We started off with the nick.
At the same time, we (Lucas) started coppying error & reply messages from the rfc and implementing them as a macro. So when we want to reply something to a client, we just have to call a function that takes a code (int) and arg, and it will then build and return us a well formated irc packet to return to the client.

Eudald started doing the user command, but some differences in rfc messed us up because we couldnt figure out which rfc to pick (prototype of the USER packet differes in 1459 and 2812) so we went along the last one aka 2812 (pick it).

At this point while starting to do PASS, we figured out that our server wasn’t working properly with some client (they didnt seem to understand what we were sending him). After some research and debug we found out that to anwser a client for status update (nick change, mode, etc…), the packet must be formed like this:

:<nickname>@<username>!<hostname> <COMMAND> <arg>\r\n

(As of today we haven’t seen this ^^ clearly written in the rfc)
Also, when a user joins a server you have to greed him with a welcome message (rpl code n001) if you add this to the response problem, this took some time to figure out, and we lost a lot of time.

On the meantime, we also did TIME MOTD etc. (basic and simple commands), keep in mind we havent touched multi server yet (and while i’m writting this, we havent did it too lol).

This clears out our first week of work, thanks for reading.
Arthur