-
Notifications
You must be signed in to change notification settings - Fork 0
/
xep-0037.xml
859 lines (656 loc) · 48.2 KB
/
xep-0037.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
217
218
219
220
221
222
223
224
225
226
227
228
229
230
231
232
233
234
235
236
237
238
239
240
241
242
243
244
245
246
247
248
249
250
251
252
253
254
255
256
257
258
259
260
261
262
263
264
265
266
267
268
269
270
271
272
273
274
275
276
277
278
279
280
281
282
283
284
285
286
287
288
289
290
291
292
293
294
295
296
297
298
299
300
301
302
303
304
305
306
307
308
309
310
311
312
313
314
315
316
317
318
319
320
321
322
323
324
325
326
327
328
329
330
331
332
333
334
335
336
337
338
339
340
341
342
343
344
345
346
347
348
349
350
351
352
353
354
355
356
357
358
359
360
361
362
363
364
365
366
367
368
369
370
371
372
373
374
375
376
377
378
379
380
381
382
383
384
385
386
387
388
389
390
391
392
393
394
395
396
397
398
399
400
401
402
403
404
405
406
407
408
409
410
411
412
413
414
415
416
417
418
419
420
421
422
423
424
425
426
427
428
429
430
431
432
433
434
435
436
437
438
439
440
441
442
443
444
445
446
447
448
449
450
451
452
453
454
455
456
457
458
459
460
461
462
463
464
465
466
467
468
469
470
471
472
473
474
475
476
477
478
479
480
481
482
483
484
485
486
487
488
489
490
491
492
493
494
495
496
497
498
499
500
501
502
503
504
505
506
507
508
509
510
511
512
513
514
515
516
517
518
519
520
521
522
523
524
525
526
527
528
529
530
531
532
533
534
535
536
537
538
539
540
541
542
543
544
545
546
547
548
549
550
551
552
553
554
555
556
557
558
559
560
561
562
563
564
565
566
567
568
569
570
571
572
573
574
575
576
577
578
579
580
581
582
583
584
585
586
587
588
589
590
591
592
593
594
595
596
597
598
599
600
601
602
603
604
605
606
607
608
609
610
611
612
613
614
615
616
617
618
619
620
621
622
623
624
625
626
627
628
629
630
631
632
633
634
635
636
637
638
639
640
641
642
643
644
645
646
647
648
649
650
651
652
653
654
655
656
657
658
659
660
661
662
663
664
665
666
667
668
669
670
671
672
673
674
675
676
677
678
679
680
681
682
683
684
685
686
687
688
689
690
691
692
693
694
695
696
697
698
699
700
701
702
703
704
705
706
707
708
709
710
711
712
713
714
715
716
717
718
719
720
721
722
723
724
725
726
727
728
729
730
731
732
733
734
735
736
737
738
739
740
741
742
743
744
745
746
747
748
749
750
751
752
753
754
755
756
757
758
759
760
761
762
763
764
765
766
767
768
769
770
771
772
773
774
775
776
777
778
779
780
781
782
783
784
785
786
787
788
789
790
791
792
793
794
795
796
797
798
799
800
801
802
803
804
805
806
807
808
809
810
811
812
813
814
815
816
817
818
819
820
821
822
823
824
825
826
827
828
829
830
831
832
833
834
835
836
837
838
839
840
841
842
843
844
845
846
847
848
849
850
851
852
853
854
855
856
857
858
859
<?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>DSPS - Data Stream Proxy Service</title>
<abstract>A proposal for proxy support in Jabber.</abstract>
&PUBLICDOMAINNOTICE;
<number>0037</number>
<status>Rejected</status>
<type>Standards Track</type>
<sig>Standards</sig>
<dependencies/>
<supersedes/>
<supersededby/>
<shortname>N/A</shortname>
<author>
<firstname>David</firstname>
<surname>Sutton</surname>
<email></email>
<jid></jid>
</author>
<author>
<firstname>"Bac9"</firstname>
<surname></surname>
<email>[email protected]</email>
<jid>[email protected]</jid>
</author>
<revision>
<version>0.8.1</version>
<date>2016-10-04</date>
<initials>egp</initials>
<remark><p>Made the revision’s version element include only the actual version.</p></remark>
</revision>
<revision>
<version>0.8</version>
<date>2002-09-18</date>
<initials>Bac9</initials>
<remark>Streamlined and enhanced handshake procedure, and cleaned up document.</remark>
</revision>
<revision>
<version>0.7</version>
<date>2002-08-20</date>
<initials>Bac9</initials>
<remark>Added public connections and reduced number of tags.</remark>
</revision>
<revision>
<version>0.6</version>
<date>2002-08-11</date>
<initials>Bac9</initials>
<remark>Added data tracking, inviting peer, auto-disconnect for slow peers, elaboration on protocol and suggested example of file transfer.</remark>
</revision>
<revision>
<version>0.5</version>
<date>2002-07-29</date>
<initials>Bac9</initials>
<remark>Elaborated on some functionality and cleaned up XML protocol.</remark>
</revision>
<revision>
<version>0.4</version>
<date>2002-07-11</date>
<initials>lw</initials>
<remark>Converted to XML format.</remark>
</revision>
<revision>
<version>0.3</version>
<date>2002-06-25</date>
<initials>Bac9</initials>
<remark>Added support for HTTP, SSL and throughput logging. Changed relay behaviour.</remark>
</revision>
<revision>
<version>0.2</version>
<date>2002-06-21</date>
<initials>Bac9</initials>
<remark>Revised, standardized and extended XML protocol structure.</remark>
</revision>
<revision>
<version>0.1</version>
<date></date>
<initials>rn</initials>
<remark>Initial version.</remark>
</revision>
</header>
<section1 topic='Introduction'>
<p>Data Stream Proxy Service (DSPS) is designed to be a common stream protocol for multicast (unicast as special case) over P2S2P (P2P as special case) connections.</p>
</section1>
<section1 topic='Startup'>
<p>This document follows DSPS protocol version 0.5. Any XML data not explicitly defined or mentioned will be ignored without error. On startup, full fledged DSPS starts listening on port 5290 (and 80 if HTTP handshake implemented).</p>
</section1>
<section1 topic='General Operation'>
<section2 topic='Stream Creation/Relay {optional}'>
<p><em>(optional)</em> Creating or modifying stream is done like so:</p>
<example>
<iq
id='dsps1'
type='get'
from='[email protected]/dspsclient'
to='dsps.jabber.org/0beec7b5ea3f0fdbc95d0dd47f3c5bc275da8a44'>
<query type='create'
xmlns='jabber:iq:dsps'
minthroughput='1.5KB'
maxpublic='20'>
<peer port='5290'>
dsps.myjabber.net/0beec7b5ea3f0fdbc95d0dd47f3c5bc275da8a33
</peer>
<comment>public comment</comment>
</query>
</iq>
</example>
<ul>
<li><strong>"to"</strong> with resource implies reconnection to previous relay stream with previously supplied credentials and authentication as per section "DSPS relay setup", otherwise implies creation of new stream where creator is granted "master" rights.</li>
<li><strong>"minthroughput"</strong> <em>(optional)</em> is minimum 16 second average throughput below which peers will be disconnected (but not dropped). Checked after every unit of outgoing transfer against the fourth value returned by "who" query for each peer. Legal only upon initial creation of stream. If omitted or negative, 0 is assumed.</li>
<li><strong>"maxpublic"</strong> <em>(optional)</em> is maximum number of peers that can join without invitation. If omitted or negative, 0 is assumed. If positive, DSPS generates globally unique id for public peers to acknowledge, reported within "stats" message. Said id remains constant for life of stream.</li>
<li><strong><peer/></strong> <em>(optional)</em> full JID of stream on another DSPS. Relay stream will be treated using "slave" rights. Legal only upon initial creation of stream. Multiple such blocks tried in series until successful connection. First successful (last if all failed) remembered by DSPS, all successive <peer/> ignored.. On connection, DSPS initiates handshake using peer's full JID and contents of block for destination's full JID to the relay destination as per section "Connecting to DSPS via default method". Authentication is done as per section "DSPS relay setup". Upon successful handshake, DSPS sends presence notification to peer as per section "Acknowledge of DSPS connection".</li>
<li><strong>"port"</strong> <em>(optional)</em> for connecting to destination DSPS. If omitted, default is assumed.</li>
<li><strong><comment/></strong> <em>(optional)</em> all such blocks reported in "stats" message. Multiple such blocks allowed. Block may contain a full XML stack of elements. No order implied for "stats" message.</li>
</ul>
<p>Possible failure messages:</p>
<table>
<tr><th>Code</th><th>Message</th><th>Description</th></tr>
<tr><td>405</td><td>Method Not Allowed</td><td>Attempt at reconnect to relay without existing credentials, relay still connected, <peer/> block present in reconnect request, or feature not supported</td></tr>
<tr><td>504</td><td>Gateway Timeout</td><td>All destination DSPS are unreachable.</td></tr>
</table>
</section2>
<section2 topic='Connection waiting'>
<p>DSPS creates "id" (empty string is legal), used in "who" replies and notifies client of waiting connection like so:</p>
<example>
<iq
id='dsps1'
type='result'
from='dsps.jabber.org/0beec7b5ea3f0fdbc95d0dd47f3c5bc275da8a33'
to='[email protected]/dspsclient'>
<query type='create' xmlns='jabber:iq:dsps'
wait='10'
host='dsps.jabber.org'
port='5290'
minthroughput='1.5KB'
protocol='0.5'>
<feature type='http' version='1.1'/>
<feature type='ssl' version='3.0'/>
</query>
</iq>
</example>
<ul>
<li><strong>"from"</strong> full JID of DSPS, internally globally unique. Used in handshake and every subsequent communication with stream. May differ with the one specified in "invite" message.</li>
<li><strong>"wait"</strong> amount of time in <strong>milliseconds</strong> that DSPS will wait for client to initiate handshake. If timeout occurs, DSPS will totally forget prepared connection and act accordingly.</li>
<li><strong>"host"</strong> <em>(optional)</em> for handshake and data stream. If omitted default from the "from" is assumed. Intended for P2P connections to be able to report alternate hostname or IP for connection.</li>
<li><strong>"port"</strong> <em>(optional)</em> for handshake and data stream. If omitted default is assumed.</li>
<li><strong>"minthroughput"</strong> value from "create".</li>
<li><strong>"protocol"</strong> version this DSPS supports.</li>
<li><strong><feature/></strong> <em>(optional)</em> supported by this DSPS. Type and version are properties and additional data stored in body. HTTP stream will not follow HTTP protocol. SSL handshake performed encrypted. Both HTTP and SSL connections are only between client and DSPS.</li>
</ul>
</section2>
<section2 topic='Establishing prepared connection'>
<p>Upon receipt of message as per section "Connection waiting", client can either ignore it and connection will timeout, or connect to the DSPS directly via any supported connection method or via relay. There may be a maximum of 1 (one) established connection to DSPS from any Client_full_JID + DSPS_full_JID pair, deviations are handles as per section "Connecting to DSPS via default method". DSPS will not discriminate method via which direct connection is made, even if prior to "disconnect" a different method was used. Any packet from an unauthorized connection is ignored without reporting an error.</p>
<section3 topic='DSPS relay setup {optional}'>
<p>Client may request another DSPS to relay this connection as per section "Stream Creation/Relay", utilizing the "create" body. There is no limit on length of relay chain. Upon initiation of handshake with destination, DSPS reports key like so (message sequence unrelated to current DSPS handshake):</p>
<example>
<iq
id='dsps1'
type='get'
from='dsps.jabber.org/0beec7b5ea3f0fdbc95d0dd47f3c5bc275da8a33'
to='[email protected]/dspsclient'>
<query type='create' xmlns='jabber:iq:dsps'>acDgH63I27Gb1</query>
</iq>
</example>
<ul>
<li><strong>"get"</strong> denotes request for auth key.</li>
<li><strong>"create"</strong> body contains key returned by destination.</li>
</ul>
<p>Client must send said key to destination as per section "Connecting to DSPS via default method" and send response to DSPS (which will be transmitted to destination) like so:</p>
<example>
<iq
id='dsps1'
type='result'
from='[email protected]/dspsclient'
to='dsps.jabber.org/0beec7b5ea3f0fdbc95d0dd47f3c5bc275da8a33'
<query type='create' xmlns='jabber:iq:dsps'>acDgH63I27Gb1</query>
</iq>
</example>
<ul>
<li><strong>"result"</strong> denotes reply with auth key.</li>
<li><strong>"create"</strong> body contains key returned by destination.</li>
</ul>
</section3>
<section3 topic='Connecting to DSPS via HTTP method {optional}'>
<p>Client must connect to DSPS on port 80 and initiate handshake. This may be attempted after "create" result received or "disconnect" occurred, and prior to "wait" timeout expiring, then send HTTP request like so:</p>
<example>
GET /DSPS/STREAM/ HTTP/1.0<CR>
Host: dsps.server<CR>
<CR>
</example>
<p>And will receive reply from DSPS before the start of data stream, like so:</p>
<example>
HTTP/1.0 200 OK<CR>
Content-Type: application/octet-stream<CR>
<CR>
</example>
<p>Upon completion, Client must resume DSPS handshake as per either section "Connecting to DSPS via default method" or section "Connecting to DSPS via SSL method" (if applicable). Subsequent data will not follow HTTP protocol. On error connection closed immediately with optional error messages.</p>
<p>Possible failure messages:</p>
<table>
<tr><th>Code</th><th>Message</th><th>Description</th></tr>
<tr><td>401</td><td>Unauthorized</td><td><em>(optional)</em> Returned if any error in HTTP handshake.</td></tr>
</table>
</section3>
<section3 topic='Connecting to DSPS via SSL method {optional}'>
<p>Client must connect to DSPS on specified port and initiate handshake. This may be attempted after "create" result received or "disconnect" occurred, and prior to "wait" timeout expiring, then send following on stream:</p>
<example>starttls<CR></example>
<p>Next, regular TLS handshake is initiated. Upon completion, Client must resume DSPS handshake as per section "Connecting to DSPS via default method". On error connection closed immediately with optional error messages.</p>
<p>Possible failure messages:</p>
<table>
<tr><th>Code</th><th>Message</th><th>Description</th></tr>
<tr><td>401</td><td>Unauthorized</td><td><em>(optional)</em> Returned if any error in SSL handshake.</td></tr>
</table>
</section3>
<section3 topic='Connecting to DSPS via default method'>
<p>Client must connect to DSPS on specified port and initiate handshake. May be attempted after "create" result received or "disconnect" occurred, and prior to "wait" timeout expiring. Standard and SSL handshakes are identical in decrypted state and take the form of:</p>
<example>Client_full_JID DSPS_full_JID<CR></example>
<ul>
<li><strong>"Client_full_JID"</strong> client full JID as supplied in either the "create" or "acknowledge" message.</li>
<li><strong>"DSPS_full_JID"</strong> DSPS full JID as supplied in "from" field of "create" result message from section "Connection waiting"</li>
<li><strong><CR></strong> regular carriage return, commonly referred to as the newline character.</li>
</ul>
<p>For example, the appropriate string for the above request would be:</p>
<example>[email protected]/dspsclient dsps.jabber.org/0beec7b5ea3f0fdbc95d0dd47f3c5bc275da8a33</example>
<p>If Client_full_JID and DSPS_full_JID do not have an associated stream, are no longer valid, (e.g. timeout reached or client removed from stream), or connection from said Client_full_JID + DSPS_full_JID pair is in use (i.e. client is still connected to it), connection is closed immediately with possible optional error messages reported. Otherwise DSPS returns uniquely generated key followed by a <CR> like so:</p>
<example>uGhhb74d21</example>
<p>Client must now send key to DSPS via XML stream like so:</p>
<example>
<iq
id='dsps1'
type='get'
from='[email protected]/dspsclient'
to='dsps.jabber.org/0beec7b5ea3f0fdbc95d0dd47f3c5bc275da8a33'>
<query type='auth' xmlns='jabber:iq:dsps'>uGhhb74d21</query>
</iq>
</example>
<ul>
<li><strong>"get"</strong> denotes request for next auth key.</li>
<li><strong>"auth"</strong> body contains key returned by DSPS.</li>
</ul>
<p>DSPS will now check key, if not valid, close connection, report possible optional error message and resume waiting on original key. If valid, generate new key and send to client like so:</p>
<example>
<iq
id='dsps1'
type='result'
from='dsps.jabber.org/0beec7b5ea3f0fdbc95d0dd47f3c5bc275da8a33'
to='[email protected]/dspsclient'
<query type='auth' xmlns='jabber:iq:dsps'>qgqB42Ij784</query>
</iq>
</example>
<ul>
<li><strong>"result"</strong> denotes return of next auth key.</li>
<li><strong>"auth"</strong> body contains key returned by DSPS.</li>
</ul>
<p>Client must now send received key to DSPS via the stream followed by a <CR>. Once received, DSPS checks key, on mismatch connection is closed immediately with possible optional error messages reported, waiting on key is resumed. Upon successful handshake a message is sent to members of the stream in accordance with the following rules; If the client had type "master" connection, all members of the stream get notified. If the client had type "slave" connection, only other type "master" members get notified. The message takes the form of:</p>
<example>
<iq
id='dsps2'
type='set'
from='dsps.jabber.org/0beec7b5ea3f0fdbc95d0dd47f3c5bc275da8a33'
to='[email protected]/resource'>
<query type='presence' xmlns='jabber:iq:dsps'>
<peer status='connect'>JID</peer>
</query>
</iq>
</example>
<ul>
<li><strong>"presence"</strong> denotes presence change. Body may contain multiple <peer/> blocks where same JID peers must be placed in chronological order relative to each other from start to end of message.</li>
<li><strong><peer/></strong> body is full JID of the joined peer unless peer of type "relay", in which case the resource is not reported.</li>
<li><strong>"status"</strong> is new status of peer.</li>
</ul>
<p>Possible failure messages:</p>
<table>
<tr><th>Code</th><th>Message</th><th>Description</th></tr>
<tr><td>401</td><td>Unauthorized</td><td><em>(optional)</em> Returned if the DSPS is not aware of said Client_full_JID + DSPS_full_JID pair. Where "from" contains DSPS_full_JID that was used in the handshake and "to" contains Client_full_JID that was used in the handshake.</td></tr>
<tr><td>409</td><td>Conflict</td><td><em>(optional)</em> Returned if connection from said full client JID and full DSPS JID is in use (i.e. client is still connected to it). Where "from" contains DSPS_full_JID that was used in the handshake and "to" contains Client_full_JID that was used in the handshake.</td></tr>
</table>
</section3>
</section2>
<section2 topic='Stream administration'>
<p>DSPS protocol allows multiple peers to use the same stream. Manipulation of the authorized peer list is done through admin functionality described in next several subsections. DSPS protocol allows for three types of peer connections: "master", "slave", and "relay". "master" peers get full control of the stream, "slave" peers get limited control of the stream, and "relay" are treated similar to "slave" except in reporting of JIDs where the resource must be omitted.</p>
<p>"master" peers are allowed to invite any other user to the stream and drop any peer registered with the stream, including themselves. "slave" peers are only allowed to drop themselves from the stream. Any administrative changes coming from a "slave" peer that are not for the peer's own connection are ignored. Dropping one's own connection is the preferred way of permanently disconnecting from the stream.</p>
<p>Any data received from a "master" gets copied to every other peer on the stream. Any data received from a "slave" peer gets copied to all "master" peers on the stream only.</p>
<p>Stream administration request looks like so:</p>
<example>
<iq
id='dsps3'
type='set'
from='[email protected]/dspsclient'
to='dsps.jabber.org/0beec7b5ea3f0fdbc95d0dd47f3c5bc275da8a33'>
<query type='admin' xmlns='jabber:iq:dsps' expire='20' wait='10'>
<comment>welcome to the stream</comment>
<peer type='master'>[email protected]</peer>
</query>
</iq>
</example>
<ul>
<li><strong>"admin"</strong> denotes administrative functions are to follow. Any properties within this block apply to this block alone. Multiple such blocks are allowed.</li>
<li><strong>"expire"</strong> time DSPS should wait for the "acknowledge" message from any invited peer within block. An "expire" of 0 denotes no time limit. Actual value sent to peer as "expire" is <em>minimum</em> of this value and default value preset for DSPS. If value unparseable or not present, default is used.</li>
<li><strong>"wait"</strong> time DSPS should wait for invited peer to connect to DSPS after "acknowledge" is received and message from section "Connection waiting". is sent. A "wait" of 0 denotes no time limit. Actual value sent to peer as "wait" is <em>minimum</em> of this value and default value preset for DSPS. If the value unparseable or not present, default is used.</li>
<li><strong><comment/></strong> <em>(optional)</em> block sent to each of the peers. Multiple such blocks are allowed. Block may contain a full XML stack of elements. All such blocks are sent to each of the invited peers as is. No guarantee is made on their order in the <invite/> message.</li>
<li><strong><peer/></strong> JID to execute action upon. If invitation then body will not necessarily be same full JID as one that would respond. Multiple such blocks allowed.</li>
<li><strong>"type"</strong> type of action to do. "master" denotes invitation, granting master rights. "slave" denotes invitation, granting slave rights. "drop" denotes request to drop peer from stream. "relay" peers may not be invited but may be dropped using this method.</li>
</ul>
<p>Possible optional errors include the following:</p>
<example>
<iq
id='dsps3'
type='result'
from='dsps.jabber.org/0beec7b5ea3f0fdbc95d0dd47f3c5bc275da8a33'
to='[email protected]/resource'>
<query type='admin' xmlns='jabber:iq:dsps'>
<peer acknowledge='expire'>[email protected]/net</peer>
<peer acknowledge='reject'>[email protected]/home</peer>
<peer acknowledge='timeout'>[email protected]/net</peer>
<peer acknowledge='missing'>[email protected]/winjab</peer>
</query>
</iq>
</example>
<ul>
<li><strong>"admin"</strong> denotes admin response, sent to sender of "admin" request for every peer in block. Peers may be combined from multiple "admin" requests or peers from single "admin" request may be split over multiple "admin" replies.</li>
<li><strong><peer/></strong> peer in question. For "expire" JID is one from invite request. For "reject" JID is one from which reject received. For "timeout" JID is one from invite request. For "missing" is one from drop request. After this DSPS will totally forget about this peer.</li>
<li><strong>"acknowledge"</strong> reason for failure. "expire" denotes "expire" timeout sent, has ended. "reject" denotes peer rejected invite. "timeout" denotes "wait" timeout sent, has ended. "missing" denotes peer marked for drop not found registered on tis stream.</li>
</ul>
<p>Possible failure messages:</p>
<table>
<tr><th>Code</th><th>Message</th><th>Description</th></tr>
<tr><td>403</td><td>Forbidden</td><td><em>(optional)</em> Returned if peer with "slave" rights attempts to use "master" admin privileges.</td></tr>
</table>
<section3 topic='Invitation to stream {optional}'>
<p>Upon invite DSPS will attempt to invite each of the peers like so:</p>
<example>
<iq
id='dsps4'
type='get'
from='dsps.jabber.org/0beec7b5ea3f0fdbc95d0dd47f3c5bc275da8a33'
to='[email protected]/resource'>
<query type='acknowledge'
xmlns='jabber:iq:dsps'
status='master'
expire='20'>
<peer>[email protected]/dspsclient</peer>
<comment>some long comment block or structure</comment>
</query>
</iq>
</example>
<ul>
<li><strong>"from"</strong> is unique JID/resource pair generated for this JID, not necessarily same as JID/resource pair specified in section "Connection waiting". It is used for identification of the "acknowledge" message.</li>
<li><strong>"acknowledge"</strong> denotes request for invitation acknowledge.</li>
<li><strong>"status"</strong> type of connection the client is granted. Same type as tag in invitation request.</li>
<li><strong>"expire"</strong> time DSPS will wait for the "acknowledge" message.</li>
<li><strong><peer/></strong> peer who initiated this invite. Multiple such blocks may exist if multiple distinct peers sent invitation that have not yet been received by the invitee.</li>
<li><strong><comment/></strong> is <comment/> structure(s) sent in admin request, present if admin request contained it.</li>
</ul>
</section3>
<section3 topic='Dropping from stream'>
<p>Upon drop DSPS will immediately closes the connection to the dropped peer. It then will totally forget this peer right after sending it a notification message like so:</p>
<example>
<iq
id='dsps5'
type='set'
from='dsps.jabber.org/0beec7b5ea3f0fdbc95d0dd47f3c5bc275da8a33'
to='[email protected]/resource'>
<query type='acknowledge' xmlns='jabber:iq:dsps' status='drop'>
<comment>some long comment block or structure</comment>
</query>
</iq>
</example>
<ul>
<li><strong>"from"</strong> is the DSPS JID/resource pair which DSPS has associated with this connection.</li>
<li><strong>"acknowledge"</strong> denotes drop notification. Despite the block name, this message does not require a reply.</li>
<li><strong>"status"</strong> drop denotes a connection drop.</li>
<li><strong><comment/></strong> is <comment/> structure(s) sent in admin request, preset if admin request contained it.</li>
</ul>
<p>For every successfully dropped peer a message is sent to all other stream members, following the rules stated for the "presence" message, and takes the form of:</p>
<example>
<iq
id='dsps6'
type='set'
from='dsps.jabber.org/0beec7b5ea3f0fdbc95d0dd47f3c5bc275da8a33'
to='[email protected]/resource'>
<query type='presence' xmlns='jabber:iq:dsps'>
<peer status='drop'>JID</peer>
</query>
</iq>
</example>
<ul>
<li><strong>"from"</strong> is the DSPS JID/resource pair which DSPS has associated with the connection of the recipient of the message.</li>
<li><strong>"presence"</strong> denotes presence change. Body may contain multiple <peer/> blocks where same JID peers must be placed in chronological order relative to each other from start to end of message.</li>
<li><strong><peer/></strong> body is full JID of the dropped peer registered on the stream, unless peer is of type "relay", in which case the resource is not reported.</li>
<li><strong>"status"</strong> is new status of peer.</li>
</ul>
</section3>
</section2>
<section2 topic='Invitation reply'>
<p>An invited peer has the option to accept or reject an invitation to a stream.</p>
<section3 topic='Accepting an invite'>
<p>To accept an invitation to a stream, the peer must reply like so:</p>
<example>
<iq
id='dsps4'
type='result'
from='[email protected]/moredsps'
to='dsps.jabber.org/0beec7b5ea3f0fdbc95d0dd47f3c5bc275da8a33>
<query type='acknowledge' xmlns='jabber:iq:dsps' status='connect'/>
</iq>
</example>
<ul>
<li><strong>"from"</strong> is the JID/resource pair which will be associated with this connection, only it will be allowed to connect to this stream as this user. A peer may be registered to multiple streams from the same full JID, hence all DSPS full JIDs linked to a given peer must be unique.</li>
<li><strong>"to"</strong> contains the DSPS JID/resource pair which was the source in the original "acknowledge" message.</li>
<li><strong>"acknowledge"</strong> denotes acknowledgment to invitation.</li>
<li><strong>"status"</strong> connect denotes an acceptance of invitation.</li>
</ul>
<p>Upon receipt of this reply the DSPS creates a unique resource for this client JID/resource pair. It then prepares the "create" message as described in section "Connection waiting".</p>
</section3>
<section3 topic='Rejecting an invite'>
<p>Rejecting an invitation can be done in two ways. A peer can forget about the invitation and let the invitation "expire", or preferably a message can be sent like so:</p>
<example>
<iq
id='dsps4'
type='result'
from='[email protected]/moredsps'
to='dsps.jabber.org/0beec7b5ea3f0fdbc95d0dd47f3c5bc275da8a33>
<query type='acknowledge' xmlns='jabber:iq:dsps' status='drop'/>
</iq>
</example>
<ul>
<li><strong>"to"</strong> contains the DSPS JID/resource pair which was the source in the original "acknowledge" message.</li>
<li><strong>"acknowledge"</strong> denotes acknowledgment to invitation.</li>
<li><strong>"status"</strong> drop denotes an rejection of invitation.</li>
</ul>
<p>Regardless of the way a rejection was achieved a notification message is sent to the inviting peer, as was described in section "Stream administration". If unknown "type" is sent, it will be interpreted as a reject. A maximum of one "acknowledge" is allowed during the lifetime of an invitation. If multiple such tags are sent, the first tag takes precedence. Any rejection of a public connection will be ignored.</p>
</section3>
</section2>
<section2 topic='Disconnection handling'>
<p>If a peer ever disconnects without first dropping themselves, the following policy applies:</p>
<p>The peer may reconnect within the "wait" timeout provided in the "create" reply in section "Connection waiting". The peer may choose any supported mode of reconnection supplied in "create" reply, regardless of mode previously used. The "wait" timeout is not cumulative over multiple disconnects. After reconnect, peer will not receive any data that exists on the stream while it was disconnected.</p>
<p>Upon such disconnection DSPS notifies all other members of the stream, following the rules stated for the "presence" message, and takes the form of:</p>
<example>
<iq
id='dsps7'
type='set'
from='dsps.jabber.org/0beec7b5ea3f0fdbc95d0dd47f3c5bc275da8a33'
to='[email protected]/resource'>
<query type='presence' xmlns='jabber:iq:dsps'>
<peer status='waiting'>JID</peer>
</query>
</iq>
</example>
<ul>
<li><strong>"from"</strong> is the DSPS JID/resource pair which DSPS has associated with the connection of the recipient of the message.</li>
<li><strong>"presence"</strong> denotes presence change. Body may contain multiple <peer/> blocks where same JID peers must be placed in chronological order relative to each other from start to end of message.</li>
<li><strong><peer/></strong> body is full JID of the disconnected peer registered on the stream, unless peer is of type "relay", in which case the resource is not reported.</li>
<li><strong>"status"</strong> is new status of peer.</li>
</ul>
<p>Upon reaching "wait" timeout the procedure is the same if the peer dropped its own connection.</p>
</section2>
<section2 topic='Ending a connection'>
<p>Permanent termination of connection can be done in two ways: peer may disconnect from the stream and let the "wait" timeout expire, or more preferably the peer will drop itself from the stream via an "admin" message. The "admin" is still allowed to contain multiple "peer" blocks.</p>
</section2>
<section2 topic='Stream use'>
<p>The use policy for the stream follows the standard rules described in this document. Type and structure of the data must be negotiated by the peers separately (presumably via the normal XML message stream or within <comment/> blocks). The DSPS stream operates at the speed of the slowest connection (or slower if it is so configured in its internal configuration).</p>
<p>Data read from peer in a unit of transfer (decided by DSPS) is sent to other peers in a format like so:</p>
<example>0<size><CR><id><CR><data></example>
<ul>
<li><strong>"0"</strong> at beginning for checking start of block.</li>
<li><strong><size></strong> length in bytes including id and its trailing CR in form of [1-9][0-9]*[0-9A-Z], where last character is base 36 numerical equivalent power of 1024.</li>
<li><strong><id></strong> id of the sender as per "who" query.</li>
<li><strong><data></strong> data sent.</li>
<li><strong><CR></strong> regular carriage return, commonly referred to as the newline character.</li>
</ul>
<p>For example, the appropriate string for the above block would be:</p>
<example>
0340<CR>
010<CR>
this is the data in ASCII form
</example>
<p>First block received after connection will always be full block. If discrepancy occurs, receiving peer should disconnect and reconnect back to stream.</p>
</section2>
<section2 topic='Stream information'>
<p>Two mechanisms exists to gain information about the stream configuration and its members. They are described within next few subsections.</p>
<section3 topic='Stream peer listing'>
<p>To retrieve listing of all registered peers of this stream and their respective connection status any registered peer sends a message like so:</p>
<example>
<iq
id='dsps8'
type='get'
from='[email protected]/dspsclient'
to='dsps.jabber.org/0beec7b5ea3f0fdbc95d0dd47f3c5bc275da8a33'>
<query type='who' xmlns='jabber:iq:dsps'/>
</iq>
</example>
<ul>
<li><strong>"to"</strong> has the usual meaning for this client when referring to this DSPS stream.</li>
<li><strong>"who"</strong> denotes that this is a listing request. It may not contain a body or attributes, otherwise it will be ignored without error.</li>
</ul>
<p>The query follows the standard rules: query originating from a "master" peer will return listing of all registered peers and their associated statuses, query originating from a "slave" peer will only return listing of all registered "master" peers and their associated statuses. Returned results do not have any strict order. If multiple "who" queries were requested by a peer that have not yet received a reply, only one reply need be sent.</p>
<p>The query reply is formatted like so:</p>
<example>
<iq
id='dsps8'
type='result'
from='dsps.jabber.org/0beec7b5ea3f0fdbc95d0dd47f3c5bc275da8a33'
to='[email protected]/dspsclient'>
<query type='who' xmlns='jabber:iq:dsps'>
<peer
type='master'
id='0'
status='connect'
throughput='1KB////4.8KB//3KB'>
[email protected]/dspsclient
</peer>
</query>
</iq>
</example>
<ul>
<li><strong>"from"</strong> is unique DSPS JID/resource pair for the peer receiving the result.</li>
<li><strong><peer/></strong> body is full JID of registered peer, unless peer is of type "relay", in which case the resource is not reported. A separate block exists for every viewable peer.</li>
<li><strong>"type"</strong> the type of connection peer has. May contain value of "master", "slave", or "relay".</li>
<li><strong>"id"</strong> id prepended to data coming from this peer.</li>
<li><strong>"status"</strong> current status of peer. "connect" denotes peer able to receive data. "wait" denotes peer registered but not connected. "expire" denotes peer was invited but no reply was received yet.</li>
<li><strong>"throughput"</strong> shows the average throughput to that peer per second in the units specified after the number (e.g. B, KB, MB, GB, TB, EB) in capital letters. Time is measured only during data transfer. Value contains multiple fields delimited by slash (/). Each field represents time span of power of two (2), relative to its position from start of the string. Each filled-in field contains the average throughput over that timespan. e.g. (1B per sec in last sec)/(1.1B per sec in last 2 sec)/(0.9B per sec in last 4 sec). Only fields representing power of zero (2^0 sec) and power of four (2^4 sec) are required. Last field must be filled-in.</li>
</ul>
</section3>
<section3 topic='Stream status listing'>
<p>To retrieve listing of all stream configuration/statistics values or public streams, any registered peer sends a message like so:</p>
<example>
<iq
id='dsps9'
type='get'
from='[email protected]/dspsclient'
to='dsps.jabber.org/0beec7b5ea3f0fdbc95d0dd47f3c5bc275da8a33'>
<query type='stats' xmlns='jabber:iq:dsps'/>
</iq>
</example>
<ul>
<li><strong>"to"</strong> if contains a resource, will return statistics for specified stream. Otherwise will return listing of public streams, i.e. any stream with "maxpublic" greater then 0.</li>
<li><strong>"stats"</strong> denotes that this is a configuration/statistics request. It may not contain a body or attributes, otherwise it will be ignored without error.</li>
</ul>
<p>The query reply is formatted like so:</p>
<example>
<iq
id='dsps9'
type='result'
from='dsps.jabber.org/0beec7b5ea3f0fdbc95d0dd47f3c5bc275da8a33'
to='[email protected]/dspsclient'>
<query type='stats' xmlns='jabber:iq:dsps'
init='00000000000000'
protocol='0.5'
port='5290'
minthroughput='1.5KB'
expiredefault='150'
waitdefault='100'
wait='10'
public='5'
maxpublic='25'
mastercount='20'
slavecount='40'
relaycount='0'>
<feature type='http' version='1.1'/>
<feature type='ssl' version='3.0'/>
<peer>[email protected]/8xd67f56df4f546fdgsfdg65f6g58f</peer>
<comment>some server comment</comment>
</query>
</iq>
</example>
<ul>
<li><strong>"from"</strong> the DSPS JID/resource pair for the peer receiving the result.</li>
<li><strong>"init"</strong> UNIX timestamp of the date this stream was initiated.</li>
<li><strong>"protocol"</strong> protocol version this DSPS supports.</li>
<li><strong>"port"</strong> default port this DSPS listens for connections on.</li>
<li><strong>"minthroughput"</strong> as defined in "create".</li>
<li><strong>"expiredefault"</strong> default time this DSPS will wait for an "acknowledge" response.</li>
<li><strong>"waitdefault"</strong> default time this DSPS will wait for a connection to its default port after an invitation is accepted.</li>
<li><strong>"wait"</strong> time this DSPS will wait for this particular client to reconnect if it ever gets disconnected. This is the same value as one sent in the "create" response.</li>
<li><strong>"public"</strong> number of "slave" peers registered with stream without invitation.</li>
<li><strong>"maxpublic"</strong> maximum number of "slave"peers allowed without invitation.</li>
<li><strong>"mastercount"</strong> number of peers with a "master" connection registered on this stream.</li>
<li><strong>"slavecount"</strong> number of peers with a "slave" connection registered on this stream.</li>
<li><strong>"relaycount"</strong> number of peers with a "relay" connection registered on this stream.</li>
<li><strong><feature/></strong> <em>(optional)</em> denotes a supported feature. All supported features must be listed.</li>
<li><strong><peer/></strong> <em>(optional)</em> list of public stream connections where all reported statistics match. Present only if "to" in original request contained no resource. Multiple allowed where statistics match for all.</li>
<li><strong><comment/></strong> <em>(optional)</em> parameter(s) with a comments from "create". This block may contain full XML stack of elements. Multiple such blocks are allowed.</li>
</ul>
<p>All "status" attributes are required. Any other undefined blocks with any multiplicity, are legal in this block as long as their tags are not identical to any tag within the protocol. Results returned do not have any strict order. If "to" in original request contained no resource, multiple "stats" blocks are allowed, where each contains at least one <peer/> block which has "maxpublic" greater than 0. To join a public stream a client must send message as per section "Accepting an invite".</p>
</section3>
</section2>
<section2 topic='Stream shutdown'>
<p>Stream exists from its "create"ion time to the time when there are no more "master" peers registered with the stream.</p>
<p>When last "master" peer is dropped from the stream, DSPS will make sure that all the data sent by all the "master" peers was actually copied to all the "slave" peers still present. For every remaining "slave" peer DSPS will initiate a drop event. Once stream is void of any peers it will be totally forgotten by the DSPS and all associated data is released.</p>
</section2>
<section2 topic='Error message format'>
<p>Error messages look like so:</p>
<example>
<iq
id='dsps9'
type='error'
from='dsps.jabber.org/0beec7b5ea3f0fdbc95d0dd47f3c5bc275da8a33'
to='[email protected]/dspsclient'>
<error code='405'>Method Not Allowed</error>
</iq>
</example>
<ul>
<li><strong><error/></strong> denotes error block where body is text description.</li>
<li><strong>"code"</strong> denotes error code.</li>
</ul>
</section2>
</section1>
<section1 topic='Possible applications'>
<section2 topic='File transfer'>
<p>File transfer can be easily accomplished over DSPS. Where one user invites another user to a DSPS stream. File details can be transfered in the invitation comment as such: <meta type='file' name='myfile.txt' size='500K' crc32='12345' sha1='23451' mime='application/octet-stream' timestamp='12345' date='20020412T00:00:00'/>. Where the "size" would be in bytes. All properties should reflect their appropriate values for this instance. Once the second peer has accepted, it can simply put a CR on the stream stating that transfer can begin. then the first party simply dumps the contents of file on the stream, closes the stream and "drop"s itself from the stream. DSPS will make sure the second party gets everything that the first party sent before closing the connection. If multiple recipients of the file are required, the sending client can save a lot of bandwidth and transmit only one copy if the file to the DSPS which in term will transmit the data over to all the other connected clients.</p>
</section2>
<section2 topic='VoIP'>
<p>Same idea as the file transfer. However if more then two parties are involved, every party must have a "master" connection.</p>
</section2>
<section2 topic='Multicast'>
<p>A server has a JID which it registers with a stream. Any client wishing to join the multicast sends an XML message to the server, which then invites the client with a "slave" connection. Thus everything the server sends is received by every client on the stream. If there are multiple back-up servers, they can be invited with a "master" connection, thus if one of them goes down, the others can take over.</p>
</section2>
<section2 topic='File Storage'>
<p>It has long been discussed in many Jabber places that a file storage facility is desired. The communication with such a facility can be easily accommodated with DSPS, as such a facility would merely appear as a user to DSPS which can either be "invite"ed or "invite" other users onto personal streams to transfer files as described in 6.1.</p>
</section2>
</section1>
<section1 topic='Why DSPS instead of PASS'>
<p>PASS has the following design flaws that make it unsuitable for its stated purpose of providing raw data-streams to all classes of users, including those behind firewalls or NAT.</p>
<section2 topic='Ports'>
<p>PASS requires the use of a large number of individual ports, which on a heavily loaded server can lead to the number of spare ports dropping to zero, causing connections to be refused.</p>
<p>This is also problematic if PASS is situated behind a firewall. Firewall administrators are typically loathe to allow incoming connections to a large range of ports.</p>
<p>DSPS only uses one port, and so resolves the first problem, while making the second almost a non-issue.</p>
</section2>
<section2 topic='Knowledge of IP'>
<p>PASS requires the client to have some knowledge of IP, which immediately forces the assumption that the XML stream's underlying protocol is in fact, IP. While at the time of writing this is always the case, it may not always be this way.</p>
<p>DSPS uses the Jabber ID to do its routing, and so avoids these problems. And while DSPS does use the concept of a TCP connection and an IP port, this information is never actually used anywhere on the XML stream, making the actual connection to the DSPS implementation-defined.</p>
</section2>
<section2 topic='IP Addresses'>
<p>PASS makes the IP address of the remote client available to the local client. While it is rare that this is an actual problem, many users and administrators prefer that IP address information is never actually revealed.</p>
<p>DSPS never transmits IP address information across the XML stream, and so does not have this problem.</p>
</section2>
<section2 topic='Intuitiveness'>
<p>PASS requires a client to initiate a connection by opening a (proxied) listening socket, and then soliciting connections. However, TCP works by having the client connect to a remote resource directly. This difference can make the operation of PASS difficult to understand. Also, it is left to the client to distribute the information about this listening socket, which places an additional burden on the client.</p>
<p>DSPS, while it uses listening sockets to do its work, does all the work of setting up the connection after a client initiates it. All the initiating client has to do is request a connection, connect to the DSPS, and wait - everything else is handled automatically.</p>
</section2>
<section2 topic='Scalability'>
<p>Due to the master/slave design, DSPS is already able to handle multicasts of streams or such, whilst PASS was only designed for simple p2p stream connections. This will becoming increasingly more important as more emphasis is made on streaming capabilities, for technologies such as audio and video conferencing.</p>
<p>Due to DSPS generality, the protocol can be easily used for either P2P or P2S2P needs. This eliminates the need for a separate protocol for each of the tasks.</p>
</section2>
</section1>
<section1 topic='DSPS with P2P'>
<p>It is not mandated for DSPS to reside beside a Jabber server. It is entirely possible for any client to implement a stripped down version of such a server. In such a case the only sections that are required are any error reporting, invitation acknowledgment and statistical responses. Any other area of the protocol becomes optional since the recipient peer will not have the ability to use it anyway.</p>
<p>Any client may, but is not required to utilize the striped down functionality. When utilizing such functionality the serving client sends an invitation to the recipient client to join the serving client's DSPS stream. Thus the "create" message would list the serving client as the DSPS and would utilize the "host" attribute to tell the recipient client where to connect to the DSPS.</p>
<p>This ability is advantageous since the recipient client only needs to know one protocol for data transmission over P2P or P2S2P connections, and would not see a difference between the two. The proposed method is for one side to fist try serving a connection to the other. If that fails the other side may attempt to serve the connection. If the second attempt fails the clients may utilize an external DSPS server. The negotiation of who will serve is done outside DSPS protocol. DSPS has no functionality to decide when a P2P connection is possible or desirable, nor does it have enough information to do so reliably.</p>
</section1>
</xep>