Jabberd/XMPP 学习之九:服务器-服务器示例

以下示例展示一个服务器和对端服务器协商XML流,交换XML节, 和关闭已协商的流的数据流. 初始化服务器("Server1")是im.example.com; 接收服务器("Server2")是example.net 并且要求使用TLS; im.example.com递交一个证书并通过SASL EXTERNAL机制验证. 假定在发送初始化流头之前, Server1已经解析了一个SRV记录_xmpp-server._tcp.example.net并且已经打开了一个TCP连接到已解析的IP地址的声明的端口上. 注意Server1怎样声明内容命名空间"jabber:server"作为缺省的命名空间并为流相关的元素使用前缀, 反之Server2使用免前缀标准.

TLS

第一步: Server1初始化流到Server2:

S1: <stream:stream
      from='im.example.com'
      to='example.net'
      version='1.0'
      xmlns='jabber:server'
      xmlns:stream='http://etherx.jabber.org/streams'>

第二步: Server2发送一个应答流头到Server1来应答:

S2: <stream
      from='example.net'
      id='hTiXkW+ih9k2SqdGkk/AZi0OJ/Q='
      to='im.example.com'
      version='1.0'
      xmlns='http://etherx.jabber.org/streams'>

第三步: Server2发送流特性给Server1(在这个点上只有STARTTLS扩展, 它是强制协商的):

S2: <features xmlns='http://etherx.jabber.org/streams'>
      <starttls xmlns='urn:ietf:params:xml:ns:xmpp-tls'>
        <required/>
      </starttls>
    </features>

第四步: Server1发送STARTTLS指令给Server2:

S1: <starttls xmlns='urn:ietf:params:xml:ns:xmpp-tls'/>

第五步: Server2通知Server1它被允许继续:

S2: <proceed xmlns='urn:ietf:params:xml:ns:xmpp-tls'/>

第五步(替代): Server2通知Server1 STARTTLS协商失败了, 关闭流, 并中止TCP连接(于是, 流协商过程以不成功结束并且双方不再进行下一步):

S2: <failure xmlns='urn:ietf:params:xml:ns:xmpp-tls'/>
    </stream>

第六步: Server1和Server2尝试通过TCP完成TLS协商(详见TLS).

第七步: 如果TLS协商成功了, Server1在受TLS保护的TCP连接上初始化一个新流到Server2:

S1: <stream:stream
      from='im.example.com'
      to='example.net'
      version='1.0'
      xmlns='jabber:server'
      xmlns:stream='http://etherx.jabber.org/streams'>

第七步(替代): 如果TLS协商不成功, Server2关闭TCP连接(所以, 流协商过程以不成功结束并且双方不再进行下一步).

SASL

第八步: Server2发送一个应答流头给Server1并带上可用的流特性(包括优先的SASL EXTERNAL机制):

S2: <stream
      from='example.net'
      id='RChdjlgj/TIBcbT9Keu31zDihH4='
      to='im.example.com'
      version='1.0'
      xmlns='http://etherx.jabber.org/streams'>
 
S2: <features xmlns='http://etherx.jabber.org/streams'>
      <mechanisms xmlns='urn:ietf:params:xml:ns:xmpp-sasl'>
        <mechanism>EXTERNAL</mechanism>
      </mechanisms>
    </features>

第九步: Server1选择EXTERNAL机制(包含一个"="的空应答):

S1: <auth xmlns='urn:ietf:params:xml:ns:xmpp-sasl'
          mechanism='EXTERNAL'>=</auth>

第十步: Server2返回成功:

S2: <success xmlns='urn:ietf:params:xml:ns:xmpp-sasl'/>

第十步(替代): Server2通知Server1验证失败了(所以, 流协商过程以不成功结束并且双方不再进行下一步):

S2: <failure xmlns='urn:ietf:params:xml:ns:xmpp-sasl'>
      <not-authorized/>
    </failure>
    </stream>

第十一步: Server1初始化一个新流到Server2:

S1: <stream:stream
      from='im.example.com'
      to='example.net'
      version='1.0'
      xmlns='jabber:server'
      xmlns:stream='http://etherx.jabber.org/streams'>

第十二步: Server2发送一个流头给并带上任何附加的特性(或, 在这个例子中, 一个空的特性元素)来应答:

S2: <stream
      from='example.net'
      id='MbbV2FeojySpUIP6J91qaa+TWHM='
      to='im.example.com'
      version='1.0'
      xmlns='http://etherx.jabber.org/streams'>
 
S2: <features xmlns='http://etherx.jabber.org/streams'/>
节交换

现在Server1被允许通过已协商的从im.example.com到example.net的流发送XML节给Server2; 这里我们假定被传输的节就是前面演示的那些客户端-服务器通讯的节, 尽管是在一个服务器-服务器由'jabber:server'命名空间限定的流上.

Server1发送XML节给Server2:

S1: <message from='juliet@im.example.com/balcony'
             id='ju2ba41c'
             to='romeo@example.net'
             type='chat'
             xml:lang='en'>
    <body>Art thou not Romeo, and a Montague?</body>
   </message>
关闭

想不再发送更多消息, Server1关闭它到Server2的流但是等待从Server2的入站数据. (实践中, 流大部分时候保持打开一段时间, 因为Server1和Server2不是立刻知道流是否需要更多通讯.)

S1: </stream:stream>

和建议的流关闭握手一致, Server2同样关闭流:

S2: </stream>

Server1现在发送一个TLS close_notify警告, 从Server2接收一个close_notify警告应答, 然后中止当前的TCP连接.

转载:http://wiki.jabbercn.org/RFC6120

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值