The "psyc:" URL type currently being the only supported one, can be left out. Hostname information may not be left out, also port information should be provided. Object-names may also be provided, so you can directly start to communicate with a specific object on a server, if it exists.
Commands are not to be integrated into the URL used by the MTP. They must be extracted by the client program and handled on the PSYC layer.
Especially for secure communication, the {source} URL may have an asterisk '*' appended followed by a {signature} which is a series of non-zero bytes. This {signature} is generated by the client and sent to trusted mtp daemons only. The mtpd pass the signature on, but the last mtpd gives the target client only the information, that this user is certified by {signature}, not the {signature} itself. Should anyone attempt to fake a user's message, he will need to obtain the {signature} from a hacked mtpd, which will hopefully be hard to achieve, especially since the sender can choose which mtpds to use.
vl-ints are used to specify the length of a message.
{packet} := [ {revision} := {one byte} 0x81, UDP only ] {length} := {vl-int != 0} {msg counter} := {one byte} [ {target} := {null-terminated string} UDP only ] [ {flags} := {one byte} UDP only ] [ {source} := {null-terminated id} ] [ {eff targets} := {null-t. list of ids, seperated by ' '} ] [ {frag#} := {vl-int} ] {data} := any binary information [ {route trace} := {null-t. list of ids, seperated by ' '} ] {flags} := 0x01 # targets are provided in each msg | 0x02 # source is provided in each msg | 0x04 # fragment numbering is provided | 0x08 # attach route trace to the msg as it travels | 0x10 # send route trace notifications backThe {target} is either one object id or a {group name}, such that if the group is already defined, the {eff targets} which is the list of objects on that group can be left out.
The {msg counter} is a number the originator increments for any message it sends out to any destination, so that {source} id plus {msg counter} produce a unique message identification. The client program restarts the {msg counter} unavoidably at 0x100, and picks a random value at startup.
On TCP connections directly between clients this may seem rather paranoid, but in case of a network failure a connection and incomplete message buffers can safely be dropped as messages can be resent or requested for resending.
{msg id} := {source} {target} {msg counter} [ {frag#} ]
{control msg} := {escape} := 0x00 {length of msg} := {vl-int} {command} := {vl-int} [ {arguments} ] := {depending on command}Control commands are:
## NOT! like this, I forgot the reply-flag! So the numbering is wrong.
#def FLAGS #def ACK-TIME 0x00: AYT # Are you there? 0x01: QINFO # Reissue header info 0x20: TARGETS # Destination is {targets} 0x21: SOURCE # Origin is {object} 0x40: QMSG # Please resend {list of message ids} 0x70: INFO # Header information, details below 0x80: OK # Ok (positive acknowledgment) 0x81: ACK # Acknowledgment of received {list of message ids} 0xa0: EUNDEF # No such {object} defined here 0xc0: RTEMP # {object} is currently reachable as {id} 0xc1: RPERM # {object} has permanently moved to {id}.The temporary relocate will be a very common message, as whenever a user is logged in, his psyc server is likely to inform inquiring users directly of his current host and port number. A permanent relocate message is typically generated whenever a user changes home server, or a channel does. These conditions are handled on this low level, since they will be relevant to message routing in future revisions of MTP.
{TCP hello} := {protocol name} := {3 bytes, ASCII: "MTP"} {MTP revision} := {ASCII representation, '1'} '\r\n' := CR LFAs the communication between two entities begins, basic information needs to be exchanged. Whenever a TCP connection is established the caller first transmits the {TCP hello} which in a human readable tells the callee that binary MTP protocol is going to follow. The callee may choose to generate this message immediately, too, or await the caller's. The caller may directly proceed to send the MTP {header}, which is itself a {control msg}. The callee may again choose to await the {header} or send it immediately after link creation, too. This allows the callee to handle other protocols as HTTP on the same port with PSYC, if it chooses to. Both send the {TCP hello} and the {header} information in the same format.
In the case of UDP communication, no "hello" messages are exchanged. The first message that is sent with UCP is the {header}. If the other side agrees that it hasn't communicated with you for a while, it will send the {header} as well. If it doesn't you'll have to request it (as the first data packet comes in and you wonder what to do with it).
{header} := {MTP revision} := {one byte: currently 0x01} {my id} := {null-terminated string} {your id} := {null-terminated string} [{TCP flags}] := {one byte, as defined above}
The link-flags are significant mostly for the MTP daemon implementation so that it can tell another MTP daemon where a message comes from and where it belongs to, as well as being able to split up huge messages into smaller ones for transport safety. Particularely important when using UDP, as the messages then have a limit of 512 bytes.
Client implementations may choose to reject (with the appropriate error message) any incoming connection that attempts to use a format other than flags 0 or 2. Even UDP-capable ones.