forked from xsf/xeps
-
Notifications
You must be signed in to change notification settings - Fork 0
/
xep-0046.xml
216 lines (174 loc) · 7.91 KB
/
xep-0046.xml
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
179
180
181
182
183
184
185
186
187
188
189
190
191
192
193
194
195
196
197
198
199
200
201
202
203
204
205
206
207
208
209
210
211
212
213
214
215
216
<?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>DTCP</title>
<abstract>Direct TCP connection between two Jabber entities.</abstract>
&LEGALNOTICE;
<number>0046</number>
<status>Retracted</status>
<type>Standards Track</type>
<sig>Standards</sig>
<dependencies/>
<supersedes/>
<supersededby><spec>XEP-0065</spec></supersededby>
<shortname>None</shortname>
<author>
<firstname>Justin</firstname>
<surname>Karneges</surname>
<email>justin@affinix.com</email>
<jid>justin@andbit.net</jid>
</author>
<revision>
<version>0.8</version>
<date>2003-04-11</date>
<initials>psa</initials>
<remark>At the request of the author, changed status to Retracted.</remark>
</revision>
<revision>
<version>0.7</version>
<date>2002-12-10</date>
<initials>jk</initials>
<remark>Remove 'comment' block</remark>
</revision>
<revision>
<version>0.6</version>
<date>2002-12-02</date>
<initials>jk</initials>
<remark>Simplification of the document</remark>
</revision>
<revision>
<version>0.5</version>
<date>2002-11-19</date>
<initials>jk</initials>
<remark>Changed handshake and namespace, merged active/passive</remark>
</revision>
<revision>
<version>0.4</version>
<date>2002-10-10</date>
<initials>jk</initials>
<remark>Change to 'comment' block</remark>
</revision>
<revision>
<version>0.3</version>
<date>2002-09-18</date>
<initials>jk</initials>
<remark>Support for SSL</remark>
</revision>
<revision>
<version>0.2</version>
<date>2002-09-18</date>
<initials>jk</initials>
<remark>Simplified things.</remark>
</revision>
<revision>
<version>0.1</version>
<date>2002-09-12</date>
<initials>jk</initials>
<remark>Initial version.</remark>
</revision>
</header>
<section1 topic='Introduction'>
<p>There are cases where it would be more optimal for clients to exchange data directly with each other rather than through the server. DTCP specifies a method for establishing a direct TCP socket connection between two entities, so that a reliable bytestream can be created out-of-band.</p>
</section1>
<section1 topic='Requirements'>
<p>The following design goals are considered:</p>
<ul>
<li>The protocol should be reasonably effective in scenarios involving NAT and/or firewalls.<note>DTCP works in situations where at least one client can accept incoming connections.</note></li>
<li>It should be reasonably secure.</li>
<li>Establishing a connection should be fast.</li>
<li>The protocol should be simple.</li>
</ul>
</section1>
<section1 topic='Implementation'>
<section2 topic='Requesting a DTCP connection'>
<p>Say you wish to initiate a DTCP session with Joe:</p>
<example caption='Requesting a DTCP session'><![CDATA[
<iq type="set" id="dtcp_1" to="joe@blow.com/Home">
<query xmlns="http://jabber.org/protocol/dtcp">
<key>c7b5ea3f</key>
<host>192.168.0.32:8000</host>
<host>63.110.44.12:8000</host>
</query>
</iq>
]]></example>
<p>The 'key' given is a unique key for Joe to use when referencing this session with you. If a 'host' element is present, then you are indicating that you can be reached at the given "host:port". Multiple hosts may be specified, but Joe cannot be expected to act on more than three of them.</p>
<example caption='Success response'><![CDATA[
<iq type="result" id="dtcp_1" from="joe@blow.com/Home">
<query xmlns="http://jabber.org/protocol/dtcp">
<key>a1b2c3d4</key>
<host>192.168.0.33:8000</host>
</query>
</iq>
]]></example>
<p>The success response is in exactly the same format as the request. As before, Joe cannot expect you to act on more than three hosts. The 'key' is a unique key from Joe that you will use when referring to the session with him.</p>
<example caption='Error response'><![CDATA[
<iq type="error" id="dtcp_1" from="joe@blow.com/Home">
<error code="501">DTCP not supported</error>
</iq>
]]></example>
<p>Or he may send an error.</p>
</section2>
<section2 topic='Establishing the TCP connection'>
<p>If you received a success response, then the next step is to form the TCP connection. Each entity should have a list of hosts (between 0-3 inclusive) and key of the other. With this information, they should each try to establish a direct connection with the hosts provided. When these connections take place is implementation dependent. Clients may choose to connect to all provided hosts at once, and both clients may even end up connecting to each other simultaneously. Clients may delay between connections, etc. As such, clients that are listening for connections should be prepared for anything.</p>
<p>The procedure ends when either a successful DTCP connection is formed (and all other TCP connections discarded), or when both entities have given up. An entity gives up when it is no longer trying to connect to any hosts. This is done by sending an additional iq-error packet, with the key of the other entity:</p>
<example><![CDATA[
<iq type="error" to="joe@blow.com/Home">
<query xmlns="http://jabber.org/protocol/dtcp">
<key>a1b2c3d4</key>
</query>
<error code="503">Could not connect to any of the hosts.</error>
</iq>
]]></example>
<p>If an entity was not provided any hosts, then it is assumed that he has given up and this packet need not be sent.</p>
</section2>
<section2 topic='The handshake'>
<p>For a given host, a TCP socket connection is established. Once connected, the connecting client must send a command across the channel. Each command is a line of text terminated by the ASCII linefeed character (0x0A).</p>
<example caption='Command format'>
[command]:[argument]<LF>
</example>
<p>Some commands may have an argument, which is placed on the same line and separated by a colon character. If there is no argument, then the colon need not be present.</p>
<p>The serving client should keep the connection open after responding to a command, even if it resulted in an error, in case the connecting client wishes to try another command.</p>
<section3 topic='SSL/TLS'>
<p>If you want an encrypted channel, then it must be requested using the 'starttls' command</p>
<example>
starttls<LF>
</example>
<p>If successful, the serving client should send back:</p>
<example>
ok<LF>
</example>
<p>This means that the serving client supports SSL and the connecting client should begin the SSL/TLS negotiation. After this, further data sent/received over the channel should be in encrypted form.</p>
<p>Or the serving client might report an error:</p>
<example>
error<LF>
</example>
<p>This means SSL is not supported by the serving client.</p>
</section3>
<section3 topic='Authenticating'>
<p>To complete the DTCP connection, the connecting client must authenticate with the serving client. This is done by exchanging keys. First, the connecting client sends the serving client's key:</p>
<example>
key:a1b2c3d4<LF>
</example>
<p>If the serving client recognizes the key, then it should respond by sending the connecting client's key:</p>
<example>
ok:c7b5ea3f<LF>
</example>
<p>Or the serving client might report an error:</p>
<example>
error<LF>
</example>
<p>On success, there may be one more step necessary. If the connecting client is also the original requestor of the DTCP connection (ie, he did the iq-set), then he must send the following "ack":</p>
<example>
ok<LF>
</example>
<p>This gives the final say to the requestor, to prevent any sort of race-condition due to the clients contacting each other at the same time. If the serving client is the requestor, then this extra "ack" is NOT needed and must NOT be sent.</p>
<p>At this point, the channel is established. No further commands may be issued, as the TCP connection is now for application data only.</p>
</section3>
</section2>
</section1>
</xep>