Chat Protocol (v1.0)

While the zChat Protocol is similar to the protocol used by MUDMaster, it is not the same, and is not formally compatible.  zChat recognizes both the zChat Protocol and the MUDMaster protocol.  For details on the MUDMaster Chat protocol, contact it's author directly.

The zChat protocol was designed to support enhanced chat security, and to be a robust network protocol.  In fact, zChat looks very much like any other TCP/IP protocol.

Definition of Terms

Client
The computer program that initiates the chat request.
Server
The computer program that listens for incoming chat requests.

So, the Client "calls" the Server, and the Server answers.

\t is a Tab character (Ascii code 9)
\lf is a Linefeed character (Ascii code 10) (\n on a UNIX system)
Items within brackets <> indicate data fields to be filled in.

Negotiating a Connection (Making a Call)

Request a connection

Send the following data through a normal TCP/IP packet.  The TCP/IP packet contains the IP address and Port number of the Server being called.   The data in the connection request packet is:

ZCHAT:<ChatName>\t<ChatID>\lf<ClientIPAddress><ClientPort>\lf<SecurityInfo>

The ClientPort is formatted as a five-digit number with leading zeros.  The sprintf syntax is: "ZCHAT:%s\t%s\n%s%-5u\n%s".  Optional information can be included in the connection request by adding another \lf after the SecurityInfo and then sending the optional data.

ChatName
is the name chosen by the Client, such as "Zugg".
ChatID
is a unique number generated when the user registers.  It can be used to distinguish between multiple instances of the same chat name.  zChat v1.x does not support the ChatID and simply sends a zero.
ClientIPAddress
is the IP address of the client making the request.   This is the local address of the Client machine, and is usually the address used to respond to the chat request, except for if the Client is behind a firewall.  zChat stores this address to be displayed to the user, but responds to whatever IP address the TCP/IP connection packet came from.
ClientPort
is the port number that the client is listening for chat requests on.   The default port is 4050.
SecurityInfo
is used to verify the identity of the Client.  This string can be a PGP-encrypted message, or a simple Security Phrase (see below for how this is used).   If the string is a PGP-encrypted message, then you must replace all newlines (CR/LF) with | characters to keep the message on one line.  In zChat, if PGP is used, the text "SecID" (without quotes) is encrypted using PGP v2.62 using the command line:
pgp -sea ServerPublicKey -u ClientSecretKey

The client then waits for a response from the Server

Connection Response

When the Server receives a Connection Request, it must determine whether or not to accept the connection.

Accepting a Connection Request

The Server accepts the connection request if the Server is set up to accept calls (not in Do Not Disturb mode).  If the Server is not in Auto-Accept mode, the user on the Server is prompted whether to accept the call or not.  Also, if the SecurityInfo is a PGP-encrypted message, the | characters are replaced with the original CR/LF characters, and is decrypted with PGP 2.62.  The output of the PGP decryption is checked to see if a valid digital signature was present.  If the digital signature was valid and the contents of the encrypted message was "SecID", the connection is accepted.  If SecurityInfo was not a PGP message, it is simply checked against the Security Phrase that the Server has listed for this Client (based upon the ClientChatName and ChatID).  If the Security Phrase stored on the Server matches what is sent by the client, the connection is accepted.  Finally, if the SecurityInfo field is empty, the connection is accepted.

To accept a connection, the Server sends a TCP/IP packet back to the client with the data:

YES:<ServerChatName>\lf

Also at this time, the Server sends several zChat commands including: Version, Icon, Status, Stamp, EmailAddr.  See the Commands section below for more details on these commands.

Denying a Connection Request

If the Server is not accepting connections or if the security tests fail, or if the Server wants to reject the request for any other reason, it sends a TCP/IP packet back to the client with the data:

NO

Note that the Server should not generate any spam on the screen until a connection is accepted.  This prevents hackers from generating text on the Server's screen by repeatedly trying to connect.  Of course, these attempts may be logged.

When the Client receives the Connection Request Response, it takes the appropriate action.  If the Connection Request was accepted, the Client then sends zChat commands including: Version, Icon, Status, Stamp, and EmailAddr.  See the Commands section below for more details on these commands.

Terminating a connection

Either the Client or the Server may terminate a chat connection at any time by simply closing the network socket.  Note that zChat connections are persistent; they remain open.  Once the socket is closed, it can only be opened again by initiating a new Connection Request as described above.

Chat Commands

Once the chat connection is open, the Client and the Server can communicate by sending commands.  Commands are normal TCP/IP packets that contain the following data format:

<CommandID><Length><Data>
CommandID
is a 16-bit value, with the lower 8-bits sent first, followed by the upper 8-bits.  It represents the ID of the command being sent.  Each Command ID is described below in more detail.
Length
is a 16-bit value, with the lower 8-bits sent first , followed by the upper 8-bits.  It represents the length of the Data field in bytes.  By using a Length field instead of a terminating character after the Data, any data value can be easily sent.
Data
is the data required by the command.

Command IDs

Name Change (1)

The Data is the new ChatName.  This is broadcast to all open chat connections whenever the user changes their chat name.

Request Connections (2)

This is used to query the public connections that someone else has.   The receiver responds with a Connection List command described below.  The Data for the Request Connections command is empty.

Connection List (3)

The response to the Request Connections command above.  The Data sent by the receiver is:

<IPAddr>,<Port>,<IPAddr>,<Port> etc

If there is no IP Address for a connection, the string "<Unknown>" is sent in place of the IP Address field.  For example, the Data field might look like:

192.168.0.2,4050,<Unknown>,4050,192.168.0.1,4000

Only data for Public connections are sent.  Private connections are kept private.

When the Sender of the initial Request Connections command receives the Connection List data, it then makes an attempt to connect to each one of the connections sent.

Text Everybody (4)

Data is the StampedText to send.  The Sender formats the entire message to be displayed (like "<Name> chats to everybody: hello") so the the Receiver just has to display the message.  The Sender should only send this command to connections that it is not ignoring.

StampedText has the format

<Stamp><Text>

where Stamp is a 4-byte session ID number.  When Sending, send your Stamp Code, which is the random number you generated and broadcast when zChat first started.  If the received Stamp value matches the Receivers Stamp ID, the message is ignored (since it represents a message loop).

Text may be PGP signed  with the Sender's SecretKey.  If so, the Receiver must decrypt the message using the Sender's PublicKey before displaying it.

As the Receiver, if the connection is not being ignored, print the Text message.  Then check to see if you are "serving" any other connections.  For connections that you are serving, echo the Text to those connections so that they see the message as well.

In zChat, the "serving" flag is set by the zChat user.   Connections are not automatically flagged as being "served" or not; it is left as a user choice.

Text Personal (5)

Like the Text Everybody command, but the Text is only sent by the Sender to a single Receiver.  The Sender formats the entire message to be displayed (like "<Name> chats to you: hello").  The Receiver simply displays the message.

StampedText has the format

<Stamp><Text>

where Stamp is a 4-byte session ID number.  When Sending, send your Stamp Code, which is the random number you generated and broadcast when zChat first started.  If the received Stamp value matches the Receivers Stamp ID, the message is ignored (since it represents a message loop).

The Text may be PGP signed with the Sender's SecretKey and encrypted the Receiver's PublicKey.  If so, the Receiver must decrypt the message before displaying it.

Text Group (6)

Like the Text Everybody command, but the Text is sent to a specific group of connections.  The Data field is:

<Stamp><GroupName><Text>

where GroupName is a 15-character string, padded with spaces on the left, that gives the Name of the group.  The Sender formats the entire message to be displayed (like "<Name> chats to the group <GroupName>: hello").   The Receiver simply displays the message.

Stamp is a 4-byte session ID number.  When Sending, send your Stamp Code, which is the random number you generated and broadcast when zChat first started.  If the received Stamp value matches the Receivers Stamp ID, the message is ignored (since it represents a message loop).

The Text may be PGP signed with the Sender's SecretKey and encrypted the Receiver's PublicKey.  If so, the Receiver must decrypt the message before displaying it.

As the Receiver, if the connection is not being ignored, print the Text message.  Then check to see if you are "serving" any other connections.  For connections that you are serving that are part of the same GroupName, forward the message to them also.

Message (7)

Data is the Text of the message

This is used to send system messages to another connection.   The Receiver simply prints the message.  zChat displays system messages on the status bar instead of in the main output window and keeps a separate log of them.   For example, if a connection tries to send you a file and you are not to allow files from that user, you would use the Message command to send a message like "Not accepting files at this time."

Version (19)

Data is the Version string.

This is used to send the version of the Chat client being used.   If zChat is running as a zMUD plugin, the version of zMUD being used is also sent.   The Receiver simply notes this information and can display it when requested by the user.

File Start (20)

This is sent to initiate a file transfer.  The Sender sends this command with a Data format of:

<FileName>,<Length>

FileName is just the name of the file, and not the Path.

Length is the length of the file to be sent in bytes.

When the Receiver gets this command, it first checks to see if it is accepting file transfers.  If not, it should sent a File Deny command back to the Sender.  If files are being accepted, any path information in the Filename is stripped, and an attempt is made to create the file.  If successful, the Receiver then requests the file contents by sending a File Block Request command.  If the file creation fails, the File Deny command is sent.

File Deny (21)

