Editing XEP-0065: SOCKS5 Bytestreams

From JaWiki (Jabber/XMPP wiki)
Jump to: navigation, search

Warning: The database has been locked for maintenance, so you will not be able to save your edits right now. You may wish to copy and paste your text into a text file and save it for later.

The administrator who locked it offered this explanation: MediaWiki upgrading

The edit can be undone. Please check the comparison below to verify that this is what you want to do, and then save the changes below to finish undoing the edit.
Latest revision Your text
Line 7: Line 7:
 
Этот документ определяет [[XEP|расширение протокола XMPP]] для установление [[out-of-band|внеканального]] байтового потока между двумя произвольными [[entity|сущностями]] Jabber.
 
Этот документ определяет [[XEP|расширение протокола XMPP]] для установление [[out-of-band|внеканального]] байтового потока между двумя произвольными [[entity|сущностями]] Jabber.
  
: '''ПРИМЕЧАНИЕ:''' Настоящий протокол имеет статус "Черновик". Его реализации поощряются, и протокол подходит для развёртывания в производственных системах<!-- Implementations are encouraged and the protocol is appropriate for deployment in production systems -->, но прежде, чем он станет Окончательным Стандартом, в протоколе могут произойти некоторые изменения.
+
: '''ПРИМЕЧАНИЕ:''' Настоящий протокол является [[Draft Standard|Черновым Стандартом]] [[XMPP Standards Foundation|Организации Стандартизации XMPP]]. Его реализации поощряются, и протокол подходит для развёртывания в производственных системах<!-- Implementations are encouraged and the protocol is appropriate for deployment in production systems -->, но прежде, чем он станет [[Final Standard|Окончательным Стандартом]], в протоколе могут произойти некоторые изменения.
  
 
= Входные данные =
 
= Входные данные =
Line 16: Line 16:
 
* Номер: 0065
 
* Номер: 0065
 
* Издатель: [[XMPP Standards Foundation|Организации Стандартизации XMPP]]
 
* Издатель: [[XMPP Standards Foundation|Организации Стандартизации XMPP]]
* Статус: Черновик
+
* Статус: [[Draft Standard|Черновик]]
 
* Тип: {{fixme|Standards Track}}
 
* Тип: {{fixme|Standards Track}}
 
* Версия: 1.7
 
* Версия: 1.7
Line 22: Line 22:
 
* Утвердивший орган: [[XMPP Council|Совет XMPP]]
 
* Утвердивший орган: [[XMPP Council|Совет XMPP]]
 
* Опирается на:
 
* Опирается на:
** [[XMPP Core|Основы XMPP]],
+
** [[RFC 3920: XMPP Core|Основы XMPP]],
 
** RFC 1928: SOCKS Protocol Version 5,
 
** RFC 1928: SOCKS Protocol Version 5,
 
** RFC 3174: US Secure Hash Algorithm 1 (SHA1),
 
** RFC 3174: US Secure Hash Algorithm 1 (SHA1),
Line 58: Line 58:
 
== Отношение к XMPP ==
 
== Отношение к XMPP ==
  
[[XMPP|Расширяемый протокол передачи сообщений и информации о присутствии (XMPP)]] определён в документах [[XMPP Core|«Основы XMPP»]] (RFC 3920) и [[XMPP IM|«Обмен сообщениями в XMPP»]] (RFC 3921), внесённых [[XMPP Standards Foundation|Организацией Стандартизации XMPP]] в Процесс Стандартизации Интернета (Internet Standards Process), который управляется [[w:IETF|IETF]] в соответствии с RFC 2026. Каждый протокол, определённый в этом документе, разработан вне Процесса Стандартизации Интернета и должен рассматриваться как дополнение к XMPP, а не как развитие, продолжение самого XMPP.
+
[[XMPP|Расширяемый протокол передачи сообщений и информации о присутствии (XMPP)]] определён в документах [[RFC 3920: XMPP Core|«Основы XMPP» (RFC 3920)]] и [[RFC 3921: XMPP IM|«Обмен сообщениями в XMPP» (RFC 3921)]], внесённых [[XMPP Standards Foundation|Организацией Стандартизации XMPP]] в Процесс Стандартизации Интернета (Internet Standards Process), который управляется [[w:IETF|IETF]] в соответствии с RFC 2026. Каждый протокол, определённый в этом документе, разработан вне Процесса Стандартизации Интернета и должен рассматриваться как дополнение к XMPP, а не как развитие, продолжение самого XMPP.
  
 
== Слова соответствия ==
 
== Слова соответствия ==
Line 73: Line 73:
 
== Введение ==
 
== Введение ==
  
