mirror of
https://github.com/moparisthebest/xeps
synced 2025-02-16 07:10:15 -05:00
Merge remote-tracking branch 'upstream/master'
This commit is contained in:
commit
3305ed1358
71
.gitignore
vendored
Normal file
71
.gitignore
vendored
Normal file
@ -0,0 +1,71 @@
|
||||
# Python
|
||||
# https://github.com/github/gitignore/blob/master/Python.gitignore
|
||||
|
||||
# Byte-compiled / optimized / DLL files
|
||||
__pycache__/
|
||||
*.py[cod]
|
||||
*$py.class
|
||||
|
||||
# C extensions
|
||||
*.so
|
||||
|
||||
# Distribution / packaging
|
||||
.Python
|
||||
env/
|
||||
build/
|
||||
develop-eggs/
|
||||
dist/
|
||||
downloads/
|
||||
eggs/
|
||||
.eggs/
|
||||
lib/
|
||||
lib64/
|
||||
parts/
|
||||
sdist/
|
||||
var/
|
||||
*.egg-info/
|
||||
.installed.cfg
|
||||
*.egg
|
||||
|
||||
# PyInstaller
|
||||
# Usually these files are written by a python script from a template
|
||||
# before PyInstaller builds the exe, so as to inject date/other infos into it.
|
||||
*.manifest
|
||||
*.spec
|
||||
|
||||
# Installer logs
|
||||
pip-log.txt
|
||||
pip-delete-this-directory.txt
|
||||
|
||||
# Unit test / coverage reports
|
||||
htmlcov/
|
||||
.tox/
|
||||
.coverage
|
||||
.coverage.*
|
||||
.cache
|
||||
nosetests.xml
|
||||
coverage.xml
|
||||
*,cover
|
||||
|
||||
# Translations
|
||||
*.mo
|
||||
*.pot
|
||||
|
||||
# Django stuff:
|
||||
*.log
|
||||
|
||||
# Sphinx documentation
|
||||
docs/_build/
|
||||
|
||||
# PyBuilder
|
||||
target/
|
||||
|
||||
# Vim
|
||||
# https://github.com/github/gitignore/blob/master/Global/Vim.gitignore
|
||||
|
||||
[._]*.s[a-w][a-z]
|
||||
[._]s[a-w][a-z]
|
||||
*.un~
|
||||
Session.vim
|
||||
.netrwhist
|
||||
*~
|
193
inbox/http-upload.xml
Normal file
193
inbox/http-upload.xml
Normal file
@ -0,0 +1,193 @@
|
||||
<?xml version='1.0' encoding='UTF-8'?>
|
||||
<!DOCTYPE xep SYSTEM 'xep.dtd' [
|
||||
<!ENTITY % ents SYSTEM 'xep.ent'>
|
||||
%ents;
|
||||
]>
|
||||
<?xml-stylesheet type='text/xsl' href='xep.xsl'?>
|
||||
<xep>
|
||||
<header>
|
||||
<title>HTTP File Upload</title>
|
||||
<abstract>This specification defines a protocol to request permissions from another entity to upload a file to a specific path on an HTTP server and at the same time receive a URL from which that file can later be downloaded again.</abstract>
|
||||
&LEGALNOTICE;
|
||||
<number>xxxx</number>
|
||||
<status>ProtoXEP</status>
|
||||
<type>Standards Track</type>
|
||||
<sig>Standards</sig>
|
||||
<approver>Council</approver>
|
||||
<dependencies>
|
||||
<spec>XMPP Core</spec>
|
||||
<spec>XEP-0001</spec>
|
||||
<spec>Etc.</spec>
|
||||
</dependencies>
|
||||
<supersedes/>
|
||||
<supersededby/>
|
||||
<shortname>NOT_YET_ASSIGNED</shortname>
|
||||
<author>
|
||||
<firstname>Daniel</firstname>
|
||||
<surname>Gultsch</surname>
|
||||
<email>daniel@gultsch.de</email>
|
||||
<jid>daniel@gultsch.de</jid>
|
||||
</author>
|
||||
<revision>
|
||||
<version>0.0.1</version>
|
||||
<date>2015-07-25</date>
|
||||
<initials>dg</initials>
|
||||
<remark><p>First draft.</p></remark>
|
||||
</revision>
|
||||
</header>
|
||||
<section1 topic='Introduction' anchor='intro'>
|
||||
<p>XMPP protocol extensions already define methods for peer-to-peer file transfer such as &xep0096; or &xep0234; however due to their very nature of being peer-to-peer they don't work very well in scenarios where it is requeried to send a file to multiple receipients or multiple resources of the same receipient at once. They also don’t work alongside offline storage, MUC history and &xep0313;.</p>
|
||||
<p>Uploading files manually to an HTTP server and sharing the link has been a workaround for this for a long time now. While users have a variety of services to choose from the downside of this manual approach is that an XMPP client can not automate this process on behalf of the user since these services don’t share a common api. Furthermore using a third party service would probably require the user to enter addional credentials into their XMPP client specifically for the file upload.</p>
|
||||
<p>This XEP defines an approach to request permissions from another entity to upload a file to a specific path on an HTTP server and at the same time receive an URL from which that file can later be downloaded again. These tuples consisting of a PUT and a GET-URL are called slots.</p>
|
||||
</section1>
|
||||
<section1 topic='Requirements' anchor='reqs'>
|
||||
<ul>
|
||||
<li>Be as easy to implement as possible. This is grounded on the idea that most programming languages already have HTTP libraries available.</li>
|
||||
<li>Be agnostic toward the distributon of the actual URL. Users can choose to send the URL in the body of a message stanza, utilize &xep0066; or even use it as their avatar in &xep0084;</li>
|
||||
<li>Do not provide any kind of access control or security beyond Transport Layer Security in form of HTTPS and long random pathes that are impossible to guess. That means everyone who knows the URL SHOULD be able to access it.</li>
|
||||
</ul>
|
||||
</section1>
|
||||
<section1 topic='Discovering Support' anchor='disco'>
|
||||
<p>An entity advertises support for this protocol by including the "urn:xmpp:http:upload" in its service discovery information features as specified in &xep0030; or section 6.3 of &xep0115;. A users server SHOULD include any known entities that provide such services into its service discovery items.</p>
|
||||
<example caption='Client sends service discovery request to server'><![CDATA[
|
||||
<iq from='romeo@montague.tld/garden'
|
||||
id='step_01'
|
||||
to='montague.tld'
|
||||
type='get'>
|
||||
<query xmlns='http://jabber.org/protocol/disco#items'/>
|
||||
</iq>]]></example>
|
||||
<example caption='Server replies to service discovery request'><![CDATA[
|
||||
<iq from='montague.tld'
|
||||
id='step_01'
|
||||
to='romeo@montague.tld/garden'
|
||||
<query xmlns='http://jabber.org/protocol/disco#items'>
|
||||
<item jid='upload.montague.tld' name='HTTP File Upload' />
|
||||
<item jid='conference.montague.tld' name='Chatroom Service' />
|
||||
</query>
|
||||
</iq>]]></example>
|
||||
<example caption='Client sends service discorvey request to upload service'><![CDATA[
|
||||
<iq from='romeo@montague.tld/garden
|
||||
id='step_02'
|
||||
to='upload.montague.tld'
|
||||
type='get'>
|
||||
<query xmlns='http://jabber.org/protocol/disco#info'/>
|
||||
</iq>]]></example>
|
||||
<example caption='Upload service replies to service discovery request'><![CDATA[
|
||||
<iq from='upload.montague.tld
|
||||
id='step_02'
|
||||
to='romeo@montague.tld/garden'
|
||||
type='result'>
|
||||
<query xmlns='http://jabber.org/protocol/disco#info'>
|
||||
<identity category='store'
|
||||
type='file'
|
||||
name='HTTP File Upload' />
|
||||
<feature var='urn:xmpp:http:upload' />
|
||||
</query>
|
||||
</iq>]]></example>
|
||||
</section1>
|
||||
<section1 topic='Requesting a slot' anchor='request'>
|
||||
<p>A client requests a new upload slot by sending an IQ-get to the upload service containing a <request> child element qualified by the urn:xmpp:http:upload namespace. This element MUST include elements <filename> and <size> containing the file name and size respectively.</p>
|
||||
<p>An additional element <content-type> containing the Content-Type is OPTIONAL.</p>
|
||||
<example caption='Client requests a slot on the upload service'><![CDATA[
|
||||
<iq from='romeo@montague.tld/garden
|
||||
id='step_03'
|
||||
to='upload.montague.tld'
|
||||
type='get'>
|
||||
<request 'urn:xmpp:http:upload'>
|
||||
<filename>my_juliet.png</filename>
|
||||
<size>23456</size>
|
||||
<content-type>image/jpeg</content-type>
|
||||
</request>
|
||||
</iq>]]></example>
|
||||
<p>The upload service responds with both a PUT and a GET URL wrapped by a <slot> element. The service SHOULD keep the file name and especially the file ending intact. Using the same hostname for PUT and GET is OPTIONAL. The host SHOULD provide Transport Layer Security.</p>
|
||||
<example caption='The upload service responsd with a slot'><![CDATA[
|
||||
<iq from='upload.montague.tld
|
||||
id='step_03'
|
||||
to='romeo@montague.tld/garden
|
||||
type='result'>
|
||||
<slot xmlns='urn:xmpp:http:upload'>
|
||||
<put>https://upload.montague.tld/4a771ac1-f0b2-4a4a-9700-f2a26fa2bb67/my_juliet.png</put>
|
||||
<get>https://download.montague.tld/4a771ac1-f0b2-4a4a-9700-f2a26fa2bb67/my_juliet.png</get>
|
||||
</slot>
|
||||
</iq>]]></example>
|
||||
</section1>
|
||||
<section1 topic='Error conditions' anchor='errors'>
|
||||
<p>Instead of providing the client with a slot the service MAY respond with an error if the requested file size is too large.</p>
|
||||
<example caption='Alternative response by the upload service if the file size was too large'><![CDATA[
|
||||
<iq from='upload.montague.tld
|
||||
id='step_03'
|
||||
to='romeo@montague.tld/garden
|
||||
type='error'>
|
||||
<request 'urn:xmpp:http:upload>
|
||||
<filename>my_juliet.png</filename>
|
||||
<size>23456</size>
|
||||
</request>
|
||||
<error type='modify'>
|
||||
<not-acceptable xmlns='urn:ietf:params:xml:ns:xmpp-stanzas' />
|
||||
<text xmlns='urn:ietf:params:xml:ns:xmpp-stanzas>file too large. the maximum file size is 20000 bytes</text>
|
||||
<file-too-large xmlns='urn:xmpp:http:upload'>
|
||||
<max-size>20000</max-size>
|
||||
</file-too-large>
|
||||
</error>
|
||||
</iq>]]></example>
|
||||
<p>For any other type of error the service SHOULD respond with appropriate error types to indicate temporary or permanent errors.</p>
|
||||
<example caption='Alternative response by the upload service to indicate a temporary error after the client exceeded a quota'><![CDATA[
|
||||
<iq from='upload.montague.tld
|
||||
id='step_03'
|
||||
to='romeo@montague.tld/garden
|
||||
type='error'>
|
||||
<request 'urn:xmpp:http:upload>
|
||||
<filename>my_juliet.png</filename>
|
||||
<size>23456</size>
|
||||
</request>
|
||||
<error type='wait'>
|
||||
<resource-constraint xmlns='urn:ietf:params:xml:ns:xmpp-stanzas' />
|
||||
<text xmlns='urn:ietf:params:xml:ns:xmpp-stanzas>Quota reached. You can only upload 5 files in 5 minutes</text>
|
||||
</error>
|
||||
</iq>]]></example>
|
||||
<example caption='Alternative response by the upload service to indicate a permanent error to a client that is not allowed to upload files'><![CDATA[
|
||||
<iq from='upload.montague.tld
|
||||
id='step_03'
|
||||
to='romeo@montague.tld/garden
|
||||
type='error'>
|
||||
<request 'urn:xmpp:http:upload>
|
||||
<filename>my_juliet.png</filename>
|
||||
<size>23456</size>
|
||||
</request>
|
||||
<error type='cancel'>
|
||||
<not-allowed xmlns='urn:ietf:params:xml:ns:xmpp-stanzas' />
|
||||
<text xmlns='urn:ietf:params:xml:ns:xmpp-stanzas>Only premium members are allowed to upload files</text>
|
||||
</error>
|
||||
</iq>]]></example>
|
||||
</section1>
|
||||
<section1 topic='Upload' anchor='upload'>
|
||||
<p>The actual upload of the file happens via HTTP-PUT and is out of scope of this document. The upload service MUST reject the file upload if the Content-Length does not match the size of the slot request. The service SHOULD reject the file if the Content-Type has been specified beforehand and does not match. The service MAY assume application/octet-stream as a Content-Type if it the client did not specficy a Content-Type at all.</p>
|
||||
<p>There is no further XMPP communication required between the upload service and the client. A HTTP status Code of 201 means that the server is now ready to serve the file via the provided GET URL. If the upload fails for whatever reasons the client MAY request a new slot.</p>
|
||||
</section1>
|
||||
<section1 topic='Implementation Notes' anchor='impl'>
|
||||
<p>The upload service SHOULD choose an appropriate timeout for the validity of the PUT URL. Since there is no reason for a client to wait between requesting the slot and starting the upload relativly low time out values of around 60s are RECOMENDED.</p>
|
||||
<p>It is RECOMMENDED that the service stores the files for as long as possible which is of course limited by storage capacity. A service MAY choose to store the latest x MiB of a given user.</p>
|
||||
</section1>
|
||||
<section1 topic='Security Considerations' anchor='security'>
|
||||
<ul>
|
||||
<li>Client implementors MUST consider the fact that without additional end-to-end-encryption files uploaded to a service described in this document will store those files in plain text on that service. Client implementors SHOULD either use this only for semi public files (for example files shared in a public MUC or a PEP Avatar) or implement appropriate end-to-end encryption.</li>
|
||||
<li>Service implementors SHOULD use long randomized parts in their URLs making it impossible to guess the location of arbitrary files</li>
|
||||
<li>Server operators SHOULD consider the responsibilty that comes with storing user data and MAY consider appropriate measures such as full disk encryption.</li>
|
||||
</ul>
|
||||
</section1>
|
||||
<section1 topic='IANA Considerations' anchor='iana'>
|
||||
<p>This document requires no interaction with the Internet Assigned Numbers Authority (IANA).</p>
|
||||
</section1>
|
||||
<section1 topic='XMPP Registrar Considerations' anchor='registrar'>
|
||||
<section2 topic='Protocol Namespaces' anchor='registrar-ns'>
|
||||
<p>This specification defines the following XML namespace:</p>
|
||||
<ul>
|
||||
<li>urn:xmpp:http:upload</li>
|
||||
</ul>
|
||||
<p>Upon advancement of this specification from a status of Experimental to a status of Draft, the ®ISTRAR; shall add the foregoing namespace to the registry located at &NAMESPACES;, as described in Section 4 of &xep0053;.</p>
|
||||
</section2>
|
||||
</section1>
|
||||
<section1 topic='XML Schema' anchor='schema'>
|
||||
<p>tbd</p>
|
||||
</section1>
|
||||
</xep>
|
108
inbox/mid.xml
108
inbox/mid.xml
@ -1,108 +0,0 @@
|
||||
<?xml version='1.0' encoding='UTF-8'?>
|
||||
<!DOCTYPE xep SYSTEM 'xep.dtd' [
|
||||
<!ENTITY % ents SYSTEM 'xep.ent'>
|
||||
%ents;
|
||||
]>
|
||||
<?xml-stylesheet type='text/xsl' href='xep.xsl'?>
|
||||
<xep>
|
||||
<header>
|
||||
<title>Unique and stable message IDs</title>
|
||||
<abstract>This specification describes unique and stable IDs for message stanzas.</abstract>
|
||||
<legal>
|
||||
<copyright>This XMPP Extension Protocol is copyright (c) 1999 - 2014 by the XMPP Standards Foundation (XSF).</copyright>
|
||||
<permissions>Permission is hereby granted, free of charge, to any person obtaining a copy of this specification (the "Specification"), to make use of the Specification without restriction, including without limitation the rights to implement the Specification in a software program, deploy the Specification in a network service, and copy, modify, merge, publish, translate, distribute, sublicense, or sell copies of the Specification, and to permit persons to whom the Specification is furnished to do so, subject to the condition that the foregoing copyright notice and this permission notice shall be included in all copies or substantial portions of the Specification. Unless separate permission is granted, modified works that are redistributed shall not contain misleading information regarding the authors, title, number, or publisher of the Specification, and shall not claim endorsement of the modified works by the authors, any organization or project to which the authors belong, or the XMPP Standards Foundation.</permissions>
|
||||
<warranty>## NOTE WELL: This Specification is provided on an "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, express or implied, including, without limitation, any warranties or conditions of TITLE, NON-INFRINGEMENT, MERCHANTABILITY, or FITNESS FOR A PARTICULAR PURPOSE. In no event shall the XMPP Standards Foundation or the authors of this Specification be liable for any claim, damages, or other liability, whether in an action of contract, tort, or otherwise, arising from, out of, or in connection with the Specification or the implementation, deployment, or other use of the Specification. ##</warranty>
|
||||
<liability>In no event and under no legal theory, whether in tort (including negligence), contract, or otherwise, unless required by applicable law (such as deliberate and grossly negligent acts) or agreed to in writing, shall the XMPP Standards Foundation or any author of this Specification be liable for damages, including any direct, indirect, special, incidental, or consequential damages of any character arising out of the use or inability to use the Specification (including but not limited to damages for loss of goodwill, work stoppage, computer failure or malfunction, or any and all other commercial damages or losses), even if the XMPP Standards Foundation or such author has been advised of the possibility of such damages.</liability>
|
||||
<conformance>This XMPP Extension Protocol has been contributed in full conformance with the XSF's Intellectual Property Rights Policy (a copy of which may be found at <<link url='http://xmpp.org/extensions/ipr-policy.shtml'>http://xmpp.org/extensions/ipr-policy.shtml</link>> or obtained by writing to XSF, P.O. Box 1641, Denver, CO 80201 USA).</conformance>
|
||||
</legal>
|
||||
<number>xxxx</number>
|
||||
<status>ProtoXEP</status>
|
||||
<type>Standards Track</type>
|
||||
<sig>Standards</sig>
|
||||
<approver>Council</approver>
|
||||
<dependencies>
|
||||
<spec>XMPP Core</spec>
|
||||
</dependencies>
|
||||
<supersedes/>
|
||||
<supersededby/>
|
||||
<shortname>NOT_YET_ASSIGNED (suggested: mid)</shortname>
|
||||
<author>
|
||||
<firstname>Florian</firstname>
|
||||
<surname>Schmaus</surname>
|
||||
<email>flo@geekplace.eu</email>
|
||||
<jid>flo@geekplace.eu</jid>
|
||||
</author>
|
||||
<revision>
|
||||
<version>0.0.1</version>
|
||||
<date>2015-06-01</date>
|
||||
<initials>fs</initials>
|
||||
<remark><p>First draft.</p></remark>
|
||||
</revision>
|
||||
</header>
|
||||
<section1 topic='Introduction' anchor='intro'>
|
||||
<p>Unique and stable IDs for message stanzas, which are set by a XMPP service, are beneficial in various ways. They can be used together with &xep0313; to uniquely identify a message within an archive. They are also useful in the context of &xep0045; conferences, to identify a message reflected by a MUC service back to the originating entity. And they could be used together with &xep0280;, so that clients are able to retrieve the archive starting from a given message.</p>
|
||||
</section1>
|
||||
<section1 topic='Requirements' anchor='reqs'>
|
||||
<p>The herein defined messages IDs must be unique and stable within the scope of the generating XMPP entity.</p>
|
||||
</section1>
|
||||
<section1 topic='Use Cases' anchor='usecases'>
|
||||
<section2 topic='Unique message IDs' anchor='message-id'>
|
||||
<example caption='The message ID extension.'><![CDATA[
|
||||
<message-id xmlns='urn:xmpp:mid:0' id='de305d54-75b4-431b-adb2-eb6b9e546013'/>
|
||||
]]></example>
|
||||
The service generates the value of the id attribute. The value must be service local unique and stable, i.e. it MUST NOT change later for some reason. It is RECOMMENDED that the id generating service uses UUID (RFC 4122) to generate the IDs.
|
||||
</section2>
|
||||
<section2 topic='Client generated message IDs' anchor='client-id'>
|
||||
<p>
|
||||
Some use cases require the client to generate the message ID. In this case, the client MUST use "client-id" as attribute name for the ID.
|
||||
</p>
|
||||
<example caption='A message stanza with the message ID extension.'><![CDATA[
|
||||
<message xmlns='jabber:client'
|
||||
to='room@muc.example.org'
|
||||
type='groupchat'>
|
||||
<body>Typical body text</body>
|
||||
<message-id xmlns='urn:xmpp:mid:0' client-id='de305d54-75b4-431b-adb2-eb6b9e546013'/>
|
||||
</message>]]></example>
|
||||
<p>
|
||||
The server MAY add an 'id' attribute to the message-id element. In that case, it MUST preserve the content of the 'client-id' attribute.
|
||||
</p>
|
||||
<example caption='A message stanza with the message ID extension.'><![CDATA[
|
||||
<message xmlns='jabber:client'
|
||||
to='room@muc.example.org'
|
||||
type='groupchat'>
|
||||
<body>Typical body text</body>
|
||||
<message-id xmlns='urn:xmpp:mid:0'
|
||||
id='new-id-overrides-client-id'
|
||||
client-id='de305d54-75b4-431b-adb2-eb6b9e546013'/>
|
||||
</message>]]></example>
|
||||
<p>
|
||||
Otherwise, if the server does not override the ID, it MAY omit the 'client-id' attribute.
|
||||
</p>
|
||||
</section2>
|
||||
</section1>
|
||||
<section1 topic='Business Rules' anchor='rules'>
|
||||
<ol>
|
||||
<li>XMPP entities, which are routing stanzas, MUST NOT strip the message-id element from message stanzas.</li>
|
||||
<li>The values of the 'id' attribute SHOULD be unpredictable.</li>
|
||||
<li>Message ID generating entities, which encounter a <message-id/> element where 'id' and 'client-id' is already set, MUST ignore the existing value of 'id' and override it.</li>
|
||||
<li>&MESSAGE; stanzas MUST posses at most one 'message-id' extension element in the direct child level of the stanza.</li>
|
||||
</ol>
|
||||
</section1>
|
||||
<section1 topic='Security Considerations' anchor='security'>
|
||||
<p>The value of the 'id' attribute should not provide any further information besides the opaque ID itself. Entities observing the value MUST NOT be able to infer any information from it, e.g. the size of the message archive.</p>
|
||||
</section1>
|
||||
<section1 topic='IANA Considerations' anchor='iana'>
|
||||
<p>This document requires no interaction with &IANA;.</p>
|
||||
</section1>
|
||||
<section1 topic='XMPP Registrar Considerations' anchor='registrar'>
|
||||
<section2 topic='Protocol Namespaces' anchor='ns'>
|
||||
<p>The ®ISTRAR; includes "urn:xmpp:mid:0" in its registry of protocol namespaces (see &NAMESPACES;).</p>
|
||||
</section2>
|
||||
</section1>
|
||||
<section1 topic='XML Schema' anchor='schema'>
|
||||
<p>REQUIRED for protocol specifications.</p>
|
||||
</section1>
|
||||
<section1 topic='Acknowledgements' anchor='ack'>
|
||||
<p>Thanks to Thijs Alkemade and Georg Lukas for providing feedback.</p>
|
||||
</section1>
|
||||
</xep>
|
@ -1,123 +0,0 @@
|
||||
<?xml version='1.0' encoding='UTF-8'?>
|
||||
<!DOCTYPE xep SYSTEM 'xep.dtd' [
|
||||
<!ENTITY % ents SYSTEM 'xep.ent'>
|
||||
%ents;
|
||||
]>
|
||||
<?xml-stylesheet type='text/xsl' href='xep.xsl'?>
|
||||
<xep>
|
||||
<header>
|
||||
<title>Zero Handshake Server to Server Protocol</title>
|
||||
<abstract>
|
||||
This specification defines an approach for a pair of servers to eliminate initial handshakes and associated
|
||||
data transfer when using the XMPP S2S Protocol. This approach may only be used with a priori agreement and configuration
|
||||
of the two servers involved. This is of significant benefit in high latency environments.
|
||||
</abstract>
|
||||
<legal>
|
||||
<copyright>This XMPP Extension Protocol is copyright (c) 1999 - 2015 by the XMPP Standards Foundation (XSF).</copyright>
|
||||
<permissions>Permission is hereby granted, free of charge, to any person obtaining a copy of this specification (the "Specification"), to make use of the Specification without restriction, including without limitation the rights to implement the Specification in a software program, deploy the Specification in a network service, and copy, modify, merge, publish, translate, distribute, sublicense, or sell copies of the Specification, and to permit persons to whom the Specification is furnished to do so, subject to the condition that the foregoing copyright notice and this permission notice shall be included in all copies or substantial portions of the Specification. Unless separate permission is granted, modified works that are redistributed shall not contain misleading information regarding the authors, title, number, or publisher of the Specification, and shall not claim endorsement of the modified works by the authors, any organization or project to which the authors belong, or the XMPP Standards Foundation.</permissions>
|
||||
<warranty>## NOTE WELL: This Specification is provided on an "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, express or implied, including, without limitation, any warranties or conditions of TITLE, NON-INFRINGEMENT, MERCHANTABILITY, or FITNESS FOR A PARTICULAR PURPOSE. In no event shall the XMPP Standards Foundation or the authors of this Specification be liable for any claim, damages, or other liability, whether in an action of contract, tort, or otherwise, arising from, out of, or in connection with the Specification or the implementation, deployment, or other use of the Specification. ##</warranty>
|
||||
<liability>In no event and under no legal theory, whether in tort (including negligence), contract, or otherwise, unless required by applicable law (such as deliberate and grossly negligent acts) or agreed to in writing, shall the XMPP Standards Foundation or any author of this Specification be liable for damages, including any direct, indirect, special, incidental, or consequential damages of any character arising out of the use or inability to use the Specification (including but not limited to damages for loss of goodwill, work stoppage, computer failure or malfunction, or any and all other commercial damages or losses), even if the XMPP Standards Foundation or such author has been advised of the possibility of such damages.</liability>
|
||||
<conformance>This XMPP Extension Protocol has been contributed in full conformance with the XSF's Intellectual Property Rights Policy (a copy of which may be found at <<link url='http://xmpp.org/extensions/ipr-policy.shtml'>http://xmpp.org/extensions/ipr-policy.shtml</link>> or obtained by writing to XSF, P.O. Box 1641, Denver, CO 80201 USA).</conformance>
|
||||
</legal>
|
||||
<number>xxxx</number>
|
||||
<status>ProtoXEP</status>
|
||||
<type>Informational</type>
|
||||
<sig>Standards</sig>
|
||||
<approver>Council</approver>
|
||||
<dependencies>
|
||||
<spec>RFC 6120</spec>
|
||||
<spec>RCC 6121</spec>
|
||||
|
||||
</dependencies>
|
||||
<supersedes/>
|
||||
<supersededby/>
|
||||
<shortname>X2X</shortname>
|
||||
<author>
|
||||
<firstname>Steve</firstname>
|
||||
<surname>Kille</surname>
|
||||
<email>steve.kille@isode.com</email>
|
||||
<jid>steve.kille@isode.com</jid>
|
||||
</author>
|
||||
<revision>
|
||||
<version>0.0.1</version>
|
||||
<date>2015-06-22</date>
|
||||
<initials>sek</initials>
|
||||
<remark><p>First draft.</p></remark>
|
||||
</revision>
|
||||
</header>
|
||||
<section1 topic='Introduction' anchor='intro'>
|
||||
<p>
|
||||
This specification arose from work on deploying XMPP in high latency environments, with round trips of several second. Even with data transfer rates as low as 2400 bit per second, XMPP works well once connections are established as compressed messages are small and the protocols are fully asynchronous. However the combination of low data rate and high latency led to connection establishment times of several minutes. This was unworkable, particularly when connections were prone to failure.
|
||||
</p>
|
||||
<p>
|
||||
The solution set out here is to eliminate all the initial handshaking and to start the S2S communication as if the handshaking had been correctly completed. This cannot be used for communication between an arbitrary pair of servers, as in general the negotiation associated with the handshaking is vital for correctly determining a variety of parameters for use in the connection. However, a pair of servers may operate by locally configuring information that would have been negotiated. This enables the pair of servers to eliminate initial handshaking and data exchange.
|
||||
</p>
|
||||
</section1>
|
||||
<section1 topic='Requirements' anchor='reqs'>
|
||||
<p>
|
||||
This specification can be considered as a profile for server to server XMPP communication, to enable XMPP deployment over high latency links. This profile MUST only be used where its use has been pre-agreed and configured for both participating servers.
|
||||
</p>
|
||||
</section1>
|
||||
<section1 topic='Glossary' anchor='glossary'>
|
||||
<p>OPTIONAL.
|
||||
</p>
|
||||
<p> Sections without text to be removed prior to sending doc for XSF review.</p>
|
||||
</section1>
|
||||
<section1 topic='Use Cases' anchor='usecases'>
|
||||
<p>STRONGLY RECOMMENDED.</p>
|
||||
</section1>
|
||||
<section1 topic='Business Rules' anchor='rules'>
|
||||
<p>Typically a pair of XMPP servers connecting using this protocol will communicate with multiple domains (e.g., a base domain and a MUC domain). It is generally desirable to configure things so that all communications will share the same link, rather than establishing separate links for each domain. Two or more connections MAY be initiated from one server to the other but this is NOT RECOMMENDED. </p>
|
||||
<p>
|
||||
An XMPP server receiving messages over such a link should appropriately validate to and from elements of inbound messages. The rules for this SHOULD be controlled by an priori agreement. An inbound connection will generally be associated with several peer domains. A RECOMMENDED approach is to consider each of these peers in turn and validate in the manner of a peer XMPP server connected using RFC 6120 for that domain. In the event that an inbound message is not considered to be valid, it should be handled in a manner that this invalid message would be handled if it arrived over standard S2S.
|
||||
</p>
|
||||
</section1>
|
||||
<section1 topic='Implementation Notes' anchor='impl'>
|
||||
<section2 topic="General">
|
||||
<p>
|
||||
In simple terms, this can be considered as operation of RFC 6121 communication between a pair of XMPP servers without the preliminary negotiation done in RFC 6120. It might be considered that the start point is the
|
||||
DONE box in Figure 3 of RFC 6120. The TCP connection is opened and messages start to flow. All configuration information, including choice of port is handled by a the a priori configuration.</p>
|
||||
</section2>
|
||||
<section2 topic="Connection Direction">
|
||||
<p>
|
||||
Connections may be opened by one server only or by either server. The choice is part of the a priori configured agreement. It is generally recommended to allow connections to be opened by either server. However policy or network constraints may require that the connection is initiated by one server only. When a server initiates a connection it MUST use this connection to send messages to the other server. The server opening a connection is responsible for closing it at the end of its use.
|
||||
</p>
|
||||
<p>
|
||||
When a connection is opened by the peer server, the local server MAY use this connection to send messages or MAY open a connection. It is recommended that only a single connection is used in this scenario and so in many cases this protocol will proceed with a single TCP connection and messages flowing in both directions. In the event of both servers opening connections at the same time, both TCP connections SHOULD be used with messages sent on the connection opened by the message sender only.
|
||||
</p>
|
||||
</section2>
|
||||
<section2 topic="Use of TLS">
|
||||
<p>
|
||||
This protocol MAY be deployed directly over TCP. This will often be appropriate for environments where network security is handled at IP or lower layers or where the system is operated in closed network environment.
|
||||
</p>
|
||||
<p>
|
||||
This protocol may be deployed over TLS operating over TCP. If this is done, TLS client and or server X.509 based authentication may be used, with certificate validation achieved by PKI or simply pinning (configuring) a trusted certificate. This configuration and authentication is a part of the a priori configuration.
|
||||
</p>
|
||||
</section2>
|
||||
</section1>
|
||||
<section1 topic='Accessibility Considerations' anchor='access'>
|
||||
<p>OPTIONAL.</p>
|
||||
</section1>
|
||||
<section1 topic='Internationalization Considerations' anchor='i18n'>
|
||||
<p>OPTIONAL.</p>
|
||||
</section1>
|
||||
<section1 topic='Security Considerations' anchor='security'>
|
||||
<p>
|
||||
This protocol operates without the standard XMPP security negotiation. It is imperative that consideration is given to link security whenever this protocol is set up. In particular it is important to validate the source IP address and source IP port of inbound connections against the a priori configuration. This can be done directly by match of IP address or by use of reverse DNS lookup to identify the connecting server.
|
||||
</p>
|
||||
</section1>
|
||||
<section1 topic='IANA Considerations' anchor='iana'>
|
||||
<p>None.</p>
|
||||
</section1>
|
||||
<section1 topic='XMPP Registrar Considerations' anchor='registrar'>
|
||||
<p>None.</p>
|
||||
</section1>
|
||||
<section1 topic='XML Schema' anchor='schema'>
|
||||
<p>n/a.</p>
|
||||
</section1>
|
||||
<section1 topic="Acknowledgement">
|
||||
<p>
|
||||
Dave Cridland, Curtis King, Kevin Smith and Kurt Zeilenga worked out and validated the approach documented in this XEP.
|
||||
</p>
|
||||
</section1>
|
||||
</xep>
|
291
inbox/otr-info.xml
Normal file
291
inbox/otr-info.xml
Normal file
@ -0,0 +1,291 @@
|
||||
<?xml version='1.0' encoding='UTF-8'?>
|
||||
<!DOCTYPE xep SYSTEM 'xep.dtd' [
|
||||
<!ENTITY % ents SYSTEM 'xep.ent'>
|
||||
%ents;
|
||||
]>
|
||||
<?xml-stylesheet type='text/xsl' href='xep.xsl'?>
|
||||
<xep>
|
||||
<header>
|
||||
<title>Current Off-the-Record Messaging Usage</title>
|
||||
<abstract>
|
||||
This document outlines the current usage of Off-the-Record messaging in
|
||||
XMPP, its drawbacks, its strengths, and recommendations for improving the
|
||||
end user experience.
|
||||
</abstract>
|
||||
&LEGALNOTICE;
|
||||
<number>xxxx</number>
|
||||
<status>ProtoXEP</status>
|
||||
<type>Informational</type>
|
||||
<sig>Standards</sig>
|
||||
<approver>Council</approver>
|
||||
<dependencies>
|
||||
<spec>XMPP Core</spec>
|
||||
</dependencies>
|
||||
<supersedes/>
|
||||
<supersededby/>
|
||||
<shortname>NOT_YET_ASSIGNED</shortname>
|
||||
<author>
|
||||
<firstname>Sam</firstname>
|
||||
<surname>Whited</surname>
|
||||
<email>sam@samwhited.com</email>
|
||||
<jid>sam@samwhited.com</jid>
|
||||
</author>
|
||||
<revision>
|
||||
<version>0.0.1</version>
|
||||
<date>2015-07-28</date>
|
||||
<initials>ssw</initials>
|
||||
<remark><p>Initial draft.</p></remark>
|
||||
</revision>
|
||||
</header>
|
||||
<section1 topic='Introduction' anchor='intro'>
|
||||
<p>
|
||||
The Off-the-Record messaging protocol (OTR) was originally introduced in
|
||||
the 2004 paper
|
||||
<i><link url='https://otr.cypherpunks.ca/otr-wpes.pdf'>
|
||||
Off-the-Record Communication, or, Why Not To Use PGP
|
||||
</link></i>
|
||||
<note>
|
||||
Nikita Borisov, Ian Goldberg, Eric Brewer (2004-10-28). "Off-the-Record
|
||||
Communication, or, Why Not To Use PGP"
|
||||
<<link url='https://otr.cypherpunks.ca/otr-wpes.pdf'>
|
||||
https://otr.cypherpunks.ca/otr-wpes.pdf
|
||||
</link>>
|
||||
</note>
|
||||
and has since become the de facto standard for performing end-to-end
|
||||
encryption in XMPP. OTR provides encryption, deniable authentication,
|
||||
forward secrecy, and malleable encryption.
|
||||
</p>
|
||||
<p>
|
||||
The OTR protocol itself is currently described by the document:
|
||||
<i><link url='https://otr.cypherpunks.ca/Protocol-v3-4.0.0.html'>
|
||||
Off-the-Record Messaging Protocol version 3
|
||||
</link></i>
|
||||
<note>
|
||||
"Off-the-Record Messaging Protocol version 3"
|
||||
<<link url='https://otr.cypherpunks.ca/Protocol-v3-4.0.0.html'>
|
||||
https://otr.cypherpunks.ca/Protocol-v3-4.0.0.html
|
||||
</link>>
|
||||
</note>
|
||||
and will not be redescribed here. Instead, this document aims to describe
|
||||
OTR's usage and best practices within XMPP. It is not intended to be a
|
||||
current standard, or technical specification, as better (albeit, newer and
|
||||
less well tested) methods of end-to-end encryption exist for XMPP.
|
||||
</p>
|
||||
</section1>
|
||||
<section1 topic='Overview' anchor='overview'>
|
||||
<p>
|
||||
Though this document will not focus on the OTR protocol itself, a brief
|
||||
overview is warranted to better understand the protocols strengths and
|
||||
weaknesses.
|
||||
</p>
|
||||
<p>
|
||||
OTR uses 128 bit AES symmetric-key encryption and the SHA-1 hash function.
|
||||
An OTR session can be held only between two parties, meaning that OTR is
|
||||
incompatible with &xep0045;. It provides deniability in the form of
|
||||
malleable encryption (a third party may generate fake messages after the
|
||||
session has ended). This means that if you were not a part of the original
|
||||
conversation, you cannot prove based on captured messages alone that a
|
||||
message from the conversation was actually sent by a given party. Unlike
|
||||
PGP, OTR also provides forward secrecy; even if a session is recorded and
|
||||
the primary key is compromised at a later date, the OTR messages will not
|
||||
be able to be decrypted as each was encrypted with an ephemeral key
|
||||
exchanged with Diffie-Hellman key exchange with a 1536 bit modulus.
|
||||
</p>
|
||||
</section1>
|
||||
<section1 topic='Discovery'>
|
||||
<p>
|
||||
Clients that support the OTR protocol do not advertise it in any of the
|
||||
normal XMPP ways. Instead, OTR provides its own discovery mechanism. If a
|
||||
client wishes to indicate support for OTR they include a special whitespace
|
||||
tag in their messages. This tag can appear anywhere in the body of the
|
||||
message stanza, but it is most often found at the end. The OTR tag
|
||||
comprises the following bytes:
|
||||
|
||||
<example caption='OTR tag'>
|
||||
\x20\x09\x20\x20\x09\x09\x09\x09 \x20\x09\x20\x09\x20\x09\x20\x20
|
||||
</example>
|
||||
|
||||
and is followed by one or more of the following sequences to indicate the
|
||||
version of OTR which the client supports:
|
||||
|
||||
<example caption='OTR tag version 1'>
|
||||
\x20\x09\x20\x09\x20\x20\x09\x20
|
||||
</example>
|
||||
|
||||
Note that this version 1 tag must come before other version tags for
|
||||
compatibility; it is, however, NOT RECOMMENDED to implement version 1 of
|
||||
the OTR protocol.
|
||||
|
||||
<example caption='OTR tag version 2'>
|
||||
\x20\x20\x09\x09\x20\x20\x09\x20
|
||||
</example>
|
||||
|
||||
<example caption='OTR tag version 3'>
|
||||
\x20\x20\x09\x09\x20\x20\x09\x09
|
||||
</example>
|
||||
</p>
|
||||
<p>
|
||||
When a client sees this special string in the body of a message stanza it
|
||||
may choose to start an OTR session immediately, or merely indicate support
|
||||
to the user and allow the user to manually start a session. This is done by
|
||||
sending a message stanza containing an OTR query message in the body which
|
||||
indicates the supported versions of OTR. In XMPP these are most commonly
|
||||
version 2 and version 3, which would be indicated by a message stanza which
|
||||
has a body that starts with the string:
|
||||
|
||||
<example caption='OTR query'>
|
||||
?OTR?v23?
|
||||
</example>
|
||||
</p>
|
||||
<p>
|
||||
Any message which begins with the afforementioned string (note that the
|
||||
version number[s] may be different), postfixed with a payload should be
|
||||
decrypted as an OTR message. The initialization message should not contain
|
||||
a payload, and should just be the initialization string by itself.
|
||||
</p>
|
||||
</section1>
|
||||
<section1 topic='OTR Messages'>
|
||||
<section2 topic='Construction and Decoding'>
|
||||
<p>
|
||||
When sending a message encrypted with OTR, it is RECOMMENDED to encrypt
|
||||
only the text node of the <body/> element (the message itself).
|
||||
However, there are some clients in the wild which will encrypt the entire
|
||||
contents of the <body/> element, including sub-nodes. Because of
|
||||
this behavior, it is RECOMMENDED that clients decrypt and expand any OTR
|
||||
messages inside of the body element before re-processing the element as a
|
||||
whole. Clients that support OTR MUST tolerate encrypted payloads which
|
||||
expand to XML, and those which expand to plain text messages.
|
||||
</p>
|
||||
</section2>
|
||||
<section2 topic='Routing'>
|
||||
<p>
|
||||
XMPP is designed so that the client needs to know very little about where
|
||||
and how a message will be routed. Generally, clients are encouraged to
|
||||
send messages to the bare JID and allow the server to route the messages
|
||||
as it sees fit. However, OTR requires that messages be sent to a
|
||||
particular resource. Therefore clients SHOULD send OTR messages to a full
|
||||
JID, possibly allowing the user to determine which resource they wish to
|
||||
start an encrypted session with. Furthermore, if a client receives a
|
||||
request to start an OTR session in a carboned message (due to a server
|
||||
which does not support the aforementioned "private" directive, or a
|
||||
client which does not set it), it SHOULD be silently ignored.
|
||||
</p>
|
||||
</section2>
|
||||
<section2 topic='Processing Hints'>
|
||||
<p>
|
||||
&xep0334; defines a set of hints for how messages should be handled by
|
||||
XMPP servers. These hints are not hard and fast rules, but suggestions
|
||||
which the servers may or may not choose to follow. Best practice is to
|
||||
include the following hints on all OTR messages:
|
||||
|
||||
<code><![CDATA[
|
||||
<no-copy xmlns="urn:xmpp:hints"/>
|
||||
<no-permanent-store xmlns="urn:xmpp:hints"/>
|
||||
]]></code>
|
||||
</p>
|
||||
|
||||
<p>
|
||||
Similarly the "private" directive from &xep0280; should also be included
|
||||
to indicate that carbons are not necessary (since no other resource will
|
||||
be able to read the message):
|
||||
|
||||
<code><![CDATA[
|
||||
<private xmlns="urn:xmpp:carbons:2"/>
|
||||
]]></code>
|
||||
|
||||
All together, an example OTR message might look like this (with the
|
||||
majority of the body stripped out for readability):
|
||||
|
||||
<example caption='OTR message with processing hints'><![CDATA[
|
||||
<message
|
||||
from='malvolio@stewardsguild.lit/countesshousehold'
|
||||
to='olivia@countess.lit/veiled'>
|
||||
<body>?OTR?v23?...</body>
|
||||
<no-copy xmlns="urn:xmpp:hints"/>
|
||||
<no-permanent-store xmlns="urn:xmpp:hints"/>
|
||||
<private xmlns="urn:xmpp:carbons:2"/>
|
||||
</message>
|
||||
]]></example>
|
||||
</p>
|
||||
</section2>
|
||||
</section1>
|
||||
<section1 topic='Use in XMPP URIs'>
|
||||
<p>
|
||||
&rfc5122; defines a Uniform Resource Identifier (URI) and Internationalized
|
||||
Resource Identifier (IRI) scheme for XMPP entities, and &xep0147; defines
|
||||
various query components for use with XMPP URI's. When an entity has an
|
||||
associated OTR fingerprint it's URI is often formed with "otr-fingerprint"
|
||||
in the query string. Eg.
|
||||
|
||||
<example caption='OTR Fingerprint'>
|
||||
xmpp:feste@allfools.lit?otr-fingerprint=AEA4D503298797D4A4FC823BC1D24524B4C54338
|
||||
</example>
|
||||
</p>
|
||||
<p>
|
||||
The ®ISTRAR; maintains a registry of queries and key-value pairs for use
|
||||
in XMPP URIs at &QUERYTYPES;. As of the date this document was authored,
|
||||
the 'otr-fingerprint' query string has not been formally defined and has
|
||||
therefore is not officially recognized by the registrar.
|
||||
</p>
|
||||
</section1>
|
||||
<section1 topic='Acknowledgements' anchor='acks'>
|
||||
<p>
|
||||
Thanks to Daniel Gultsch for his excellent
|
||||
<link url='https://github.com/siacs/Conversations/blob/development/docs/observations.md'>
|
||||
article
|
||||
</link>
|
||||
<note>
|
||||
Daniel Gultsch (Retreived on 2015-07-29). "Observations on Imlementing
|
||||
XMPP"
|
||||
<<link url='https://github.com/siacs/Conversations/blob/development/docs/observations.md'>
|
||||
https://github.com/siacs/Conversations/blob/development/docs/observations.md
|
||||
</link>>
|
||||
</note>
|
||||
on the pitfalls of implementing OTR, and to Georg Lukas for his feedback.
|
||||
</p>
|
||||
</section1>
|
||||
<section1 topic='Security Considerations' anchor='security'>
|
||||
<p>
|
||||
While this document describes an existing protocol which is streamed over
|
||||
XMPP and therefore does not introduce any new security concerns itself, it
|
||||
is worth mentioning a few security issues with the underlying OTR protocol:
|
||||
</p>
|
||||
<p>
|
||||
Because Diffie-Hellman (D-H) key exchange is unauthenticated, the initial
|
||||
D-H exchange which sets up the encrypted channel is vulnerable to a
|
||||
man-in-the-middle attack. No sensitive information should be sent over the
|
||||
encrypted channel until mutual authentication has been performed
|
||||
inside the encrypted channel.
|
||||
</p>
|
||||
<p>
|
||||
OTR makes use of the SHA-1 hash algorithm. While no practical attacks have
|
||||
been observed in SHA-1 at the time of this writing, theoretical attacks
|
||||
have been constructed, and attacks have been performed on hash functions
|
||||
that are similar to SHA-1. One cryptographer estimated that the cost
|
||||
of generating SHA-1 collisions was $2.77 million dollars in 2012, and would
|
||||
drop to $700,000 by 2015.
|
||||
<note>
|
||||
Bruce Schneier (2012-10-05). "When Will We See Collisions for SHA-1?"
|
||||
<<link url='https://www.schneier.com/blog/archives/2012/10/when_will_we_se.html'>
|
||||
https://www.schneier.com/blog/archives/2012/10/when_will_we_se.html
|
||||
</link>>
|
||||
</note>.
|
||||
This puts generating SHA-1 collisions well within the reach of governments
|
||||
and well funded criminal organizations. In this authors opinion, there are
|
||||
no theoretical vulnerabilities, and SHA-1 should be treated as with extreme
|
||||
caution.
|
||||
</p>
|
||||
</section1>
|
||||
<section1 topic='IANA Considerations' anchor='iana'>
|
||||
<p>
|
||||
This document requires no interaction with the Internet Assigned Numbers
|
||||
Authority (IANA).
|
||||
</p>
|
||||
</section1>
|
||||
<section1 topic='XMPP Registrar Considerations' anchor='registrar'>
|
||||
<p>
|
||||
No namespaces or parameters need to be registered with the XMPP Registrar
|
||||
as a result of this document.
|
||||
</p>
|
||||
</section1>
|
||||
</xep>
|
27
prettify.css
Executable file
27
prettify.css
Executable file
@ -0,0 +1,27 @@
|
||||
/* Pretty printing styles. Used with prettify.js. */
|
||||
|
||||
.str { color: #080; }
|
||||
.kwd { color: #008; }
|
||||
.com { color: #800; }
|
||||
.typ { color: #606; }
|
||||
.lit { color: #066; }
|
||||
.pun { color: #660; }
|
||||
.pln { color: #000; }
|
||||
.tag { color: #008; }
|
||||
.atn { color: #606; }
|
||||
.atv { color: #080; }
|
||||
.dec { color: #606; }
|
||||
pre.prettyprint { padding: 2px; border: 1px solid #888; }
|
||||
|
||||
@media print {
|
||||
.str { color: #060; }
|
||||
.kwd { color: #006; font-weight: bold; }
|
||||
.com { color: #600; font-style: italic; }
|
||||
.typ { color: #404; font-weight: bold; }
|
||||
.lit { color: #044; }
|
||||
.pun { color: #440; }
|
||||
.pln { color: #000; }
|
||||
.tag { color: #006; font-weight: bold; }
|
||||
.atn { color: #404; }
|
||||
.atv { color: #060; }
|
||||
}
|
33
prettify.js
Executable file
33
prettify.js
Executable file
@ -0,0 +1,33 @@
|
||||
(function(){
|
||||
var o=true,r=null,z=false;window.PR_SHOULD_USE_CONTINUATION=o;window.PR_TAB_WIDTH=8;window.PR_normalizedHtml=window.PR=window.prettyPrintOne=window.prettyPrint=void 0;window._pr_isIE6=function(){var N=navigator&&navigator.userAgent&&/\bMSIE 6\./.test(navigator.userAgent);window._pr_isIE6=function(){return N};return N};
|
||||
var aa="!",ba="!=",ca="!==",F="#",da="%",ea="%=",G="&",fa="&&",ja="&&=",ka="&=",H="(",la="*",ma="*=",na="+=",oa=",",pa="-=",qa="->",ra="/",sa="/=",ta=":",ua="::",va=";",I="<",wa="<<",xa="<<=",ya="<=",za="=",Aa="==",Ba="===",J=">",Ca=">=",Da=">>",Ea=">>=",Fa=">>>",Ga=">>>=",Ha="?",Ia="@",L="[",M="^",Ta="^=",Ua="^^",Va="^^=",Wa="{",O="|",Xa="|=",Ya="||",Za="||=",$a="~",ab="break",bb="case",cb="continue",db="delete",eb="do",fb="else",gb="finally",hb="instanceof",ib="return",jb="throw",kb="try",lb="typeof",
|
||||
mb="(?:^^|[+-]",nb="\\$1",ob=")\\s*",pb="&",qb="<",rb=">",sb=""",tb="&#",ub="x",vb="'",wb='"',xb=" ",yb="XMP",zb="</",Ab='="',P="",Q="\\",Bb="b",Cb="t",Db="n",Eb="v",Fb="f",Gb="r",Hb="u",Ib="0",Jb="1",Kb="2",Lb="3",Mb="4",Nb="5",Ob="6",Pb="7",Qb="\\x0",Rb="\\x",Sb="-",Tb="]",Ub="\\\\u[0-9A-Fa-f]{4}|\\\\x[0-9A-Fa-f]{2}|\\\\[0-3][0-7]{0,2}|\\\\[0-7]{1,2}|\\\\[\\s\\S]|-|[^-\\\\]",R="g",Vb="\\B",Wb="\\b",Xb="\\D",Yb="\\d",Zb="\\S",$b="\\s",ac="\\W",bc="\\w",cc="(?:\\[(?:[^\\x5C\\x5D]|\\\\[\\s\\S])*\\]|\\\\u[A-Fa-f0-9]{4}|\\\\x[A-Fa-f0-9]{2}|\\\\[0-9]+|\\\\[^ux0-9]|\\(\\?[:!=]|[\\(\\)\\^]|[^\\x5B\\x5C\\(\\)\\^]+)",
|
||||
dc="(?:",ec=")",fc="gi",gc="PRE",hc='<!DOCTYPE foo PUBLIC "foo bar">\n<foo />',ic="\t",jc="\n",kc="[^<]+|<!--[\\s\\S]*?--\>|<!\\[CDATA\\[[\\s\\S]*?\\]\\]>|</?[a-zA-Z][^>]*>|<",lc="nocode",mc=' $1="$2$3$4"',S="pln",nc="string",T="lang-",oc="src",U="str",pc="'\"",qc="'\"`",rc="\"'",V="com",sc="lang-regex",tc="(/(?=[^/*])(?:[^/\\x5B\\x5C]|\\x5C[\\s\\S]|\\x5B(?:[^\\x5C\\x5D]|\\x5C[\\s\\S])*(?:\\x5D|$))+/)",uc="kwd",vc="^(?:",wc=")\\b",xc=" \r\n\t\u00a0",yc="lit",zc="typ",Ac="0123456789",Y="pun",Bc="break continue do else for if return while auto case char const default double enum extern float goto int long register short signed sizeof static struct switch typedef union unsigned void volatile catch class delete false import new operator private protected public this throw true try alignof align_union asm axiom bool concept concept_map const_cast constexpr decltype dynamic_cast explicit export friend inline late_check mutable namespace nullptr reinterpret_cast static_assert static_cast template typeid typename typeof using virtual wchar_t where break continue do else for if return while auto case char const default double enum extern float goto int long register short signed sizeof static struct switch typedef union unsigned void volatile catch class delete false import new operator private protected public this throw true try boolean byte extends final finally implements import instanceof null native package strictfp super synchronized throws transient as base by checked decimal delegate descending event fixed foreach from group implicit in interface internal into is lock object out override orderby params partial readonly ref sbyte sealed stackalloc string select uint ulong unchecked unsafe ushort var break continue do else for if return while auto case char const default double enum extern float goto int long register short signed sizeof static struct switch typedef union unsigned void volatile catch class delete false import new operator private protected public this throw true try debugger eval export function get null set undefined var with Infinity NaN caller delete die do dump elsif eval exit foreach for goto if import last local my next no our print package redo require sub undef unless until use wantarray while BEGIN END break continue do else for if return while and as assert class def del elif except exec finally from global import in is lambda nonlocal not or pass print raise try with yield False True None break continue do else for if return while alias and begin case class def defined elsif end ensure false in module next nil not or redo rescue retry self super then true undef unless until when yield BEGIN END break continue do else for if return while case done elif esac eval fi function in local set then until ",
|
||||
Cc="</span>",Dc='<span class="',Ec='">',Fc="$1 ",Gc=" <br />",Hc="<br />",Ic="console",Jc="cannot override language handler %s",Kc="default-markup",Lc="default-code",Mc="dec",Z="lang-js",$="lang-css",Nc="lang-in.tag",Oc="htm",Pc="html",Qc="mxml",Rc="xhtml",Sc="xml",Tc="xsl",Uc=" \t\r\n",Vc="atv",Wc="tag",Xc="atn",Yc="lang-uq.val",Zc="in.tag",$c="uq.val",ad="break continue do else for if return while auto case char const default double enum extern float goto int long register short signed sizeof static struct switch typedef union unsigned void volatile catch class delete false import new operator private protected public this throw true try alignof align_union asm axiom bool concept concept_map const_cast constexpr decltype dynamic_cast explicit export friend inline late_check mutable namespace nullptr reinterpret_cast static_assert static_cast template typeid typename typeof using virtual wchar_t where ",
|
||||
bd="c",cd="cc",dd="cpp",ed="cxx",fd="cyc",gd="m",hd="null true false",id="json",jd="break continue do else for if return while auto case char const default double enum extern float goto int long register short signed sizeof static struct switch typedef union unsigned void volatile catch class delete false import new operator private protected public this throw true try boolean byte extends final finally implements import instanceof null native package strictfp super synchronized throws transient as base by checked decimal delegate descending event fixed foreach from group implicit in interface internal into is lock object out override orderby params partial readonly ref sbyte sealed stackalloc string select uint ulong unchecked unsafe ushort var ",
|
||||
kd="cs",ld="break continue do else for if return while auto case char const default double enum extern float goto int long register short signed sizeof static struct switch typedef union unsigned void volatile catch class delete false import new operator private protected public this throw true try boolean byte extends final finally implements import instanceof null native package strictfp super synchronized throws transient ",md="java",nd="break continue do else for if return while case done elif esac eval fi function in local set then until ",
|
||||
od="bsh",pd="csh",qd="sh",rd="break continue do else for if return while and as assert class def del elif except exec finally from global import in is lambda nonlocal not or pass print raise try with yield False True None ",sd="cv",td="py",ud="caller delete die do dump elsif eval exit foreach for goto if import last local my next no our print package redo require sub undef unless until use wantarray while BEGIN END ",vd="perl",wd="pl",xd="pm",yd="break continue do else for if return while alias and begin case class def defined elsif end ensure false in module next nil not or redo rescue retry self super then true undef unless until when yield BEGIN END ",
|
||||
zd="rb",Ad="break continue do else for if return while auto case char const default double enum extern float goto int long register short signed sizeof static struct switch typedef union unsigned void volatile catch class delete false import new operator private protected public this throw true try debugger eval export function get null set undefined var with Infinity NaN ",Bd="js",Cd="regex",Dd="pre",Ed="code",Fd="xmp",Gd="prettyprint",Hd="class",Id="br",Jd="\r";
|
||||
(function(){var N=function(){for(var a=[aa,ba,ca,F,da,ea,G,fa,ja,ka,H,la,ma,na,oa,pa,qa,ra,sa,ta,ua,va,I,wa,xa,ya,za,Aa,Ba,J,Ca,Da,Ea,Fa,Ga,Ha,Ia,L,M,Ta,Ua,Va,Wa,O,Xa,Ya,Za,$a,ab,bb,cb,db,eb,fb,gb,hb,ib,jb,kb,lb],b=mb,c=0;c<a.length;++c)b+=O+a[c].replace(/([^=<>:&a-z])/g,nb);b+=ob;return b}(),Ja=/&/g,Ka=/</g,La=/>/g,Kd=/\"/g;function Ld(a){return a.replace(Ja,pb).replace(Ka,qb).replace(La,rb).replace(Kd,sb)}function ga(a){return a.replace(Ja,pb).replace(Ka,qb).replace(La,rb)}var Md=/</g,Nd=/>/g,
|
||||
Od=/'/g,Pd=/"/g,Qd=/&/g,Rd=/ /g;function Sd(a){var b=a.indexOf(G);if(b<0)return a;for(--b;(b=a.indexOf(tb,b+1))>=0;){var c=a.indexOf(va,b);if(c>=0){var d=a.substring(b+3,c),g=10;if(d&&d.charAt(0)===ub){d=d.substring(1);g=16}var i=parseInt(d,g);isNaN(i)||(a=a.substring(0,b)+String.fromCharCode(i)+a.substring(c+1))}}return a.replace(Md,I).replace(Nd,J).replace(Od,vb).replace(Pd,wb).replace(Qd,G).replace(Rd,xb)}function Ma(a){return yb===a.tagName}function W(a,b){switch(a.nodeType){case 1:var c=
|
||||
a.tagName.toLowerCase();b.push(I,c);for(var d=0;d<a.attributes.length;++d){var g=a.attributes[d];if(g.specified){b.push(xb);W(g,b)}}b.push(J);for(var i=a.firstChild;i;i=i.nextSibling)W(i,b);if(a.firstChild||!/^(?:br|link|img)$/.test(c))b.push(zb,c,J);break;case 2:b.push(a.name.toLowerCase(),Ab,Ld(a.value),wb);break;case 3:case 4:b.push(ga(a.nodeValue));break}}function Na(a){for(var b=0,c=z,d=z,g=0,i=a.length;g<i;++g){var m=a[g];if(m.ignoreCase)d=o;else if(/[a-z]/i.test(m.source.replace(/\\u[0-9a-f]{4}|\\x[0-9a-f]{2}|\\[^ux]/gi,
|
||||
P))){c=o;d=z;break}}function l(j){if(j.charAt(0)!==Q)return j.charCodeAt(0);switch(j.charAt(1)){case Bb:return 8;case Cb:return 9;case Db:return 10;case Eb:return 11;case Fb:return 12;case Gb:return 13;case Hb:case ub:return parseInt(j.substring(2),16)||j.charCodeAt(1);case Ib:case Jb:case Kb:case Lb:case Mb:case Nb:case Ob:case Pb:return parseInt(j.substring(1),8);default:return j.charCodeAt(1)}}function n(j){if(j<32)return(j<16?Qb:Rb)+j.toString(16);var f=String.fromCharCode(j);if(f===Q||f===Sb||
|
||||
f===L||f===Tb)f=Q+f;return f}function q(j){for(var f=j.substring(1,j.length-1).match(new RegExp(Ub,R)),s=[],k=[],h=f[0]===M,e=h?1:0,p=f.length;e<p;++e){var t=f[e];switch(t){case Vb:case Wb:case Xb:case Yb:case Zb:case $b:case ac:case bc:s.push(t);continue}var u=l(t),x;if(e+2<p&&Sb===f[e+1]){x=l(f[e+2]);e+=2}else x=u;k.push([u,x]);if(!(x<65||u>122)){x<65||u>90||k.push([Math.max(65,u)|32,Math.min(x,90)|32]);x<97||u>122||k.push([Math.max(97,u)&-33,Math.min(x,122)&-33])}}k.sort(function(Oa,Pa){return Oa[0]-
|
||||
Pa[0]||Pa[1]-Oa[1]});var B=[],E=[NaN,NaN];for(e=0;e<k.length;++e){var A=k[e];if(A[0]<=E[1]+1)E[1]=Math.max(E[1],A[1]);else B.push(E=A)}var D=[L];h&&D.push(M);D.push.apply(D,s);for(e=0;e<B.length;++e){A=B[e];D.push(n(A[0]));if(A[1]>A[0]){A[1]+1>A[0]&&D.push(Sb);D.push(n(A[1]))}}D.push(Tb);return D.join(P)}function v(j){var f=j.source.match(new RegExp(cc,R)),s=f.length,k=[],h,e=0;for(h=0;e<s;++e){var p=f[e];if(p===H)++h;else if(Q===p.charAt(0)){var t=+p.substring(1);if(t&&t<=h)k[t]=-1}}for(e=1;e<k.length;++e)if(-1===
|
||||
k[e])k[e]=++b;for(h=e=0;e<s;++e){p=f[e];if(p===H){++h;if(k[h]===undefined)f[e]=dc}else if(Q===p.charAt(0))if((t=+p.substring(1))&&t<=h)f[e]=Q+k[h]}for(h=e=0;e<s;++e)if(M===f[e]&&M!==f[e+1])f[e]=P;if(j.ignoreCase&&c)for(e=0;e<s;++e){p=f[e];var u=p.charAt(0);if(p.length>=2&&u===L)f[e]=q(p);else if(u!==Q)f[e]=p.replace(/[a-zA-Z]/g,function(x){var B=x.charCodeAt(0);return L+String.fromCharCode(B&-33,B|32)+Tb})}return f.join(P)}var w=[];g=0;for(i=a.length;g<i;++g){m=a[g];if(m.global||m.multiline)throw new Error(P+
|
||||
m);w.push(dc+v(m)+ec)}return new RegExp(w.join(O),d?fc:R)}var ha=r;function Td(a){if(r===ha){var b=document.createElement(gc);b.appendChild(document.createTextNode(hc));ha=!/</.test(b.innerHTML)}if(ha){var c=a.innerHTML;if(Ma(a))c=ga(c);return c}for(var d=[],g=a.firstChild;g;g=g.nextSibling)W(g,d);return d.join(P)}function Ud(a){var b=0;return function(c){for(var d=r,g=0,i=0,m=c.length;i<m;++i){var l=c.charAt(i);switch(l){case ic:d||(d=[]);d.push(c.substring(g,i));var n=a-b%a;for(b+=n;n>=0;n-=" ".length)d.push(" ".substring(0,
|
||||
n));g=i+1;break;case jc:b=0;break;default:++b}}if(!d)return c;d.push(c.substring(g));return d.join(P)}}var Vd=new RegExp(kc,R),Wd=/^<\!--/,Xd=/^<\[CDATA\[/,Yd=/^<br\b/i,Qa=/^<(\/?)([a-zA-Z]+)/;function Zd(a){var b=a.match(Vd),c=[],d=0,g=[];if(b)for(var i=0,m=b.length;i<m;++i){var l=b[i];if(l.length>1&&l.charAt(0)===I){if(!Wd.test(l))if(Xd.test(l)){c.push(l.substring(9,l.length-3));d+=l.length-12}else if(Yd.test(l)){c.push(jc);++d}else if(l.indexOf(lc)>=0&&$d(l)){var n=l.match(Qa)[2],q=1,v;v=i+1;a:for(;v<
|
||||
m;++v){var w=b[v].match(Qa);if(w&&w[2]===n)if(w[1]===ra){if(--q===0)break a}else++q}if(v<m){g.push(d,b.slice(i,v+1).join(P));i=v}else g.push(d,l)}else g.push(d,l)}else{var j=Sd(l);c.push(j);d+=j.length}}return{source:c.join(P),tags:g}}function $d(a){return!!a.replace(/\s(\w+)\s*=\s*(?:\"([^\"]*)\"|'([^\']*)'|(\S+))/g,mc).match(/[cC][lL][aA][sS][sS]=\"[^\"]*\bnocode\b/)}function ia(a,b,c,d){if(b){var g={source:b,b:a};c(g);d.push.apply(d,g.c)}}function K(a,b){var c={},d;(function(){for(var m=a.concat(b),
|
||||
l=[],n={},q=0,v=m.length;q<v;++q){var w=m[q],j=w[3];if(j)for(var f=j.length;--f>=0;)c[j.charAt(f)]=w;var s=w[1],k=P+s;if(!n.hasOwnProperty(k)){l.push(s);n[k]=r}}l.push(/[\0-\uffff]/);d=Na(l)})();var g=b.length,i=function(m){for(var l=m.source,n=m.b,q=[n,S],v=0,w=l.match(d)||[],j={},f=0,s=w.length;f<s;++f){var k=w[f],h=j[k],e,p;if(typeof h===nc)p=z;else{var t=c[k.charAt(0)];if(t){e=k.match(t[1]);h=t[0]}else{for(var u=0;u<g;++u){t=b[u];if(e=k.match(t[1])){h=t[0];break}}e||(h=S)}if((p=h.length>=5&&T===
|
||||
h.substring(0,5))&&!(e&&e[1])){p=z;h=oc}p||(j[k]=h)}var x=v;v+=k.length;if(p){var B=e[1],E=k.indexOf(B),A=E+B.length,D=h.substring(5);ia(n+x,k.substring(0,E),i,q);ia(n+x+E,B,Ra(D,B),q);ia(n+x+A,k.substring(A),i,q)}else q.push(n+x,h)}m.c=q};return i}function C(a){var b=[],c=[];if(a.tripleQuotedStrings)b.push([U,/^(?:\'\'\'(?:[^\'\\]|\\[\s\S]|\'{1,2}(?=[^\']))*(?:\'\'\'|$)|\"\"\"(?:[^\"\\]|\\[\s\S]|\"{1,2}(?=[^\"]))*(?:\"\"\"|$)|\'(?:[^\\\']|\\[\s\S])*(?:\'|$)|\"(?:[^\\\"]|\\[\s\S])*(?:\"|$))/,r,pc]);
|
||||
else a.multiLineStrings?b.push([U,/^(?:\'(?:[^\\\']|\\[\s\S])*(?:\'|$)|\"(?:[^\\\"]|\\[\s\S])*(?:\"|$)|\`(?:[^\\\`]|\\[\s\S])*(?:\`|$))/,r,qc]):b.push([U,/^(?:\'(?:[^\\\'\r\n]|\\.)*(?:\'|$)|\"(?:[^\\\"\r\n]|\\.)*(?:\"|$))/,r,rc]);if(a.hashComments)a.cStyleComments?b.push([V,/^#(?:[^\r\n\/]|\/(?!\*)|\/\*[^\r\n]*?\*\/)*/,r,F]):b.push([V,/^#[^\r\n]*/,r,F]);if(a.cStyleComments){c.push([V,/^\/\/[^\r\n]*/,r]);c.push([V,/^\/\*[\s\S]*?(?:\*\/|$)/,r])}a.regexLiterals&&c.push([sc,new RegExp(M+N+tc)]);var d=
|
||||
a.keywords.replace(/^\s+|\s+$/g,P);d.length&&c.push([uc,new RegExp(vc+d.replace(/\s+/g,O)+wc),r]);b.push([S,/^\s+/,r,xc]);c.push([yc,/^@[a-z_$][a-z_$@0-9]*/i,r,Ia],[zc,/^@?[A-Z]+[a-z][A-Za-z_$@0-9]*/,r],[S,/^[a-z_$][a-z_$@0-9]*/i,r],[yc,/^(?:0x[a-f0-9]+|(?:\d(?:_\d+)*\d*(?:\.\d*)?|\.\d\+)(?:e[+\-]?\d+)?)[a-z]*/i,r,Ac],[Y,/^.[^\s\w\.$@\'\"\`\/\#]*/,r]);return K(b,c)}var ae=C({keywords:Bc,hashComments:o,cStyleComments:o,multiLineStrings:o,regexLiterals:o});function be(a){var b=a.source,c=a.f,d=a.c,
|
||||
g=[],i=0,m=r,l=r,n=0,q=0,v=Ud(window.PR_TAB_WIDTH),w=/([\r\n ]) /g,j=/(^| ) /gm,f=/\r\n?|\n/g,s=/[ \r\n]$/,k=o;function h(p){if(p>i){if(m&&m!==l){g.push(Cc);m=r}if(!m&&l){m=l;g.push(Dc,m,Ec)}var t=ga(v(b.substring(i,p))).replace(k?j:w,Fc);k=s.test(t);var u=window._pr_isIE6()?Gc:Hc;g.push(t.replace(f,u));i=p}}for(;1;){var e;if(e=n<c.length?q<d.length?c[n]<=d[q]:o:z){h(c[n]);if(m){g.push(Cc);m=r}g.push(c[n+1]);n+=2}else if(q<d.length){h(d[q]);l=d[q+1];q+=2}else break}h(b.length);m&&g.push(Cc);a.a=g.join(P)}
|
||||
var X={};function y(a,b){for(var c=b.length;--c>=0;){var d=b[c];if(X.hasOwnProperty(d))Ic in window&&console.i(Jc,d);else X[d]=a}}function Ra(a,b){a&&X.hasOwnProperty(a)||(a=/^\s*</.test(b)?Kc:Lc);return X[a]}y(ae,[Lc]);y(K([],[[S,/^[^<?]+/],[Mc,/^<!\w[^>]*(?:>|$)/],[V,/^<\!--[\s\S]*?(?:-\->|$)/],[T,/^<\?([\s\S]+?)(?:\?>|$)/],[T,/^<%([\s\S]+?)(?:%>|$)/],[Y,/^(?:<[%?]|[%?]>)/],[T,/^<xmp\b[^>]*>([\s\S]+?)<\/xmp\b[^>]*>/i],[Z,/^<script\b[^>]*>([\s\S]+?)<\/script\b[^>]*>/i],[$,/^<style\b[^>]*>([\s\S]+?)<\/style\b[^>]*>/i],
|
||||
[Nc,/^(<\/?[a-z][^<>]*>)/i]]),[Kc,Oc,Pc,Qc,Rc,Sc,Tc]);y(K([[S,/^[\s]+/,r,Uc],[Vc,/^(?:\"[^\"]*\"?|\'[^\']*\'?)/,r,rc]],[[Wc,/^^<\/?[a-z](?:[\w:-]*\w)?|\/?>$/],[Xc,/^(?!style\b|on)[a-z](?:[\w:-]*\w)?/],[Yc,/^=\s*([^>\'\"\s]*(?:[^>\'\"\s\/]|\/(?=\s)))/],[Y,/^[=<>\/]+/],[Z,/^on\w+\s*=\s*\"([^\"]+)\"/i],[Z,/^on\w+\s*=\s*\'([^\']+)\'/i],[Z,/^on\w+\s*=\s*([^\"\'>\s]+)/i],[$,/^sty\w+\s*=\s*\"([^\"]+)\"/i],[$,/^sty\w+\s*=\s*\'([^\']+)\'/i],[$,/^sty\w+\s*=\s*([^\"\'>\s]+)/i]]),[Zc]);y(K([],[[Vc,/^[\s\S]+/]]),
|
||||
[$c]);y(C({keywords:ad,hashComments:o,cStyleComments:o}),[bd,cd,dd,ed,fd,gd]);y(C({keywords:hd}),[id]);y(C({keywords:jd,hashComments:o,cStyleComments:o}),[kd]);y(C({keywords:ld,cStyleComments:o}),[md]);y(C({keywords:nd,hashComments:o,multiLineStrings:o}),[od,pd,qd]);y(C({keywords:rd,hashComments:o,multiLineStrings:o,tripleQuotedStrings:o}),[sd,td]);y(C({keywords:ud,hashComments:o,multiLineStrings:o,regexLiterals:o}),[vd,wd,xd]);y(C({keywords:yd,hashComments:o,multiLineStrings:o,regexLiterals:o}),
|
||||
[zd]);y(C({keywords:Ad,cStyleComments:o,regexLiterals:o}),[Bd]);y(K([],[[U,/^[\s\S]+/]]),[Cd]);function Sa(a){var b=a.e,c=a.d;a.a=b;try{var d=Zd(b),g=d.source;a.source=g;a.b=0;a.f=d.tags;Ra(c,g)(a);be(a)}catch(i){if(Ic in window){console.log(i);console.h()}}}function ce(a,b){var c={e:a,d:b};Sa(c);return c.a}function de(a){for(var b=window._pr_isIE6(),c=[document.getElementsByTagName(Dd),document.getElementsByTagName(Ed),document.getElementsByTagName(Fd)],d=[],g=0;g<c.length;++g)for(var i=0,m=c[g].length;i<
|
||||
m;++i)d.push(c[g][i]);c=r;var l=Date;l.now||(l={now:function(){return(new Date).getTime()}});var n=0,q;function v(){for(var j=window.PR_SHOULD_USE_CONTINUATION?l.now()+250:Infinity;n<d.length&&l.now()<j;n++){var f=d[n];if(f.className&&f.className.indexOf(Gd)>=0){var s=f.className.match(/\blang-(\w+)\b/);if(s)s=s[1];for(var k=z,h=f.parentNode;h;h=h.parentNode)if((h.tagName===Dd||h.tagName===Ed||h.tagName===Fd)&&h.className&&h.className.indexOf(Gd)>=0){k=o;break}if(!k){var e=Td(f);e=e.replace(/(?:\r\n?|\n)$/,
|
||||
P);q={e:e,d:s,g:f};Sa(q);w()}}}if(n<d.length)setTimeout(v,250);else a&&a()}function w(){var j=q.a;if(j){var f=q.g;if(Ma(f)){for(var s=document.createElement(gc),k=0;k<f.attributes.length;++k){var h=f.attributes[k];if(h.specified){var e=h.name.toLowerCase();if(e===Hd)s.className=h.value;else s.setAttribute(h.name,h.value)}}s.innerHTML=j;f.parentNode.replaceChild(s,f);f=s}else f.innerHTML=j;if(b&&f.tagName===gc)for(var p=f.getElementsByTagName(Id),t=p.length;--t>=0;){var u=p[t];u.parentNode.replaceChild(document.createTextNode(Jd),
|
||||
u)}}}v()}window.PR_normalizedHtml=W;window.prettyPrintOne=ce;window.prettyPrint=de;window.PR={combinePrefixPatterns:Na,createSimpleLexer:K,registerLangHandler:y,sourceDecorator:C,PR_ATTRIB_NAME:Xc,PR_ATTRIB_VALUE:Vc,PR_COMMENT:V,PR_DECLARATION:Mc,PR_KEYWORD:uc,PR_LITERAL:yc,PR_NOCODE:lc,PR_PLAIN:S,PR_PUNCTUATION:Y,PR_SOURCE:oc,PR_STRING:U,PR_TAG:Wc,PR_TYPE:zc}})();
|
||||
})()
|
@ -19,6 +19,9 @@
|
||||
<supersedes/>
|
||||
<supersededby/>
|
||||
<shortname>privacy</shortname>
|
||||
<schemaloc>
|
||||
<url>http://xmpp.org/schemas/privacy.xsd</url>
|
||||
</schemaloc>
|
||||
&pgmillard;
|
||||
&stpeter;
|
||||
<revision>
|
||||
|
@ -4261,7 +4261,7 @@ And by opposing end them?
|
||||
<example caption='Node or service does not support subscription management'><![CDATA[
|
||||
<iq type='error'
|
||||
from='pubsub.shakespeare.lit'
|
||||
id='purge1'>
|
||||
id='subman1'>
|
||||
<error type='cancel'>
|
||||
<feature-not-implemented xmlns='urn:ietf:params:xml:ns:xmpp-stanzas'/>
|
||||
<unsupported xmlns='http://jabber.org/protocol/pubsub#errors'
|
||||
@ -4287,7 +4287,7 @@ And by opposing end them?
|
||||
<example caption='Node does not exist'><![CDATA[
|
||||
<iq type='error'
|
||||
from='pubsub.shakespeare.lit'
|
||||
id='purge1'>
|
||||
id='subman1'>
|
||||
<error type='cancel'>
|
||||
<item-not-found xmlns='urn:ietf:params:xml:ns:xmpp-stanzas'/>
|
||||
</error>
|
||||
|
@ -80,7 +80,7 @@
|
||||
<p>The following acronyms and characters are used herein to represent time-related concepts:</p>
|
||||
<table caption='Acronyms and Characters'>
|
||||
<tr><th>Term</th><th>Definition</th></tr>
|
||||
<tr><td>CCYY</td><td>four-digit year portion of Date</td></tr>
|
||||
<tr><td>CCYY</td><td>four-digit year portion of Date <note>According to the XML schema datatypes specification <<link url='http://www.w3.org/TR/xmlschema11-2/#dateTime'>http://www.w3.org/TR/xmlschema11-2/#dateTime</link>>, the year portion of a Date can be more than four digits (for years after 9999) and can be preceded by a minus sign (for years before 1 BCE); given that Jabber/XMPP technologies did not exist before 1999, the use of the minus sign is not recommended.</note></td></tr>
|
||||
<tr><td>MM</td><td>two-digit month portion of Date</td></tr>
|
||||
<tr><td>DD</td><td>two-digit day portion of Date</td></tr>
|
||||
<tr><td>-</td><td>ISO 8601 separator among Date portions</td></tr>
|
||||
@ -102,7 +102,7 @@
|
||||
<code>
|
||||
CCYY-MM-DD
|
||||
</code>
|
||||
<p>This profile is equivalent to the 'date' datatype defined in XML Schema <note>The 'date' datatype is defined at <<link url='http://www.w3.org/TR/xmlschema-2/#date'>http://www.w3.org/TR/xmlschema-2/#date</link>>.</note>. When an XML schema is used to define an XMPP protocol extension that uses this profile, the datatype MUST be an XML Schema 'date'. If there are differences between the description in this document and those in XML Schema, the latter overrule.</p>
|
||||
<p>This profile is equivalent to the 'date' datatype defined in XML Schema <note>The 'date' datatype is defined at <<link url='http://www.w3.org/TR/xmlschema11-2/#date'>http://www.w3.org/TR/xmlschema11-2/#date</link>>.</note>. When an XML schema is used to define an XMPP protocol extension that uses this profile, the datatype MUST be an XML Schema 'date'. If there are differences between the description in this document and those in XML Schema, the latter overrule.</p>
|
||||
<example caption='The date of American independence'>
|
||||
1776-07-04
|
||||
</example>
|
||||
@ -113,7 +113,7 @@
|
||||
CCYY-MM-DDThh:mm:ss[.sss]TZD
|
||||
</code>
|
||||
<p>The Time Zone Definition is mandatory and MUST be either UTC (denoted by addition of the character 'Z' to the end of the string) or some offset from UTC (denoted by addition of '[+|-]' and 'hh:mm' to the end of the string). The fractions of a second are optional and MAY be ignored if included (although an XMPP protocol extension using the DateTime profile MAY require the fractions of a second).</p>
|
||||
<p>This profile is equivalent to the 'dateTime' datatype defined in XML Schema <note>The 'dateTime' datatype is defined at <<link url='http://www.w3.org/TR/xmlschema-2/#dateTime'>http://www.w3.org/TR/xmlschema-2/#dateTime</link>>.</note>. When an XML schema is used to define a Jabber protocol that uses this profile, the datatype MUST be an XML Schema 'dateTime'. If there are differences between the description in this document and those in XML Schema, the latter overrule.</p>
|
||||
<p>This profile is equivalent to the 'dateTime' datatype defined in XML Schema <note>The 'dateTime' datatype is defined at <<link url='http://www.w3.org/TR/xmlschema11-2/#dateTime'>http://www.w3.org/TR/xmlschema11-2/#dateTime</link>>.</note>. When an XML schema is used to define a Jabber protocol that uses this profile, the datatype MUST be an XML Schema 'dateTime'. If there are differences between the description in this document and those in XML Schema, the latter overrule.</p>
|
||||
<example caption='Datetime of the first human steps on the Moon (UTC)'>
|
||||
1969-07-21T02:56:15Z
|
||||
</example>
|
||||
@ -127,7 +127,7 @@
|
||||
hh:mm:ss[.sss][TZD]
|
||||
</code>
|
||||
<p>The Time Zone Definition is optional; if included, it MUST be either UTC (denoted by addition of the character 'Z' to the end of the string) or some offset from UTC (denoted by addition of '[+|-]' <note>Inclusion of the '+' character means that the time in that zone is ahead of UTC; e.g., a Time Zone Definition of "+07:00" means that if the UTC time is 12:00 then the local time is 19:00 (typically this is true of an area that is east of 0° degrees latitude and west of 180° latitude, such as Bangkok, Thailand). Inclusion of the '-' character means that the time in that zone is behind UTC; e.g., a Time Zone Definition of "-07:00" means that if the UTC time is 12:00 then the local time is 05:00 (typically this is true of an area that is west of 0° degrees latitude and east of 180° latitude, such as Denver, Colorado, USA).</note> and 'hh:mm' to the end of the string). The fractions of a second are optional and MAY be ignored if included (although a Jabber protocol using the DateTime profile MAY require the fractions of a second).</p>
|
||||
<p>This profile is equivalent to the 'time' datatype defined in XML Schema <note>The 'time' datatype is defined at <<link url='http://www.w3.org/TR/xmlschema-2/#time'>http://www.w3.org/TR/xmlschema-2/#time</link>>.</note>. When an XML schema is used to define a Jabber protocol that uses this profile, the datatype MUST be an XML Schema 'time'. If there are differences between the description in this document and those in XML Schema, the latter overrule.</p>
|
||||
<p>This profile is equivalent to the 'time' datatype defined in XML Schema <note>The 'time' datatype is defined at <<link url='http://www.w3.org/TR/xmlschema11-2/#time'>http://www.w3.org/TR/xmlschema11-2/#time</link>>.</note>. When an XML schema is used to define a Jabber protocol that uses this profile, the datatype MUST be an XML Schema 'time'. If there are differences between the description in this document and those in XML Schema, the latter overrule.</p>
|
||||
<example caption='Time for tea'>
|
||||
16:00:00
|
||||
</example>
|
||||
|
16
xep-0198.xml
16
xep-0198.xml
@ -28,6 +28,18 @@
|
||||
&fabio;
|
||||
&dcridland;
|
||||
&mwild;
|
||||
<interim/>
|
||||
<revision>
|
||||
<version>1.4rc1</version>
|
||||
<date>2015-07-27</date>
|
||||
<initials>dc</initials>
|
||||
<remark>
|
||||
<ul>
|
||||
<li>Expressed how to handle duplicate enable requests.</li>
|
||||
<li>Noted the use of delay stamping in redelivery/offline messaging by servers.</li>
|
||||
</ul>
|
||||
</remark>
|
||||
</revision>
|
||||
<revision>
|
||||
<version>1.3</version>
|
||||
<date>2011-06-29</date>
|
||||
@ -224,6 +236,8 @@ S: <failed xmlns='urn:xmpp:sm:3'>
|
||||
<unexpected-request xmlns='urn:ietf:params:xml:ns:xmpp-stanzas'/>
|
||||
</failed>
|
||||
]]></example>
|
||||
<p>Note that a client SHALL only make at most one attempt to enable stream management. If a server receives a second <enable/> element it SHOULD respond with a stream error, thus terminating the client connection
|
||||
.</p>
|
||||
</section1>
|
||||
|
||||
<section1 topic='Acks' anchor='acking'>
|
||||
@ -278,7 +292,7 @@ S: <a xmlns='urn:xmpp:sm:3' h='1'/>
|
||||
<p>When a party receives an <a/> element, it SHOULD keep a record of the 'h' value returned as the sequence number of the last handled outbound stanza for the current stream (and discard the previous value).</p>
|
||||
<p>If a stream ends and it is not resumed within the time specified in the original <enabled/> element, the sequence number and any associated state MAY be discarded by both parties. Before the session state is discarded, implementations SHOULD take alternative action regarding any unhandled stanzas (i.e., stanzas sent after the most recent 'h' value received):</p>
|
||||
<ul>
|
||||
<li>A server SHOULD treat unacknowledged stanzas in the same way that it would treat a stanza sent to an unavailable resource, by either returning an error to the sender or committing the stanza to offline storage.</li>
|
||||
<li>A server SHOULD treat unacknowledged stanzas in the same way that it would treat a stanza sent to an unavailable resource, by either returning an error to the sender, delivery to an alternate resource, or committing the stanza to offline storage. (Note that servers SHOULD add a delay element with the original (failed) delivery timestamp, as per &xep0203;).</li>
|
||||
<li>A user-oriented client SHOULD try to silently resend the stanzas upon reconnection or inform the user of the failure via appropriate user-interface elements.</li>
|
||||
</ul>
|
||||
<p>Because unacknowledged stanzas might have been received by the other party, resending them might result in duplicates; there is no way to prevent such a result in this protocol, although use of the XMPP 'id' attribute on all stanzas can at least assist the intended recipients in weeding out duplicate stanzas.</p>
|
||||
|
@ -53,7 +53,7 @@
|
||||
<li>Two endpoints want to enforce end-to-end encryption</li>
|
||||
<li>Two endpoints want to send a high volume of XMPP traffic but the intermediate servers enforce rate limits</li>
|
||||
</ul>
|
||||
<p>The first situation is addressed by &xep0174;. However, if the endpoints already have client-to-server connections but wish to bypass those connections or leverage those streams for a higher-level application such as end-to-end encryption, it is desirable for the two endpoints to negotiate an end-to-end XML stream. This specification defines methods for doing so, where the application format is an XML stream and the transport method is any direct or mediated streaming transport, such as &xep0261; (mediated), &xep0260; (direct or mediated), or a future ice-tcp Jingle transport (direct or mediated) based on &ice-tcp;.</p>
|
||||
<p>The first situation is addressed by &xep0174;. However, if the endpoints already have client-to-server connections but wish to bypass those connections or leverage those streams for a higher-level application such as end-to-end encryption, it is desirable for the two endpoints to negotiate an end-to-end XML stream. This specification defines methods for doing so, where the application format is an XML stream and the transport method is any direct or mediated streaming transport, such as &xep0261; (mediated), &xep0260; (direct or mediated), or a future ice-tcp Jingle transport (direct or mediated) based on &rfc6544;.</p>
|
||||
</section1>
|
||||
|
||||
<section1 topic='Protocol' anchor='protocol'>
|
||||
@ -79,7 +79,7 @@
|
||||
| ack |
|
||||
|------------------------------>|
|
||||
| [ XML stream over IBB ] |
|
||||
|<----------------------------->|
|
||||
|<=============================>|
|
||||
| terminate |
|
||||
|<------------------------------|
|
||||
| ack |
|
||||
@ -118,7 +118,7 @@
|
||||
id='hwd987h'
|
||||
to='romeo@montague.lit/orchard'
|
||||
type='set'>
|
||||
<jingle xmlns='urn:xmpp:jingle:0'>
|
||||
<jingle xmlns='urn:xmpp:jingle:0'
|
||||
action='session-accept'
|
||||
initiator='romeo@montague.lit/orchard'
|
||||
sid='a73sjjvkla37jfea'>
|
||||
|
@ -10,7 +10,8 @@
|
||||
<abstract>In order to keep all IM clients for a user engaged in a conversation, outbound messages are carbon-copied to all interested resources.</abstract>
|
||||
&LEGALNOTICE;
|
||||
<number>0280</number>
|
||||
<status>Experimental</status>
|
||||
<status>Proposed</status>
|
||||
<lastcall>2015-08-28</lastcall>
|
||||
<type>Standards Track</type>
|
||||
<sig>Standards</sig>
|
||||
<approver>Council</approver>
|
||||
|
312
xep-0286.xml
312
xep-0286.xml
@ -6,11 +6,14 @@
|
||||
<?xml-stylesheet type='text/xsl' href='xep.xsl'?>
|
||||
<xep>
|
||||
<header>
|
||||
<title>XMPP on Mobile Devices</title>
|
||||
<abstract>This document provides background information for XMPP implementors concerned with mobile devices operating in a cellular network such as 3G.</abstract>
|
||||
<title>Mobile Considerations</title>
|
||||
<abstract>
|
||||
This document provides background information for XMPP implementors
|
||||
concerned with mobile devices operating on an LTE cellular network.
|
||||
</abstract>
|
||||
&LEGALNOTICE;
|
||||
<number>0286</number>
|
||||
<status>Deferred</status>
|
||||
<status>Experimental</status>
|
||||
<type>Informational</type>
|
||||
<sig>Standards</sig>
|
||||
<approver>Council</approver>
|
||||
@ -26,6 +29,24 @@
|
||||
<email>dave.cridland@isode.com</email>
|
||||
<jid>dave.cridland@isode.com</jid>
|
||||
</author>
|
||||
<author>
|
||||
<firstname>Sam</firstname>
|
||||
<surname>Whited</surname>
|
||||
<email>sam@samwhited.com</email>
|
||||
<jid>sam@samwhited.com</jid>
|
||||
</author>
|
||||
<revision>
|
||||
<version>0.3</version>
|
||||
<date>2015-07-24</date>
|
||||
<initials>ssw</initials>
|
||||
<remark><p>Include real world compression numbers and additional recommended reading.</p></remark>
|
||||
</revision>
|
||||
<revision>
|
||||
<version>0.2</version>
|
||||
<date>2015-07-22</date>
|
||||
<initials>ssw</initials>
|
||||
<remark><p>Overhaul to include LTE.</p></remark>
|
||||
</revision>
|
||||
<revision>
|
||||
<version>0.1</version>
|
||||
<date>2010-09-15</date>
|
||||
@ -40,140 +61,181 @@
|
||||
</revision>
|
||||
</header>
|
||||
<section1 topic='Introduction' anchor='intro'>
|
||||
<p>The use of XMPP on mobile devices is little understood, since few XMPP implementors have good mobile knowledge, and few mobile engineers have good XMPP knowledge. In addition, as the mobile landscape has changed, optimal protocol designs and usage patterns have also changed. This has led to the sub-optimal combination of a large amount of mostly undocumented lore, as well as several outdated concepts being discussed as fact.</p>
|
||||
<p>This XEP aims to provide useful background knowledge of mobile handset behaviours, and essentially distills a number of conversations with experienced mobile engineers and XMPP implementors, providing useful background as general suggestions.</p>
|
||||
<p>
|
||||
XMPP as a protocol was designed before the wide spread adoption of mobile
|
||||
devices, and is often cited as not being very mobile friendly as a result.
|
||||
However, this mostly stems from undocumented lore and outdated notions of
|
||||
how XMPP works. As the Internet and protocol design have changed to be more
|
||||
accommodating for mobile, so has XMPP.
|
||||
</p>
|
||||
<p>
|
||||
This XEP aims to provide useful background knowledge of mobile handset
|
||||
behavior, and those considerations that client and server designers can
|
||||
take to ensure that bandwidth and battery are used efficiently.
|
||||
</p>
|
||||
</section1>
|
||||
<section1 topic='Overview' anchor='overview'>
|
||||
<p>Mobile handsets typically have two constraints - power and bandwidth. The advent of 3G technology and beyond has tended to mean that bandwidth is radically higher, and comparable to broadband speeds - however many operators still charge based on transferred data, hence bandwidth remains an important issue for cost purposes.</p>
|
||||
<p>The major cost of power in the handset for our purposes is the radio - here, too, bandwidth plays a part, but as this document will show, the time the radio is forced to be available to receive also costs substantially.</p>
|
||||
<p>Whilst this document refers to &rfc3920;, implementors are advised to take note of &rfc6120;.</p>
|
||||
<p>
|
||||
The two major constraints on mobile devices are power and bandwidth. With
|
||||
the wide spread proliferation of 3G and LTE technologies, mobile bandwidth
|
||||
and speeds have become broadly comparable to broadband. However, they are
|
||||
still relatively expensive compared to traditional wired networks, and
|
||||
should therefore still be considered. This XEP mostly focuses on LTE as it
|
||||
already has a very wide deployment and will only continue to further
|
||||
replace 3G technologies.
|
||||
</p>
|
||||
</section1>
|
||||
<section1 topic='Compression'>
|
||||
<p>XMPP is known to compress well. Both TLS, part of &xmppcore;, and &xep0138; can provide access to the DEFLATE codec (<span class='ref'><link url='http://tools.ietf.org/html/rfc1951'>RFC 1951</link></span> <note>RFC 1951 DEFLATE Compressed Data Format Specification version 1.3
|
||||
<<link url='http://tools.ietf.org/html/rfc1951'>http://tools.ietf.org/html/rfc1951</link>>.</note>), which provides access to simple stream compression.</p>
|
||||
<p>Compression ratios vary with usage, however, typical usage by a general client appears to show a 20% ratio (an 80% reduction in bandwidth) in longer sessions<note>Fixed-purpose clients, such as the Buddycloud client, do see even lower ratios, approaching 10%.</note>. Server implementors should note that there is a substantial memory cost per codec of 300KB assuming maximum settings - this may be dramatically reduced by reducing the memory level and window bits of the implementation - lowering memory level primarily causes increased CPU usage, whereas lowering the window bits directly degrade compression.</p>
|
||||
<p>At an exemplary point in one experiment, the author found the following figures<note>The compression ratio is here given as Original/Compressed, hence a 100% compression ratio is no compression at all, and 0% would represent infinite compression.</note>:</p>
|
||||
<table>
|
||||
<tr>
|
||||
<th>Window Bits</th>
|
||||
<th>Compression Ratio (approx)</th>
|
||||
</tr>
|
||||
<tr>
|
||||
<td>15</td>
|
||||
<td>20%</td>
|
||||
</tr>
|
||||
<tr>
|
||||
<td>14</td>
|
||||
<td>22%</td>
|
||||
</tr>
|
||||
<tr>
|
||||
<td>13</td>
|
||||
<td>25%</td>
|
||||
</tr>
|
||||
<tr>
|
||||
<td>12</td>
|
||||
<td>30%</td>
|
||||
</tr>
|
||||
<tr>
|
||||
<td>11</td>
|
||||
<td>38%</td>
|
||||
</tr>
|
||||
<tr>
|
||||
<td>10</td>
|
||||
<td>43%</td>
|
||||
</tr>
|
||||
<tr>
|
||||
<td>9</td>
|
||||
<td>60%</td>
|
||||
</tr>
|
||||
</table>
|
||||
<p>Although there is an equal cost for the mobile device to compress, it is considered that the compression codec memory and CPU costs - while certainly translating into power cost - are outweighed by two factors. Firstly, they're likely to reduce the transmission cost by a greater amount, and secondly they will also reduce the encryption cost in TLS.</p>
|
||||
<p>Care, however, should be taken not to use XEP-0138 compression when TLS compression is in effect.</p>
|
||||
|
||||
<section1 topic='Compression' anchor='compression'>
|
||||
<p>
|
||||
XML, and by extension XMPP, is known to be highly compressible.
|
||||
Compression of XMPP data can be achieved with the DEFLATE algorithm
|
||||
(&rfc1951;) via TLS compression (&rfc3749;) or &xep0138; (which also
|
||||
supports other compression algorithms). While the security implications of
|
||||
stream compression are beyond the scope of this document (See the
|
||||
aforementioned RFC or XEP for more info), the author does not recommend
|
||||
using TLS compression with XMPP (or in general). If compression must be
|
||||
used, stream level compression should be implemented instead, and the
|
||||
compressed stream should have a full flush performed on stanza boundaries
|
||||
to help prevent a class of chosen plaintext attacks which can cause data
|
||||
leakage in compressed streams. While this may mitigate some of the benefits
|
||||
of compression by raising compression ratios, in a large, real world
|
||||
deployment at HipChat, network traffic was still observed to decrease by a
|
||||
factor of 0.58 when enabling &xep0138; with ZLIB compression!
|
||||
</p>
|
||||
<p>
|
||||
While the CPU cost of compression may directly translate to higher power
|
||||
usage, it is vastly outweighed by the benefits of reduced network
|
||||
utilization, especially on modern LTE networks which use a great deal more
|
||||
power per bit than 3G networks as will be seen later in this document.
|
||||
However, CPU usage is also not guaranteed to rise due to compression. In
|
||||
the aforementioned deployment of stream compression, a <em>decrease</em> in
|
||||
CPU utilization by a factor of 0.60 was observed due to the fact that there
|
||||
were fewer packets that needed to be handled by the OS (which also takes
|
||||
CPU time), and, potentially more importantly, less data that needed to be
|
||||
TLS-encrypted (which is a much more CPU-expensive operation than
|
||||
compression). Therefore CPU time spent on compression (for ZLIB, at least;
|
||||
other algorithms were not tested) should be considered negligable.
|
||||
</p>
|
||||
<p>
|
||||
Supporting compression and flushing on stanza boundaries is highly
|
||||
recommended.
|
||||
</p>
|
||||
</section1>
|
||||
<section1 topic='Radio Power'>
|
||||
<p>Mobile handsets have a number of levels for radio activity. 3G radios can be either Idle, or else in an increasingly capable - and increasingly power-hungry - series of levels, through FACH to DCH.</p>
|
||||
<p>For the purposes of investigating this, power consumption (or rather battery depletion rate, as current) and timeouts where measured on the 3UK network, with a Nokia E71, using the Energy Profiler. A "typical handset" mentioned here has a 1000mAh battery - some smartphones have up to 1500mAh. Note that all timeouts are under the control of the network operator, not the handset or application.</p>
|
||||
<section2 topic='Idle'>
|
||||
<p>Idle state is when the radio is neither receiving nor transmitting. It may have live (although silent) TCP connections. The cost is low. There is also a PCH level, which is similarly low-power, and again is only used when the radio is silent.</p>
|
||||
<p>The current here was measured as 8mA - likely affected more by the energy profiler than much else.</p>
|
||||
</section2>
|
||||
<section2 topic='FACH'>
|
||||
<p>FACH uses a shared channel for low-bandwidth communications. Packet sizes must be small - around 128 octets maximum, although this is operator controlled. Raising to this state takes around 2.5 seconds before the data can flow - although the power cost rises instantly - and after the session has returned to silence, it will remain at FACH level for some time.</p>
|
||||
<p>Note that this threshold includes the overheads from TCP and TLS, which are 52 and 5 octets respectively, leaving around 70 octets for the payload data.</p>
|
||||
<p>Here, the current was measured as 140mA, and a timeout of 8 seconds - this timeout is at the lower end of the expected range, which could be up to around 2 minutes. On a typical handset, this will exhaust the battery in around 7 hours.</p>
|
||||
</section2>
|
||||
<section2 topic='DCH'>
|
||||
<p>DCH uses a dedicated channel for high bandwidth communications. Again, raising to this state takes 2.5 seconds at the DCH power level, and there is a timeout before dropping back. Some operators will drop back to FACH for the duration fo the FACH timeout - others will drop back to Idle/PCH.</p>
|
||||
<p>Sending more than the FACH threshold will raise the radio all the way to DCH - taking, again, 2.5 seconds.</p>
|
||||
<p>The measurements here were 380mA and 8 seconds - this is sufficient to flatten a typical handset battery in less than 3 hours, and the figures are considered normal.</p>
|
||||
</section2>
|
||||
<p>Transmission of data can use up to 2W<note>The author's hazy recollection of P=IV suggests around a 570mA current</note>, and raising the level itself takes between 2 and 3 seconds to take effect - during which time the handset cannot receive or transmit, but still incurs the power cost. There are packets sent from and to the handset during this time.</p>
|
||||
<p>Experimentation suggests that uncompressed XMPP will never trigger the FACH state, leaping directly into the more costly DCH state. However, compression does make FACH possible, if rare.</p>
|
||||
<section1 topic='Power Consumption' anchor='power'>
|
||||
<p>
|
||||
While the wide spread adoption of LTE has dramatically increased available
|
||||
bandwidth on mobile devices, it has also increased power consumption.
|
||||
According to one study, early LTE devices consumed 5–20% more power
|
||||
than their 3G counterparts
|
||||
<note>LTE Smartphone measurements <<link url='http://networks.nokia.com/system/files/document/lte_measurements_final.pdf'>http://networks.nokia.com/system/files/document/lte_measurements_final.pdf</link>></note>.
|
||||
On some networks that support the legacy SVLTE (Simultaneous Voice and LTE)
|
||||
instead of the more modern VoLTE (Voice Over LTE) standard, or even CSFB
|
||||
(Circuit-switched fallback) this number would (presumably) be even higher.
|
||||
</p>
|
||||
<p>
|
||||
XMPP server and client implementers, bearing this increased power usage in
|
||||
mind, and knowing a bit about how LTE radios work, can optimize their
|
||||
traffic to minimize network usage. For the downlink, LTE user equipment
|
||||
(UE) utilizes Orthogonal Frequency Division Multiplexing (OFDM), which is
|
||||
somewhat inefficient
|
||||
<note>A Close Examination of Performance and Power Characteristics of 4G LTE Networks <<link url='http://www.cs.columbia.edu/~lierranli/coms6998-7Spring2014/papers/rrclte_mobisys2012.pdf'>http://www.cs.columbia.edu/~lierranli/coms6998-7Spring2014/papers/rrclte_mobisys2012.pdf</link>></note>.
|
||||
On the uplink side a different technology, Single-carrier frequency
|
||||
division multiple access (SC-FDMA) is used, which is slightly more
|
||||
efficient than traditional (non linearly-precoded) OFDM, slightly
|
||||
offsetting the fact that broadcasting requires more power than receiving.
|
||||
LTE UE also implements a Discontinuous reception (DRX) mode in which the
|
||||
hardware can sleep until it is woken by a paging message or is needed to
|
||||
perform some task. LTE radios have two power modes: RRC_CONNECTED and
|
||||
RRC_IDLE. DRX is supported in both of these power modes. By attempting to
|
||||
minimize the time which the LTE UE state machine spends in the
|
||||
RCC_CONNECTED state, and maximize the time it stays in the DRX state (for
|
||||
RCC_CONNECTED and RRC_IDLE), we can increase battery life without degrading
|
||||
the XMPP experience. To do so, the following rules should be observed:
|
||||
</p>
|
||||
<section2 topic='Transmit no data'>
|
||||
<p>
|
||||
Whenever possible, data that is not strictly needed should not be
|
||||
transmitted (by the server or client). Supporting &xep0352; is highly
|
||||
recommended. Most importantly, XMPP pings should be kept as far apart as
|
||||
possible and only used when necessary. Server operators are encouraged to
|
||||
set high ping timeouts, and client implementors are advised to only send
|
||||
pings when absolutely necessary to prevent the server from closing the
|
||||
socket.
|
||||
</p>
|
||||
</section2>
|
||||
<section2 topic='Transmit as much data as you can at once'>
|
||||
<p>
|
||||
If one is on 3G, transmitting a small amount of data will cause the radio
|
||||
to enter FACH mode which is significantly cheaper than its high power
|
||||
mode. On LTE radios, however, transmitting small amounts of data is
|
||||
vastly more expensive per bit due to the significantly higher tail-times
|
||||
(the time it takes for the radio to change state). On LTE radios, one
|
||||
should transmit as much data as possible when the radio is already on
|
||||
(eg. by placing messages in a send queue and executing the queue as a
|
||||
batch). Similarly, when data is being received the radio is already in a
|
||||
high power state and therefore any data that needs to be sent should be.
|
||||
</p>
|
||||
<p>
|
||||
These rules also apply to server operators: If you receive data, the
|
||||
phones radio is already on therefore you should send anything you have.
|
||||
Otherwise, batching data to be sent and sending it all at once (and as
|
||||
much as possible) will help reduce power consumption.
|
||||
</p>
|
||||
</section2>
|
||||
</section1>
|
||||
<section1 topic='Conclusions'>
|
||||
<p>As with anything, there are no hard and fast rules. If there were, they might look like these. First, for devices:</p>
|
||||
<dl>
|
||||
<di>
|
||||
<dt>Transmit no data.</dt>
|
||||
<dd>Transmitting costs significant power, and moreover raises the radio state. Not transmitting will allow it to maximize the time spent in the low-cost Idle state.</dd>
|
||||
</di>
|
||||
<di>
|
||||
<dt>If you must transmit, then transmit only a small volume.</dt>
|
||||
<dd>If there is only a small amount of data transmitted - less than 128 octets typically - the radio will only raise to FACH, which is significantly cheaper than DCH.</dd>
|
||||
</di>
|
||||
<di>
|
||||
<dt>If you must transmit, then compress as hard as possible.</dt>
|
||||
<dd>Since individual octets have an associate power - and often financial - cost, it's worth maximizing the compression algorithm, even if the volume of traffic will raise to DCH.</dd>
|
||||
</di>
|
||||
<di>
|
||||
<dt>If you have transmit a lot, then do a lot</dt>
|
||||
<dd>If the radio is raised to DCH anyway, then you may as well go fetch that avatar you were missing, since you're chewing through power anyway.</dd>
|
||||
</di>
|
||||
<di>
|
||||
<dt>If you receive, then transmit</dt>
|
||||
<dd>If your peer raises the radio state, you may as well use it.</dd>
|
||||
</di>
|
||||
</dl>
|
||||
<p>And for servers, similar rules apply:</p>
|
||||
<dl>
|
||||
<di>
|
||||
<dt>Send no data.</dt>
|
||||
<dd>Sending data will cause the handset to be raised out of Idle. This immediately costs massively higher power.</dd>
|
||||
</di>
|
||||
<di>
|
||||
<dt>If you must send, send tiny bits.</dt>
|
||||
<dd>Sending small enough data maximizes the likelyhood that the devices radio will only be raised to FACH levels.</dd>
|
||||
</di>
|
||||
<di>
|
||||
<dt>If you receive, then send anything you have.</dt>
|
||||
<dd>Receiving data indicates that the radio is active - it'll stay active for some time, so sending data doesn't incur the overhead of raising the radio state, and won't increase power drain on the handset.</dd>
|
||||
</di>
|
||||
<di>
|
||||
<dt>If you must send when not receiving, send plenty.</dt>
|
||||
<dd>Sending data will raise the radio's state - unless you can tell this will only raise it to FACH, it's worth sending as much as possible.</dd>
|
||||
</di>
|
||||
</dl>
|
||||
<p>Finally, protocol designers should aim to minimize any responses required from the handset, and ensure keepalive traffic, if any, fits inside FACH wherever possible.</p>
|
||||
</section1>
|
||||
<section1 topic='Notable Extensions'>
|
||||
<p>This section provides pointers to other documents which may be of interest to those developing mobile clients, or considering support for them in servers.</p>
|
||||
<p>&xep0138; provides application stream level compression, useful if the device TLS stack does not support TLS-based compression.</p>
|
||||
<p>&xep0115; provides a mechanism for caching, and hence eliding, the disco#info requests needed to negotiate optional features.</p>
|
||||
<p>&xep0237; provides a relatively widely deployed extension for reducing the roster fetch bandwidth, in most cases reducing it to a simple affirmation that the client has the current roster. This saves not only bandwidth, but also reduces local storage writes.</p>
|
||||
<p>&xep0198; provides session resumption over TCP, enabling a client to handle the case where the coverage is patchy. The <r/> and <a/> elements also provide a keepalive facility in a small number of octets.</p>
|
||||
<p>&xep0273; provides a mechanism which, amongst other things, would allow a presence "hush", buffering presence during certain states.</p>
|
||||
<section1 topic='Notable Extensions' anchor='xeps'>
|
||||
<p>
|
||||
This section provides pointers to other documents which may be of interest
|
||||
to those developing mobile clients, or considering support for them in
|
||||
servers.
|
||||
</p>
|
||||
<p>&xep0138; provides stream level compression.</p>
|
||||
<p>&xep0322; allows XMPP streams to use the EXI XML format.</p>
|
||||
<p>
|
||||
&xep0115; provides a mechanism for caching, and hence eliding, the
|
||||
disco#info requests needed to negotiate optional features.
|
||||
</p>
|
||||
<p>
|
||||
&xep0237; provides a relatively widely deployed extension for reducing
|
||||
roster fetch sizes.
|
||||
</p>
|
||||
<p>
|
||||
&xep0198; allows the client to send and receive smaller keep-alive
|
||||
messages, and resume existing sessions without the full handshake. Useful
|
||||
on unstable connections.
|
||||
</p>
|
||||
<p>
|
||||
&xep0357; implements push notifications (third party message delivery),
|
||||
which are often used on mobile devices and highly optimized to conserve
|
||||
battery. Push notifications also allow delivery of notifications to mobile
|
||||
clients that are currently offline (eg. in an XEP-0198 "zombie" state).
|
||||
</p>
|
||||
<p>
|
||||
&xep0313; lets clients fetch messages which they missed (eg. due to poor
|
||||
mobile coverage and a flaky network connection).
|
||||
</p>
|
||||
</section1>
|
||||
<section1 topic='Acknowledgements' anchor='acks'>
|
||||
<p>The author is not a mobile expert, and relied on the knowledge and patient help of several others. In particular, thanks are due to Jussi Laako, Markku Vampari, and Markus Isomaki of Nokia, and Simon Tennant of Buddycloud.</p>
|
||||
<p>The attribution of any mistakes herein is zealously guarded by the author, however.</p>
|
||||
<p>
|
||||
This XEP was originally written by Dave Cridland, and parts of his original
|
||||
work were used in this rewrite. Thanks to Atlassian for allowing me to
|
||||
release hard numbers from their XMPP compression deployment.
|
||||
</p>
|
||||
</section1>
|
||||
<section1 topic='Security Considerations' anchor='security'>
|
||||
<p>This document does not discuss a protocol, thus introduces no new security considerations.</p>
|
||||
<p>This document introduces no new security considerations.</p>
|
||||
</section1>
|
||||
<section1 topic='IANA Considerations' anchor='iana'>
|
||||
<p>None.</p>
|
||||
<p>
|
||||
This document requires no interaction with the Internet Assigned Numbers
|
||||
Authority (IANA).
|
||||
</p>
|
||||
</section1>
|
||||
<section1 topic='XMPP Registrar Considerations' anchor='registrar'>
|
||||
<p>None.</p>
|
||||
<p>
|
||||
No namespaces or parameters need to be registered with the XMPP Registrar
|
||||
as a result of this document.
|
||||
</p>
|
||||
</section1>
|
||||
</xep>
|
||||
|
14
xep-0293.xml
14
xep-0293.xml
@ -13,8 +13,7 @@
|
||||
sessions</abstract>
|
||||
&LEGALNOTICE;
|
||||
<number>0293</number>
|
||||
<status>Proposed</status>
|
||||
<lastcall>2015-01-20</lastcall>
|
||||
<status>Draft</status>
|
||||
<type>Standards Track</type>
|
||||
<sig>Standards</sig>
|
||||
<approver>Council</approver>
|
||||
@ -22,6 +21,9 @@
|
||||
<spec>XEP-0167</spec>
|
||||
<spec>RFC 4585</spec>
|
||||
</dependencies>
|
||||
<schemaloc>
|
||||
<url>http://xmpp.org/schemas/jingle-apps-rtp-rtcp-fb.xsd</url>
|
||||
</schemaloc>
|
||||
<author>
|
||||
<firstname>Olivier</firstname>
|
||||
<surname>Crête</surname>
|
||||
@ -29,6 +31,12 @@
|
||||
<jid>olivier.crete@collabora.co.uk</jid>
|
||||
</author>
|
||||
<discuss>jingle</discuss>
|
||||
<revision>
|
||||
<version>1.0</version>
|
||||
<date>2015-08-11</date>
|
||||
<initials>XEP Editor (mam)</initials>
|
||||
<remark><p>Advanced to Draft per a vote of the XMPP Council.</p></remark>
|
||||
</revision>
|
||||
<revision>
|
||||
<version>0.3</version>
|
||||
<date>2015-04-29</date>
|
||||
@ -139,7 +147,7 @@ milliseconds for this media session. It corresponds to the
|
||||
|
||||
|
||||
<section1 topic='Negotiation' anchor='negotiation'>
|
||||
<p>Feedback messages are negotiated along the codecs. They follow
|
||||
<p>Feedback messages are negotiated along side the codecs. They follow
|
||||
the same Offer/Answer mechanism based on SDP Offer/Answer. The
|
||||
initiator signals which feedback messages it wants to send or
|
||||
receive in the the <session-initiate/> iq stanza. If the
|
||||
|
12
xep-0294.xml
12
xep-0294.xml
@ -12,8 +12,7 @@
|
||||
with Jingle RTP sessions</abstract>
|
||||
&LEGALNOTICE;
|
||||
<number>0294</number>
|
||||
<status>Proposed</status>
|
||||
<lastcall>2015-01-20</lastcall>
|
||||
<status>Draft</status>
|
||||
<type>Standards Track</type>
|
||||
<sig>Standards</sig>
|
||||
<approver>Council</approver>
|
||||
@ -21,6 +20,9 @@
|
||||
<spec>XEP-0167</spec>
|
||||
<spec>RFC 5285</spec>
|
||||
</dependencies>
|
||||
<schemaloc>
|
||||
<url>http://xmpp.org/schemas/jingle-apps-rtp-rtp-hdrext.xsd</url>
|
||||
</schemaloc>
|
||||
<author>
|
||||
<firstname>Olivier</firstname>
|
||||
<surname>Crête</surname>
|
||||
@ -28,6 +30,12 @@
|
||||
<jid>olivier.crete@collabora.co.uk</jid>
|
||||
</author>
|
||||
<discuss>jingle</discuss>
|
||||
<revision>
|
||||
<version>1.0</version>
|
||||
<date>2015-08-11</date>
|
||||
<initials>XEP Editor (mam)</initials>
|
||||
<remark><p>Advanced to Draft per a vote of the XMPP Council.</p></remark>
|
||||
</revision>
|
||||
<revision>
|
||||
<version>0.2</version>
|
||||
<date>2015-03-25</date>
|
||||
|
55
xep-0298.xml
55
xep-0298.xml
@ -16,7 +16,7 @@
|
||||
</abstract>
|
||||
&LEGALNOTICE;
|
||||
<number>0298</number>
|
||||
<status>Deferred</status>
|
||||
<status>Experimental</status>
|
||||
<type>Standards Track</type>
|
||||
<sig>Standards</sig>
|
||||
<approver>Council</approver>
|
||||
@ -30,15 +30,27 @@
|
||||
<firstname>Emil</firstname>
|
||||
<surname>Ivov</surname>
|
||||
<email>emcho@jitsi.org</email>
|
||||
<jid>emcho@sip-communicator.org</jid>
|
||||
<jid>emcho@jit.si</jid>
|
||||
</author>
|
||||
<author>
|
||||
<firstname>Enrico</firstname>
|
||||
<surname>Marocco</surname>
|
||||
<email>enrico.marocco@telecomitalia.it</email>
|
||||
<jid>enrico@tilab.com </jid>
|
||||
<jid>enrico@tilab.com</jid>
|
||||
</author>
|
||||
<author>
|
||||
<firstname>Saúl Ibarra</firstname>
|
||||
<surname>Corretgé</surname>
|
||||
<email>saul@ag-projects.com</email>
|
||||
<jid>saul@ag-projects.com</jid>
|
||||
</author>
|
||||
<discuss>jingle</discuss>
|
||||
<revision>
|
||||
<version>0.2</version>
|
||||
<date>2015-07-02</date>
|
||||
<initials>sic</initials>
|
||||
<remark><p>Correcting errors in grammar and examples; aligning closer to dependent specifications.</p></remark>
|
||||
</revision>
|
||||
<revision>
|
||||
<version>0.1</version>
|
||||
<date>2011-06-09</date>
|
||||
@ -74,8 +86,8 @@
|
||||
<p>A conference participant exchanges Coin IQs only with the agent they
|
||||
have established a session with. This means that it can also be used in
|
||||
cases where only a subset of the users on a call are using XMPP while others
|
||||
are connected via alternative mechanisms such as SIP's conference
|
||||
package &rfc4575;</p>
|
||||
are connected via alternative mechanisms such as SIP conferencing as defined
|
||||
in &rfc4579;</p>
|
||||
</section1>
|
||||
<section1 topic='Terminology' anchor='terms'>
|
||||
<dl>
|
||||
@ -86,7 +98,9 @@
|
||||
signalling and media. Other specifications refer to mixers and focus
|
||||
agents as two distinct entities but we find this separation to be
|
||||
unnecessary in the current specification and view both as a single logical
|
||||
entity</dd>
|
||||
entity. This entity may be a person hosting the conference and doing the mixing
|
||||
or a dedicated entity to which participants connect in order to establish a conference.
|
||||
For the purposes of this specification, both scenarios are equivalent.</dd>
|
||||
</di>
|
||||
</dl>
|
||||
</section1>
|
||||
@ -97,12 +111,12 @@
|
||||
<li>Provide a means for mixer agents in tightly coupled
|
||||
conferences to advertise call and member state information to the call
|
||||
participants.</li>
|
||||
<li>Reuse as much as possible the existing format and XML schema already
|
||||
<li>Reuse the existing format and XML schema already
|
||||
defined in <cite>RFC 4575</cite>.</li>
|
||||
<li>Impose no requirements on agents joining the call other than those
|
||||
necessary to establish a regular one-to-one call.</li>
|
||||
<li>Allow straightforward interoperability with other conferencing
|
||||
mechanisms such as <cite>RFC 4575</cite>; or &xep0272;</li>
|
||||
mechanisms such as &rfc4579; or &xep0272;</li>
|
||||
</ol>
|
||||
</section1>
|
||||
<section1 topic='How It Works' anchor='howitworks'>
|
||||
@ -114,8 +128,8 @@
|
||||
accordingly.</p>
|
||||
|
||||
|
||||
<p>Once in a call, call members and mixers can use Coin to exchange
|
||||
<cite>RFC 4575</cite> conference information indicating what participants
|
||||
<p>Once in a call, participants and mixers can use Coin to exchange
|
||||
&rfc4575; conference information indicating what participants
|
||||
are currently on the call and what their status is.</p>
|
||||
</section1>
|
||||
<section1 topic='Creating a conference call' anchor='call-create'>
|
||||
@ -138,7 +152,7 @@
|
||||
<description xmlns='urn:xmpp:jingle:apps:stub:0'/>
|
||||
<transport xmlns='urn:xmpp:jingle:transports:stub:0'/>
|
||||
</content>
|
||||
<conference-info isfocus='true'/>
|
||||
<conference-info xmlns='urn:xmpp:coin:1' isfocus='true'/>
|
||||
</jingle>
|
||||
</iq>
|
||||
]]></code>
|
||||
@ -164,6 +178,7 @@
|
||||
id='zid615d9'
|
||||
to='juliet@capulet.lit/balcony'
|
||||
type='set'>
|
||||
<jingle xmlns='urn:xmpp:jingle:1' sid='a73sjjvkla37jfea'/>
|
||||
<conference-info xmlns="urn:ietf:params:xml:ns:conference-info"
|
||||
entity="xmpp:romeo@monague.lit/orchard"
|
||||
state="full"
|
||||
@ -203,10 +218,10 @@
|
||||
</user>
|
||||
|
||||
<user entity="xmpp:juliet@capulet.lit" state="full">
|
||||
<display-text>Romeo</display-text>
|
||||
<display-text>Juliet</display-text>
|
||||
|
||||
<!-- ENDPOINTS -->
|
||||
<endpoint entity="juliet@capulet.lit/balcony/orchard">
|
||||
<endpoint entity="juliet@capulet.lit/balcony">
|
||||
<display-text>Juliet's netbook</display-text>
|
||||
<status>connected</status>
|
||||
|
||||
@ -239,13 +254,15 @@
|
||||
|
||||
]]></code>
|
||||
|
||||
<p>The IQ message containing the conference info document MAY also contain a jingle element with the
|
||||
session id attribute indicting the session to which the conference information refers to.</p>
|
||||
|
||||
</section1>
|
||||
|
||||
|
||||
<section1 topic='Determining Support' anchor='support'>
|
||||
<p>If an entity supports Coin, it SHOULD advertise that fact by returning
|
||||
a feature of "urn:xmpp:coin" in response to a &xep0030;
|
||||
a feature of "urn:xmpp:coin:1" in response to a &xep0030;
|
||||
information request.</p>
|
||||
<example caption="Service Discovery Information Request"><![CDATA[
|
||||
<iq from='kingclaudius@shakespeare.lit/castle'
|
||||
@ -261,7 +278,7 @@
|
||||
to='kingclaudius@shakespeare.lit/castle'
|
||||
type='result'>
|
||||
<query xmlns='http://jabber.org/protocol/disco#info'>
|
||||
<feature var='urn:xmpp:coin'/>
|
||||
<feature var='urn:xmpp:coin:1'/>
|
||||
</query>
|
||||
</iq>
|
||||
]]></example>
|
||||
@ -294,14 +311,14 @@
|
||||
|
||||
<xs:schema
|
||||
xmlns:xs='http://www.w3.org/2001/XMLSchema'
|
||||
targetNamespace='urn:xmpp:jingle:apps:coin:1'
|
||||
xmlns='urn:xmpp:jingle:apps:coin:1'
|
||||
targetNamespace='urn:xmpp:coin:1'
|
||||
xmlns='urn:xmpp:coin:1'
|
||||
elementFormDefault='qualified'>
|
||||
|
||||
<xs:annotation>
|
||||
<xs:documentation>
|
||||
The protocol documented by this schema is defined in
|
||||
XEP-0XXX: http://www.xmpp.org/extensions/xep-0XXX.html
|
||||
XEP-0298: http://www.xmpp.org/extensions/xep-0298.html
|
||||
</xs:documentation>
|
||||
</xs:annotation>
|
||||
|
||||
@ -329,7 +346,7 @@
|
||||
<xs:documentation>
|
||||
The protocol documented by this schema is defined in
|
||||
RFC 4575: http://tools.ietf.org/html/rfc4575 and reused by
|
||||
XEP XXXX http://www.xmpp.org/extensions/xep-XXXX.html
|
||||
XEP-0298 http://www.xmpp.org/extensions/xep-0298.html
|
||||
</xs:documentation>
|
||||
</xs:annotation>
|
||||
|
||||
|
96
xep-0327.xml
96
xep-0327.xml
@ -11,7 +11,6 @@
|
||||
&LEGALNOTICE;
|
||||
<number>0327</number>
|
||||
<status>Proposed</status>
|
||||
<lastcall>2015-04-17</lastcall>
|
||||
<type>Standards Track</type>
|
||||
<sig>Standards</sig>
|
||||
<approver>Council</approver>
|
||||
@ -35,6 +34,12 @@
|
||||
<jid>jdecastro@tropo.com</jid>
|
||||
<uri>http://tropo.com</uri>
|
||||
</author>
|
||||
<revision>
|
||||
<version>0.7</version>
|
||||
<date>2015-07-15</date>
|
||||
<initials>bl</initials>
|
||||
<remark><p>Updates based on XMPP Council feedback.</p></remark>
|
||||
</revision>
|
||||
<revision>
|
||||
<version>0.6</version>
|
||||
<date>2015-04-29</date>
|
||||
@ -89,7 +94,7 @@
|
||||
|
||||
<p>The relationship between the calling parties, the Rayo server and the Rayo client looks something like this:</p>
|
||||
<code>
|
||||
[caller] ----SIP---- [rayo server] ( -----Jingle---- [callee] ) optional
|
||||
[caller] ----e.g. SIP---- [rayo server] ( -----e.g. Jingle---- [callee] ) optional
|
||||
|
|
||||
|
|
||||
rayo client
|
||||
@ -326,6 +331,9 @@
|
||||
|
||||
<p>Components have a lifecycle and are started by sending a specialized command to a call or mixer. Thus, a request for creation of a component will return a reference to the component's ID, and the component will continue to execute until it completes, potentially sending events and processing commands along the way (such as an instruction to pause or terminate), before finally issuing an event indicating its completion and thus unavailability. Multiple components may be active on a call or mixer at any one time, and commands may be executed on any entity during the execution of a component.</p>
|
||||
</section3>
|
||||
<section3 topic='Remote Party' anchor='concepts-actors-remote-party'>
|
||||
<p>A call's Remote Party is the software or device with which the Call's signalling (and optionally media) connection is established. This might be a software or hardware phone, a PBX, a gateway or some other such system.</p>
|
||||
</section3>
|
||||
</section2>
|
||||
|
||||
<section2 topic="Addressing Scheme" anchor='addressing'>
|
||||
@ -434,7 +442,9 @@
|
||||
|
||||
<p>On successfully receiving and parsing the dial command, the server SHOULD perform its own proprietary authorization measures to ensure that only desirable outbound sessions are created. If it is established that the command should not be allowed, the server MUST return an error giving an authorization reason.</p>
|
||||
|
||||
<p>If a 'uri' attribute is set on the dial command, the server should attempt to create the call at the requested URI. This allows clients to know the URI of the call prior to it coming into existence, for clients where this distinction might be important.</p>
|
||||
<p>If a 'uri' attribute is set on the dial command, the server MUST attempt to create the call at the requested URI. This allows clients to know the URI of the call prior to it coming into existence, for clients where this distinction might be important. Such a URI MUST be a valid Rayo call address.</p>
|
||||
|
||||
<p>The specified metadata in the form of the 'from' attribute and any <header/> elements SHOULD be mapped to the underlying signalling protocol for communication to the remote party.</p>
|
||||
|
||||
<section4 topic='Errors' anchor='session-establishment-outbound-errors'>
|
||||
<p>There are several reasons why the server might immediately return an error instead of acknowledging the creation of a new call:</p>
|
||||
@ -567,7 +577,7 @@
|
||||
</iq>
|
||||
]]></example>
|
||||
|
||||
<p>Once the server receives notification that the session has been accepted by the third party, it should send a ringing event to the client to indicate such:</p>
|
||||
<p>Once the server receives notification that the session has been accepted by the remote party, it should send a ringing event to the client to indicate such:</p>
|
||||
<example caption="Call announces its ringing state (accepted by 3rd party but not yet answered)."><![CDATA[
|
||||
<presence from='9f00061@call.shakespeare.lit'
|
||||
to='juliet@capulet.lit/balcony'>
|
||||
@ -575,7 +585,7 @@
|
||||
</presence>
|
||||
]]></example>
|
||||
|
||||
<p>Similarly, once the server receives notification that the session has been answered, it should negotiate media between the dialed party and its local media server. Once media negotiation is complete, it should send an answered event to the client to indicate such:</p>
|
||||
<p>Similarly, once the server receives notification that the session has been answered, it should negotiate media between the remote party and its local media server. Once media negotiation is complete, it should send an answered event to the client to indicate such:</p>
|
||||
<example caption="Call announces its answered state (media connected)."><![CDATA[
|
||||
<presence from='9f00061@call.shakespeare.lit'
|
||||
to='juliet@capulet.lit/balcony'>
|
||||
@ -598,14 +608,14 @@
|
||||
</iq>
|
||||
]]></example>
|
||||
|
||||
<p>In this case, the server MUST treat the session creation in the same way as without the join element, until the point of media negotiation. Here, the server should negotiate media as specified by the join element, in accordance with the rules defined in <link url='#session-joining'>joining calls</link>. Media MUST NOT be negotiated with the local media server, unless the join specifies so. The join operation MUST behave as described in <link url='#session-joining'>joining calls</link>.</p>
|
||||
<p>In this case, the server MUST negotiate media as specified by the join element, in accordance with the rules defined in <link url='#session-joining'>joining calls</link>. Media MUST NOT be negotiated with the local media server, unless the join specifies so. The join operation MUST behave as described in <link url='#session-joining'>joining calls</link>.</p>
|
||||
</section4>
|
||||
</section3>
|
||||
|
||||
<section3 topic='Inbound Call' anchor='session-establishment-inbound'>
|
||||
<p>When the system receives a call from one of its connected networks, it MUST then expose that requested session to Rayo clients. It SHOULD use an implementation-specific routing mechanism to map incoming calls to some set of registered JIDs which are considered appropriate controlling parties. From this set, it SHOULD then remove any parties whom it can identify as being temporarily inappropriate for control (either unavailable based on presence, under too much load, or any other metric which the server has available). If, as a result, the set of Potentially Controlling Parties is empty, the server MUST reject the call indicating that the requested service was unavailable.</p>
|
||||
<p>When the Server receives a call from one of its connected networks, it MUST then expose that requested session to Rayo clients. It SHOULD use an implementation-specific routing mechanism to map incoming calls to some set of registered JIDs which are considered appropriate controlling parties. From this set, it SHOULD then remove any parties whom it can identify as being temporarily inappropriate for control (either unavailable based on presence, under too much load, or any other metric which the server has available). If, as a result, the set of Potentially Controlling Parties is empty, the server MUST reject the call indicating that the requested service was unavailable.</p>
|
||||
|
||||
<p>If the server can identify active Potential Controlling Parties, it MUST offer them control of the call simultaneously. The server must broadcast an offer on behalf of the call to all Potential Controlling Parties, using applicable to/from/header data from the incoming session. The server MUST also include entity capabilities information in the presence stanza containing the offer, in order to advertise the fact that the entity is a call, qualified by the node name "urn:xmpp:rayo:call:1".</p>
|
||||
<p>If the server can identify active Potential Controlling Parties, it MUST offer them control of the call according to its particular distribution method, which MAY be simultaneous or staged. The server must broadcast an offer on behalf of the call to all Potential Controlling Parties, using applicable to/from/header data from the incoming session. The server MUST also include entity capabilities information in the presence stanza containing the offer, in order to advertise the fact that the entity is a call, qualified by the node name "urn:xmpp:rayo:call:1".</p>
|
||||
<example caption="New call announces itself to a potential controlling party"><![CDATA[
|
||||
<presence from='9f00061@call.shakespeare.lit'
|
||||
to='juliet@capulet.lit/balcony'>
|
||||
@ -622,7 +632,7 @@
|
||||
</presence>
|
||||
]]></example>
|
||||
|
||||
<p>Once the server has offered control, it MUST wait indefinitely for a response from a PCP. The server SHOULD monitor the availability of PCPs to whom offers have been sent. If they all cease to be PCPs (eg by going offline) then the call should be rejected in the same way as if there had not been any available PCPs to begin with.</p>
|
||||
<p>Once the server has offered control, it MUST wait for a response from a PCP or for the remote party to end the call. The server SHOULD monitor the availability of PCPs to whom offers have been sent. If they all cease to be PCPs (eg by going offline) then the call should be rejected in the same way as if there had not been any available PCPs to begin with.</p>
|
||||
|
||||
<p>If an offered PCP executes a command against the call, by sending a command node to the call's JID inside an IQ 'set', the server should execute the following routine:</p>
|
||||
<ol>
|
||||
@ -649,7 +659,7 @@
|
||||
</section2>
|
||||
|
||||
<section2 topic='Joining Calls' anchor='session-joining'>
|
||||
<p>Calls in a Rayo system are capable of having their media streams moved/manipulated. Once such manipulation is to join the media streams of two calls. In a scenario where callA and callB should be joined, the client MUST send a join command to either call (not both) specifying the call ID of the other call, like so:</p>
|
||||
<p>Calls on a Rayo Server are capable of having their media streams moved/manipulated. Once such manipulation is to join the media streams of two calls. In a scenario where callA and callB should be joined, the client MUST send a join command to either call (not both) specifying the call ID of the other call, and optionally media attributes (direction and media) specified in the schema, like so:</p>
|
||||
<example caption="Client instructs callA to join to callB and the server acknowledges the join was completed"><![CDATA[
|
||||
<iq from='juliet@capulet.lit/balcony'
|
||||
to='callA@call.shakespeare.lit'
|
||||
@ -925,7 +935,7 @@
|
||||
</section2>
|
||||
|
||||
<section2 topic='Mixers' anchor='session-mixers'>
|
||||
<p>While calls may generally be joined peer-to-peer in any desirable combination, such an implementation is not necessarily scalable or practical to manage. Rayo, therefore, includes the concept of mixers, which are entities like calls, to which calls or other mixers may be joined in the same way as joining multiple calls directly. A mixer MUST be implicitly created the first time a call attempts to join it, MUST immediately broadcast presence to all controlling parties who have calls joined to it, and must respond to the join command with a reference to the mixer. The server MUST include entity capabilities information in the first presence stanza it sends, in order to advertise the fact that the entity is a mixer, qualified by the node name "urn:xmpp:rayo:mixer:1". A mixer MUST emit events (joined, unjoined) to all controlling parties who have calls joined to it, using the same semantics as joining calls.</p>
|
||||
<p>While calls may generally be joined peer-to-peer in any desirable combination, such an implementation is not necessarily scalable or practical to manage. Rayo, therefore, includes the concept of mixers, which are entities like calls, to which calls or other mixers may be joined in the same way as joining multiple calls directly. A mixer MUST be implicitly created the first time a call attempts to join it, MUST immediately broadcast presence to all controlling parties who have calls joined to it, and must respond to the join command with a reference to the mixer. If a mixer cannot be created, an error similar to those specified for <dial/> should be returned in response to the <join/> command. The server MUST include entity capabilities information in the first presence stanza it sends, in order to advertise the fact that the entity is a mixer, qualified by the node name "urn:xmpp:rayo:mixer:1". A mixer MUST emit events (joined, unjoined) to all controlling parties who have calls joined to it, using the same semantics as joining calls.</p>
|
||||
|
||||
<p>In order to support friendly-named mixers without causing naming collisions between security zones, a server SHOULD represent a mixer internally using some alternative name scoped to the client's security zone and mapped to the friendly name/URI presented to the client for the emission of events and processing of commands. A server MUST NOT allow clients to interact with mixers allocated within other security zones either by observing their status or media.</p>
|
||||
|
||||
@ -963,7 +973,7 @@
|
||||
</presence>
|
||||
]]></example>
|
||||
|
||||
<p>Mixers MUST respect the normal rules of XMPP presence subscriptions. If a client sends directed presence to a mixer, the mixer MUST implicitly create a presence subscription for the client. On receiving unavailable presence, the mixer MUST stop sending events to the client.</p>
|
||||
<p>Mixers MUST respect the normal rules of XMPP presence subscriptions, and presence subscriptions from clients within the same security zone as the mixer must be implicitly permitted.</p>
|
||||
|
||||
<p>The error conditions on joining a mixer are the same as for calls, as are the unjoin and join modification semantics. Additionally, mixers SHOULD be able to host components just like calls, following the rules defined for each component.</p>
|
||||
|
||||
@ -972,7 +982,11 @@
|
||||
to='myMixer@mixer.shakespeare.lit'
|
||||
type='set'
|
||||
id='h7ed2'>
|
||||
<output xmlns='urn:xmpp:rayo:output:1'/>
|
||||
<output xmlns='urn:xmpp:rayo:output:1'>
|
||||
<document content-type='text/plain'>
|
||||
Thanks for calling, goodbye!
|
||||
</document>
|
||||
</output>
|
||||
</iq>
|
||||
|
||||
<iq from='myMixer@mixer.shakespeare.lit'
|
||||
@ -1020,7 +1034,11 @@
|
||||
to='9f00061@call.shakespeare.lit'
|
||||
type='set'
|
||||
id='h7ed2'>
|
||||
<output xmlns='urn:xmpp:rayo:output:1'/>
|
||||
<output xmlns='urn:xmpp:rayo:output:1'>
|
||||
<document content-type='text/plain'>
|
||||
Thanks for calling, goodbye!
|
||||
</document>
|
||||
</output>
|
||||
</iq>
|
||||
]]></example>
|
||||
|
||||
@ -1054,7 +1072,11 @@
|
||||
to='juliet@capulet.lit/balcony'
|
||||
type='error'
|
||||
id='h7ed2'>
|
||||
<output xmlns='urn:xmpp:rayo:output:1'/>
|
||||
<output xmlns='urn:xmpp:rayo:output:1'>
|
||||
<document content-type='text/plain'>
|
||||
Thanks for calling, goodbye!
|
||||
</document>
|
||||
</output>
|
||||
<error type='cancel'>
|
||||
<feature-not-implemented xmlns='urn:ietf:params:xml:ns:xmpp-stanzas'/>
|
||||
</error>
|
||||
@ -1095,7 +1117,11 @@
|
||||
to='juliet@capulet.lit/balcony'
|
||||
type='error'
|
||||
id='h7ed2'>
|
||||
<output xmlns='urn:xmpp:rayo:output:1'/>
|
||||
<output xmlns='urn:xmpp:rayo:output:1'>
|
||||
<document content-type='text/plain'>
|
||||
Thanks for calling, goodbye!
|
||||
</document>
|
||||
</output>
|
||||
<error type='wait'>
|
||||
<resource-constraint xmlns='urn:ietf:params:xml:ns:xmpp-stanzas'/>
|
||||
</error>
|
||||
@ -1108,7 +1134,11 @@
|
||||
to='juliet@capulet.lit/balcony'
|
||||
type='error'
|
||||
id='h7ed2'>
|
||||
<output xmlns='urn:xmpp:rayo:output:1'/>
|
||||
<output xmlns='urn:xmpp:rayo:output:1'>
|
||||
<document content-type='text/plain'>
|
||||
Thanks for calling, goodbye!
|
||||
</document>
|
||||
</output>
|
||||
<error type='wait'>
|
||||
<resource-constraint xmlns='urn:ietf:params:xml:ns:xmpp-stanzas'/>
|
||||
</error>
|
||||
@ -1121,7 +1151,11 @@
|
||||
to='juliet@capulet.lit/balcony'
|
||||
type='error'
|
||||
id='h7ed2'>
|
||||
<output xmlns='urn:xmpp:rayo:output:1'/>
|
||||
<output xmlns='urn:xmpp:rayo:output:1'>
|
||||
<document content-type='text/plain'>
|
||||
Thanks for calling, goodbye!
|
||||
</document>
|
||||
</output>
|
||||
<error type='wait'>
|
||||
<unexpected-request xmlns='urn:ietf:params:xml:ns:xmpp-stanzas'/>
|
||||
</error>
|
||||
@ -1257,7 +1291,7 @@
|
||||
]]></example>
|
||||
|
||||
<section3 topic='Output Component' anchor='session-component-execution-output'>
|
||||
<p>Media output is a core concept in Rayo, and is provided by the output component. The component allows media to be rendered to a call or a mixer, using the server's local media server. A server MUST support audio file playback and MUST support the text/uri-list document format. A server MAY support speech synthesis and MAY support SSML. The component is created using an <link url='def-component-output'><output/> command</link>, containing one or more documents to render, along with a set of options to determine the nature of the rendering.</p>
|
||||
<p>Media output is a core concept in Rayo, and is provided by the output component. The component allows media to be rendered to a call or a mixer, using the server's local media server. A server MUST support audio file playback and MUST support the text/uri-list document format. A server MAY support speech synthesis and MAY support <link url='http://www.w3.org/TR/speech-synthesis/'>SSML</link> (in which case the document should be escaped or enclosed in CDATA). The component is created using an <link url='def-component-output'><output/> command</link>, containing one or more documents to render, along with a set of options to determine the nature of the rendering.</p>
|
||||
|
||||
<example caption='Client renders a simple SSML document to a call'><![CDATA[
|
||||
<iq from='juliet@capulet.lit/balcony'
|
||||
@ -1297,9 +1331,7 @@
|
||||
id='h7ed2'>
|
||||
<output xmlns='urn:xmpp:rayo:output:1'>
|
||||
<document content-type='text/plain'>
|
||||
<![CDATA[
|
||||
Thanks for calling, goodbye!
|
||||
]]]]><![CDATA[>
|
||||
Thanks for calling, goodbye!
|
||||
</document>
|
||||
</output>
|
||||
</iq>
|
||||
@ -1308,7 +1340,7 @@
|
||||
<p>The server MUST validate that it has apropriate resources/mechanisms to render the requested document before acknowledging the component creation.</p>
|
||||
|
||||
<section4 topic='Join considerations' anchor='session-component-exection-output-joins'>
|
||||
<p>In the case that an output component is executed on a call joined to other calls or mixers, the output SHOULD be rendered only to the call and not the joined parties (also known as 'whisper'). In the case that an output component is executed on a mixer, the output should be rendered into the mixer, such that all participants receive the output (also known as 'announce').</p>
|
||||
<p>In the case that an output component is executed on a call joined to other calls or mixers, the output MUST be rendered only to the call and not the joined parties (also known as 'whisper'). In the case that an output component is executed on a mixer, the output should be rendered into the mixer, such that all participants receive the output (also known as 'announce').</p>
|
||||
</section4>
|
||||
|
||||
<section4 topic='Commands' anchor='session-component-execution-output-commands'>
|
||||
@ -1461,7 +1493,7 @@
|
||||
</section3>
|
||||
|
||||
<section3 topic='Input Component' anchor='session-component-execution-input'>
|
||||
<p>Media input is a core concept in Rayo, and is provided by the input component. The component allows input to be collected from a call by way of either DTMF (dual-tone multi-frequency) or ASR (automatic speech recognition), using the server's local media server. A Rayo server MUST support DTMF input and MUST support SRGS XML grammars (application/srgs+xml). A server MAY suport speech input, and MAY support other grammar formats. The component is created using an <link url='def-component-input'><input/> command</link>, containing one or more grammar documents by which to control input, along with a set of options to determine the nature of the collection.</p>
|
||||
<p>Media input is a core concept in Rayo, and is provided by the input component. The component allows input to be collected from a call by way of either <link url='http://www.itu.int/rec/T-REC-Q.23-198811-I/en'>DTMF</link> (dual-tone multi-frequency) or ASR (automatic speech recognition), using the server's local media server. A Rayo server MUST support DTMF input and MUST support <link url='http://www.w3.org/TR/speech-grammar/'>SRGS</link> XML grammars (application/srgs+xml). A server MAY suport speech input, and MAY support other grammar formats. The component is created using an <link url='def-component-input'><input/> command</link>, containing one or more grammar documents by which to control input, along with a set of options to determine the nature of the collection.</p>
|
||||
|
||||
<example caption='Client requests DTMF input collection from a call'><![CDATA[
|
||||
<iq from='juliet@capulet.lit/balcony'
|
||||
@ -1514,7 +1546,7 @@
|
||||
<p>The server MUST validate that it has appropriate resources/mechanisms to collect the requested input before acknowledging the component creation.</p>
|
||||
|
||||
<section4 topic='Join considerations' anchor='session-component-exection-input-joins'>
|
||||
<p>In the case that an input component is executed on a call joined to other calls or mixers, the input SHOULD be collected only from the call and not the joined parties. Input components executed on a mixer SHOULD collect and combine input from all participants joined to the mixer.</p>
|
||||
<p>In the case that an input component is executed on a call joined to other calls or mixers, the input MUST be collected only from the call and not the joined parties. Input components executed on a mixer MUST collect and combine input from all participants joined to the mixer.</p>
|
||||
</section4>
|
||||
|
||||
<section4 topic='Commands' anchor='session-component-execution-input-commands'>
|
||||
@ -1661,7 +1693,7 @@
|
||||
</section3>
|
||||
|
||||
<section3 topic='Record Component' anchor='session-component-execution-record'>
|
||||
<p>Call recording is a core concept in Rayo, and is provided by the record component. The component allows media to be captured from a call or a mixer, using the server's local media server, stored, and made available to clients. The component is created using a <link url='def-component-record'><record/> command</link>, with a set of options to determine the nature of the recording.</p>
|
||||
<p>Call recording is a core concept in Rayo, and is provided by the record component. The component allows media to be captured from a call or a mixer, using the server's local media server, stored, and made available to clients. The component is created using a <link url='def-component-record'><record/> command</link>, potentially with a set of options to determine the nature of the recording.</p>
|
||||
|
||||
<example caption='Client requests a simple recording'><![CDATA[
|
||||
<iq from='juliet@capulet.lit/balcony'
|
||||
@ -2170,7 +2202,7 @@ Art thou not Romeo, and a Montague?
|
||||
</tr>
|
||||
<tr>
|
||||
<td>timeout</td>
|
||||
<td>Indicates the maximum time allowed for a response to be provided by the third party before the call should be considered to have come to an end.</td>
|
||||
<td>Indicates the maximum time allowed for a response to be provided by the remote party before the call should be considered to have come to an end.</td>
|
||||
<td>OPTIONAL</td>
|
||||
<td>-1</td>
|
||||
</tr>
|
||||
@ -2870,7 +2902,7 @@ Art thou not Romeo, and a Montague?
|
||||
<p>The <resume/> element has no attributes.</p>
|
||||
</section4>
|
||||
|
||||
<section4 topic='Recording Element' anchor='def-component-input-recording'>
|
||||
<section4 topic='Recording Element' anchor='def-component-record-recording'>
|
||||
<p>Provides the result of a recording, as a reference to its location.</p>
|
||||
<p>The <recording/> element MUST be empty.</p>
|
||||
<p>The attributes of the <recording/> element are as follows.</p>
|
||||
@ -2902,19 +2934,19 @@ Art thou not Romeo, and a Montague?
|
||||
</table>
|
||||
</section4>
|
||||
|
||||
<section4 topic='Max Duration Element' anchor='def-component-input-max-duration'>
|
||||
<section4 topic='Max Duration Element' anchor='def-component-record-max-duration'>
|
||||
<p>Indicates that the component came to an end due to the max duration being reached.</p>
|
||||
<p>The <max-duration/> element MUST be empty.</p>
|
||||
<p>The <max-duration/> element has no attributes.</p>
|
||||
</section4>
|
||||
|
||||
<section4 topic='Initial Timeout Element' anchor='def-component-input-initial-timeout'>
|
||||
<section4 topic='Initial Timeout Element' anchor='def-component-record-initial-timeout'>
|
||||
<p>Indicates that the component came to an end due to no input being detected before the initial-timeout.</p>
|
||||
<p>The <initial-timeout/> element MUST be empty.</p>
|
||||
<p>The <initial-timeout/> element has no attributes.</p>
|
||||
</section4>
|
||||
|
||||
<section4 topic='Final Timeout Element' anchor='def-component-input-final-timeout'>
|
||||
<section4 topic='Final Timeout Element' anchor='def-component-record-final-timeout'>
|
||||
<p>Indicates that the component came to an end because no input had been detected for the final timeout duration.</p>
|
||||
<p>The <final-timeout/> element MUST be empty.</p>
|
||||
<p>The <final-timeout/> element has no attributes.</p>
|
||||
@ -3316,7 +3348,7 @@ Art thou not Romeo, and a Montague?
|
||||
<attribute name="timeout" type="tns:timeoutType" use="optional" default="-1">
|
||||
<annotation>
|
||||
<documentation>
|
||||
Indicates the maximum time allowed for a response to be provided by the third party before the call should be considered to have come to an end.
|
||||
Indicates the maximum time allowed for a response to be provided by the remote party before the call should be considered to have come to an end.
|
||||
</documentation>
|
||||
</annotation>
|
||||
</attribute>
|
||||
|
17
xep-0358.xml
17
xep-0358.xml
@ -25,6 +25,12 @@
|
||||
&fippo;
|
||||
&lance;
|
||||
&stpeter;
|
||||
<revision>
|
||||
<version>0.2</version>
|
||||
<date>2015-08-11</date>
|
||||
<initials>ls</initials>
|
||||
<remark><p>Add <uri/> element.</p></remark>
|
||||
</revision>
|
||||
<revision>
|
||||
<version>0.1</version>
|
||||
<date>2015-06-29</date>
|
||||
@ -63,6 +69,7 @@
|
||||
<jinglepub xmlns='urn:xmpp:jinglepub:1'
|
||||
from='sender-jid'
|
||||
id='someid'>
|
||||
[<uri/> element for an alternate or informational URI of the content]
|
||||
[<meta/> element(s) for human-friendly information]
|
||||
[<description/> element(s) for application format(s)]
|
||||
</jinglepub>
|
||||
@ -71,6 +78,7 @@
|
||||
<p>The 'id' attribute is an opaque identifier. This attribute MUST be present, and MUST be a valid non-empty string. It uniquely identifies the published request at the session owner's JID.</p>
|
||||
<p>The <jinglepub/> element MUST contain a <description/> element qualified by the namespace of the relevant Jingle application format (e.g., <description xmlns='urn:xmpp:jingle:apps:file-transfer:4'/> for file transfer).</p>
|
||||
<p>The <jinglepub/> element MAY contain one or more <meta/> elements qualified by the jingle-pub namespace; if more than one element is included, each element MUST have a different value for the 'xml:lang' attribute.</p>
|
||||
<p>The <jinglepub/> element MAY contain a <uri/> element which contains a URI for an alternative way to access the content, or other information about the content. The resource provided by the URI SHOULD be meaningful for clients that do not directly support the included Jingle content definitions, and accessing the URI MAY result in a different experience than initiating the published Jingle session. For example, the URI could be to a content landing page of an image hosting service from which an image could be viewed instead of directly downloading the image file.</p>
|
||||
<p>The <jinglepub/> information is typically provided via pubsub.</p>
|
||||
<p>The following example shows a possible payload for streaming of recorded audio/video sessions, here pushed out via PEP.</p>
|
||||
<example caption='Sender advertises session via PEP'><![CDATA[
|
||||
@ -251,10 +259,11 @@
|
||||
|
||||
<xs:element name='jinglepub'>
|
||||
<xs:complexType>
|
||||
<xs:sequence>
|
||||
<xs:any namespace='##other' minOccurs='1' maxOccurs='unbounded'/>
|
||||
<xs:element name='meta' type='metaElementType'/>
|
||||
</xs:sequence>
|
||||
<xs:all>
|
||||
<xs:any namespace='##other' minOccurs='0' maxOccurs='unbounded'/>
|
||||
<xs:element name='meta' type='metaElementType' minOccurs='0' maxOccurs='unbounded' />
|
||||
<xs:element name='uri' type='xs:anyURI' minOccurs='0' maxOccurs='1' />
|
||||
</xs:all>
|
||||
<xs:attribute name='description' type='xs:string' use='optional'/>
|
||||
<xs:attribute name='from' type='xs:string' use='required'/>
|
||||
<xs:attribute name='id' type='xs:string' use='required'/>
|
||||
|
125
xep-0359.xml
Normal file
125
xep-0359.xml
Normal file
@ -0,0 +1,125 @@
|
||||
<?xml version='1.0' encoding='UTF-8'?>
|
||||
<!DOCTYPE xep SYSTEM 'xep.dtd' [
|
||||
<!ENTITY % ents SYSTEM 'xep.ent'>
|
||||
%ents;
|
||||
]>
|
||||
<?xml-stylesheet type='text/xsl' href='xep.xsl'?>
|
||||
<xep>
|
||||
<header>
|
||||
<title>Unique and Stable Stanza IDs</title>
|
||||
<abstract>This specification describes unique and stable IDs for stanzas.</abstract>
|
||||
&LEGALNOTICE;
|
||||
<number>0359</number>
|
||||
<status>Experimental</status>
|
||||
<type>Standards Track</type>
|
||||
<sig>Standards</sig>
|
||||
<approver>Council</approver>
|
||||
<dependencies>
|
||||
<spec>XMPP Core</spec>
|
||||
</dependencies>
|
||||
<supersedes/>
|
||||
<supersededby/>
|
||||
<shortname>NOT_YET_ASSIGNED (suggested: sid)</shortname>
|
||||
<author>
|
||||
<firstname>Florian</firstname>
|
||||
<surname>Schmaus</surname>
|
||||
<email>flo@geekplace.eu</email>
|
||||
<jid>flo@geekplace.eu</jid>
|
||||
</author>
|
||||
<revision>
|
||||
<version>0.1</version>
|
||||
<date>2015-07-14</date>
|
||||
<initials>XEP Editor (mam)</initials>
|
||||
<remark><p>Initial published version approved by the XMPP Council.</p></remark>
|
||||
</revision>
|
||||
<revision>
|
||||
<version>0.0.2</version>
|
||||
<date>2015-06-22</date>
|
||||
<initials>fs</initials>
|
||||
<remark>
|
||||
<ul>
|
||||
<li>Rename the XEP from "Message IDs" to "Stanza IDs"</li>
|
||||
<li>Add 'by' attribute</li>
|
||||
</ul>
|
||||
</remark>
|
||||
</revision>
|
||||
<revision>
|
||||
<version>0.0.1</version>
|
||||
<date>2015-06-01</date>
|
||||
<initials>fs</initials>
|
||||
<remark><p>First draft.</p></remark>
|
||||
</revision>
|
||||
</header>
|
||||
<section1 topic='Introduction' anchor='intro'>
|
||||
<p>Unique and stable IDs for stanzas, which are set by a XMPP service, are beneficial in various ways. They can be used together with &xep0313; to uniquely identify a message within an archive. They are also useful in the context of &xep0045; conferences, in order to identify a message reflected by a MUC service back to the originating entity.</p>
|
||||
</section1>
|
||||
<section1 topic='Requirements' anchor='reqs'>
|
||||
<p>The herein defined stanza IDs must be unique and stable within the scope of the generating XMPP entity.</p>
|
||||
</section1>
|
||||
<section1 topic='Use Cases' anchor='usecases'>
|
||||
<section2 topic='Unique stanza IDs' anchor='stanza-id'>
|
||||
<example caption='The stanza ID extension.'><![CDATA[
|
||||
<stanza-id xmlns='urn:xmpp:sid:0'
|
||||
id='de305d54-75b4-431b-adb2-eb6b9e546013'
|
||||
by='room@muc.xmpp.org'/>
|
||||
]]></example>
|
||||
In order to create a 'stanza-id' extension, the creating XMPP entity generates and sets the value of the 'id' attribute, and puts its own JID as value of the 'by' attribute. The value of the 'id' attribute must be unique and stable, i.e. it MUST NOT change later for some reason, within the scope of the 'by' value. Thus the IDs defined in this extension MUST be unique and stable within the scope of the generating XMPP entity. It is RECOMMENDED that the ID generating service uses UUID and the algorithm defined in RFC 4122, to generate the IDs.
|
||||
</section2>
|
||||
<section2 topic='Client generated stanza IDs' anchor='client-id'>
|
||||
<p>
|
||||
Some use cases require the client to generate the stanza ID. In this case, the client MUST use 'client-id' as attribute name for the ID.
|
||||
</p>
|
||||
<example caption='A message stanza with the stanza ID extension.'><![CDATA[
|
||||
<message xmlns='jabber:client'
|
||||
to='room@muc.example.org'
|
||||
type='groupchat'>
|
||||
<body>Typical body text</body>
|
||||
<stanza-id xmlns='urn:xmpp:sid:0' client-id='de305d54-75b4-431b-adb2-eb6b9e546013'/>
|
||||
</message>]]></example>
|
||||
<p>
|
||||
The server MAY add an 'id' attribute to the stanza-id element. In that case, it MUST preserve the content of the 'client-id' attribute.
|
||||
</p>
|
||||
<example caption='A message stanza with the stanza ID extension.'><![CDATA[
|
||||
<message xmlns='jabber:client'
|
||||
to='room@muc.example.org'
|
||||
type='groupchat'>
|
||||
<body>Typical body text</body>
|
||||
<stanza-id xmlns='urn:xmpp:sid:0'
|
||||
id='new-id-overrides-client-id'
|
||||
by='room@muc.example.org'
|
||||
client-id='de305d54-75b4-431b-adb2-eb6b9e546013'/>
|
||||
</message>]]></example>
|
||||
<p>
|
||||
Otherwise, if the server does not override the ID, it MAY omit the 'client-id' attribute.
|
||||
</p>
|
||||
</section2>
|
||||
</section1>
|
||||
<section1 topic='Business Rules' anchor='rules'>
|
||||
<ol>
|
||||
<li>XMPP entities, which are routing stanzas, MUST NOT strip stanza-id elements from message stanzas.</li>
|
||||
<li>The values of the 'id' (and 'client-id') attribute SHOULD be unpredictable.</li>
|
||||
<li>Stanza ID generating entities, which encounter a <stanza-id/> element where 'id' (and 'client-id') is already set and where the 'by' attribute matches their own JID, MUST ignore the existing value of 'id' and override it.</li>
|
||||
<li>Stanzas MUST posses, in the direct child level of the stanza, at most one 'stanza-id' extension element with the same JID as value of the 'by' attribute.</li>
|
||||
<li>Stanza ID extension elements which have a 'id' attribute MUST also have the 'by' attribute set.</li>
|
||||
<li>Stanza ID extension elements MUST either posses a 'id' attribute, a 'client-id' attribute or both.</li>
|
||||
<li>The value of the 'by' attribute MUST be a normalized JID as defined in &rfc6122;</li>
|
||||
</ol>
|
||||
</section1>
|
||||
<section1 topic='Security Considerations' anchor='security'>
|
||||
<p>The value of the 'id' attribute should not provide any further information besides the opaque ID itself. Entities observing the value MUST NOT be able to infer any information from it, e.g. the size of the message archive. The value of 'id' and 'client-id' MUST be considered as non-secret values.</p>
|
||||
</section1>
|
||||
<section1 topic='IANA Considerations' anchor='iana'>
|
||||
<p>This document requires no interaction with &IANA;.</p>
|
||||
</section1>
|
||||
<section1 topic='XMPP Registrar Considerations' anchor='registrar'>
|
||||
<section2 topic='Protocol Namespaces' anchor='ns'>
|
||||
<p>The ®ISTRAR; includes "urn:xmpp:sid:0" in its registry of protocol namespaces (see &NAMESPACES;).</p>
|
||||
</section2>
|
||||
</section1>
|
||||
<section1 topic='XML Schema' anchor='schema'>
|
||||
<p>REQUIRED for protocol specifications.</p>
|
||||
</section1>
|
||||
<section1 topic='Acknowledgements' anchor='ack'>
|
||||
<p>Thanks to Thijs Alkemade and Georg Lukas for providing feedback.</p>
|
||||
</section1>
|
||||
</xep>
|
@ -8,15 +8,9 @@
|
||||
<header>
|
||||
<title>Nonzas (are not Stanzas)</title>
|
||||
<abstract>This specification defines the term "Nonza", describing every top level stream element that is not a Stanza.</abstract>
|
||||
<legal>
|
||||
<copyright>This XMPP Extension Protocol is copyright (c) 1999 - 2014 by the XMPP Standards Foundation (XSF).</copyright>
|
||||
<permissions>Permission is hereby granted, free of charge, to any person obtaining a copy of this specification (the "Specification"), to make use of the Specification without restriction, including without limitation the rights to implement the Specification in a software program, deploy the Specification in a network service, and copy, modify, merge, publish, translate, distribute, sublicense, or sell copies of the Specification, and to permit persons to whom the Specification is furnished to do so, subject to the condition that the foregoing copyright notice and this permission notice shall be included in all copies or substantial portions of the Specification. Unless separate permission is granted, modified works that are redistributed shall not contain misleading information regarding the authors, title, number, or publisher of the Specification, and shall not claim endorsement of the modified works by the authors, any organization or project to which the authors belong, or the XMPP Standards Foundation.</permissions>
|
||||
<warranty>## NOTE WELL: This Specification is provided on an "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, express or implied, including, without limitation, any warranties or conditions of TITLE, NON-INFRINGEMENT, MERCHANTABILITY, or FITNESS FOR A PARTICULAR PURPOSE. In no event shall the XMPP Standards Foundation or the authors of this Specification be liable for any claim, damages, or other liability, whether in an action of contract, tort, or otherwise, arising from, out of, or in connection with the Specification or the implementation, deployment, or other use of the Specification. ##</warranty>
|
||||
<liability>In no event and under no legal theory, whether in tort (including negligence), contract, or otherwise, unless required by applicable law (such as deliberate and grossly negligent acts) or agreed to in writing, shall the XMPP Standards Foundation or any author of this Specification be liable for damages, including any direct, indirect, special, incidental, or consequential damages of any character arising out of the use or inability to use the Specification (including but not limited to damages for loss of goodwill, work stoppage, computer failure or malfunction, or any and all other commercial damages or losses), even if the XMPP Standards Foundation or such author has been advised of the possibility of such damages.</liability>
|
||||
<conformance>This XMPP Extension Protocol has been contributed in full conformance with the XSF's Intellectual Property Rights Policy (a copy of which may be found at <<link url='http://xmpp.org/extensions/ipr-policy.shtml'>http://xmpp.org/extensions/ipr-policy.shtml</link>> or obtained by writing to XSF, P.O. Box 1641, Denver, CO 80201 USA).</conformance>
|
||||
</legal>
|
||||
<number>xxxx</number>
|
||||
<status>ProtoXEP</status>
|
||||
&LEGALNOTICE;
|
||||
<number>0360</number>
|
||||
<status>Experimental</status>
|
||||
<type>Standards Track</type>
|
||||
<sig>Standards</sig>
|
||||
<approver>Council</approver>
|
||||
@ -32,6 +26,12 @@
|
||||
<email>flo@geekplace.eu</email>
|
||||
<jid>flo@geekplace.eu</jid>
|
||||
</author>
|
||||
<revision>
|
||||
<version>0.1</version>
|
||||
<date>2015-07-14</date>
|
||||
<initials>XEP Editor (mam)</initials>
|
||||
<remark><p>Initial published version approved by the XMPP Council.</p></remark>
|
||||
</revision>
|
||||
<revision>
|
||||
<version>0.0.1</version>
|
||||
<date>2015-06-01</date>
|
153
xep-0361.xml
Normal file
153
xep-0361.xml
Normal file
@ -0,0 +1,153 @@
|
||||
<?xml version='1.0' encoding='UTF-8'?>
|
||||
<!DOCTYPE xep SYSTEM 'xep.dtd' [
|
||||
<!ENTITY % ents SYSTEM 'xep.ent'>
|
||||
%ents;
|
||||
]>
|
||||
<?xml-stylesheet type='text/xsl' href='xep.xsl'?>
|
||||
<xep>
|
||||
<header>
|
||||
<title>Zero Handshake Server to Server Protocol</title>
|
||||
<abstract>
|
||||
This specification defines an approach for a pair of servers to eliminate initial handshakes and associated
|
||||
data transfer when using the XMPP S2S Protocol. This approach may only be used with a priori agreement and configuration
|
||||
of the two servers involved. This is of significant benefit in high latency environments.
|
||||
</abstract>
|
||||
&LEGALNOTICE;
|
||||
<number>0361</number>
|
||||
<status>Experimental</status>
|
||||
<type>Informational</type>
|
||||
<sig>Standards</sig>
|
||||
<approver>Council</approver>
|
||||
<dependencies>
|
||||
<spec>RFC 6120</spec>
|
||||
<spec>RCC 6121</spec>
|
||||
</dependencies>
|
||||
<supersedes/>
|
||||
<supersededby/>
|
||||
<shortname>X2X</shortname>
|
||||
<author>
|
||||
<firstname>Steve</firstname>
|
||||
<surname>Kille</surname>
|
||||
<email>steve.kille@isode.com</email>
|
||||
<jid>steve.kille@isode.com</jid>
|
||||
</author>
|
||||
<revision>
|
||||
<version>0.2</version>
|
||||
<date>2015-07-18</date>
|
||||
<initials>sek</initials>
|
||||
<remark><p>Assume an open <stream:stream>, implicitly parenting all XML elements received and sent.</p></remark>
|
||||
</revision>
|
||||
<revision>
|
||||
<version>0.1</version>
|
||||
<date>2015-07-16</date>
|
||||
<initials>XEP Editor (mam)</initials>
|
||||
<remark><p>Initial published version approved by the XMPP Council.</p></remark>
|
||||
</revision>
|
||||
<revision>
|
||||
<version>0.0.1</version>
|
||||
<date>2015-06-22</date>
|
||||
<initials>sek</initials>
|
||||
<remark><p>First draft.</p></remark>
|
||||
</revision>
|
||||
</header>
|
||||
<section1 topic='Introduction' anchor='intro'>
|
||||
<p>
|
||||
This specification arose from work on deploying XMPP in high latency environments, with round trips of several second. Even with data transfer rates as low as 2400 bit per second, XMPP works well once connections are established as compressed messages are small and the protocols are fully asynchronous. However the combination of low data rate and high latency led to connection establishment times of several minutes. This was unworkable, particularly when connections were prone to failure.
|
||||
</p>
|
||||
<p>
|
||||
The solution set out here is to eliminate all the intial handshaking and to start the S2S communication as if the handshaking had been correctly completed. This cannot be used for communication between an arbitrary pair of servers, as in general the negotiation associated with the handshaking is vital for correctly determining a variety of parameters for use in the connection. However, a pair of servers may operate by locally configuring information that would have been negotiated. This enables the pair of servers to eliminate initial handshaking and data exchange.
|
||||
</p>
|
||||
</section1>
|
||||
<section1 topic='Requirements' anchor='reqs'>
|
||||
<p>
|
||||
This specification can be considered as a profile for server to server XMPP communication, to enable XMPP deployment over high latency links. This profile MUST only be used where its use has been pre-agreed and configured for both participating servers.
|
||||
</p>
|
||||
</section1>
|
||||
|
||||
<section1 topic='Use Cases' anchor='usecases'>
|
||||
<p>
|
||||
An example scenario where this protocol is important is to support use of XMPP communication on an aircraft which only has slow high latency air ground communication, with round trips of several seconds (e.g., UHF or Satcom). Use of stanard XMPP protocols (server to server or client to server) leads to long setup times. This protocol can be deployed between an XMPP server on the aircraft and one on the ground. This will be operated over a closed private network, where security considerations can be addressed primarily at the network level.
|
||||
</p>
|
||||
</section1>
|
||||
<section1 topic='Business Rules' anchor='rules'>
|
||||
|
||||
|
||||
<section2 topic="General">
|
||||
<p>
|
||||
In simple terms, this can be considered as operation of RFC 6121 communication between a pair of XMPP servers without the preliminary negotiation done in RFC 6120. It might be considered that the start point is the
|
||||
DONE box in Figure 3 of RFC 6121. The TCP connection is opened and messages start to flow, as if the preceding RFC 6120 exchanges had taken place. All configuration informaition, including choice of port is handled by the a priori configuration.</p>
|
||||
<p>
|
||||
Note that stream open is not sent. The interaction takes place as if this had completed. All XML elements received over the stream are treated as if they were inside a normal S2S stream that has been opened with the following stream opening tag, defining the default namespace of jabber:server and the stream namespace of <stream:stream xmlns:stream='...' xmlns='...'>. When a stream is closed, a stream close SHOULD be exchanged.
|
||||
</p>
|
||||
</section2>
|
||||
|
||||
<section2 topic="Identity Determination">
|
||||
<p>
|
||||
A connection between a pair of servers will be by TCP, with or without TLS. The pair of servers need to identify each other at the connection level. Three mechanisms are noted:
|
||||
</p>
|
||||
<ol start="1.">
|
||||
<li>Implicit. The responder assumes identity of sender because it knew where to connect to. This is NOT RECOMMENDED.</li>
|
||||
<li>Validation of source IP and port. </li>
|
||||
<li>Validation of digital signature using a certificate. This requires TLS to be used.</li>
|
||||
</ol>
|
||||
<p>The server will then associate one or more XMPP domains with this connection level identity.</p>
|
||||
</section2>
|
||||
<section2 topic="Connection Direction">
|
||||
<p>
|
||||
Connections may be opened by one server only or by either server. The choice is part of the a priori configured agreement. It is generally recommended to allow connections to be opened by either server. However policy or network constraints may require that the connection is initiated by one server only. When a server initiates a connection it will generally use this connection to send messages to the other server. The server opening a connection is responsible for closing it at the end of its use.
|
||||
</p>
|
||||
<p>
|
||||
Consider a scenario with two servers: server A and server B.
|
||||
When a connection is opened by server A to server B, the server B MAY use this connection to send messages to server A or MAY open a connection to server A. It is recommended that only a single connection is used in this scenario and so in many cases this protocol will proceed with a single bidirectional TCP connection and messages flowing in both directions. In the event of both servers opening connections at the same time, both TCP connections SHOULD be used unidirectional with messages sent on the connection opened by the message sender only.
|
||||
</p>
|
||||
</section2>
|
||||
<section2 topic="Multiple Domains">
|
||||
<p>Typically a pair of XMPP servers connecting using this protocl will communcicate with multiple domains (e.g., a base domain and a MUC domain). It is generally desirable to configure things so that all communications will share the same link, rather than establishing separate links for each domain, essentially piggy-backing multiple logical connections onto a single TCP connection. Two or more connections MAY be initiated from one server to the other but this is NOT RECOMMENDED. </p>
|
||||
</section2>
|
||||
|
||||
<section2 topic="Message Validation">
|
||||
|
||||
<p>
|
||||
An XMPP server receiving data over such a link should appropriately validate to and from elements of stream child elements. The rules for this SHOULD be controlled by an priori agreement. An inbound connection will generally be associated with several peer domains. A RECOMMENDED approach is to consider each of these peers in turn and validate in the manner of a peer XMPP server connected using RFC 6020 for that domain. In the event that an inbound message is not considered to be valid, it should be handled in a manner that this invalid message would be handled if it arrived over standard S2S.
|
||||
</p>
|
||||
</section2>
|
||||
<section2 topic="Use of TLS">
|
||||
<p>
|
||||
This protocol MAY be deployed directly over TCP. This will often be appropriate for environments where network security is handled at IP or lower layers or where the system is operated in closed network environment.
|
||||
</p>
|
||||
<p>
|
||||
This protocol may be deployed over TLS operating over TCP. If this is done, TLS client and or server X.509 based authentication may be used, with certificate validation achieved by PKI or simply pinning (configuring) a trusted certificate. This configuration and authentication is a part of the a priori configuration.
|
||||
</p>
|
||||
</section2>
|
||||
</section1>
|
||||
|
||||
|
||||
<section1 topic='Security Considerations' anchor='security'>
|
||||
<p>
|
||||
This protocol operates without the standard XMPP security negotiation. It is imperative that consideration is given to link security whenever this protocol is set up. The identity verification facilities of Server Dialback and SASL EXTERNAL are not available in this protocol so other mechanisms are needed. Use of TLS with mutual authentication is the approach that provides best security with this protocol.
|
||||
|
||||
</p>
|
||||
<p>
|
||||
|
||||
When TLS is not used, the only option available is for the responder to identify the initiator based on source IP address and port. This mechanism is prone to attacks, and so should be used with care.
|
||||
Where source IP address is checked, this may
|
||||
be done directly by match of IP address or by use of reverse DNS lookup to identify the connecting server. If reverse DNS Lookup is used, it is RECOMMENDED to use DNS SEC to mitigate against DNS attacks.
|
||||
|
||||
|
||||
</p>
|
||||
</section1>
|
||||
<section1 topic='IANA Considerations' anchor='iana'>
|
||||
<p>None.</p>
|
||||
</section1>
|
||||
<section1 topic='XMPP Registrar Considerations' anchor='registrar'>
|
||||
<p>None.</p>
|
||||
</section1>
|
||||
<section1 topic="Acknowledgements">
|
||||
<p>
|
||||
Dave Cridland, Curtis King, Kevin Smith and Kurt Zeilenga worked out and validated the approach documented in this XEP.
|
||||
</p>
|
||||
<p>
|
||||
Kevin Smith and Kurt Zeilenga provided review and input to this document.
|
||||
</p>
|
||||
</section1>
|
||||
</xep>
|
202
xep-0362.xml
Normal file
202
xep-0362.xml
Normal file
@ -0,0 +1,202 @@
|
||||
<?xml version='1.0' encoding='UTF-8'?>
|
||||
<!DOCTYPE xep SYSTEM 'xep.dtd' [
|
||||
<!ENTITY % ents SYSTEM 'xep.ent'>
|
||||
%ents;
|
||||
]>
|
||||
<?xml-stylesheet type='text/xsl' href='xep.xsl'?>
|
||||
<xep>
|
||||
<header>
|
||||
<title>Raft over XMPP</title>
|
||||
<abstract>This specification provides a means for transporting messages from the Raft consensus algorithm over XMPP.</abstract>
|
||||
&LEGALNOTICE;
|
||||
<number>0362</number>
|
||||
<status>Experimental</status>
|
||||
<type>Standards Track</type>
|
||||
<sig>Standards</sig>
|
||||
<approver>Council</approver>
|
||||
<dependencies>
|
||||
<spec>XMPP Core</spec>
|
||||
<spec>XEP-0001</spec>
|
||||
<spec>Etc.</spec>
|
||||
</dependencies>
|
||||
<supersedes/>
|
||||
<supersededby/>
|
||||
<shortname>NOT_YET_ASSIGNED</shortname>
|
||||
<author>
|
||||
<firstname>Peter</firstname>
|
||||
<surname>Membrey</surname>
|
||||
<email>peter@membrey.hk</email>
|
||||
<jid>peter@membrey.hk</jid>
|
||||
</author>
|
||||
<revision>
|
||||
<version>0.1</version>
|
||||
<date>2015-08-11</date>
|
||||
<initials>XEP Editor (mam)</initials>
|
||||
<remark><p>Initial published version approved by the XMPP Council.</p></remark>
|
||||
</revision>
|
||||
<revision>
|
||||
<version>0.0.3</version>
|
||||
<date>2015-07-28</date>
|
||||
<initials>pm</initials>
|
||||
<remark><p>Removed references to SHOULD/MUST.</p></remark>
|
||||
</revision>
|
||||
<revision>
|
||||
<version>0.0.2</version>
|
||||
<date>2015-07-22</date>
|
||||
<initials>pm</initials>
|
||||
<remark><p>Updates based on list and council feedback.</p></remark>
|
||||
</revision>
|
||||
<revision>
|
||||
<version>0.0.1</version>
|
||||
<date>2015-07-20</date>
|
||||
<initials>pm</initials>
|
||||
<remark><p>First draft.</p></remark>
|
||||
</revision>
|
||||
</header>
|
||||
<section1 topic='Introduction' anchor='intro'>
|
||||
<p>This XEP does not attempt to implement Raft. Rather, based on the message exchanges defined in the <link url="https://ramcloud.stanford.edu/raft.pdf">Raft paper</link>, it defines a complementary set of &MESSAGE; stanza elements to allow Raft messages to be transported cleanly over XMPP. The messages for Node to Node communication are well documented in the <link url="https://ramcloud.stanford.edu/raft.pdf">Raft paper</link> and are reproduced here with minor additions to leverage the benefits of XMPP. However Client to Node communication is only hinted at and, as it does not use Raft natively it is outside the scope of this XEP.</p>
|
||||
|
||||
<p>Raft is a consensus algorithm that is easy to understand and implement. When you want to keep a distributed system consistent, you will need some form of consensus algorithm. Raft was developed at Stanford University as an alternative to the incumbent consensus algorithm PAXOS. PAXOS is claimed to be very complex, hard to teach and even harder to implement. All of these are discussed in a paper <link url="https://ramcloud.stanford.edu/raft.pdf">here</link> and additional information (including a graphical simulation of a cluster) can be found on the project's website: <link url="https://raftconsensus.github.io/">https://raftconsensus.github.io/</link>.</p>
|
||||
|
||||
|
||||
<p>Raft defines a set of core messages needed to implement the protocol. However, it does not specify the transport layer for this protocol. Most implementations have chosen to use vanilla TCP due to its simplicity. However if you want to run a cluster over the Internet, you are likely going to want more than what vanilla TCP provides. This is where XMPP would really shine as a transport layer for Raft. XMPP offers:</p>
|
||||
|
||||
<ol>
|
||||
<li> Encrypted transport (TLS) </li>
|
||||
<li> Authenticated Endpoints </li>
|
||||
<li> Ability to use JIDs to identify cluster nodes </li>
|
||||
<li> Re-use XMPP if the application is already XMPP enabled </li>
|
||||
</ol>
|
||||
|
||||
<p>These are all things that would traditionally have to be re-engineered each time somebody wanted to use Raft across the public Internet. By supporting Raft in XMPP, developers looking to use Raft would have a transport layer that's as easy to use and understand as the Raft protocol itself. As Raft does not offer its own transport protocol and has deliberately left that to the developer, there is no conflict in standardizing an XMPP based transport layer.</p>
|
||||
|
||||
<section2 topic='Why &MESSAGE; and not &IQ;'>
|
||||
<p>The Raft algorithm can be categorized as a request-response protocol. Normally this would make it a prime candidate for using &IQ; stanzas to handle the communication. However because Raft is designed to cope with message loss, it intrinsically supports automatic recovery. There is no need for the transport layer to report errors as even if the transport layer provided them (such as an &IQ; 'error' response), the Raft implementation cannot use it.</p>
|
||||
|
||||
<p>This has a number of benefits. First, it makes Raft adaptable to lossy transport layers where packets can (and do) get lost. Raft is able to automatically recover in this scenario because the next message the Leader sends will allow a Follower to detect that it has missed a message and ask for it to be sent again. The Leader has no way to deal with an error condition caused by sending a message to a Follower.</p>
|
||||
|
||||
<p>Second, when it comes to implementing Raft over XMPP, using &MESSAGE; instead of &IQ; greatly simplifies the implementation. As &IQ; stanzas require a reply, the implementation would need to handle detecting and reporting errors conditions back to the sender. This could mean adding arbitrary timers to try to determine if a Follower has 'timed out'. This adds complexity and uncertainty to the system, and given that Raft itself cannot make use of this information, using &IQ; does not add any value to the Raft over XMPP protocol.</p>
|
||||
|
||||
</section2>
|
||||
|
||||
<section2 topic='Example Usecase'>
|
||||
<p>Making databases or datastores available over the Internet has been the norm for many years. Databases containing PGP keys, certificates or other information can be found hosted by many different organizations. The problem with these systems is that as they become more critical to users, the impact of a server failing increases dramatically. For example, a server that provides a spam database that clients can verify email against, must be operational for those clients to be able to filter spam. Having a single server in this scenario is not acceptable; to provide redundancy there must be multiple servers.</p>
|
||||
|
||||
<p>The problem then becomes how to keep the servers in sync. Raft partly solves this problem by providing the means to ensure the cluster maintains consensus i.e. maintains a consistent view of the data. As mentioned previously, it does not however provide a means for the nodes in the cluster to actually communicate with each other or clients.</p>
|
||||
|
||||
<p>This is where being able to use Raft over XMPP would be highly beneficial. As it stands now, developers must implement their own transport and security, which although certainly possible, is not ideal. First, most developers are not security experts and a wealth of knowledge and experience is needed to properly design a secure system. Second, even with the required expertise, it takes a considerable amount of time and effort to actually implement and test any new implementation. Third, this extra work takes developers' focus away from the problem that they were trying to solve in the first place.</p>
|
||||
|
||||
<p>So how could Raft over XMPP be applied in this instance? First, XMPP has an excellent history when it comes to security. Considerable time and effort was spent ensuring that XMPP was secure when XMPP Core was being standardized. By using XMPP, this hard work and battle tested approach can be leveraged by Raft. This means developers do not need to concern themselves with securing Raft messages, rather they now only need to concern themselves with using XMPP appropriately.</p>
|
||||
|
||||
<p>Raft over XMPP further simplifies things by allowing developers to think at a higher level of abstraction. Nodes in the cluster can be communicated with simply by knowing their JID. It would not be necessary to know a node's IP address (which could change) or what TCP port the node is running on. In addition developers would not need to worry about which node connects to which, managing multiple TCP sockets and how to multiplex data across them.</p>
|
||||
|
||||
<p>Lastly, integrating a Raft implementation with Raft over XMPP, would be relatively straight forward as Raft over XMPP defines and uses the same names as those provided by the <link url="https://ramcloud.stanford.edu/raft.pdf">Raft paper</link> with few additions. This means that it could be much easier to get a Raft implementation up and running using Raft over XMPP than it would be to do so even with pure vanilla sockets.</p>
|
||||
</section2>
|
||||
|
||||
|
||||
|
||||
|
||||
</section1>
|
||||
<section1 topic='Requirements' anchor='reqs'>
|
||||
<p>The author has designed Raft over XMPP with the following requirements in mind:</p>
|
||||
|
||||
<ol>
|
||||
<li> The protocol needs to support all messages as defined in the <link url="https://ramcloud.stanford.edu/raft.pdf">Raft paper</link> </li>
|
||||
<li> The protocol ought to leverage the benefits of using XMPP as the transport layer </li>
|
||||
<li> Client to Node interaction is out of scope for this XEP</li>
|
||||
</ol>
|
||||
</section1>
|
||||
<section1 topic='Glossary' anchor='glossary'>
|
||||
|
||||
<dl>
|
||||
<di><dt>Raft</dt><dd>A distributed consensus algorithm designed at Stanford University to be simple and easy to implement. It aims to replace PAXOS as the conensus algorithm of choice for real world use and teaching. The Raft website is <link url="https://raftconsensus.github.io/">https://raftconsensus.github.io/</link></dd></di>
|
||||
<di><dt>Log Replication</dt><dd>Log replication is how Raft exchanges commands with the rest of the cluster.</dd></di>
|
||||
<di><dt>Follower</dt><dd>The default state of a cluster member. It receives and applies updates from the Leader</dd></di>
|
||||
<di><dt>Candidate</dt><dd>When a Follower has not seen a heartbeat from the Leader for a period of time, it will assume the leader has failed and will look to become the Leader itself.</dd></di>
|
||||
<di><dt>Leader</dt><dd>The Leader of the cluster is responsible for making all changes to the log and sending them to the other members of the cluster</dd></di>
|
||||
|
||||
<di><dt>VoteRequest</dt><dd>A VoteRequest message is sent by a Candidate in order to solicit votes to become the Leader of a cluster</dd></di>
|
||||
<di><dt>AppendEntries</dt><dd>An AppendEntries message is sent by a Leader to other nodes in the cluster when it has updates that it needs to replicate.</dd></di>
|
||||
|
||||
</dl>
|
||||
|
||||
|
||||
</section1>
|
||||
<section1 topic='Protocol' anchor='protocol'>
|
||||
<p>This XEP defines a transport layer for Raft and not an actual implementation. That is, it does not seek to implement the Raft consensus algorithm within XMPP, but instead to simply define the means for Raft messages to be transported over XMPP. To facilitate this, both the message name used in the Raft spec (shown in camel case) and the corresponding element name are mentioned together where appropriate.</p>
|
||||
|
||||
<p>Node to Node communication is the back-bone of a Raft cluster. In operation, only the Leader or a Candidate will send messages. In all other cases, nodes will only reply to messages received. The two messages are AppendEntries and RequestVote.</p>
|
||||
|
||||
<section2 topic="RequestVote">
|
||||
<p>When a Follower has not received a heartbeat from the Leader for a given period of time, it will determine that the Leader has failed and will seek to replace it. To do this it needs the support of the majority of nodes in the cluster. It can solicit support from other nodes by declaring itself a Candidate and sending a 'request-vote' (RequestVote) message to all nodes in the cluster:</p>
|
||||
|
||||
<example caption="Duncan is soliciting votes to become leader of the cluster"><![CDATA[
|
||||
<message from="duncan@inverness.lit/castle" to="macbeth@cawdor.lit/castle">
|
||||
<request-vote xmlns="urn:xmpp:raft" term="1" last-log-term="1" last-log-index="1" cluster="scotland"/>
|
||||
</message>
|
||||
]]></example>
|
||||
|
||||
<p>A node will respond with a 'vote' (RequestVoteResponse) message:</p>
|
||||
|
||||
<example caption="Macbeth votes for Duncan to become the next leader"><![CDATA[
|
||||
<message from="macbeth@cawdor.lit/castle" to="duncan@inverness.lit/castle">
|
||||
<vote xmlns="urn:xmpp:raft" term="1" vote-granted="true" cluster="scotland"/>
|
||||
</message>
|
||||
]]></example>
|
||||
|
||||
<p> A node can either vote for a given Candidate (vote-granted="true") or against a Candidate (vote-granted="false").</p>
|
||||
|
||||
<p>If a node does not receive a reply, no special handling is required.</p>
|
||||
|
||||
</section2>
|
||||
|
||||
<section2 topic="AppendEntries">
|
||||
<p>The 'append' (AppendEntries) message is used by the Leader to tell Followers that they should append a new entry (or entries) to their logs. It contains additional information to allow a Follower to determine which log entries have been executed and committed on the Leader and also if it has dropped any messages. These features are implemented in Raft directly.</p>
|
||||
|
||||
<example caption="Duncan sends an append message to his followers"><![CDATA[
|
||||
<message from="duncan@inverness.lit/castle" to="macbeth@cawdor.lit/castle">
|
||||
<append xmlns="urn:xmpp:raft" term="1" prev-log-index="1" leader-commit="1" cluster="scotland">
|
||||
<entry xmlns="urn:xmpp:raft" encoded="false">
|
||||
SET X = 1
|
||||
</entry>
|
||||
<entry xmlns="urn:xmpp:raft" encoded="true">
|
||||
U0VUIFggPSAx
|
||||
</entry>
|
||||
</append>
|
||||
</message>
|
||||
]]></example>
|
||||
|
||||
<p>The AppendEntries message is described as a simple array in the <link url="https://ramcloud.stanford.edu/raft.pdf">Raft paper</link> and this has been expanded on in XMPP to take advantage of structured XML. In addition, Raft is designed to be able to replicate any form of command and this could be binary data rather than textual data. To accommodate this, an attribute has been added to the 'append-entries' element to allow a sender to flag when the receiver needs to decode the Entry before passing it to the Raft implementation. The data is encoded using base64.</p>
|
||||
|
||||
<p>When followers receive this message, they send a single 'append-response' (AppendEntriesResponse) in reply as follows:</p>
|
||||
|
||||
<example caption="Macbeth sends an append-response message to Duncan"><![CDATA[
|
||||
<message from="macbeth@cawdor.lit/castle" to="duncan@inverness.lit/castle">
|
||||
<append-response xmlns="urn:xmpp:raft" term="1" success="true" cluster="scotland"/>
|
||||
</message>
|
||||
]]></example>
|
||||
|
||||
<p>As before, if a message is missed in either direction, the transport layer does not need to take action.</p>
|
||||
|
||||
|
||||
</section2>
|
||||
</section1>
|
||||
|
||||
<section1 topic='Security Considerations' anchor='security'>
|
||||
<section2 topic='Checking cluster membership'>
|
||||
<p>It is not the responsibility of the transport layer to determine whether a node is a member of a cluster or not before delivering messages to the Raft implementation. The Raft implementation should ignore messages that it receives from nodes that aren't part of the cluster.</p>
|
||||
</section2>
|
||||
|
||||
</section1>
|
||||
<section1 topic='IANA Considerations' anchor='iana'>
|
||||
<p>This document requires no interaction with the Internet Assigned Numbers Authority (IANA).</p>
|
||||
</section1>
|
||||
<section1 topic='XMPP Registrar Considerations' anchor='registrar'>
|
||||
<section2 topic='Protocol Namespaces' anchor='registrar-ns'>
|
||||
<p>The ®ISTRAR; includes 'urn:xmpp:raft' in its registry of protocol namespaces.</p>
|
||||
</section2>
|
||||
</section1>
|
||||
<section1 topic='XML Schema' anchor='schema'>
|
||||
<p>REQUIRED for protocol specifications.</p>
|
||||
</section1>
|
||||
</xep>
|
12
xep.ent
12
xep.ent
@ -308,8 +308,8 @@ THE SOFTWARE.
|
||||
<!ENTITY w3xml "<span class='ref'><link url='http://www.w3.org/TR/REC-xml/'>XML 1.0</link></span> <note>Extensible Markup Language (XML) 1.0 (Fourth Edition) <<link url='http://www.w3.org/TR/REC-xml/'>http://www.w3.org/TR/REC-xml/</link>>.</note>" >
|
||||
<!ENTITY w3xmlenc "<span class='ref'><link url='http://www.w3.org/TR/2002/REC-xmlenc-core-20021210/'>XML Encryption</link></span> <note>XML Encryption Syntax and Processing <<link url='http://www.w3.org/TR/2002/REC-xmlenc-core-20021210/'>http://www.w3.org/TR/2002/REC-xmlenc-core-20021210/</link>>.</note>" >
|
||||
<!ENTITY w3xmlnamespaces "<span class='ref'><link url='http://www.w3.org/TR/REC-xml-names/'>Namespaces in XML</link></span> <note>Namespaces in XML <<link url='http://www.w3.org/TR/REC-xml-names/'>http://www.w3.org/TR/REC-xml-names/</link>>.</note>" >
|
||||
<!ENTITY w3xmlschema1 "<span class='ref'><link url='http://www.w3.org/TR/xmlschema-1/'>XML Schema Part 1</link></span> <note>XML Schema Part 1: Structures <<link url='http://www.w3.org/TR/xmlschema-1/'>http://www.w3.org/TR/xmlschema-1/</link>>.</note>" >
|
||||
<!ENTITY w3xmlschema2 "<span class='ref'><link url='http://www.w3.org/TR/xmlschema-2/'>XML Schema Part 2</link></span> <note>XML Schema Part 2: Datatypes <<link url='http://www.w3.org/TR/xmlschema-2/'>http://www.w3.org/TR/xmlschema-2/</link>>.</note>" >
|
||||
<!ENTITY w3xmlschema1 "<span class='ref'><link url='http://www.w3.org/TR/xmlschema11-1/'>XML Schema Part 1</link></span> <note>XML Schema Part 1: Structures <<link url='http://www.w3.org/TR/xmlschema11-1/'>http://www.w3.org/TR/xmlschema11-1/</link>>.</note>" >
|
||||
<!ENTITY w3xmlschema2 "<span class='ref'><link url='http://www.w3.org/TR/xmlschema11-2/'>XML Schema Part 2</link></span> <note>XML Schema Part 2: Datatypes <<link url='http://www.w3.org/TR/xmlschema11-2/'>http://www.w3.org/TR/xmlschema11-2/</link>>.</note>" >
|
||||
<!ENTITY w3xmlsig "<span class='ref'><link url='http://www.w3.org/TR/2002/REC-xmldsig-core-20020212/'>XML Signature</link></span> <note>XML Signature Syntax and Processing <<link url='http://www.w3.org/TR/2002/REC-xmldsig-core-20020212/'>http://www.w3.org/TR/2002/REC-xmldsig-core-20020212/</link>>.</note>" >
|
||||
<!ENTITY w3xop "<span class='ref'><link url='http://www.w3.org/TR/xop10/'>XML-binary Optimized Packaging</link></span> <note>XML-binary Optimized Packaging <<link url='http://www.w3.org/TR/xop10/'>http://www.w3.org/TR/xop10/</link>>.</note>" >
|
||||
<!ENTITY w3xpath "<span class='ref'><link url='http://www.w3.org/TR/xpath'>XPath</link></span> <note>XML Path Language <<link url='http://www.w3.org/TR/xpath'>http://www.w3.org/TR/xpath</link>>.</note>" >
|
||||
@ -405,6 +405,7 @@ THE SOFTWARE.
|
||||
<!ENTITY rfc1939 "<span class='ref'><link url='http://tools.ietf.org/html/rfc1939'>RFC 1939</link></span> <note>RFC 1939: Post Office Protocol - Version 3 <<link url='http://tools.ietf.org/html/rfc1939'>http://tools.ietf.org/html/rfc1939</link>>.</note>" >
|
||||
<!ENTITY rfc1945 "<span class='ref'><link url='http://tools.ietf.org/html/rfc1945'>RFC 1945</link></span> <note>RFC 1945: Hypertext Transfer Protocol -- HTTP/1.0 <<link url='http://tools.ietf.org/html/rfc1945'>http://tools.ietf.org/html/rfc1945</link>>.</note>" >
|
||||
<!ENTITY rfc1950 "<span class='ref'><link url='http://tools.ietf.org/html/rfc1950'>RFC 1950</link></span> <note>RFC 1950: ZLIB Compressed Data Format Specification version 3.3 <<link url='http://tools.ietf.org/html/rfc1950'>http://tools.ietf.org/html/rfc1950</link>>.</note>" >
|
||||
<!ENTITY rfc1951 "<span class='ref'><link url='http://tools.ietf.org/html/rfc1951'>RFC 1951</link></span> <note>RFC 1951: DEFLATE Compressed Data Format Specification version 1.3 <<link url='http://tools.ietf.org/html/rfc1951'>http://tools.ietf.org/html/rfc1951</link>>.</note>" >
|
||||
<!ENTITY rfc2026 "<span class='ref'><link url='http://tools.ietf.org/html/rfc2026'>RFC 2026</link></span> <note>RFC 2026: The Internet Standards Process <<link url='http://tools.ietf.org/html/rfc2026'>http://tools.ietf.org/html/rfc2026</link>>.</note>" >
|
||||
<!ENTITY rfc2045 "<span class='ref'><link url='http://tools.ietf.org/html/rfc2045'>RFC 2045</link></span> <note>RFC 2045: Multipurpose Internet Mail Extensions (MIME) Part One: Format of Internet Message Bodies <<link url='http://tools.ietf.org/html/rfc2045'>http://tools.ietf.org/html/rfc2045</link>>.</note>" >
|
||||
<!ENTITY rfc2068 "<span class='ref'><link url='http://tools.ietf.org/html/rfc2068'>RFC 2068</link></span> <note>RFC 2068: Hypertext Transport Protocol -- HTTP/1.1 <<link url='http://tools.ietf.org/html/rfc2068'>http://tools.ietf.org/html/rfc2068</link>>.</note>" >
|
||||
@ -876,7 +877,8 @@ IANA Service Location Protocol, Version 2 (SLPv2) Templates</link></span> <note>
|
||||
<author>
|
||||
<firstname>Dave</firstname>
|
||||
<surname>Cridland</surname>
|
||||
<email>dave@cridland.net</email>
|
||||
<email>dave.cridland@surevine.com</email>
|
||||
<jid>dave.cridland@surevine.com</jid>
|
||||
</author>
|
||||
" >
|
||||
<!ENTITY fabio "
|
||||
@ -1339,3 +1341,7 @@ IANA Service Location Protocol, Version 2 (SLPv2) Templates</link></span> <note>
|
||||
<!ENTITY xep0356 "<span class='ref'><link url='http://xmpp.org/extensions/xep-0356.html'>Privileged Entity (XEP-0356)</link></span> <note>XEP-0356: Privileged Entity <<link url='http://xmpp.org/extensions/xep-0356.html'>http://xmpp.org/extensions/xep-0356.html</link>>.</note>" >
|
||||
<!ENTITY xep0357 "<span class='ref'><link url='http://xmpp.org/extensions/xep-0357.html'>Push (XEP-0357)</link></span> <note>XEP-0357: Push <<link url='http://xmpp.org/extensions/xep-0357.html'>http://xmpp.org/extensions/xep-0357.html</link>>.</note>" >
|
||||
<!ENTITY xep0358 "<span class='ref'><link url='http://xmpp.org/extensions/xep-0358.html'>Publishing Available Jingle Sessions (XEP-0358)</link></span> <note>XEP-0358: Publishing Available Jingle Sessions <<link url='http://xmpp.org/extensions/xep-0358.html'>http://xmpp.org/extensions/xep-0358.html</link>>.</note>" >
|
||||
<!ENTITY xep0359 "<span class='ref'><link url='http://xmpp.org/extensions/xep-0359.html'>Unique and Stable Stanza IDs (XEP-0359)</link></span> <note>XEP-0359: Unique and Stable Stanza IDs <<link url='http://xmpp.org/extensions/xep-0359.html'>http://xmpp.org/extensions/xep-0359.html</link>>.</note>" >
|
||||
<!ENTITY xep0360 "<span class='ref'><link url='http://xmpp.org/extensions/xep-0360.html'>Nonzas (are not Stanzas) (XEP-0360)</link></span> <note>XEP-0360: Nonzas (are not Stanzas) <<link url='http://xmpp.org/extensions/xep-0360.html'>http://xmpp.org/extensions/xep-0360.html</link>>.</note>" >
|
||||
<!ENTITY xep0361 "<span class='ref'><link url='http://xmpp.org/extensions/xep-0361.html'>Zero Handshake Server to Server Protocol (XEP-0361)</link></span> <note>XEP-0361: Zero Handshake Server to Server Protocol <<link url='http://xmpp.org/extensions/xep-0361.html'>http://xmpp.org/extensions/xep-0361.html</link>>.</note>" >
|
||||
<!ENTITY xep0362 "<span class='ref'><link url='http://xmpp.org/extensions/xep-0362.html'>Raft over XMPP (XEP-0362)</link></span> <note>XEP-0362: Raft over XMPP <<link url='http://xmpp.org/extensions/xep-0362.html'>http://xmpp.org/extensions/xep-0362.html</link>>.</note>" >
|
||||
|
13
xep.xsl
13
xep.xsl
@ -2,7 +2,7 @@
|
||||
|
||||
<!--
|
||||
|
||||
Copyright (c) 1999 - 2014 XMPP Standards Foundation
|
||||
Copyright (c) 1999 - 2015 XMPP Standards Foundation
|
||||
|
||||
Permission is hereby granted, free of charge, to any
|
||||
person obtaining a copy of this software and
|
||||
@ -131,7 +131,7 @@ OR OTHER DEALINGS IN THE SOFTWARE.
|
||||
</xsl:if>
|
||||
<tr valign='top'>
|
||||
<td><strong>Copyright:</strong></td>
|
||||
<td>© 1999 - 2014 XMPP Standards Foundation. <a href='#appendix-legal'>SEE LEGAL NOTICES</a>.</td>
|
||||
<td>© 1999 - 2015 XMPP Standards Foundation. <a href='#appendix-legal'>SEE LEGAL NOTICES</a>.</td>
|
||||
</tr>
|
||||
<tr valign='top'>
|
||||
<td><strong>Status:</strong></td>
|
||||
@ -169,7 +169,7 @@ OR OTHER DEALINGS IN THE SOFTWARE.
|
||||
<p style='color:green'>NOTICE: This Procedural document defines a process or activity of the XMPP Standards Foundation (XSF) that has been approved by the XMPP Council and/or the XSF Board of Directors. The XSF is currently following the process or activity defined herein and will do so until this document is deprecated or obsoleted.</p>
|
||||
</xsl:if>
|
||||
<xsl:if test='$thestatus = "Deferred"'>
|
||||
<p style='color:red'>WARNING: Consideration of this document has been <strong>Deferred</strong> by the XMPP Standards Foundation. Implementation of the protocol described herein is not recommended.</p>
|
||||
<p style='color:red'>WARNING: This document has been automatically Deferred after 12 months of inactivity in its previous Experimental state. Implementation of the protocol described herein is not recommended for production systems. However, exploratory implementations are encouraged to resume the standards process.</p>
|
||||
</xsl:if>
|
||||
<xsl:if test='$thestatus = "Deprecated"'>
|
||||
<p style='color:red'>WARNING: This document has been <strong>Deprecated</strong> by the XMPP Standards Foundation. Implementation of the protocol described herein is not recommended. Developers desiring similar functionality are advised to implement the protocol that supersedes this one (if any).</p>
|
||||
@ -196,7 +196,10 @@ OR OTHER DEALINGS IN THE SOFTWARE.
|
||||
<p style='color:red'>WARNING: This document has been obsoleted by the XMPP Standards Foundation. Implementation of the protocol described herein is not recommended. Developers desiring similar functionality are advised to implement the protocol that supersedes this one (if any).</p>
|
||||
</xsl:if>
|
||||
<xsl:if test='$thestatus = "Proposed"'>
|
||||
<p style='color:red'>NOTICE: This document is currently within Last Call or under consideration by the XMPP Council for advancement to the next stage in the XSF standards process. The Last Call ends on <xsl:value-of select='/xep/header/lastcall'/>. Please send your feedback to the <a href='http://mail.jabber.org/mailman/listinfo/standards'>standards@xmpp.org</a> discussion list.</p>
|
||||
<p style='color:red'>NOTICE: This document is currently within Last Call or under consideration by the XMPP Council for advancement to the next stage in the XSF standards process.
|
||||
<xsl:if test='/xep/header/lastcall'>The Last Call ends on <xsl:value-of select='/xep/header/lastcall'/>.
|
||||
</xsl:if>
|
||||
Please send your feedback to the <a href='http://mail.jabber.org/mailman/listinfo/standards'>standards@xmpp.org</a> discussion list.</p>
|
||||
</xsl:if>
|
||||
<xsl:if test='$thestatus = "ProtoXEP"'>
|
||||
<p style='color:red'>WARNING: This document has not yet been accepted for consideration or approved in any official manner by the XMPP Standards Foundation, and this document is not yet an XMPP Extension Protocol (XEP). If this document is accepted as a XEP by the XMPP Council, it will be published at <<a href="http://xmpp.org/extensions/">http://xmpp.org/extensions/</a>> and announced on the <standards@xmpp.org> mailing list.</p>
|
||||
@ -310,7 +313,7 @@ OR OTHER DEALINGS IN THE SOFTWARE.
|
||||
<br />
|
||||
</xsl:if>
|
||||
<xsl:variable name='sourceHTML'>
|
||||
<xsl:text>http://gitorious.org/xmpp/xmpp/blobs/master/extensions/xep-</xsl:text>
|
||||
<xsl:text>https://github.com/xsf/xeps/blob/master/xep-</xsl:text>
|
||||
<xsl:value-of select='/xep/header/number'/>
|
||||
<xsl:text>.xml</xsl:text>
|
||||
</xsl:variable>
|
||||
|
154
xmpp.css
Executable file
154
xmpp.css
Executable file
@ -0,0 +1,154 @@
|
||||
BODY {
|
||||
background-color: #ffffff;
|
||||
color: #000000;
|
||||
font-family: Verdana, Arial, Helvetica, Geneva, sans-serif;
|
||||
font-size: small;
|
||||
line-height: 130%;
|
||||
margin-left: 7%;
|
||||
margin-right: 7%;
|
||||
}
|
||||
#left {
|
||||
border: 0px;
|
||||
border-color: #aaaaaa;
|
||||
border-right: 1px;
|
||||
border-style: solid;
|
||||
float: left;
|
||||
margin: 0% 0% 5% 0%;
|
||||
padding: 4px 2% 10px 2%;
|
||||
width: 12%;
|
||||
}
|
||||
#main {
|
||||
border: 0px;
|
||||
color: #000000;
|
||||
font-weight: normal;
|
||||
margin: 0% 0% 5% 17%;
|
||||
padding: 4px 2% 10px 2%;
|
||||
text-decoration: none;
|
||||
}
|
||||
#foot {
|
||||
border-top: 0px solid;
|
||||
clear: both;
|
||||
color: #666666;
|
||||
font-size: x-small;
|
||||
font-weight: normal;
|
||||
text-align: center;
|
||||
text-decoration: none;
|
||||
}
|
||||
A:link {
|
||||
color: #336699;
|
||||
}
|
||||
A.standardsButton {
|
||||
background-color: #ff6600;
|
||||
border: 1px solid;
|
||||
border-color: #ffc8a4 #7d3302 #3f1a01 #ff9a57;
|
||||
color: #ffffff;
|
||||
padding: 0px 3px 0px 3px;
|
||||
text-decoration: none;
|
||||
margin: 0px;
|
||||
}
|
||||
A:visited {
|
||||
color: #663399;
|
||||
}
|
||||
H1, H2, H3, H4, H5, H6 {
|
||||
color: #336699;
|
||||
line-height: 0.8;
|
||||
}
|
||||
pre {
|
||||
font-family: Courier, monospace;
|
||||
}
|
||||
ul {
|
||||
list-style: disc outside;
|
||||
}
|
||||
.body {
|
||||
font-family: Verdana, Arial, Helvetica, Geneva, sans-serif;
|
||||
font-size: small;
|
||||
}
|
||||
.bold {
|
||||
font-weight: bold;
|
||||
}
|
||||
.box {
|
||||
border: thin dotted;
|
||||
padding-bottom: 1em;
|
||||
padding-left: 2em;
|
||||
padding-right: 2em;
|
||||
padding-top: 1em;
|
||||
}
|
||||
.caption {
|
||||
font-weight: bold;
|
||||
}
|
||||
.code {
|
||||
font-family: "Courier New", Courier, monospace;
|
||||
white-space: pre;
|
||||
}
|
||||
.def {
|
||||
text-indent: -6.3em;
|
||||
padding-bottom: 1em;
|
||||
padding-left: 6.5em;
|
||||
padding-right: 10em;
|
||||
padding-top: 1em;
|
||||
}
|
||||
.em {
|
||||
font-style: italic;
|
||||
}
|
||||
.example {
|
||||
background-color: yellow;
|
||||
margin-left: 5%;
|
||||
margin-right: 25%;
|
||||
}
|
||||
.indent {
|
||||
padding-left: 5%;
|
||||
padding-right: 5%;
|
||||
}
|
||||
.head {
|
||||
color: #336699;
|
||||
font-weight: bold;
|
||||
}
|
||||
.highlight {
|
||||
color: #336699;
|
||||
}
|
||||
.nav {
|
||||
font-size: small;
|
||||
line-height: 45%;
|
||||
text-decoration: none;
|
||||
white-space: nowrap;
|
||||
}
|
||||
.navhead {
|
||||
color: #336699;
|
||||
font-size: medium;
|
||||
line-height: 90%;
|
||||
padding-left: 0px;
|
||||
text-decoration: none;
|
||||
}
|
||||
.pagehead {
|
||||
color: #336699;
|
||||
text-decoration: none;
|
||||
}
|
||||
A:visited.pagehead {
|
||||
color: #336699;
|
||||
text-decoration: none;
|
||||
}
|
||||
.ref {
|
||||
font-weight: bold;
|
||||
}
|
||||
.strong {
|
||||
font-weight: bold;
|
||||
}
|
||||
.subhead {
|
||||
font-style: italic;
|
||||
}
|
||||
.sub {
|
||||
font-size: xx-small;
|
||||
vertical-align: sub;
|
||||
}
|
||||
.super {
|
||||
font-size: xx-small;
|
||||
vertical-align: super;
|
||||
}
|
||||
.tablebody {
|
||||
font-family: Verdana, Arial, Helvetica, Geneva, sans-serif;
|
||||
font-size: small;
|
||||
white-space: nowrap;
|
||||
}
|
||||
.event {
|
||||
color: #336699;
|
||||
}
|
Loading…
Reference in New Issue
Block a user