Building an IRC Server 7
by Arthur
READ (and multi server)
Okay so basicly we put the site on hold for a long time because we wanted to end the project asap, things that should have happened, happened, we forgot about the site.
So now we are middle of holidays and i’m writting this in a fucking camping in the middle of nowhere (south france).
Don’t look at the week anymore, the following post will cover things that happened to us and how we handle it, order might be wrong.
As you may know irc server are capable of handling client, service, and server connection, but what are those, here’s a little schema taken from wikipedia.
Multiple client even if not on the same server are capable of talking to each other.
How ?
Here are a few pre-requisities:
- Each server must have some sort of database wich hold every server that are part of the netowrk + all their user associated (to avoid nick collision as an example).
- If a nick collision occurs, all clients that are concerned by that collision must be kicked
- There MUST be a password for a server to connect
And that’s it, easy isn’t it ?
Well of course fucking not
I won’t talk about the PASS packet that happened prior cause it’s boring af like just check the password and ignore all other info (for a simple server, cause like protocol used etc are specified in this msg)
When a server connects directly to you he will send something like this:
SERVER irc.ircgod.com :ircGOD server
1 2 3
- the SERVER packet
- the hostname of the remote server
- the info of the remote server
To this server you must awnser (a PASS packet containing the password of the server that just connected to you) and your reply to the server command wich can look like this:
:irc1.ircgod.com SERVER irc1.ircgod.com 1 :ircGOD server number 1
1 2 3 4 5
- our hostname
- SERVER packet
- once again our hostname
- hopcount (always 1 in this situation)
- our server info
YAY the handshake is done the 2 server are now connected, but we are not done yet, first, we must share every server (probably the part we had the most trouble doing)
When sharing a server (this happened at the end of a server handshake or when a new server joins the network).
The packet looks like this:
:irc.ircgod.com SERVER irc4.ircgod.com 3 4528718 :ircGOD server number 4
1 2 3 4 5 6
- our link for the new server that just registered in the the network
- the SERVER packet
- the new server hostname
- how far is the new server (hopcount)
- the token that irc.ircgod.com (the uplink) will use when reffering to action on the server irc4.ircgod.com (the new server)
- the new server info
Every time a server connects to you or you are told of the existence of another server in the network you must share the server in question to every other server that are connected to you wich means:
- Generating a random token for every directly connected server when you will refer to the new server.
- Augment the hopcount by 1
Well we have shared server, now time to share all client :D
Sharing a client looks like this (hopefully i didn’t fucked up here):
:irc.ircgod.com NICK avan-pra 2 username 127.0.0.1 4528718 +i :realname
1 2 3 4 5 6 7 8 9
- The server wich is our link for the client (ie if we want to talk to this client we have to ge trough him)
- NICK packet
- introduced client’s nick
- how far is the client (hopcount)
- introduced client username
- introduced client hostname
- server token wich identify on what server the client is
- client mode
- his realname
ps: you only need to share client when:
- a new server is directly registering to you
- a new user join the network
ps2: ofc you must not share the server that just joined the network to this same server (yes this may sound dumb but anyway)
me having fun on free time (irc into minecraft, yes it’s a dumb pipe, but it’s cool)
irc funny gif
probably 5 month after starting writting this, we completly fucked up user sharing between server (we were having some fun lol) so now multi server is completly broken but heh who cares…
SO, now you have shared all users, you must share all your channels and need to know every channel of every other server :p
Here’s how (do this for every non local channel (channel starting with &)):
:irc.ircgod.com NJOIN #test :avan-pra,@avan-pra2,+avan-pra3
1 2 3 4
:irc.ircgod.com MODE #test +ikl password 10
5 6 7 8
or
:irc.ircgod.com MODE #test +ik password +l 10
5 6 7 8
- our hostname
- NJOIN packet
- channel name
- nick inside the channel with their status (operator, voice, normal et…), comma separated
- our hostname
- MODE packet
- channel concerned
- channel modes
Well done !
Most of the work is done now only remains broadcasting the new server to all other connected server :D
The new server knows everything about the network, but the network knows nothing about him yet.
For every server (not counting the new one) directly connected to you, you will do this:
:irc.ircgod.com SERVER irc5.ircgod.com 2 3525326 :ircGOD server number 5
1 2 3 4 5 6
- our hostname
- SERVER packet
- new server hostname
- how far away is the new server from the one you are broadcasting it to (always 2 in this situation)
- a random token that identify the new server FOR the server you are sending this packet to, it’s very important, you need to store it, it obviously change for each server you are sending this packet to
- the new server’s info
AND YOU ARE DONE
CONGRATULATION, multi server is now complete, well obviously all the info you just sent, the other server will send it to you ¯\(ツ)/¯.
So, im too bored to talk about the token for now but if one day i do it will be here
You will have to parse all those infos and attach them to the server because when the server does quit, well, all those infos must disapear, see where this is going ? Another needle in the ass… let’s go
I hope you did attach all the info (incomming new server, remote client, remote channel etc…) to the right server because now the fun begin and the destructor will be helpful.
Now imagine the server directly connected to you disconnect itself without any warning at all.
You need to tell the network that the server disconnected itself, no example needed, it’s just a basic SQUIT with some basic arguments.
Problem is that internally there are a lot of things to do:
for every server he introduced us
{
destroy their user (you need to tell OUR client that somebody left if they were in the same channel)
destroy their channel (kick our client that were inside)
}
destroy his users
destroy his channels
destroy him
Done, this is the end, for real it’s the end of multi server, here we only discussed authentification and disconnection, but a lot of commands needs to work with multi server, so your code may get AT LEAST 1.5 to 2.5 times bigger.
It’s really cool but so freaking hard to do, that’s why we dont encourage you to do multiserver…
We will talk a bit about STATS and i think we are done, fuck services by the way.
Stats
short talk about stats, stats allows you to get 4 things:
-
l gives you info on every connection to the server the request is headed to, it gives, how much data was sent, received and how long every connection has been up to, impossible to do it properly without a Message class
-
m same as l but for each command, impossible to do properly without a Message class
-
o very easy, you probably won’t do it, (show operator configured)
-
u very easy, return how long the server has been running
That clear out our post, the website has been being in build for too long and we are quite bored to do any doc on irc anymore.
If you have any question regarding irc, feel free to contact us, we will be happy to help.
Thanks a lot for reading all the way to here.
Good luck on building your one :D.