Another historic prototype protocol of PSYC, which in contrast to VM Shell never got implemented.
Basically it was a more object oriented form of IRC protocol, not yet addressing many of the IRC scalability issues. So you could say PSYC has come a long way from the cafe.
A new CONFERENCE protocol called Cafe published on comp.protocols.misc in 1990 through the account of Snake.
The reason why it was called cafe is two-fold:
- I prefered the word play "relay cafe" over relay chat.
- I envisioned a regular cafe were people would sit at mainframe terminals such as 3270 or vt100 while sipping a coffee or cocoa and having a good time talking to people from somewhere else in the world. Again I thought relay cafe would have been a great name for such a thing. Nowadays they are called internet cafe, they have brand new PCs with webcams, neon lights, snacks and phone booths.
Contents |
CONNECTIONS
The system has 3 levels of communication:
- Server-server-communication:
- binary, basically like this: <source-id><target-id><text>
- Server-client-communication:
- also binary, similar to the one before.
- Server-user-communication:
- ascii, direct user interface, output to screen, input with cmdchars / etc.
You may ask what the difference is between client & user, & why I want it. The "user" is somebody issuing a line mode telnet to a server, & the server should be able to understand basic commands such as /j for join etc. so that people, who are banned on some weird system, do not get excluded from the rest of the chatting world, even though they have access to Internet.
It doesn't take much, so why shouldn't people be enabled to chat via Telnet, because some telnet always exists, when a system is connected to Internet, instead, writing new client software for each system isn't always as easy as one would want it to be. The server should therefore be able to recognize abbreviations and... I'll talk about this again later on.
The client instead is the program-controlled connection to the server, which should be able to open windows and some other things.
CONFERENCE OBJECTS
Conference objects are: User, Server, Group (was: channel)
the identificator
Currently IRC uses <nickname> <servername> & <channelnumber> to identify each of the conference objects, in my concept they all get to have a kind of conference-id, for names cause troubles (servers connecting and finding people having names of groups or servers or other weird situations) The <id> can be structured like this:
<net-id> <obj-id> <4-byte-address> = 6 bytes.
The <net-id> is a number from 1 to 64 identifying the net, where we could define 1-16 to be internet-kind nets (we only have one now, but who knows what future will bring) and 17-64 to be other nets, the difference is relevant for the <address>, the <address> is made up by 4 bytes - and guess, yes, it's the internet address, while on other nets we have to interface the node-id's into 4 bytes (for example BITNET) so only for internet addresses the 4 bytes have a significance also for the user, and should therefore be displayed in decimal+dot form if the user requests info about a server, while with the others this information should be suppressed. The <net-id> = 0 has a special meaning. In fact the <net-id> takes 6 bits, leaving 10 bits to the
Ah yes, I don't want to exclude other nets from conferences, the whole thing is conceived in a way it can be realized on bitnet, internet & i-don't-know-what-other nets, and all connected together, that means also that future brings much more users and conference data than IRC has to couple with today, but that's what a new protocol must be able to afford if it wants to be worth replacing our beloved IRC.
Here's the structures for the main conference objects, partly based on what has already been said by other thinkers :-)
the server structure
SERVER: <id> <father=host> <nickname> <status> <name>
The <id> is the <net-id><0><net-address>, <father> is the <id> of the Server it connected to. This data is passed through the whole network. Knowing the <father> of each server only one "unlink" message is needed so that each server can locally "quit" all the servers & users that depended on that link. <nickname> is a short form of the name a user can easily refer to, like "tolsun", "mit", "tumuc", "unido", "peru". The <status> I propose could be like this:
< ALIVE | SUSPENDED > is information that is spread for each server in the network. < ACTIVE | PASSIVE | STANDBY > is information only the directly connected servers need to have, so it is put into the connection structures.
Active means the server is connected, alive & has active objects, like users or password groups (see below). Passive is a server without objects, which therefore doesn't need to have the current conference structure updated, it's as if it wasn't connected, yet to the users and other servers there is no difference. Standby is almost the same, the server just decided (maybe after a timeout) to release the connection until some user signs on, on the other hand, if someone in the net requests a summon or so, than the "father-server" will try to open the connection again. But, if the connection fails or any other drops, than a "suspended" info is sent through the net, which doesn't mean the server has "left", it just tells other servers that they can, if they have that server in their connect-list, try to linkup instead! Should two connections be created, than somehow one will be dropped due to "already existing server". If after the burp-timeout still no connection could be created, the server is declared dead, and removed with all his sub-servers and users. It would probably be nice to tell all users, who are chatting with people on a burping line, that the connection is temp. suspended... if it doesn't happen too often! While the connection is suspended all messages to it are stored into buffers, so when a new connection has been established they can travel the new way to destination.
A server, that links to others together, but has no own users, might move into standby status, with the result that the servers create a direct connection between each other. Raise your hand if I'm getting too fantastic. ;-D Ah yes, i was forgetting the <name>, the name now is the network address users can connect to, for the numeric one contained in the id is of no use to BITNET users etc., organization name & geographical location (like "You can't find it in the atlas"). I'm not sure if this kind of information really has to be spread and stored into every server after all, if someone really wants to know the organization or exact location, he could send some command to the server (let his local server do it if he's a telnet-user or let the client do it if he's running one, so that user doesn't need to worry, that's transparency! :-)).
the user structure
USER: <id> ( <host> ) <standard-nick> <status> <name & address>
where <host> is unnecessary for the <id> with the <obj-id> set to null IS the <host-id>, this <id> is unique as long as the server is unique (server-id's on other networks should be defined by some higher instance). <standard-nick> is again a kind of user identification, it is the one users use to send a private message to somebody, a user might want to change his nickname inside a group, for some reasons of conversation, but still be reachable for others with his official <standard-nick>.
- [Some servers could even offer a netwide service to protect nicknames to be used by other people by assigning passwords to them. If a client using a protected nickname doesn't provide the password or change to a different one, he gets kicked out by this special server after a timeout.]
In normal use more than one user could have the same nickname without causing inconsistency, it would just make problems to the person who wants to send a message to that person, he'd get a sort of weird question like this: "Well, do you want larry from oink.cs.tum.de or from cunyvm.bit?" It's like a tty-select on UNIX, I don't think we should /kill users for their nicknames, if we don't need to anymore.
The <status> is the most complex element, and surely subject to change: Here's my proposal: <status> is devided in groups: <level> <flags> where <flags> is <VISIBLE|INVISIBLE> & <HUMAN|AUTOMATON> and <level> is currently 0-4:
4 -- Netwide operator, these people have to be registered, otherwise they get blasted, even if their server announces them as such. they have technical privileges that are yet to be defined, However nothing like reading other peoples chat, or similar! 3 -- Local operator, also someone who is entitled to enter the operator group (a kind of channel where people having problems can send a message to or operators can discuss technical stuff). This operator type has a few netwide entitlements, too. 2 -- "Master" user, a user who is entitled to open up groups as many as he likes and all the normal user stuff. This is the default a new user gets if the server isn't setup in an other way. 1 -- Simple user, if people play around with groups, by opening many of them or in some other way behaving badly, this is something to scare them off with, a simple user can only open one new group, for all of his session! And he is not entitled to send a message to a group he's not in, so he can't annoy people in "semi-private" groups. 0 -- Guest. This is the situation where a user can only join other peoples' channels and can request only restricted services from servers and... well, let's not be too cruel...
The most important privileges the net-op has is to change all data in every server. That means that he can change any data in the object structures net-wide, I know this is dangerous, the net-op can raise or lower other users in their level, make password groups open to all and so on. Maybe it isn't that good after all, if he can do THIS much! This is something to discuss & flame about again...
A little note about visibility: if a user is not interested in being publicly accessable, he's not just marked as such, his data isn't even transmitted to servers who do not need to know! Only those where other people chat in same groups with them are put into knowledge, and, if the software has not been modified by hackers, also the servers on the way ignore the user-data, if it's not meant to be public, and just pass it to destination, in fact no server has to care about the contents of a message if it's just for one defined destination, so future command expansion is no problem.
the group structure
Well, this should be the replacement for channel, it's more generic, as others have said. Each user can be part of <n> groups, some by default like "all" or "oper" or "local" (the group of local users), and some created and then chosen, like "fin42", the future finnish group :-), here's a possible definition for it:
GROUP: <id> <owner> <name> <limit> <status> <list-of-users> <topic>
<id> is the usual id defined by the server who created it for a user.
<owner> are 2 bytes that mean the following: if it's null, than the group is of type public, anyone can enter it. if it is a number between 1 and 1024, than this is the number of the owner, he is the "moderator" of the group, he can decide explicitily who is entitled to enter a group, in fact the users he summons are directly put into the group, but with a flag of "standby", not really inside. Only a message carrying the owners' <id> will be entitled to modify the group data on all servers, and a server should check if the message comes from the right "direction", if it doesn't it should immediately warn all operators, cause this would only happen if someone modified the server sources to permit that! If the owner is negative, than the group is owned by the server itself, this means the server handles the people who want to get it, normally by requesting a password, if someone sends a requested-join message containing the password this user is joined into the group. Of course server could also make up other criteria, like a group for finnish only :-)). If no owner is defined, the structures can only be modified by entitled operators (in that case the server would give some info into the oper group about the fact, so that again people misusing the id of netwide opers could be found) except for the join stuff, if its public, then joining is ok. If a netburp occurs, the group is still in domain of the owner, only that the owner isn't active anymore, the people can still chat in that group, but nobody can be invited, new groups have to be created if that case is found, but, in most cases no owner will be needed anyway.
<name> a nickname for a channel, can be numeric, so that good old IRC can be interfaced into this. :-), the name should not be changed after creation.
<limit> maximum user in group number, null is endless, operators can change this value if the group is not owned (anymore).
<status> is made out of flags, where on/off means visible/invisible. nickname on/off, nameslist on/off, topic on/off, secret off/on.
- name off means the name of the group is not listed, neither for those outside nor those inside, so a public channel can have a hidden name even though everything else is visible, yet the name is needed to enter such a channel, of course an owned one doesn't need to hide the name. - list off means the people inside the group are not listed, this group would then not appear in /names, even if everything else is open. - topic on/off is obvious, a group can decide to keep it's topics hidden, in that case the group would not appear in /list. - secret now is somehow the combination of all, but it means more: a secret group is not told to servers, who do not need to know it, and to those, who are inside or enabled to come inside, all data appears when they call /names or suchlike, let's say, with /groups they can see the bits that have been set, and giggle if they have secret ones at their disposition.
I decided, that if a group is not secret, at least the number of people using it can be decovered, like /list does on IRC, because it doesn't say much anyway, just that people can find out if others are having a ball without letting it know. ;)
<list-of-users> The format could be: <id><f><nick>#<id><f>#...#<id>#...## where <id> is the user-id of one user, f is a flag saying if this guy is really active, listening to what is said, or if he's just entitled to come in anytime (e.g. if he closed the window with the gadget). <nick> is the nickname, given only if it isn't the official one. Also <f> can be left out, if both <nick> & <f> are the defaults. The right default for <f> i don't know, experience will tell if people like to have many accessable groups or they really enter them all. Ah yes, the <f> flag is only needed for non-public groups!! End the # is the delimiter, could be a <spc> for instance. End-of-List could be defined by a double-delimeter, or by putting the whole list into brackets {...} ..., then comes the
<topic> ascii string.
future object structures - user defined structures!?
even future object structures could be introduced later on, like, for example, an adventure room structure, containing the id's of other adjacent rooms and other info, those servers who will not know such a structure will simply pass it on.
PROTOCOL
From server to server
There are three formats of a message:
1) Messages with specific destination: - a user or server - a group of users (a group of servers??, users & servers?, servers running game services?) 2) Broadcast messages (for all servers and/or users). 3) The ping/pong message.
1) MSG TO; the format is: <from><to><nu><text>0 where from & to are id's, to doesn't even have to be known precisely if it's a secret user or group the message gets to destination just the same, because only the <address> is checked, not the <obj-id>, well, to be exact, the server first checks if <to> is a known group, if it is, then there must be some users/clients who want to know about this message after it has been passed to the next servers! If the address is oneself, then it must be some message or notice for a single user or a locally defined group (would be found on the check before), or, if it's 0, a server service request. These services are not bound to be the same, they can grow with time, for example small files could be available for the user to dump, or a note could be dropped for a user that is not present, the server could then check the /etc/passwd if this guy really exists. Imagining a server to run a game, or to join groups is possible, who knows, future might find applications where this prooves useful. <text> is the actual command and parameters in binary format! Only the receivers need to understand the meaning of it. <nu> is a not used byte left for future expansion, I thought about the possibility to use it as a message counter, so that a message can be identified, the consequence is clear: circular networks could be based on that, if servers for example keep a history of incoming messages, they would recognize double ones & avoid processing them. The sender too should keep a history of 256 messages he sent, so that it becomes impossible, that a message isn't considered if it is sent again, the same way, exactly 255 messages later. The server would detect this and choose a different message-id-number. I have no idea sincerely, is this a realistic view? These are the kind of things one should learn in university before thinking about them. Right? Well - I consider it future expansion anyway, so don't worry if it's stupid.
2) MSG ALL; here the format is: <from>0<nu><text>0 Now you know why the network-id cannot be 0, cause 0 is the way to identify null id's! This message has somehow no destination, it means that all servers shall process it the way the command in <text> requires, servers won't panic on unknown commands, let's leave everything open for expansions. What I forgot to say before: <text> can obviously not contain the 0-char for I imagined 0 to be the EOL-marker. (I'm just phylosophing, I don't really know if an 0 can be used such way in the TCP/IP!). A "WALL" could be coded like this: <network><obj-id><hostaddress>00<PRIVMSG-code><real-text>0
3) PING; format: 0 A lonesome 0, where nobody expects it, is the ping message, it is answered with another 0. The server that pings sets the PING-SENT status in the connection-structure, so, when such a 0 comes back, it knows it's not a ping, but a pong! If by chance both send pings at the same time, everythings fine, they'll interpret them as pongs on the other side. Of course this is not for time measuring, but for connection checking it is cool, isn't it?
Here's to the actual commands, I'll just propose some, I don't think I should get that deep into stuff, that in the end gets decided during development...
There should be two basic kinds of message, the message and the notice. The difference lays in the fact that the notice appears without header, and it can (should) only be sent by servers... and maybe... entitled automatons? Well, that's something the local server has to cope with, then.
Then there are the conference system commands, that can only be sent to servers or "all", like SERVER, USER & GROUP, the CANCEL command that can "destroy" any of these structures, the REMOVE command that can be sent by servers or opers, just like /kill. Of course correct restrictions have to be found - only the netwide-ops should be able to kill a server, and if this happens it should be logged here & there... or everywhere? the MODIFY can be imagined as a multipurpose command, it's args are an <id> of some object, the parameter number and the new value. For lists a JOIN & PART is needed, that is a bit like a cut & paste. Of course such commands need to be ultra-controlled!! Only the owner can modify the registers of his group, and some registers are NOT to be modified, like the name of a server!! On the other hand, a user is now entitled to modify his signup name... but not his real address (userid @ node). Of course these commands should have binary counterparts, don't get confused by the names, they're just #defines in a headerfile. :-)
Getting inspired by the never used VOICE, XTRA & GRPH commands of IRC I'd say that a file and/or picture dump could be defined, and that a file dump must first be announced to the counterpart, which then allows or not (some pic receive flag?), if a server on the way thinks he cannot afford a dump because of too much traffic he'll just send a notice about that...
From server to client
To be exact there are two types of clients, the passive & the active ones. News to you? I'll explain: The IRC-clients are passive clients in my distinction, cause active clients are those, who keep their own lists of users in the system and therefore avoid bothering the server with /names, this has good & bad sides, but in my experience with these kind of clients I think they should be considered. So this part is dedicated to the active clients, for the passive ones could either easily make use of the TELNET-USER interface or a binary one where data is transmitted in the same format as for the server, only that the right data arrives and the right data is permitted to leave. So the passive client just enhances the output & this & that... Let's instead imagine an active client in a Xwindows or similar environment. Of course the new software would have to open windows for each group, or mark gadgets in a way that they show they can be opened. Let's say one window contains groups, each group with a graphic symbol that the mouse can click on, an owned group with a closed door or a doorbell, clicking on this symbol will cause a join-request to be sent... once.., if the person got invited the door stands open, clicking on it will open a window for the actual group chat. Password groups are shown with a keyhole, selecting it the user will be prompted (requester) for the password, or the password will be read from a rc-file. If the password's right, then the key fitting into the keyhole appears, if it isn't then the group vanishes. No-name groups would have a question mark, and so on. If the client is an active one, it would get updates concerning groups being created or canceled and show them immediately at the screen. If the user wants to open up a group, he can choose this command from a menu and will be prompted for the parameters in a requester-window, parms are the name, flags, own-flag, optional password, preset topic and most of all ** people! **, if it's a public channel people just get an invite-notice on their main window. There can be also an other window, the people window, all people, or only known ones appear with gadgets, if one clicks on them a dialogue-window is opened... One could dream hours about it... So I'll better stop getting further into this.
One thing in general about clients: they should all support the coded chat with crypt algorythms, again passwords could be read from rc-files (one for each group) and the messages coded & decoded that way, the password itself must be told to the people individually, the securest way would then be to email it! Note: the crypt password and the group entry passwords are independent, but they can be the same. The whole thing should be transparently automatic, once the passwords are in the rc-file opening up those groups and talking coded should happen without user's explicit request. This should be a quite effective way of protecting the chat!
From server to TELNET-user
Well, think about a basic IRC-client, then you are near to what I want. It's just the structures that make things different:
Some commands:
/c(hoose-current-group) /m(essage-to-user/group/server) \ (switch-to-last-query-mode), / (switch-back-to-group) \nick (set-query-partner)
Some possible outputs:
- person from current group says something (nick) blah blah - person from other group speaks group (nick) blah blah again - private message (*realnick*) text - notice from server No one logged on tolneptune. - oper goes wall all (realnick) text - oper wall's with notice Server tolvenus coming down for one & half seconds. - user sends /h g Help on /Gengrp - Generate a new group. Format: /g [-o] [-p passwd] [-l limit] [-n -u -t -s] name [users] - user sends /topic, response is joined-myself+flags+pw/own name topic ----s- secro "you're one of the ... phew!" *--t-- hi "you can only read this topic because you're in the group" *nu--p ? "we're hungry /m bogart" -----o pi314 "this channel is mine, but i might let you in /m pi" - user sends /list, response: joined/open+flags+pw/own name list-of-users ----s- secro one two *--t-- hi some one else pa -----o pi314 pi pa po - user sends /hosts, response: servernick people-on-that-server tolsun WiZ root tolmoon janne_b tumvm lolo Lynx JMD Snake43 Larry ... (hosts without users do not appear) - user at tumvm sends /links, response: father sons lrzmuc tumvm fauern lrzmuc belwue cnam belwue irauka cunyvm ... - user sends /who wiz tumvm secro WiZ is net-op Jarkko Oikarinen (j...@tolsun.oulu.fi) via tolsun tumvm is server VM Technische Universitaet Muenchen, FRG (dm0tui1s.bit) secro is secret group of 2, not joined, "you're one of the ... phew!"
Something unimportant to conclude: A telnet user should have the right to go /away, too. If he does, than the server shouldn't expect pongs from him, where ping would be a notice saying *ping*, and the user goes /p. But, is this pinging really needed here?