Assignment 2: Supporting Multiple Clients¶
In this part of the project, your main goal will be to allow users to send messages to each other. You will also implement a couple extra messages that will make your server compliant enough to test with existing IRC clients.
Since you will be supporting multiple users, you will now have to spawn a new thread for each user that connects to your server. This, in turn, may result in race conditions in your code. You must identify the shared resources in your server, and make sure they are protected by adequate synchronization primitives.
The messages you have to implement are presented in suggested order of implementation. Nonetheless, once you’ve implemented Connection Registration, the remaining messages are mostly independent of each other.
Connection Registration¶
Implement connection registration, as described in [RFC2812 §3.1], with the following exceptions:
You must implement the
NICK,USER, andQUITmessages. You must not implement thePASS,SERVICE, orSQUITmessages. You do not need to implement theOPERandMODEmessages yet (you will implement them in the next assignment).In the
NICKmessage, you must implement theERR_NONICKNAMEGIVENandERR_NICKNAMEINUSEreplies.You can ignore the
<mode>and<unused>parameters of theUSERmessage.In the
USERmessage, you must implement theERR_ALREADYREGISTRED, andERR_NEEDMOREPARAMS. Note: You will need to support theERR_NEEDMOREPARAMSreply in several other messages. It will pay off to write a function that validates the number of parameters in a message, and returns anERR_NEEDMOREPARAMSreply if the number of parameters is insufficient.After a connection has been registered, the
RPL_WELCOMEreply must be followed by theRPL_YOURHOST,RPL_CREATED,RPL_MYINFOreplies (in that order). For theRPL_MYINFOreply, the user modes areaoand the channel modes aremtov.The
ERRORmessage sent in reply to aQUITmust include this error message:Closing Link: HOSTNAME (MSG)
Where
HOSTNAMEis the user’s hostname and MSG` is the<Quit Message>parameter provided in theQUITmessage. If none is provided, the default isClient Quit
Take into account the following:
The
NICKandUSERmessages can be received in any order, and a connection is not fully registered until both messages have been received (and neither contain any errors)If you receive any message other than
NICKorUSERbefore the connection registration is complete, you must send aERR_NOTREGISTEREDreply if that message contained a supported command (i.e., one of the commands we are asking you to implement in this project). Otherwise, you should just silently ignore that message. Take into account that, once registration is complete, this behavior will change (seeERR_UNKNOWNCOMMANDbelow)The
NICKcommand can also be used after the connection registration to change a user’s nick.You can safely skip the
QUITcommand and revisit it later, as no other commands depend on it.Most IRC servers send the replies corresponding to the
MOTDandLUSERmessages after the welcome messages are sent. Most of our tests expect this but, until you implementMOTDandLUSER, you can get away with simply sending the following replies verbatim::hostname 251 user1 :There are 1 users and 0 services on 1 servers :hostname 252 user1 0 :operator(s) online :hostname 253 user1 0 :unknown connection(s) :hostname 254 user1 0 :channels formed :hostname 255 user1 :I have 1 clients and 1 servers :hostname 422 user1 :MOTD File is missing
This will be enough to pass the connection registration tests (they check that the correct replies are sent, but don’t actually check whether they contain accurate information).
PRIVMSG and NOTICE¶
Implement messaging between users, as described in [RFC2812 §3.3], with the following exceptions:
The only supported
<msgtarget>is nicknames.You must implement the
ERR_NORECIPIENT,ERR_NOTEXTTOSEND. andERR_NOSUCHNICKreplies.
Take into account the following:
If user
user1sends a sequence ofPRIVMSGmessages touser2, thenuser2must receive them in the same order thatuser1sent them.If users
user1anduser2each send a single message touser3, the messages are not expected to arrive in the same order thatuser1anduser2sent them.
PING and PONG¶
Implement the PING and PONG commands, as described in [RFC2812 §3.7.2]
and [RFC2812 §3.7.3],
with the following exceptions:
You can ignore the parameters in
PING, and simply send thePONGresponse to the client that sent thePINGmessage.You must silently drop any
PONGmessages you receive (do not send aERR_UNKNOWNCOMMANDreply)
Take into account the following:
Implementing
PINGandPONGis essential to testing your server with real IRC clients. IRC clients will sentPINGmessages periodically and, if they do not receive aPONGmessage back, they will close the connection.
MOTD¶
Implement the MOTD command, as described in [RFC2812 §3.4.1],
with the following exceptions:
You can ignore the
<target>parameter.
Take into account the following:
Your server should read the “Message Of The Day” from a file called
motd.txtin the directory from where you ran the server.If the file does not exist, you must return a
ERR_NOMOTDreply.
LUSERS¶
Implement the LUSERS command, as described in [RFC2812 §3.4.2],
with the following exceptions:
You can ignore the
<mask>and<target>parameters.You must return the replies in the following order:
RPL_LUSERCLIENT,RPL_LUSEROP,RPL_LUSERUNKNOWN,RPL_LUSERCHANNELS,RPL_LUSERMEYou do not need to support the
ERR_NOSUCHSERVERreply
Take into account the following:
You must send the replies even when they are reporting a zero value (i.e., ignore this from [RFC2812 §5.1]: “When replying, a server MUST send back RPL_LUSERCLIENT and RPL_LUSERME. The other replies are only sent back if a non-zero count is found for them.”)
An “unknown connection” is any connected client for which we cannot yet tell whether the connection corresponds to a user (or, starting in Assignment 5, another server). Once a connection receives either a
NICKor aUSERcommand, we can assume that it corresponds to a user connection.The number of users in the
RPL_LUSERCLIENTreply is the number of registered users (i.e., connections that have successfully sent bothNICKandUSERand have completed their registration).The number of clients in the
RPL_LUSERMEreply is the total number of connections, not including unknown connections.
WHOIS¶
Implement the WHOIS command, as described in [RFC2812 §3.6.2], with the
following exceptions:
The command must accept a single parameter: a nick (i.e., there is only a single
<mask>, and it must be a nick; ignore the<target>parameter)Ordinarily, the
WHOIScommand can be used without parameters, so the RFC does not not require aERR_NEEDMOREPARAMSreply in this case. However, since we do not supportWHOISwithout parameters, if you receive such a message you should silently ignore it (i.e., don’t send any reply back at all)You must only send back the following replies, in this order:
RPL_WHOISUSER,RPL_WHOISSERVER,RPL_ENDOFWHOIS.You must supply a value for parameter
<server info>inRPL_WHOISSERVER, but we won’t be checking its contents.You must support the
ERR_NOSUCHNICKreply.
Take into account the following:
You will be implementing
RPL_WHOISOPERATOR,RPL_WHOISCHANNELS, andRPL_AWAYin the next assignment.
ERR_UNKNOWNCOMMAND¶
If, after registering correctly, your server receives any message not described here
(or in the next assignment), you must return a ERR_UNKNOWNCOMMAND reply.
Robustness¶
Your code must pass the “Robustness” suite of tests (see Testing your Implementation for instructions on how to run the tests). These tests check that your code does not crash in certain corner cases (e.g., when using messages that are 511, 512, or 513 bytes long), and when commands include arbitrary amounts of whitespace. This is not specified in the RFC, but most production IRC servers are able to deal with the kind of messages sent by the “Robustness” tests.