[[XMPP]] разработан для пересылки сравнительно малых кусков [[XML]] между [[entity|сетевыми сущностями]] (см. «[[XMPP Core|Основы XMPP]]») и не предназначен для пересылки двоичных данных. Тем не менее, иногда требуется передать двоичные данные другой сущности, найденной в сети XMPP (например, передать файл). Поэтому в сообществе Jabber многие признают, что было бы полезно иметь общий протокол для пересылки двоичных данных между двумя произвольными сущностями в сети. Основным приложением такой технологии передачи была бы [[file transfer|передача файлов]], для которой в настоящее время есть несколько несовместимых протоколов (что выливается в отсутствие совместимости). Тем не менее, возможны и другие приложения, из-за которых важно разработать общий протокол, а не ограниченный частным применением, таким, передача файлов. Этот документ определяет протокол, удовлетворяющий следующим условиям:
+
[[XMPP]] разработан для пересылки сравнительно малых кусков [[XML]] между [[entity|сетевыми сущностями]] (см. «[[RFC 3920: XMPP Core|Основы XMPP]]») и не предназначен для пересылки двоичных данных. Тем не менее, иногда требуется передать двоичные данные другой сущности, найденной в сети XMPP (например, передать файл). Поэтому в сообществе Jabber многие признают, что было бы полезно иметь общий протокол для пересылки двоичных данных между двумя произвольными сущностями в сети. Основным приложением такой технологии передачи была бы [[file transfer|передача файлов]], для которой в настоящее время есть несколько несовместимых протоколов (что выливается в отсутствие совместимости). Тем не менее, возможны и другие приложения, из-за которых важно разработать общий протокол, а не ограниченный частным применением, таким, передача файлов. Этот документ определяет протокол, удовлетворяющий следующим условиям:
 
* Байтовые потоки устанавливаются поверх стандартных соединений [[w:TCP|TCP]] (RFC 793) или [[w:UDP|UDP]] (RFC 768), причём поддержка TCP ОБЯЗАТЕЛЬНА, а поддержка UDP НЕОБЯЗАТЕЛЬНА.
 
* Байтовые потоки устанавливаются поверх стандартных соединений [[w:TCP|TCP]] (RFC 793) или [[w:UDP|UDP]] (RFC 768), причём поддержка TCP ОБЯЗАТЕЛЬНА, а поддержка UDP НЕОБЯЗАТЕЛЬНА.
 
* [[w:Сокет|Сокеты]] могут быть прямыми (peer-to-peer) или опосредованными (устанавливаемыми через передающий сервис).
 
* [[w:Сокет|Сокеты]] могут быть прямыми (peer-to-peer) или опосредованными (устанавливаемыми через передающий сервис).
 
* Где возможно, используются стандартные протоколы передачи.
 
* Где возможно, используются стандартные протоколы передачи.
  
Конкретно, данный документ предполагает, что сообщество Jabber пользуется протоколом [[w:en:SOCKS|SOCKS 5]] — технологией передачи данных, принятой [[w:IETF|IETF]] и совместимой с [[w:IPv6|IPv6]]. (Примечание: Предлагаемая технология использует подмножество протокола SOCKS 5, специально адаптированное для передачи данных в Jabber, поэтому существующие SOCKS 5 [[w:Прокси-сервер|прокси-серверы]] не могут использоваться для её реализации без соответствующей доработки.)
+
Конкретно, данный документ предполагает, что сообщество Jabber пользуется протоколом [[w:en:SOCKS|SOCKS 5]] — технологией передачи данных, принятой [[w:IETF|IETF]] и совместимой с [[w:IPv6|IPv6]]. (Примечание: Предлагаемая технология использует подмножество протокола SOCKS 5, специально адаптированное для передачи данных в Jabber, поэтому существующие SOCKS 5 [[proxy|прокси-серверы]] не могут использоваться для её реализации без соответствующей доработки.)
  
 
== Терминология ==
 
== Терминология ==
Line 121: Line 121:
 
# Инициатор и Цель могут начать пересылку данных.
 
# Инициатор и Цель могут начать пересылку данных.
  
=== Опосредованное соединение ===
+
=== Mediated Connection ===
  
Опосредованное соединение немного сложнее. В этом случае ВедущимУзлом является не Инициатор, а Посредник; это означает, что Инициатор должен узнать сетевой адрес ВедущегоУзла перед посылкой начального [[iq|запроса IQ-set]], должен согласовать соединение с ВедущимУзлом таким же образом, как и Цель, и должен запросить, чтобы ВедущийУзел активировал канал передачи прежде, чем он может быть использован. Процесс установки каналов передачи таков:
+
Mediated connection is slightly more complicated. In this situation, the StreamHost is not the Initiator but a Proxy, which means that the Initiator must discover the network address of the StreamHost before sending the initial IQ-set, must negotiate a connection with the StreamHost in the same way that the Target does, and must request that the StreamHost activate the bytestream before it can be used. The process for establishing bytestreams in this case is as follows:
  
