LSL Protocol/Ganymedia OpenMAIP v1.0 Specification
- 1 Preamble
- 2 Introduction
- 3 Multimodal Transmission Layer (MTL): OSI Layer 0/1 (Physical)
- 4 Datagram Routing Layer (DRL): OSI Layer 2 (Network)
- 5 Datagram Transport Layer (DTL): OSI Layer 3 (Transport)
NOTE: THIS IS AN ALPHA DRAFT SPECIFICATION. IT IS A WORK IN PROGRESS AND SUBJECT TO CHANGE WITHOUT NOTICE.
- Important changes: The DTL frame format has changed with the addition of new fields. The former IP address data format has changed from IPv4 to IPv6, and there are now four address fields rather than two to permit forward-on routing. The CIDR mappings below still stand, but should be taken as IPv6 rather than IPv4 addresses with larger assigned ranges. The protocol revision constant has incremented from
0x0101to reflect this change. --Ganymede Ceriaptrix 03:01, 25 April 2010 (UTC)
This document reflects the current Beta testing version of Ganymedia OpenMAIP Engine:
The Ganymedia OpenMAIP v1.0 Specification ALPHA FIRST DRAFT
Copyright (C) 2010 Ganymede Ceriaptrix <firstname.lastname@example.org>
This work is licensed under the Creative Commons Attribution-Share Alike 3.0 Unported License. To view a copy of this license, visit http://creativecommons.org/licenses/by-sa/3.0/ or send a letter to Creative Commons, 171 Second Street, Suite 300, San Francisco, California, 94105, USA.
Ganymede Ceriaptrix <email@example.com> is responsible for maintenance and specification of this protocol. It is used extensively in Ganymedia Engineering's in-world applications and server-side PHP solutions, and interoperability with those applications may be achieved by conformance to this specification.
Ganymedia OpenMAIP v1.0 (the Ganymedia Open Metaverse Application Internetworking Protocol) provides a common standard datagram communications protocol for Second Life script applications, each fulfilling their own respective functionality contracts to exchange interoperable messages by exposing query-discoverable command services and command syntax to external objects. It is designed along the lines of TCP/IP, with each OpenMAIP client being assigned an IP address, communication taking place between IP addresses rather than object keys.
However, OpenMAIP's scope goes beyond chat messaging; it supports a series of communications methods, ranging from direct chat transmission to HTTP relay and e-mail, allowing communication between scripts running on Linden Labs' servers and third-party OpenSim grids, and even other virtual worlds systems on which an OpenMAIP implementation has been created (or is simulated via an HTTP server). Therefore, it is useful for a whole range of applications, from simple attachment-to-attachment communications, to object-to-attachment interaction, to cross-simulator and cross-grid object communications.
OpenMAIP communications are byte-oriented -- they consists of ASCII-armoured hex string messages rather than Unicode character representations of data and list delimiters (though frames may optionally contain literal data), breaking from the SL norm; therefore it is better suited to script-to-viewer communications than traditional "loose" multi-type LSL protcols or delimited lists and, indeed, could potentially be encapsulated directly within UDP and other TCP/IP network services in the future. It has been designed with this ultimate goal in mind, for future integration of server-side networking services directly with in-world application scripts.
The basic notion of OpenMAIP is that it provides a common network discovery, service query and message communication framework; therefore, applications such as attachments may query for other OpenMAIP-supporting devices in their vicinity that support common functionality protocols, and also query those devices for acceptable command formats. The provision of challenge/response RC4 authentication allows conformance with closed protocols to be verified as well; it is expected that the RC4 challenge/response authentication keys will be published by architects of open protocols.
At its higher implementation levels, OpenMAIP provides industry-standard cryptographic message exchange for secure script-script, script-viewer and viewer-viewer communications across the Second Life chat messaging system. (By secure, in the sense of scripts "talking" to one another, this is meant "secure" as in "with high immunity to interception by other residents"; any individual with access to the LSL script engine would, of course, be capable of eavesdropping.)
OpenMAIP supercedes the functionality provided by the Ganymedia Open Cryptographic Exchange Protocol, and is backwards-compatible with it.
Multimodal Transmission Layer (MTL): OSI Layer 0/1 (Physical)
Chat Channel Transport (CCT)
- Chat Channel Transport (CCT) is the preferred method of communication, consisting of the encapsulated frame being transmitted over the current simulator's chat channel system. This is possible when both the frame sender and recipient are present within the same simulator, and MUST be used if possible. It is also the method by which OpenMAIP messages are relayed to an OpenMAIP-capable Second Life viewer application, the method by which script-to-viewer communications MUST occur.
External Relay Transport (ERT)
- If the recipient is not present on the same simulator as the sender, and an HTTP-based route to a relay server is possible (the nature of which is implementation-dependent), the message SHALL be relayed via that HTTP relay to the destination simulator for retransmission over CCT.
Object E-mail Transport (OET)
- Failing the above two preferred transport methods (if a route via ERT is not known in the host routing table to a distant sender), the encapsulated frame SHALL transmitted via the simulator's local e-mail functionality to the destination object's key. In the case of the Linden Lab servers, this behaviour results in an e-mail message being sent to
<key>@lsl.lindenlab.com. Implementations forwarding to other providers' virtual world grids MAY be specific to e-mail transport behaviour on that simulator or simulator-like environment. In this case, the
recipient_domainfield present within the frame SHALL be used to determine the domain suffix.
Datagram Routing Layer (DRL): OSI Layer 2 (Network)
|Constant||Value Hex||Value Dec||Description|
OpenMAIP address assignments
|Domain||Assignment||Description||Host Numbering Scheme|
|*.agni.lindenlab.com||As DNS lookup until otherwise amended, prefixing optional||Generic-range host prefix for Linden Lab main grid simulators.||To be published.|
|*.phrygia.ganymede-labs.com||As DNS lookup until otherwise amended, prefixing optional||Host prefix for Ganymedia Engineering's servers.||To be published.|
|MULTICAST_ALL_NODES||ff02::1||If frames are addressed to MULTICAST_ALL_NODES, they MUST be processed by all receiving hosts in the current simulator. Single address. See IANA IPv6 Multicast Address Space Registry.|
|MULTICAST_ALL_RELAYS||ff02::2||If frames are addressed to MULTICAST_ALL_RELAYS, they MUST be processed by all receiving External Relay Transport (ERT) and/or Object E-mail Transport (ORT) relays in the current simulator. Single address. See IANA IPv6 Multicast Address Space Registry.|
|LOCAL_HOST_RANGE||fd7c:08ce:1752:f4a8::/64|| The final 64 bits of an OpenMAIP IPv6 are self-assigned by each client according to the SELF_ASSIGN/COLLISION protocol components. If a node is not connected to a server from which to self-configure a domain, it uses the above fixed prefix (for Prefix, Global ID and Subnet ID). If a node is connected to an OpenMAIP server, it obtains the IP address appropriate to the simulator (the simulator IP address taken from llGetSimulatorHostname(), prefixed IPv4-to-IPv6 standard Prefix as per the IANA ranges) and uses this as the address prefix. The latter 64 bits that are self-assigned are irrespective of this; e.g. an address of
This behaviour has been fixed so that it conforms to RFC 3789, which in 0.7.1 it did not. Use of site-local prefixes (fec0::/10) is now deprecated.
Datagram Transport Layer (DTL): OSI Layer 3 (Transport)
|Constant||Value Hex||Value Dec||Description|
|CURRENT_VERSION||0x0101||257|| Protocol version: |
|FRAME_COUNT_MAX||0x00FF||255||Max 255 frames per message|
|FRAME_PAYLOAD_MAX||0x0200||880||Max 880 characters of payload per frame (440 binary bytes in ENCODING_BINHEX) based on the LSL maximum message length of 1024 characters|
|FRAME_FIELDS_MIN||0x0090||144||Frame format specifies a minimum of 144 characters of data (72 bytes in ENCODING_BINHEX) of control fields|
|FRAME_TOTAL_MAX||0x0400||1024|| Maximum frame size of control fields plus payload (the LSL limit for sending |
|Constant||Value Hex||Value Dec||Description|
|ENCODING_INVALID||0x0000||0||This frame does not contain a payload of recognised encapsulation format.|
|ENCODING_PASSTHROUGH||0x0001||1||Not recommended. The payload of this frame is unencapsulated (the datastream is environment-dependent, and in the case of LSL strings, the payload will be in local Second Life Unicode text). Avoid use of this mode, as preservation of verbatim character data cannot be guaranteed should the frame be forwarded over HTTP.|
|ENCODING_BINHEX||0x0002||2||The input payload string is converted as bytes, which are binary-hexadecimal encoded (BinHex) into a string of undelimited hexadecimal octets, each octet representing the hexadecimal value of that byte (e.g. little-endian numerical literals in the case of floats and integers; ASCII values in the case of strings). This is the preferred mode; note, however, that non-ASCII character values MUST be stripped out, and so any special characters will be lost. Please use ENCAP_HEX_UTF16 if Unicode characters are expected in payload data. Note that all frame control fields MUST be encoded in this format in all implementations and modes of delivery.|
|ENCODING_BINHEX_UTF16||0x0003||3|| Optional - implementation of this mode may be omitted.|
As ENCODING_BINHEX_ASCII, except characters are transliterated into hexadecimal octets representing an RFC 2781 Unicode-encoded string, which MUST be prefixed with an appropriate Byte Order Mark.
|ENCODING_LEMPEURER||0x0004||4|| Optional - implementation of this mode may be omitted.|
|#||Byte Index||Byte Len||Field Name|| String
|Field Type||Desc||Validity rule|
|0||0||2||head||ENCODING_BINHEX||16-bit unsigned integer constant||Frame-start indicator sequence||head = FRAME_START_TOKEN|
|1||2||16||destination||ENCODING_BINHEX||RFC 2460 IPv6 address||Next destination (current hop); pseudo-IPv6 address (128-bit)||not validated at this layer|
|2||18||16||recipient||ENCODING_BINHEX||RFC 2460 IPv6 address||Final destination (ultimate recipient); pseudo-IPv6 address (128-bit)||not validated at this layer|
|3||34||16||forwarder||ENCODING_BINHEX||RFC 2460 IPv6 address||Source of the datagram (the forwarder); pseudo-IPv6 address (128-bit)||not validated at this layer|
|4||50||16||originator||ENCODING_BINHEX||RFC 2460 IPv6 address||Origin of the datagram (the sender); pseudo-IPv6 address (128-bit)||not validated at this layer|
|5||66||1||version||ENCODING_BINHEX||8-bit unsigned integer||Protocol version identifier||version <= CURRENT_VERSION|
|6||67||1||frame_count||ENCODING_BINHEX||8-bit unsigned integer||Total length, in frames, of the entire datagram||1 <= n <= FRAME_COUNT_MAX|
|7||68||1||index||ENCODING_BINHEX||8-bit unsigned integer||Index of this frame within the datagram (zero-based)||0 <= frame_index <= frame_count <= FRAME_COUNT_MAX|
|8||69||2||size||ENCODING_BINHEX||16-bit unsigned integer||Length, in characters of encoded data, of this frame's payload||0 <= frame_size <= FRAME_PAYLOAD_MAX|
|9||71||1||encoding||ENCODING_BINHEX||8-bit unsigned integer constant||Encapsulated data encoding (see above constants)||valid constant|
|10||72||n||data||encoding||Data literal||Frame payload||0 <= tx_characters(data) = frame_size <= FRAME_PAYLOAD_MAX|
|11||72 + n||2||tail||ENCODING_BINHEX||16-bit unsigned integer constant||End-of-transmission (EOT) characters||terminator = FRAME_END_TOKEN|
- Whilst it may seem odd that version is in field 5 (after the address header block) in the frame, having the current recipient address immediately after the frame start token means that the first 18 bytes of any frame can be identified as being addressed to the receiving node, without any former tests having taken place. This allows extremely simple implementations of the protocol to perform this simple check to determine whether to process a frame or not, and screening "background" packets prior to frame tear-down using this simple test improves efficiency in LSL implementations.