Zesstra@Morgengrauen | 5cad50a | 2016-04-19 21:44:10 +0200 | [diff] [blame^] | 1 | intermud v2.5 |
| 2 | ************* |
| 3 | |
| 4 | Abstract |
| 5 | ======== |
| 6 | This documents describes how intermud data is send across the internet in the |
| 7 | protocol specification v2.5. |
| 8 | This specification is derived from Zebedee Intermud (aka Intermud 2) and |
| 9 | intends to be compatible to it, i.e. hosts conforming to both protocols should |
| 10 | be able to exchange data. The aim of v2.5 is to deprecate several historic |
| 11 | ambiguities, define a more consistent (stricter, less implementation-defined) |
| 12 | behaviour, add some optional system services and improve reliability and |
| 13 | remove spoofability of MUDs by introducing hash based message authentication |
| 14 | codes. |
| 15 | |
| 16 | Introduction |
| 17 | ============ |
| 18 | |
| 19 | Overview |
| 20 | -------- |
| 21 | The intermud protocols define, how (players on) different muds can |
| 22 | communicate with each other. There are several different variants. |
| 23 | In version 2 all muds are peers and directly talking to each other. There |
| 24 | is no central router. Version 2.5 keeps this behaviour but intends to |
| 25 | strengthen the P2P character of the intermud by defining a default |
| 26 | behaviour of learning other peers from one known peer. |
| 27 | The participants of the intermud are intended to be MUDs, not |
| 28 | individual players. |
| 29 | |
| 30 | Terminology |
| 31 | ----------- |
| 32 | The capitalized key words "MUST", "MUST NOT", "REQUIRED", "SHALL", |
| 33 | "SHALL NOT", "SHOULD", "SHOULD NOT", "RECOMMENDED", "MAY", and |
| 34 | "OPTIONAL" in this document are to be interpreted as described in BCP |
| 35 | 14, RFC 2119 [TERMS]. |
| 36 | |
| 37 | MUD |
| 38 | multi user dungeon |
| 39 | intermud peer |
| 40 | a participant in the intermud |
| 41 | inetd |
| 42 | a program encoding and sending and receiving and decoding intermud data |
| 43 | peer address |
| 44 | IP address of a peer (MUD) |
| 45 | MUD name / peer name |
| 46 | a name (string) for a peer (MUD) |
| 47 | peer identifier |
| 48 | a unique combination of MUD name, peer address and peer port |
| 49 | |
| 50 | |
| 51 | Transport layer |
| 52 | =============== |
| 53 | Data between intermud peers is sent as UDP packets (datagrams) over |
| 54 | IP. |
| 55 | Each peer listens on one port and uses one to send data. This kind of |
| 56 | transfer is inherently unreliable, but it's fast and doesn't use up |
| 57 | file descriptors. |
| 58 | |
| 59 | Packet length (MTU) |
| 60 | ------------------- |
| 61 | A peer **MUST** be able to send and receive datagrams of at least 1024 |
| 62 | byte length. The default packet length **SHOULD** be 1024 bytes. If a peer |
| 63 | announces a greater possible length limit, that **SHOULD** be used by other peers |
| 64 | when sending packets to this peer. |
| 65 | |
| 66 | Packet format |
| 67 | ------------- |
| 68 | All information is encoded and transferred as a string of bytes. The header |
| 69 | names **SHOULD** consist of ASCII characters. |
| 70 | Each packet sent consists of a string as follows: |
| 71 | |
| 72 | M:xxx|V:nnn|F:nnn|header1:body1|headerN:bodyN|DATA:body-data |
| 73 | |
| 74 | In other words, a header name, followed by a : and then the data |
| 75 | associated with this header. Each field, consisting of a header/body pair, is |
| 76 | separated by the | character. This means that headers and their body cannot |
| 77 | contain the | character. Peers **SHOULD** check for this in outgoing |
| 78 | packets to avoid decoding errors at the receiving end. |
| 79 | |
| 80 | The exception to this is the DATA field. If it is present, it **MUST** |
| 81 | be positioned at the end of the packet. Once a DATA header is |
| 82 | found, everything following it is interpreted as the body of the DATA |
| 83 | field. This means it can contain special characters without error and |
| 84 | it is used to carry the main body or data of all packets. |
| 85 | |
| 86 | By convention, predefined system fields will use capital letters for |
| 87 | field headers and custom headers used by specific applications will |
| 88 | use lowercase names to avoid clashes. |
| 89 | |
| 90 | A header name **MUST** be unique in a packet. |
| 91 | |
| 92 | The fields M (hash based message authentication code), V (version) and F |
| 93 | (flags) **MUST** be in this order at the start of the packet before any other |
| 94 | fields. |
| 95 | |
| 96 | Fragmented packets |
| 97 | ------------------ |
| 98 | If a packet exceeds the maximum packet length, it **MUST** be split |
| 99 | (fragmented) into individual packets small enough. |
| 100 | Each fragment **MUST** start with a fragmentation header describing how the |
| 101 | fragments are to be reassembled at the receiving end. |
| 102 | |
| 103 | These fragmentation headers are of the format: |
| 104 | |
| 105 | PKT:mudname:packet-id:packet-number/total-packets|M:xxx|rest-of-packet |
| 106 | |
| 107 | In this case, the mudname and packet-id combine to form a unique id |
| 108 | for the packet. The packet-number and total-packets information is |
| 109 | used to determine when all buffered packets have been received. The |
| 110 | rest-of-packet part is not parsed, but is stored while the receiver |
| 111 | awaits the other parts of the packet. When/if all parts have been |
| 112 | received they are concatenated and decoded as a normal packet. |
| 113 | |
| 114 | Each fragment **MUST** contain its own valid HMAC in the field M. |
| 115 | |
| 116 | The sender **SHOULD** send the fragments in the correct order. However, the |
| 117 | receiver **MUST** assume the fragments arrive in any order. |
| 118 | |
| 119 | The sender **MUST** send all fragments of a packet within 30 s from sending the |
| 120 | first fragment. |
| 121 | The receiver **MUST** wait for fragments at least 60 s after the first fragment |
| 122 | arrived. After this, the receiver may discard any fragments of this packet and |
| 123 | therefore the packet as a whole. |
| 124 | |
| 125 | Packet encoding |
| 126 | --------------- |
| 127 | Only 2 generic data types are supported (namely strings and integers). All |
| 128 | other data types **MUST** be expressed as strings or integers. |
| 129 | |
| 130 | On encoding integers are simply converted to a corresponding string. |
| 131 | Strings **MUST** be prefixed with the character $. If the first character of a |
| 132 | string is the $ character, it is escaped by prepending another $ character. |
| 133 | |
| 134 | Packet decoding |
| 135 | --------------- |
| 136 | On decoding, any string with a $ as its first character will have it removed |
| 137 | and will then be treated as a string. |
| 138 | Any other strings will be converted to integers. |
| 139 | |
| 140 | The fields M, V and F **SHOULD** be stripped from the packet data that is |
| 141 | transferred from the inetd implementation to the application. |
| 142 | |
| 143 | Legacy mode packets and encoding |
| 144 | -------------------------------- |
| 145 | Any intermud v2.5 peer **MUST** send data as described above. However, when |
| 146 | receiving it **MUST** accept data in a relaxed format that is sent by older |
| 147 | intermud peers. In legacy mode, the following changes are accepted: |
| 148 | |
| 149 | * The M, V and F fields are missing (aka: **MUST NOT** be present) or are not the |
| 150 | first three header fields. |
| 151 | * A string **MAY** be prefixed with the character $, but does not have to, unless |
| 152 | there ambiguity as to wether they should be decoded as a string or an |
| 153 | integer. If a string is losslessly convertable to an integer and back to a |
| 154 | string, it **MUST** be prefixed by $. |
| 155 | This means however, that any string not starting with $ **MUST** be checked |
| 156 | whether it is to be interpreted as integer or string. |
| 157 | |
| 158 | If a peer sends to a peer with a known protocol version older than v2.5 it |
| 159 | **MAY** send the data in the legacy mode. However, this is not recommended. |
| 160 | |
| 161 | |
| 162 | Defined system headers / fields |
| 163 | =============================== |
| 164 | The fields defined in this section **MUST NOT** be used in any application sending |
| 165 | data via intermud. The sending inetd **SHOULD** check for this during input |
| 166 | validation before assembling a packet. |
| 167 | |
| 168 | "RCPNT" (RECIPIENT) |
| 169 | The body of this field should contiain the recipient the message |
| 170 | is to be sent to if applicable. |
| 171 | "REQ" (REQUEST) |
| 172 | The name of the intermud request that is being made of the |
| 173 | receiving mud. Standard requests that should be supported by |
| 174 | all systems are "ping" (PING), "query" (QUERY), and "reply" |
| 175 | (REPLY). The PING request is used to determine wether or not a |
| 176 | mud is active. The QUERY request is used to query a remote mud |
| 177 | for information about itself (look at the udp/query module for |
| 178 | details of what information can be requested). The REPLY request |
| 179 | is special in that it is the request name used for all replies |
| 180 | made to by mud B to an initial request made by a mud A. It is |
| 181 | mud A's responsibility to keep track of the original request |
| 182 | type so that the reply can be handled appropriately. |
| 183 | "SND" (SENDER) |
| 184 | The name of the person or object which sent the request or to |
| 185 | whom replies should be directed. This is essential if a reply |
| 186 | is expected. |
| 187 | "DATA" (DATA) |
| 188 | This field should contain the main body of any packet. It is |
| 189 | the only field that can contain special delimiting characters |
| 190 | without error. |
| 191 | |
| 192 | The following headers are used internally by the inetd and should |
| 193 | not be used by external objects: |
| 194 | |
| 195 | "HST" (HOST) |
| 196 | The IP address of the host from which a request was received. |
| 197 | This is set by the receiving mud and is not contained in |
| 198 | outgoing packets. |
| 199 | "ID" (ID) |
| 200 | The packet id. This field is simply an integer which is set by |
| 201 | the sending inetd. The number is incremented each time a packet |
| 202 | is sent (zero is never used). This field is only needed if a |
| 203 | reply is expected. REPLY packets _must_ include the original |
| 204 | request id. This is _not_ done by the inetd. |
| 205 | "NAME" (NAME) |
| 206 | The name of the local mud. Used for security checking and to |
| 207 | update host list information. |
| 208 | "PKT" (PACKET) |
| 209 | A special header reserved for packets which have been split. |
| 210 | See PACKET PROTOCOL / FORMAT. |
| 211 | "UDP" (UDP_PORT) |
| 212 | The UDP port the local mud is receiving on. Used for security |
| 213 | checking and updating host list information. |
| 214 | "SYS" (SYSTEM) |
| 215 | Contains special system flags. The only system flag used at |
| 216 | present is TIME_OUT. This is included in packets returned due |
| 217 | to an expected reply timing out to differentiate it from an |
| 218 | actual reply. |
| 219 | |
| 220 | |
| 221 | Intermud requests / modules |
| 222 | =========================== |
| 223 | |
| 224 | Mandatory requests / modules |
| 225 | ---------------------------- |
| 226 | The following are standard request types that **MUST** be supported |
| 227 | by all systems: |
| 228 | |
| 229 | "ping" (PING) |
| 230 | This module should return a REPLY packet that contains the |
| 231 | original requests ID in it's ID field and the SENDER in it's |
| 232 | RECIPIENT field. It should also include an appropriate string |
| 233 | in the DATA field, eg. "Mud-Name is alive.\n" |
| 234 | "query" (QUERY) |
| 235 | This module expects the type of query requested to appear in the |
| 236 | recieved DATA field. It should return a REPLY packet containing |
| 237 | the original ID in the ID field, the SENDER in it's RECIPIENT |
| 238 | field, and the query type in a QUERY field. The DATA field should |
| 239 | contain the information requested. |
| 240 | |
| 241 | |
| 242 | Optional requests / modules |
| 243 | ---------------------------- |
| 244 | |