Conferencing protocol behavior
{
ChatNet server responses
Version 0.02 - unreleased
Last modified: 01-04-96
Written by G. Hiddink
13-03-96 if a server sees a channel in a CHLST it is interrested in,
it should broadcast a CHREQ instead of unicasting one.
25-03-96 if a server receives a CHREQ from a server, it should send
a CHREQ back if the other server isn't already on the channel
30-03-96 replaced a few references to CHDAT by SIGNON...
}
This file tries to explain what a server B should do when it receives a
message from server A. This includes what it should do when the message
cannot be processed due to missing or inconsistent information.
When <Message> is mentioned in an error reply, then the message that caused
the error should be sent in the error reply.
CHREQ <ChanName>
<ChanName> unknown to B:
add <ChanName> to B's channel list
A is already in the serverlist of <ChanName>:
only send CHDATA /* just to make sure */
else:
send SIGNON's for all users on server B unknown to A
send CHDATA message to A with all users on server B
A is not on the serverlist of <ChanName>:
send CHREQ <ChanName> to A /* NOTE: the CHREQ message MUST be sent _after_ */
add A to the serverlist of <ChanName> /* the CHDATA message! */
CHREL <ChanName>
<ChanName> unknown to B:
add <ChanName> to channellist of B
<ChanName> not in B's subscribed channellist:
No action necessary
else:
remove A from serverlist of <ChanName>
CHDATA <ChanName> (<User><UserMode>) * <ChannelMode>
<ChanName> unknown to B:
send <UnknownChan> <Message> to A
B not subscribed to <ChanName>:
reply with CHREL <ChanName>
for each <User><UserMode>:
<User> unknown to B:
send <UnknownUser> CHDAT <ChanName> <User> <UserMode> <ChannelMode> to A
else:
if <User> not already at <ChanName>
add <User> with <UserMode> to channel
notify users of B at <ChanName> of that event
set channelmode to <ChannelMode>
A is not yet in <ChanName>'s serverlist:
add A to serverlist of <ChanName>
send CHREQ <ChanName> to A
CHINQ
send CHLIST <ChanName> * to A, containing the channel list of B
SRVLIST
if this server doesn't know <ChanName>
add it to the list of known channels
if this server is interrested in <ChanName>
for each serverid in the list
if the server is not in the channel's serverlist
send CHREQ <ChanName> to the server /* collect a destlist and use multicast */
else
send CHREL to each serverid in the list
/* the CHREQ is broadcast globally to regenerate routing tables */
CHLIST <ChanName> *
for each channel in the message:
if <ChanName> is unknown to B:
add <ChanName> to channel list of B
add <ChanName> to new_broadcastlist
else:
if the serverID of this server is smaller than the server sending the CHLIST
start a sum SRVREQ algorithm for <ChanName>
broadcast CHNEW new_broadcastlist
/* received by broadcast */
CHNEW <ChanName>
<ChanName> unknown to B:
add <ChanName> to channel list of B
<ChanName> is on B's subscription list and A is not in the serverlist of <ChanName>:
send CHREQ <ChanName> to A
add A to serverlist of <ChanName>
else:
no action necessary
/* received by broadcast */
CHANANN <ChanName>
<ChanName> unknown to B:
add <ChanName> to channel list of B
<ChanName> is on B's subscription list and A is not in the serverlist of <ChanName>:
broadcast CHREQ <ChanName>
else:
no action necessary
TOPIC <User> <ChanName> <Topic>
<User> unknown to B:
send <UnknownUser> <Message> to A
<ChanName> unknown to B:
send <UnknownChan> <Message> to A
<User> not at <ChanName>:
send <UserNotAtChan> <Message> to A
else:
change topic of <ChanName> into <Topic> on behalf of <User>
notify users of B at <ChanName> of this event
MODE <ChanName> <Mode>
<ChanName> unknown to B:
send <UnknownChanName> <Message> to A
else:
set mode of <ChanName> to <Mode>
notify users of B at <ChanName> of this event
CHDIE <ChanName>
<ChanName> unknown to B:
no action necessary
<ChanName> is on B's subscription list
broadcast CHNEW <ChanName>
else
remove <ChanName> from B's channel list
SIGNON <User> <UserInfo>
<User> already known to B:
update <UserInfo> if necessary
else:
add <User> to B's user list, storing <UserInfo>
SIGNOFF <User>
<User> unknown to B:
no action necessary
else
remove <User> from B's user list
/* this is one of the messages for which no purpose is found yet. It seems to
violate the statelessness of the protocol when it is used to get information
for a /whois remotely. */
USRREQ ( <User> ) *
<User> unknown to B:
send <UnknownUser> <Message> to A
else:
send USRDATA <User> <UserInfo> to A
/* this one is weird too. Dunno why I invented it. Could be handy some day;
could be annoying... */
USRDATA ( <User> <UserInfo> ) *
dunno what a server could possibly do with it; perhaps it could inform the
user that requested the data.
/* this one seems to interact with the previous one */
USRINQ
send USRDATA (<User><UserInfo>) * to A
/* dunno this one either; firstly, a <ChanName> seems necessary to preserve
statelessness */
USRLIST ( <User> ) *
do something nice with the userlist
JOIN <UserNum> <ChanName> <UserMode>
<UserNum> unknown for server A at server B:
send <UnknownUser> <Message> to server A
<ChanName> unknown to B:
send CHREL <ChanName> to server A
add <ChanName> to channel list of B /* broadcast CHNEW? */
<ChanName> not on subscription list:
send CHREL <ChanName> to server A
else:
construct <User> from <UserNum> and A's ServerID
<User> already on <ChanName> with <UserMode>:
no action necessary
else:
add <User> to userlist of <ChanName> with mode <UserMode>
notify users of B at <ChanName> of this event
LEAVE <ChanName> <UserNum>
<UserNum> unknown for server A at server B:
no action necessary
<ChanName> unknown to B:
send CHREL <ChanName> to server A
add <ChanName> to channel list of B
<ChanName> not on subscription list:
send CHREL <ChanName> to server A
construct <User> from <UserNum> and A's ServerID
<User> not known to B, or not at <ChanName>:
no action necessary
else:
remove <User> from userlist of <ChanName>
notify users of B at <ChanName> of this event
SAY <UserNum> <ChanName> <Text>
<UserNum> unknown for server A at server B:
send <UnknownUser> <Message> to A
else:
<ChanName> unknown to B:
add <ChanName> to channellist of B
<ChanName> not in B's subscribed channel list:
send <ChanRel> to A
if no errors:
construct <User> from <UserNum> and A's ServerID
<User> not known to B:
send <UnknownUser> <Message> to A
else:
<User> not at <ChanName>:
add <User> to <ChanName> and notify local clients
else:
notify local users of B at <ChanName> of <User> saying <Text>
ACT <UserNum> <ChanName> <Text>
do almost exactly the same as with SAY: notify users of <User> doing <Text>
MESG <FromUserID> <ToUserID> <Text>
<FromUserID> unknown for server A to B
send <UnknownFromUser> <Message> to A
<ToUserID> unknown to B
send <UnknownToUser> <Message> to A
else:
send <ToUserID> a private message <Text>, originating from <FromUserID>
INVITE <FromUserID> <ToUserID> <ChanName>
<FromUserID> unknown for server A to B:
send <UnknownFromUser> <Message> to A
<ToUserID> unknown to B:
send <UnknownToUser> <Message> to A
<FromUserID> not in userlist of <ChanName>:
add <FromUserID> to userlist of <ChanName>
notify users of B at <ChanName> of this event
notify <ToUserID> of the fact that (s)he is invited to <ChanName> by <FromUserID>
else:
notify <ToUserID> of the fact that (s)he is invited to <ChanName> by <FromUserID>
NICK <User> <NewNick>
<User> unknown for server A to B:
no action necessary?
else:
notify users of B at all channels in <user>'s channel list of this event
UNKNOWNCHAN <Message>
<Message> is CHDATA <ChanName> (<User><UserMode>) * <Topic> <ChannelMode>:
remove A from serverlist of <ChanName>
<Message> is TOPIC <User> <ChanName> <Topic>:
remove A from serverlist of <ChanName>
<Message> is MODE <ChanName> <Mode>:
remove A from serverlist of <ChanName>
UNKNOWNFROMUSER <Message>
<Message> is MESG <FromUserID> <ToUserID> <Text>
send SIGNON <User> <UserInfo> to A
send <Message> to A
<Message> is INV <FromUserID> <ToUserID> <ChanName>
send <SIGNON <User> <UserInfo> to A
send <Message> to A
UNKNOWNTOUSER <Message>
<Message> is MESG <FromUserID> <ToUserID> <Text>:
notify <FromUserID> of the fact that <ToUserID> does not exist at A
<Message> is INV <FromUserID> <ToUserID> <Text>:
notify <FromUserID> of the fact that <ToUserID> does not exist at A
UNKNOWNUSER <Message>
<Message> is TOPIC <User> <ChanName> <Topic>:
<User> is unknown to B:
no action necessary
<ChanName> is unknown to B:
no action necessary
<User> is not on <ChanName>:
send LEAVE <User> <ChanName> to A /* just to make sure */
else:
send SIGNON <User> <UserInfo> to A
send JOIN <User> <ChanName> to A /* just to make sure */
send <Message> to A
<Message> is JOIN <User> <ChanName>:
<User> is unknown to B, or <ChanName> unknown to B, or user not on <ChanName>:
no action necessary
else:
send SIGNON <User> <UserInfo> to A
send <Message> to A
<Message> is SAY <UserNum> <ChanName> <Text>:
<User> is unknown to B, or <ChanName> unknown to B:
no action necessary
<user> is not on <ChanName>:
send LEAVE <User> <ChanName> to A /* just to make sure */
else:
send SIGNON <User> <UserInfo> to A
send JOIN <User> <ChanName> <UserMode> to A
send <Message> to A
<Message> is CHDATA:
<User> is unknown to B, or <ChanName> unknown to B:
no action necessary
<User> is not on <ChanName>:
send LEAVE <User> <ChanName> to A
else
send SIGNON <User> <UserInfo> to A
send JOIN <User> <ChanName> to A
<Message> is USRREQ:
dunno
USERNOTATCHAN <Message>
(c) 1996 by G. Hiddink
If you have any comments, please mail to
grit@cal050031.student.utwente.nl