# (Необязательный пункт) Инициатор узнаёт сетевой адрес ВедущегоУзла [[in-band|внутри канала XMPP]].
+
Optionally, Initiator discovers the network address of StreamHost in-band.
# Инициатор посылает Цели запрос IQ-set с указанием [[JID|полного JID]] и сетевого адреса ВедущегоУзла, а также <span id="SID_definition">ИдПередачи (StreamID, SID)</span> предлагаемого канала передачи.
+
# Цель открывает соединение [[w:TCP|TCP]] с выбранным ВедущимУзлом.
+
# Цель устанавливает соединение по SOCKS5 со значениями адреса приёмника (DST.ADDR) и порта приёмника (DST.PORT), определёнными ниже.
+
# ВедущийУзел посылает подтверждение успешного соединения с Целью по SOCKS5.
+
# Цель посылает Инициатору [[iq|результат IQ-result]], используя идентификатор (параметр 'id') исходного запроса IQ-set.
+
# Инициатор открывает соединение TCP с ВедущимУзлом.
+
# Инициатор устанавливает соединение по SOCKS5 со значениями адреса приёмника (DST.ADDR) и порта приёмника (DST.PORT), определёнными ниже.
+
# ВедущийУзел посылает подтверждение успешного соединения с Инициатором по SOCKS5.
+
# Инициатор посылает IQ-set ВедущемуУзлу с запросом активации ВедущимуУзлом канала передачи, связанного с ИдПередачи.
+
# ВедущийУзел активирует канал передачи. (Данные теперь перенаправляются посредником [прокси] из одного соединения SOCKS5 в другое.)
+
# ВедущийУзел посылает результат IQ-result Инициатору, подтверждающий, что канал передачи активирован (или сообщающий об ошибке).
+
# Инициатор и Цель могут начинать использовать канал передачи.
+
  
== Протокол ==
+
Initiator sends IQ-set to Target specifying the full JID and network address of StreamHost as well as the StreamID (SID) of the proposed bytestream.
  
=== Инициатор запрашивает Цель о поддержке передачи данных ===
+
Target opens a TCP socket to the selected StreamHost.
  
Перед попыткой создания канала передачи данных Инициатор может захотеть знать, поддерживает ли Цель протокол передачи. Он может сделать это, используя [[Service Discovery|обнаружение сервисов]] следующим образом:
+
Target establishes connection via SOCKS5, with the DST.ADDR and DST.PORT parameters set to the values defined below.
  
<b id="Example_1">Пример 1. Инициатор посылает Цели запрос обнаружения сервисов.</b>
+
StreamHost sends acknowledgement of successful connection to Target via SOCKS5.
<iq    type='get'
+
        from='initiator@host1/foo'
+
        to='target@host2/bar'
+
        id='hello'>