This is sent by the Receiver of the File Start command if there is a reason it cannot accept the file.  The Data for this command is a Message explaining the reason for the failure.  It might be something like "File already exists".  The Receiver of this File Deny message should print the Message and clean up any preparation that was made to transfer a file.

File Block Request (22)

This is sent by the Receiver of the File Start command whenever it is ready for a block of file data.  The Receiver of this message (the Sender of the File Start command) should send the next block of file data using the File Block command below.  If there is no more data to send, the File End command should be sent.

File Block (23)

This command is used to actually send a block of file data.   The Data is the raw data to be sent and can be any length.  zChat sends data in blocks of 1024 bytes.  The last block might be smaller than this.  The Receiver of this data should write it to the file being created and then request the next block by sending a Block Request when it is ready.

File End (24)

This command is sent in response to a Block Request when there is no more data to be sent.  The Data field is empty.  When the Receiver gets this message, it should close the file it has created and report to the user that the file was received properly.

File Cancel (25)

Can be sent by either side to abort a file transfer in progress.   The side sending the file should close the file and clean up.  The side receiving the file should close and delete the partial file and report that the transfer was cancelled.  The Data field is empty for this command.

Ping Request (26)

This command is used to determine the round-trip delay time between the two ends of a chat connection.  The Sender sets the Data field to anything it wants, but it is usually the Clock value at the time the command is sent.  The Receiver of this command simply echoes the Data field back to the Sender using the Ping Reponse command below.

Ping Response (27)

Sent in response to the Ping Request.  The Data field is the same data received from the Ping Request.  When the Sender of the Ping Request gets this data back, it can compare the Clock value in the data field that is returned (which is the time when the initial Ping Request was sent) to the current Clock value to determine how much time passed in transit.

Peek Connections (28)

Like the Request Connections command, this is used to examine all public connections of another person.  However, instead of connecting to each connection, the connections are just displayed.  The Receiver of this command sends the Peek List response.  The Data field is empty.

Peek List (29)

In response to a Peek Connections command, a list of current Public connections is sent in the Data field with the form:

<IPAddr>,<Port>,<IPAddr>,<Port> etc

If the IP Address is not known, "<Unknown>" is sent instead of the address.  This is the same format as the list used in the Connection List command.

When the Sender of the Peek Connections command gets the Peek List response, the list of connections are displayed on the screen.

Snoop (30)

Sends a request to start/stop snooping data from a chat connection.   The Data field is empty.  The Receiver of this message decides whether to allow snooping or not.  If denied, a Message command is sent back.  Otherwise, the Receiver goes into Snoop mode and sends data using the Snoop Data command below

Snoop Data (31)

Send by a client in Snoop mode.  The Data is the text that was just received.  Basically, the client in Snoop mode echoes any text that it receives to any connections that are snooping it.  This allows other clients to see the same data on their screen.  The client can exit snoop mode at any time and simply stop sending Snoop Data packets.

Icon (100)

Used to broadcast your custom graphical icon.  Data is the raw image data.  Currently this data is in Windows Bitmap format.

Status (101)

Used to broadcast your current status to all your connections.   Data is a single byte, with the value:

0 - no status
1 - Normal status
2 - InActive status
3 - AFK status

Whenever the status of the chat client changes, this command is broadcast to all chat connections.  Normal means the user is actively using the chat client.  InActive means that the user is using some other program on their system and the chat client is not necessarily visible.  AFK means that no keyboard or mouse activity has been detected in a while and the user is probably away from the computer

Email Address (102)

The Data field is the Email Address of the user.  Sent to all chat connections when the user wishes to broadcast their email address for offline communications.

Request PGP Key (103)

Sent to request the user's Public PGP key.  The Receiver of this message should respond with the PGP Key command below, or a Message command to deny the request.  The Data field is empty.

PGP Key (104)

Used to send the user's Public PGP key to a chat connection.   Usually sent in response to a Request PGP Key message, but can be sent anytime you wish to broadcast a Public Key.  The Data field is the Public PGP Key.

Send Command (105)

Used to send a zMUD command line to another user.  The Data field is the entire zMUD command line.  The Receiver of this command can choose to execute the command line, or it can send a Message denying the request if commands are not allowed from this user.

Stamp (106)

Data value is a random number generated when zChat starts and is broadcast to all users.  This stamp is also sent in all Text commands (TextEverybody, TextPersonal, TextGroup).  If Text message is received with the same Stamp code as the client, the message is ignored to prevent message loops.

When this message is received, the Stamp value received is compared with the clients stamp value.  If they are the same, the receiver generates a new random number and broadcasts it to all of its connections.  This ensures that every connection maintains a unique stamp value.

red_bar.gif (2193 bytes)
Page modified on July 23, 2001