+
    <query xmlns='http''':'''//jabber.org/protocol/disco#info'/>
+
</iq>
+
  
Если Цель поддерживает передачу данных, она ДОЛЖНА указать это в ответе на запрос обнаружения сервисов.
+
Target sends IQ-result to Initiator, preserving the 'id' of the initial IQ-set.
  
<b id="Example_2">Пример 2. Цель отвечает за запрос обнаружения сервисов.</b>
+
Initiator opens a TCP socket at the StreamHost.
<iq    type='result'
+
        from='target@host2/bar'
+
        to='initiator@host1/foo'
+
        id='hello'>
+
    <query xmlns='http''':'''//jabber.org/protocol/disco#info'>
+
        <identity
+
                category='proxy'
+
                type='bytestreams'
+
                name='SOCKS5 Bytestreams Service'/>
+
        ...
+
        <feature var='http''':'''//jabber.org/protocol/bytestreams'/>
+
        ...
+
    </query>
+
</iq>
+
  
=== Инициатор запрашивает Посредников у сервера ===
+
Initiator establishes connection via SOCKS5, with the DST.ADDR and DST.PORT parameters set to the values defined below.
  
Перед попыткой создания канала передачи данных Инициатору надо найти посредника (прокси). Он может сделать это, используя [[Service Discovery|обнаружение сервисов]] следующим образом:
+
StreamHost sends acknowledgement of successful connection to Initiator via SOCKS5.
  
<b id="Example_3">Пример 3. Инициатор посылает серверу запрос [[Service Discovery|обнаружения сервисов (Service Discovery).]]</b>
+
Initiator sends IQ-set to StreamHost requesting that StreamHost activate the bytestream associated with the StreamID.
<iq    type='get'
+
        from='initiator@host1/foo'
+
        to='host1'
+
        id='server_items'>
+
    <query xmlns='http''':'''//jabber.org/protocol/disco#items'/>
+
</iq>
+
  
Сервер вернёт все известные [[JID|JIDы]] в своём списке сервисов.
+
StreamHost activates the bytestream. (Data is now relayed between the two SOCKS5 connections by the proxy.)
  
<b id="Example_4">Пример 4. Сервер отвечает на запрос обнаружения сервисов.</b>
+
StreamHost sends IQ-result to Initiator acknowledging that the bytestream has been activated (or specifying an error).
<iq    type='result'
+
        from='host1'
+
        to='initiator@host1/foo'
+
        id='server_items'>
+
    <query xmlns='http''':'''//jabber.org/protocol/disco#items'>
+
        ...
+
        <item jid='proxy.host3' name='Bytestreams Proxy'/>
+
        ...
+
    </query>
+
</iq>
+
  
=== Инициатор спрашивает посредника, является ли он посредником ===
+
Initiator and Target may begin using the bytestream.
  
Инициатор должен спросить у каждой сущности в списке, является ли она посредником для передачи данных. Он может сделать это, используя [[Service Discovery|обнаружение сервисов (Service Discovery)]] следующим образом:
+
== Protocol ==
  
<b id="Example_5">Пример 5. Инициатор посылает посреднику запрос обнаружения сервисов.</b>
+
=== Initiator Queries Target Regarding Bytestreams Support ===
<iq    type='get'
+
        from='initiator@host1/foo'
+
        to='proxy.host3'
+
        id='proxy_info'>
+
    <query xmlns='http''':'''//jabber.org/protocol/disco#info'/>
+
</iq>
+
  
Посредник вернёт сведения о себе. Инициатору СЛЕДУЕТ исследовать каждый элемент &lt;identity/&gt; и посмотреть, содержится ли в этих сведениях &lt;identity/&gt; категории "proxy" (свойство 'category') и типа "bytestreams" (свойство 'type').
+
Before attempting to initiate a bytestream, the Initiator may want to know if the Target supports the bytestream protocol. It may do so using Service Discovery [4] as follows:
  
<b id="Example_6">Пример 6. Сервер отвечает на запрос обнаружения сервисов.</b>
+
Example 1. Initiator Sends Service Discovery Request to Target
<iq     type='result'  
+
<iq type='get'  
        from='proxy.host3'  
+
    from='initiator@host1/foo'  
        to='initiator@host1/foo'  
+
    to='target@host2/bar'  
        id='proxy_info'>
+
    id='hello'>
    <query xmlns='http''':'''//jabber.org/protocol/disco#info'>
+
  <query xmlns='http://jabber.org/protocol/disco#info'/>
        ...
+
</iq>
        <identity
+
   
                category='proxy'
+
                type='bytestreams'
+
                name='SOCKS5 Bytestreams Service'/>
+
        ...
+
        <feature var='http''':'''//jabber.org/protocol/bytestreams'/>
+
        ...
+
    </query>
+
</iq>
+
  
=== Инициатор узнаёт сетевой адрес ВедущегоУзла ===
+
If the Target supports bytestreams, it MUST answer to that effect in the service discovery result.
  
Если ВедущимУзлом выступает Посредник, Инициатор сначала должен запросить полный сетевой адрес, используемый для передачи данных (очевидно, этого не требуется в случае, сли ВедущимУзлом является Инициатор). Это делается посылкой посреднику запроса [[iq|IQ-get]] в пространстве имён bytestreams как в следующем примере:
+
Example 2. Target Replies to Service Discovery Request
 +
<iq type='result'
 +
    from='target@host2/bar'
 +
    to='initiator@host1/foo'
 +
    id='hello'>
 +
  <query xmlns='http://jabber.org/protocol/disco#info'>
 +
    <identity
 +
        category='proxy'
 +
        type='bytestreams'
 +
        name='SOCKS5 Bytestreams Service'/>
 +
    ...
 +
    <feature var='http://jabber.org/protocol/bytestreams'/>
 +
    ...
 +
  </query>
 +
</iq>
 +
   
 +
=== Initiator Queries Server For Proxies ===
  
<b id="Example_7">Пример 7. Инициатор запрашивает у Посредника сетевой адрес.</b>
+
Before attempting to initiate a bytestream, the Initiator needs to find a proxy. It may do so using Service Discovery as follows:
<iq    type='get'
+
        from='initiator@host1/foo'
+
        to='proxy.host3'
+
        id='discover'>
+
    <query xmlns='http''':'''//jabber.org/protocol/bytestreams'/>
+
</iq>
+
  
Элемент <streamhost/>, указывающий сетевой адрес, ДОЛЖЕН иметь следующие атрибуты:
+
Example 3. Initiator Sends Service Discovery Request to Server
* '''jid''' = [[JID]] ВедущегоУзла для соединения через [[Jabber]]
+
<iq type='get'
Дополнительно, элемент <streamhost/> ДОЛЖЕН включать:
+
    from='initiator@host1/foo'
 +
    to='host1'  
 +
    id='server_items'>
 +
  <query xmlns='http://jabber.org/protocol/disco#items'/>
 +
</iq>
 +
   
  
ЛИБО
+
The server will return all of the known JIDs in its disco list.
* '''host''' = [[w:en:Hostname|сетевое имя]] или [[w:IP-адрес|IP-адрес]] ВедущегоУзла для SOCKS5-соединения через TCP
+
* '''port''' = порт, связанный с сетевым именем или IP-адресом, для SOCKS5-соединения через TCP
+
ЛИБО
+
* '''zeroconf''' = идентификатор [[w:Zeroconf|zeroconf]], к которому может подключиться сущность, для которой идентификатору службы и названию протокола СЛЕДУЕТ быть <tt>"_jabber.bytestreams"</tt>.
+
  
<b id="Example_8">Пример 8. Посредник сообщает Инициатору сетевой адрес.</b>
+
Example 4. Server Replies to Service Discovery Request
<iq     type='result'  
+
<iq type='result'  
        from='proxy.host3'  
+
    from='host1'  
        to='initiator@host1/foo'  
+
    to='initiator@host1/foo'  
        id='discover'>
+
    id='server_items'>
    <query xmlns='http''':'''//jabber.org/protocol/bytestreams'>
+
  <query xmlns='http://jabber.org/protocol/disco#items'>
        <streamhost
+
    ...
                jid='proxy.host3'  
+
    <item jid='proxy.host3' name='Bytestreams Proxy'/>
                host='24.24.24.1'
+
    ...
                zeroconf='_jabber.bytestreams'/>
+
  </query>
    </query>
+
</iq>
</iq>
+
   
 +
=== Initiator Queries Proxy to Find Out if it is a Proxy ===
  
Если у Инициатора нет права инициировать передачу данных на Посреднике по любой причине (например, реализация посредника может позволять администраторам запрещать JIDам или доменам использование Посредника), Посредник ДОЛЖЕН вернуть ошибку <tt><forbidden/></tt> («запрещено») Инициатору (за информацией о синтаксисе ошибок обращайтесь к {{xep|0086|Error Condition Mappings}}):
+
For each item in the disco#items result, the Initiator must query to determine if it is a bytestreams proxy. It may do so using Service Discovery as follows:
  
<b id="Example_9">Пример 9. Посредник возвращает Иициатору ошибку.</b>
+
Example 5. Initiator Sends Service Discovery Request to Proxy
<iq     type='error'  
+
<iq type='get'  
        from='initiator@host1/foo'  
+
    from='initiator@host1/foo'
        to='proxy.host3'  
+
    to='proxy.host3'  
        id='discover'>
+
    id='proxy_info'>
    <query xmlns='http''':'''//jabber.org/protocol/bytestreams'/>
+
  <query xmlns='http://jabber.org/protocol/disco#info'/>
        <error code='403' type='auth'>
+
</iq>
        <forbidden xmlns='urn:ietf:params:xml:ns:xmpp-stanzas'/>
+
   
    </error>
+
</iq>
+
  
Если Посредник не может выступать в качестве ВедущегоУзла, ему СЛЕДУЕТ вернуть Инициатору ошибку <tt><not-allowed/></tt> («не разрешено»):
+
The proxy will return its information. The Initiator SHOULD inspect each identity to see if it contains an identity of category "proxy" and type "bytestreams".
  
<b id="Example_10">Пример 10. Посредник возвращает Инициатору ошибку.</b>
+
Example 6. Server Replies to Service Discovery Request
<iq     type='error'  
+
<iq type='result'  
        from='initiator@host1/foo'  
+
    from='proxy.host3'
        to='proxy.host3'
+
    to='initiator@host1/foo'  
        id='discover'>
+
    id='proxy_info'>
    <query xmlns='http''':'''//jabber.org/protocol/bytestreams'/>
+
  <query xmlns='http://jabber.org/protocol/disco#info'>
        <error code='405' type='cancel'>
+
    ...
        <not-allowed xmlns='urn:ietf:params:xml:ns:xmpp-stanzas'/>
+
    <identity category='proxy'
    </error>
+
              type='bytestreams'
</iq>
+
              name='SOCKS5 Bytestreams Service'/>
 +
    ...
 +
    <feature var='http://jabber.org/protocol/bytestreams'/>
 +
    ...
 +
  </query>
 +
</iq>
 +
   
 +
=== Initiator Discovers Network Address of StreamHost ===
  
=== Инициатор сообщает Цели о ВедущихУзлах ===
+
If the StreamHost is a Proxy, the Initiator must first request the full network address used for bytestreaming (obviously this is not required if the StreamHost is the Initiator). This is done by sending an IQ-get to the proxy in the bytestreams namespace, as follows:
  
Чтобы организовать передачу данных между Инициатором и Целью, Инициатор должен предоставить Цели сведения о сетевом адресе ВедущегоУзла (или узлов). Это совершается [[in-band|внутри канала]] с помощью одного набора [[iq|IQ-set]], который должен содержать следующие сведения:
+
Example 7. Initiator Requests Network Address from Proxy
 +
<iq type='get'
 +
    from='initiator@host1/foo'
 +
    to='proxy.host3'
 +
    id='discover'>
 +
  <query xmlns='http://jabber.org/protocol/bytestreams'/>
 +
</iq>
 +
   
  
* Сетевой адрес по меньшей мере одного ВедущегоУзла, к которому может попытаться подключиться Цель.
+
The <streamhost/> element specifying a network address MUST possess the following attributes:
* ИдПередачи для этого соединения.
+
jid = the JID of the StreamHost for communications over Jabber
* Использующийся режим (mode), обычно "tcp", но при определённых условиях может быть "udp" (см. {{fixme|[[#Optional UDP Support]]}}).
+
  
Формат протокола показан ниже.
+
In addition, the <streamhost/> element MUST include:
  
<b id="Example_11">Пример 11. Начало взаимодействия.</b>
+
EITHER
<iq    type='set'
+
host = the hostname or IP address of the StreamHost for SOCKS5 communications over TCP
        from='initiator@host1/foo'
+
port = a port associated with the hostname or IP address for SOCKS5 communications over TCP
        to='target@host2/bar'
+
        id='initiate'>
+
    <query  xmlns='http''':'''//jabber.org/protocol/bytestreams'
+
            sid='mySID'
+
            mode='tcp'>
+
        <streamhost
+
                jid='initiator@host1/foo'
+
                host='192.168.4.1'
+
                port='5086'/>
+
        <streamhost
+
                jid='proxy.host3'
+
                host='24.24.24.1'
+
                zeroconf='_jabber.bytestreams'/>
+
    </query>
+
</iq>
+
  
Если Цель не желает принимать передачу, она ДОЛЖНА вернуть Инициатору ошибку <not-acceptable/> («не принято»).
+
OR
 +
zeroconf = a zeroconf [5] identifier to which an entity may connect, for which the service identifier and protocol name SHOULD be "_jabber.bytestreams".
  
<b id="Example_12">Пример 12. Цель отклоняет передачу.</b>
+
Example 8. Proxy Informs Initiator of Network Address
<iq     type='error'
+
<iq type='result'  
        from='target@host2/bar'
+
    from='proxy.host3'  
        to='initiator@host1/foo'
+
    to='initiator@host1/foo'  
        id='initiate'>
+
    id='discover'>
    <error code='406' type='auth'>
+
  <query xmlns='http://jabber.org/protocol/bytestreams'>
        <not-acceptable xmlns='urn:ietf:params:xml:ns:xmpp-stanzas'/>
+
    <streamhost
    </error>
+
        jid='proxy.host3'  
</iq>
+
        host='24.24.24.1'
 +
        zeroconf='_jabber.bytestreams'/>
 +
  </query>
 +
</iq>
 +
   
  
=== Цель устанавливает соединение SOCKS5 с ВедущимУзлом ===
+
If the Initiator does not have permissions to initiate bytestreams on the Proxy for whatever reason (e.g., a proxy implementation may enable administrators to ban JIDs or domains from using the Proxy), the Proxy MUST return a <forbidden/> error to the Initiator (for information about error syntax, refer to Error Condition Mappings [6]):
  
Если Цель согласна принять поток данных, она ДОЛЖНА попытаться открыть стандартный сокет TCP на сетевом интерфейсе ВедущегоУзла, соединённого с Инициатором. Если Инициатором было предложено несколько ВедущихУзлов, Цели СЛЕДУЕТ попытаться соединиться с ними в том порядке, в котором они указаны.
+
Example 9. Proxy Returns Error to Initiator
 +
<iq type='error'
 +
    from='initiator@host1/foo'
 +
    to='proxy.host3'
 +
    id='discover'>
 +
  <query xmlns='http://jabber.org/protocol/bytestreams'/>
 +
  <error code='403' type='auth'>
 +
    <forbidden xmlns='urn:ietf:params:xml:ns:xmpp-stanzas'/>
 +
  </error>
 +
</iq>
 +
   
  
Если Цель пытается, но не может соединиться ни с каким из ВедущихУзлов и не желает пытаться установить соединение со своей стороны {{todo|сомневаюсь в правильности перевода: it does not wish to attempt a connection from its side}}, она ДОЛЖНА вернуть Инициатору ошибку <tt>&lt;item-not-found/&gt;</tt> («элемент не найдён»).
+
If the Proxy is unable to act as a StreamHost, the Proxy SHOULD return a <not-allowed/> error to the Initiator:
  
<b id="Example_13">Пример 13. Цель не может соединиться ни с каким из ВедущихУзлов и желает завершить транзакцию.</b>
+
Example 10. Proxy Returns Error to Initiator
<iq     type='error'  
+
<iq type='error'  
        from='target@host2/bar'  
+
    from='initiator@host1/foo'  
        to='initiator@host1/foo'  
+
    to='proxy.host3'  
        id='initiate'>
+
    id='discover'>
    <error code='404' type='cancel'>
+
  <query xmlns='http://jabber.org/protocol/bytestreams'/>
        <item-not-found xmlns='urn:ietf:params:xml:ns:xmpp-stanzas'/>
+
  <error code='405' type='cancel'>
    </error>
+
    <not-allowed xmlns='urn:ietf:params:xml:ns:xmpp-stanzas'/>
</iq>
+
  </error>
 +
</iq>
 +
   
 +
=== Initiator Informs Target of StreamHosts ===
  
Если Цель может открыть сокет TCP на ВедущемУзле, она ДОЛЖНА использовать протокол SOCKS5, описанный в RFC 1982 для установления соединения с ВедущимУзлом. В соответствии с RFC по SOCKS5, у Цели МОЖЕТ быть затребован пароль для доступа к прокси-серверу. Тем не менее, всё, что касается аутентификации, находится за пределами этого документа.
+
In order to establish a bytestream between the Initiator and the Target, the Initiator must provide network address information for the StreamHost(s) to the Target. This happens in-band via a single IQ-set, which must contain the following information:
 +
The network address of at least one StreamHost to which the Target may attempt to connect
 +
The Stream ID for this connection
 +
The "mode" to use, normally "tcp" but optionally "udp" (see the Optional UDP Support section of this document)
  
Когда Цель будет успешно аутентифицирована на Посреднике (даже анонимно), ей СЛЕДУЕТ послать запрос CONNECT соответствующему узлу, чтобы продолжить процесс установления соединения. При этом применяются следующие правила:
+
The protocol format is shown below.
  
# Имя узла (hostname) должно быть SHA1(ИдПередачи + JID Инициатора + JID Цели), где [[w:Хэширование|хэш-функция]] [[w:SHA-1|SHA-1]] определена согласно RFC 3174 и её выход записывается в [[w:Шестнадцатеричная система счисления|шестнадцатеричной системе счисления]] (не двоичным кодом).
+
Example 11. Initiation of Interaction
# Порт (port) ДОЛЖЕН быть 0 (ноль).
+
<iq type='set'
# Указанные Jabber-идентификаторы ДОЛЖНЫ быть идентификаторами, использующимися для обмена IQ-стансами, которые могут быть полными JID (<tt>node@domain.tld/resource</tt>) или голыми JID (<tt>node@domain.tld</tt>).
+
    from='initiator@host1/foo'
# Перед применением алгоритма хэширования SHA-1 к Jabber-идентификаторам ДОЛЖНЫ быть применены соответствующие профили [[stringprep]] (как указано в «[[Основы XMPP|Основах XMPP]]»).
+
    to='target@host2/bar'
 +
    id='initiate'>
 +
  <query xmlns='http://jabber.org/protocol/bytestreams'
 +
        sid='mySID'
 +
mode='tcp'>
 +
    <streamhost
 +
        jid='initiator@host1/foo'
 +
        host='192.168.4.1'
 +
        port='5086'/>
 +
    <streamhost
 +
        jid='proxy.host3'
 +
        host='24.24.24.1'
 +
        zeroconf='_jabber.bytestreams'/>
 +
  </query>
 +
</iq>
 +
   
  
<b id="Example_14">Пример 14. Цель соединяется с ВедущимУзлом</b>
+
If the Target is unwilling to accept the bytestream, it MUST return a <not-acceptable/> error to the Initiator.
CMD = X'01'
+
ATYP = X'03'
+
DST.ADDR = SHA1 Hash of: (SID + Initiator JID + Target JID)
+
DST.PORT = 0
+
  
<b id="Example_14">Пример 15. ВедущийУзел принимает соединение</b>
+
Example 12. Target Refuses Bytestream
STATUS = X'00'
+
<iq type='error'
 +
    from='target@host2/bar'
 +
    to='initiator@host1/foo'
 +
    id='initiate'>
 +
  <error code='406' type='auth'>
 +
    <not-acceptable xmlns='urn:ietf:params:xml:ns:xmpp-stanzas'/>
 +
  </error>
 +
</iq>
 +
   
 +
=== Target Establishes SOCKS5 Connection with StreamHost ===
  
При ответе клиенту, в соответствии с разделом 6 RFC 1928, ВедущемуУзлу СЛЕДУЕТ выставить параметры BND.ADDR и BND.PORT в значения, предоставленные клиентом в запросе соединения.
+
If the Target is willing to accept the bytestream, it MUST attempt to open a standard TCP socket on the network address of the StreamHost communicated by the Initiator. If the Initiator provides more than one StreamHost, the Target SHOULD try to connect to them in the order they occur.
  
=== Цель подтверждает соединение SOCKS5 ===
+
If the Target tries but is unable to connect to any of the StreamHosts and it does not wish to attempt a connection from its side, it MUST return a <item-not-found/> error to the Initiator.
  
После того как Цель будет аутентифицирована ВедущимУзлом, она ДОЛЖНА послать Инициатору IQ-результат, сообщающий о том, какой ВедущийУзел она использует.
+
Example 13. Target Is Unable to Connect to Any StreamHost and Wishes to End Transaction
 +
<iq type='error'
 +
    from='target@host2/bar'
 +
    to='initiator@host1/foo'
 +
    id='initiate'>
 +
  <error code='404' type='cancel'>
 +
    <item-not-found xmlns='urn:ietf:params:xml:ns:xmpp-stanzas'/>
 +
  </error>
 +
</iq>
 +
   
  
<b id="Example_16">Пример 16. Цель уведомляет Инициатора о соединении.</b>
+
If the Target is able to open a TCP socket on a StreamHost, it MUST utilize the SOCKS5 protocol specified in RFC 1928 [7] to establish the connection with the StreamHost. In accordance with the SOCKS5 RFC, the Target MAY have to authenticate in order to use the proxy. However, any authentication required is beyond the scope of this document.
<iq    type='result'
+
        from='target@host2/bar'
+
        to='initiator@host1/foo'
+
        id='initiate'>
+
    <query xmlns='http''':'''//jabber.org/protocol/bytestreams'>
+
        <streamhost-used jid='proxy.host3'/>
+
    </query>
+
</iq>
+
  
Здесь Инициатор узнаёт, какой ВедущийУзел использует Цель.
+
Once the Target has successfully authenticated with the Proxy (even anonymously), it SHOULD send a CONNECT request to the appropriate host in order to continue the negotiation. The following rules apply:
 +
The hostname MUST be SHA1(SID + Initiator JID + Target JID) where the definition of the SHA1 hashing algorithm is as specified by RFC 3174 [8] and the output is hexadecimal-encoded (not binary).
 +
The port MUST be 0 (zero).
 +
The JIDs provided MUST be the JIDs used for the IQ exchange, which MAY be full JIDs (<node@domain.tld/resource>) or bare JIDs (<node@domain.tld>).
 +
The appropriate stringprep profiles (as specified in XMPP Core [9]) MUST be applied to the JIDs before application of the SHA1 hashing algorithm.
  
=== Инициатор устанавливает соединение SOCKS5 с ВедущимУзлом ===
+
Example 14. Target Connects to StreamHost
 +
CMD = X'01'
 +
ATYP = X'03'
 +
DST.ADDR = SHA1 Hash of: (SID + Initiator JID + Target JID)
 +
DST.PORT = 0
 +
   
  
Если ВедущийУзел использует Посредника, Инициатор ДОЛЖЕН аутентифицировать и установить соединение с ВедущимУзлом перед запросом активации потока передачи данных. Инициатор установит соединение с прокси-сервером SOCKS5 тем же способом, что и Цель (указывая те же значения в запросе CONNECT), как показано в следущих примерах.
+
Example 15. StreamHost Acknowledges Connection
 +
STATUS = X'00'
 +
   
  
 +
When replying to the client in accordance with Section 6 of RFC 1928, the StreamHost SHOULD set the BND.ADDR and BND.PORT to the values provided by the client in the connection request.
  
<b id="Example_17">Пример 17. Инициатор соединяется с ВедущимУзлом.</b>
+
=== Target Acknowledges SOCKS5 Connection ===
CMD = X'01'
+
ATYP = X'03'
+
DST.ADDR = SHA1 Hash of: (SID + Initiator JID + Target JID)
+
DST.PORT = 0
+
  
 +
After the Target has authenticated with the StreamHost, it MUST send an IQ-result to the Initiator indicating which StreamHost was used.
  
<b id="Example_18">Пример 18. ВедущийУзел принимает соединение Инициатора.</b>
+
Example 16. Target Notifies Initiator of Connection
STATUS = X'00'
+
<iq type='result'
 +
    from='target@host2/bar'
 +
    to='initiator@host1/foo'
 +
    id='initiate'>
 +
  <query xmlns='http://jabber.org/protocol/bytestreams'>
 +
    <streamhost-used jid='proxy.host3'/>
 +
  </query>
 +
</iq>
 +
   
  
 +
At this point, the Initiator knows which StreamHost was used by the Target.
 +
 +
=== Initiator Establishes SOCKS5 Connection with StreamHost ===
 +
 +
If the StreamHost used is a Proxy, the Initiator MUST authenticate and establish a connection with the StreamHost before requesting that the StreamHost activate bytestream. The Initiator will establish a connection to the SOCKS5 proxy in the same way the Target did (passing the same value for the CONNECT request), as shown in the following examples.
 +
 +
Example 17. Initiator Connects to StreamHost
 +
CMD = X'01'
 +
ATYP = X'03'
 +
DST.ADDR = SHA1 Hash of: (SID + Initiator JID + Target JID)
 +
DST.PORT = 0
 +
   
 +
 +
Example 18. StreamHost Acknowledges Connection to Initiator
 +
STATUS = X'00'
 +
   
 
=== Activation of Bytestream ===
 
=== Activation of Bytestream ===
  
Line 427: Line 448:
 
<not-allowed/> error if only one party (either Initiator or Recipient, but not both) is connected to the Proxy
 
<not-allowed/> error if only one party (either Initiator or Recipient, but not both) is connected to the Proxy
 
<internal-server-error/> error if the proxy cannot activate the bytestream because of some internal malfunction
 
<internal-server-error/> error if the proxy cannot activate the bytestream because of some internal malfunction
 
 
== Formal Use Case ==
 
== Formal Use Case ==
  

Please note that all contributions to JaWiki (Jabber/XMPP wiki) may be edited, altered, or removed by other contributors. If you do not want your writing to be edited mercilessly, then do not submit it here.
You are also promising us that you wrote this yourself, or copied it from a public domain or similar free resource (see JaWiki (Jabber/XMPP wiki):Copyrights for details). Do not submit copyrighted work without permission!

Cancel | Editing help (opens in new window)