powered by Jive Software

Smack 4.4. FaultToleranceNegotiator for Sock5ByteStream file transfer with IBB fall-back implementation error


#1

aTalk has implemented Sock5ByteStream file transfer; but would like to have IBB fall-back on failure.
Base on the Smack 4.4.0-alpha2-SNAPSHOT implementation (see captured log), it is found that smack actually auto start the IBB Initiation request protocol when it detects Sock5ByteStream failure.

Not sure if there is an option to set at the start of the file transfer negotiation to get smack to handle everything i.e. fall-back to IBB on failure to continue receive the file. Otherwise, what are the proper steps require to get aTalk to accept IBB Initiation request to continue receive the file. Any help is much appreciated.

2018-12-07 17:14:13.742 15557-16149/org.atalk.android D/SMACK: RECV (0): <iq xml:lang='en' to='swordfish@atalk.org/atalk' from='leopard@atalk.org/atalk' type='set' id='2fuCV-190'><si xmlns='http://jabber.org/protocol/si' id='jsi_509263050' mime-type='image/png' profile='http://jabber.org/protocol/si/profile/file-transfer'><file xmlns='http://jabber.org/protocol/si/profile/file-transfer' name='586431100-1.png' size='39315'><thumbnail xmlns='urn:xmpp:thumbs:0' cid='sha1+7b6f3cd32d439be60af27841c2890b4395aca994@atalk.org' mime-type='image/png' width='64' height='64'/></file><feature xmlns='http://jabber.org/protocol/feature-neg'><x xmlns='jabber:x:data' type='form'><field var='stream-method' type='list-single'><option><value>http://jabber.org/protocol/bytestreams</value></option><option><value>http://jabber.org/protocol/ibb</value></option></field></x></feature></si></iq>
2018-12-07 17:14:15.095 15557-16148/org.atalk.android D/SMACK: SENT (0): <iq to='leopard@atalk.org/atalk' id='2fuCV-190' type='result'><si xmlns='http://jabber.org/protocol/si'><feature xmlns="http://jabber.org/protocol/feature-neg"><x xmlns='jabber:x:data' type='submit'><field var='stream-method'><value>http://jabber.org/protocol/bytestreams</value><value>http://jabber.org/protocol/ibb</value></field></x></feature></si></iq>
2018-12-07 17:14:15.250 15557-16149/org.atalk.android D/SMACK: RECV (0): <iq xml:lang='en' to='swordfish@atalk.org/atalk' from='leopard@atalk.org/atalk' type='set' id='2fuCV-195'><query xmlns='http://jabber.org/protocol/bytestreams' sid='jsi_509263050' mode='tcp'><streamhost jid='leopard@atalk.org/atalk' host='fe80::f025:b7ff:fe9c:3c5%p2p0' port='7777'/><streamhost jid='leopard@atalk.org/atalk' host='fe80::f225:b7ff:fe9c:3c5%wlan0' port='7777'/><streamhost jid='leopard@atalk.org/atalk' host='192.168.1.12' port='7777'/></query></iq>
2018-12-07 17:14:18.616 15557-16148/org.atalk.android D/SMACK: SENT (0): <iq to='leopard@atalk.org/atalk' id='2fuCV-195' type='error'><error type='cancel'><item-not-found xmlns='urn:ietf:params:xml:ns:xmpp-stanzas'/><text xml:lang='en'>Could not establish socket with any provided host</text></error></iq>
2018-12-07 17:14:18.634 15557-17528/org.atalk.android E/aTalk: [3669] impl.protocol.jabber.OperationSetFileTransferJabberImpl.run().492 An exception occurred while transferring file: 
     org.jivesoftware.smack.XMPPException$XMPPErrorException: XMPPError: item-not-found - cancel
         at org.jivesoftware.smackx.bytestreams.socks5.Socks5BytestreamRequest.cancelRequest(Socks5BytestreamRequest.java:289)
         at org.jivesoftware.smackx.bytestreams.socks5.Socks5BytestreamRequest.accept(Socks5BytestreamRequest.java:255)
         at org.jivesoftware.smackx.filetransfer.Socks5TransferNegotiator.negotiateIncomingStream(Socks5TransferNegotiator.java:102)
         at org.jivesoftware.smackx.filetransfer.FaultTolerantNegotiator.createIncomingStream(FaultTolerantNegotiator.java:72)
         at org.jivesoftware.smackx.filetransfer.IncomingFileTransfer$2.call(IncomingFileTransfer.java:179)
         at org.jivesoftware.smackx.filetransfer.IncomingFileTransfer$2.call(IncomingFileTransfer.java:174)
         at java.util.concurrent.FutureTask.run(FutureTask.java:266)
         at org.jivesoftware.smackx.filetransfer.IncomingFileTransfer.negotiateStream(IncomingFileTransfer.java:182)
         at org.jivesoftware.smackx.filetransfer.IncomingFileTransfer.access$100(IncomingFileTransfer.java:58)
         at org.jivesoftware.smackx.filetransfer.IncomingFileTransfer$1.run(IncomingFileTransfer.java:132)
         at java.lang.Thread.run(Thread.java:764)
 2018-12-07 17:14:18.824 15557-16149/org.atalk.android D/SMACK: RECV (0): <iq xml:lang='en' to='swordfish@atalk.org/atalk' from='leopard@atalk.org/atalk' type='set' id='2fuCV-197'><open xmlns='http://jabber.org/protocol/ibb' block-size='4096' sid='jsi_509263050' stanza='iq'/></iq>

#2

After more investigation, Smack 4.4 actually implements FaultToleranceNegotiator to support IBB fallback in the event Socks5ByteStream failed due to negotiation error i.e.

<item-not-found xmlns='urn:ietf:params:xml:ns:xmpp-stanzas'/><text xml:lang='en'>Could not establish socket with any provided host</text></error></iq>

Under this fault condition, the sender negotiator actually re-initializes with IBB negotiation. However during the Socks5Bytestream negotiation process, it blocks the IBBStreamNegotiation with the following call and the ignoredBytestreamRequests is not clear upon the above fault condition i.e.

    @Override
    public void newStreamInitiation(final Jid from, String streamID) {
        /*
         * this method is always called prior to #negotiateIncomingStream() so the SOCKS5
         * InitiationListener must ignore the next SOCKS5 Bytestream request with the given session
         * ID
         */
        this.manager.ignoreBytestreamRequestOnce(streamID);
    }

aTalk adds an addIncomingBytestreamListener() when detected Socks5Bytestream negotiation error, however it is not being called due to the above blocking. To verify this point, aTalk implements the following patches:

InBandBytestreamManager.patch (969 Bytes)
Socks5BytestreamRequest.patch (1.8 KB)

Below is the debug log with the patch i.e. IBB fallback is working:

2018-12-14 12:28:30.375 22061-22199/org.atalk.android D/SMACK: RECV (0): <iq xml:lang='en' to='swordfish@atalk.org/atalk' from='leopard@atalk.org/atalk' type='set' id='oK7gw-544'><si xmlns='http://jabber.org/protocol/si' id='jsi_-1166856721' mime-type='image/png' profile='http://jabber.org/protocol/si/profile/file-transfer'><file xmlns='http://jabber.org/protocol/si/profile/file-transfer' name='586431100-1.png' size='39315'><thumbnail xmlns='urn:xmpp:thumbs:0' cid='sha1+7b6f3cd32d439be60af27841c2890b4395aca994@bob.xmpp.org' mime-type='image/png' width='64' height='64'/></file><feature xmlns='http://jabber.org/protocol/feature-neg'><x xmlns='jabber:x:data' type='form'><field var='stream-method' type='list-single'><option><value>http://jabber.org/protocol/bytestreams</value></option><option><value>http://jabber.org/protocol/ibb</value></option></field></x></feature></si></iq>

2018-12-14 12:28:32.420 22061-22198/org.atalk.android D/SMACK: SENT (0): <iq to='leopard@atalk.org/atalk' id='oK7gw-544' type='result'><si xmlns='http://jabber.org/protocol/si'><feature xmlns="http://jabber.org/protocol/feature-neg"><x xmlns='jabber:x:data' type='submit'><field var='stream-method'><value>http://jabber.org/protocol/bytestreams</value><value>http://jabber.org/protocol/ibb</value></field></x></feature></si></iq>
2018-12-14 12:28:32.611 22061-22199/org.atalk.android D/SMACK: RECV (0): <iq xml:lang='en' to='swordfish@atalk.org/atalk' from='leopard@atalk.org/atalk' type='set' id='oK7gw-548'><query xmlns='http://jabber.org/protocol/bytestreams' sid='jsi_-1166856721' mode='tcp'><streamhost jid='leopard@atalk.org/atalk' host='fe80::f025:b7ff:fe9c:3c5%p2p0' port='7777'/><streamhost jid='leopard@atalk.org/atalk' host='fe80::f225:b7ff:fe9c:3c5%wlan0' port='7777'/><streamhost jid='leopard@atalk.org/atalk' host='192.168.1.12' port='7777'/></query></iq>
2018-12-14 12:28:35.979 22061-22198/org.atalk.android D/SMACK: SENT (0): <iq to='leopard@atalk.org/atalk' id='oK7gw-548' type='error'><error type='cancel'><item-not-found xmlns='urn:ietf:params:xml:ns:xmpp-stanzas'/><text xml:lang='en'>Could not establish socket with any provided host</text></error></iq>
2018-12-14 12:28:35.982 22061-22297/org.atalk.android E/aTalk: [10576] impl.protocol.jabber.OperationSetFileTransferJabberImpl.run().492 An exception occurred while transferring file: 
   org.jivesoftware.smack.XMPPException$XMPPErrorException: XMPPError: item-not-found - cancel
       at org.jivesoftware.smackx.bytestreams.socks5.Socks5BytestreamRequest.cancelRequest(Socks5BytestreamRequest.java:292)
       at org.jivesoftware.smackx.bytestreams.socks5.Socks5BytestreamRequest.accept(Socks5BytestreamRequest.java:256)
       at org.jivesoftware.smackx.filetransfer.Socks5TransferNegotiator.negotiateIncomingStream(Socks5TransferNegotiator.java:102)
       at org.jivesoftware.smackx.filetransfer.FaultTolerantNegotiator.createIncomingStream(FaultTolerantNegotiator.java:72)
       at org.jivesoftware.smackx.filetransfer.IncomingFileTransfer$2.call(IncomingFileTransfer.java:179)
       at org.jivesoftware.smackx.filetransfer.IncomingFileTransfer$2.call(IncomingFileTransfer.java:174)
       at java.util.concurrent.FutureTask.run(FutureTask.java:266)
       at org.jivesoftware.smackx.filetransfer.IncomingFileTransfer.negotiateStream(IncomingFileTransfer.java:182)
       at org.jivesoftware.smackx.filetransfer.IncomingFileTransfer.access$100(IncomingFileTransfer.java:58)
       at org.jivesoftware.smackx.filetransfer.IncomingFileTransfer$1.run(IncomingFileTransfer.java:132)
       at java.lang.Thread.run(Thread.java:764)
2018-12-14 12:28:35.990 22061-22297/org.atalk.android E/aTalk: [10576] org.atalk.android.gui.chat.filetransfer.ReceiveFileConversation.statusChanged().254 Add IBB listener; Error in incoming file transfer: Could not establish socket with any provided host
2018-12-14 12:28:36.212 22061-22199/org.atalk.android D/SMACK: RECV (0): <iq xml:lang='en' to='swordfish@atalk.org/atalk' from='leopard@atalk.org/atalk' type='set' id='oK7gw-550'><open xmlns='http://jabber.org/protocol/ibb' block-size='4096' sid='jsi_-1166856721' stanza='iq'/></iq>
2018-12-14 12:28:36.233 22061-22303/org.atalk.android W/aTalk: [10581] org.atalk.android.gui.chat.filetransfer.ReceiveFileConversation.incomingBytestreamRequest().459 Received IBB Request: leopard@atalk.org/atalk
2018-12-14 12:28:36.244 22061-22198/org.atalk.android D/SMACK: SENT (0): <iq to='leopard@atalk.org/atalk' id='oK7gw-550' type='result'></iq>
2018-12-14 12:28:36.258 22061-22198/org.atalk.android D/SMACK: SENT (0): <iq to='leopard@atalk.org/atalk' id='oK7gw-544' type='result'><si xmlns='http://jabber.org/protocol/si'><feature xmlns="http://jabber.org/protocol/feature-neg"><x xmlns='jabber:x:data' type='submit'><field var='stream-method'><value>http://jabber.org/protocol/bytestreams</value><value>http://jabber.org/protocol/ibb</value></field></x></feature></si></iq>
2018-12-14 12:28:36.409 22061-22199/org.atalk.android D/SMACK: RECV (0): <iq xml:lang='en' to='swordfish@atalk.org/atalk' from='leopard@atalk.org/atalk' type='set' id='oK7gw-552'><data xmlns='http://jabber.org/protocol/ibb' seq='0' sid='jsi_-1166856721'>iVBORw0KGgoAAAANSUhEUgAAAXcAAAELCAMAAAAV/jZ2AAAABGdBTUEAALGPC/xhBQAAAAFzUkdCAK7OHOkAAAMAUExURf///y8vNerfzzIyNMzMzP7//isrMP/4sP///v7///3//y0tMufcyikpLv//++rezB4eI+XayajI1xobHyAhJhcXHCQkKKzL2DIzOezg0uvayScnLNrItqbG1N/KtqPD03iKpKHB0Z6+0One0unZxufWw////+jdzRITF+TSv+LUw+ffzqFDRbzY6sPb7dXFtZy/0+bbzujr8Mu5qDo7Qs62oOzu8t7Hsn6juuTXx7nM2v39+5u9ztzLuu/x9ebn7D0+R5/C1tK7pcWxoOHOu9W/qtzOvq/.....

There are more work to be done, as the acceptance of IBB is currently being triggered by aTalk; Although the sender transfers the whole file via IBB protocol, FaultTolerantNegotiator is not designed to fall back to receive IBB stream data and throws the following exception on timeout.

2018-12-14 12:28:46.266 22061-22305/org.atalk.android E/aTalk: [10583] impl.protocol.jabber.OperationSetFileTransferJabberImpl.run().492 An exception occurred while transferring file: 
    org.jivesoftware.smack.SmackException$NoResponseException: No response received within reply timeout. Timeout was 10000ms (~10s). While waiting for stream initiation
        at org.jivesoftware.smackx.filetransfer.StreamNegotiator.initiateIncomingStream(StreamNegotiator.java:123)
        at org.jivesoftware.smackx.filetransfer.FaultTolerantNegotiator.createIncomingStream(FaultTolerantNegotiator.java:68)
        at org.jivesoftware.smackx.filetransfer.IncomingFileTransfer$2.call(IncomingFileTransfer.java:179)
        at org.jivesoftware.smackx.filetransfer.IncomingFileTransfer$2.call(IncomingFileTransfer.java:174)
        at java.util.concurrent.FutureTask.run(FutureTask.java:266)
        at org.jivesoftware.smackx.filetransfer.IncomingFileTransfer.negotiateStream(IncomingFileTransfer.java:182)
        at org.jivesoftware.smackx.filetransfer.IncomingFileTransfer.access$100(IncomingFileTransfer.java:58)
        at org.jivesoftware.smackx.filetransfer.IncomingFileTransfer$1.run(IncomingFileTransfer.java:132)
        at java.lang.Thread.run(Thread.java:764)

#3

aTalk has enhanced the Smack FaultTolerantNegotiator to support incoming file transfer with IBB fallback. The patches are attached below. These patches applied to the latest Smack 4.4.-alpha2 source Revision 4127.

FaultTolerantNegotiator.patch (1.6 KB)
InBandBytestreamManager.patch (1.3 KB)
IBBTransferNegotiator.patch (3.6 KB)
InBandBytestreamSession.patch (2.1 KB)

Below is a debug log of the IBB fallback on Socks5Bystream failure:
Appreciate if Smack team would consider the implementation for smack libraries future release.

2018-12-16 19:51:51.759 25974-26623/org.atalk.android D/SMACK: RECV (0): <iq xml:lang='en' to='swordfish@atalk.org/atalk' from='leopard@atalk.org/atalk' type='set' id='3YU3s-118'><si xmlns='http://jabber.org/protocol/si' id='jsi_1240632326' mime-type='image/png' profile='http://jabber.org/protocol/si/profile/file-transfer'><file xmlns='http://jabber.org/protocol/si/profile/file-transfer' name='586431100-1.png' size='39315'><thumbnail xmlns='urn:xmpp:thumbs:0' cid='sha1+7b6f3cd32d439be60af27841c2890b4395aca994@bob.xmpp.org' mime-type='image/png' width='64' height='64'/></file><feature xmlns='http://jabber.org/protocol/feature-neg'><x xmlns='jabber:x:data' type='form'><field var='stream-method' type='list-single'><option><value>http://jabber.org/protocol/bytestreams</value></option><option><value>http://jabber.org/protocol/ibb</value></option></field></x></feature></si></iq>
2018-12-16 19:51:55.842 25974-26622/org.atalk.android D/SMACK: SENT (0): <iq to='leopard@atalk.org/atalk' id='3YU3s-118' type='result'><si xmlns='http://jabber.org/protocol/si'><feature xmlns="http://jabber.org/protocol/feature-neg"><x xmlns='jabber:x:data' type='submit'><field var='stream-method'><value>http://jabber.org/protocol/bytestreams</value><value>http://jabber.org/protocol/ibb</value></field></x></feature></si></iq>
2018-12-16 19:51:56.241 25974-26623/org.atalk.android D/SMACK: RECV (0): <iq xml:lang='en' to='swordfish@atalk.org/atalk' from='leopard@atalk.org/atalk' type='set' id='3YU3s-133'><query xmlns='http://jabber.org/protocol/bytestreams' sid='jsi_1240632326' mode='tcp'><streamhost jid='leopard@atalk.org/atalk' host='fe80::f025:b7ff:fe9c:3c5%p2p0' port='7777'/><streamhost jid='leopard@atalk.org/atalk' host='fe80::f225:b7ff:fe9c:3c5%wlan0' port='7777'/><streamhost jid='leopard@atalk.org/atalk' host='192.168.1.12' port='7777'/></query></iq>

2018-12-16 19:51:59.611 25974-26622/org.atalk.android D/SMACK: SENT (0): <iq to='leopard@atalk.org/atalk' id='3YU3s-133' type='error'><error type='cancel'><item-not-found xmlns='urn:ietf:params:xml:ns:xmpp-stanzas'/><text xml:lang='en'>Could not establish socket with any provided host</text></error></iq>

2018-12-16 19:51:59.884 25974-26623/org.atalk.android D/SMACK: RECV (0): <iq xml:lang='en' to='swordfish@atalk.org/atalk' from='leopard@atalk.org/atalk' type='set' id='3YU3s-135'><open xmlns='http://jabber.org/protocol/ibb' block-size='4096' sid='jsi_1240632326' stanza='iq'/></iq>
2018-12-16 19:51:59.902 25974-26622/org.atalk.android D/SMACK: SENT (0): <iq to='leopard@atalk.org/atalk' id='3YU3s-135' type='result'></iq>
2018-12-16 19:52:00.078 25974-26623/org.atalk.android D/SMACK: RECV (0): <iq xml:lang='en' to='swordfish@atalk.org/atalk' from='leopard@atalk.org/atalk' type='set' id='3YU3s-137'><data xmlns='http://jabber.org/protocol/ibb' seq='0' sid='jsi_1240632326'>iVBORw0KGgoAAAANSUhEUgAAAXcAAAELCAMAAAAV/jZ2AAAABGdBTUEAALGPC/xhBQAAAAFzUkdCAK7OHOkAAAMAUExURf///y8vNerfzzIyNMzMzP7//isrMP/4sP///v7///3//y0tMufcyikpLv//++rezB4eI+XayajI1xobHyAhJhcXHCQkKKzL2DIzOezg0uvayScnLNrItqbG1N/KtqPD03iKpKHB0Z6+0One0unZxufWw////+jdzRITF+TSv+LUw+ffzqFDRbzY6sPb7dXFtZy/0+bbzujr8Mu5qDo7Qs62oOzu8t7Hsn6juuTXx7nM2v39+5u9ztzLuu/x9ebn7D0+R5/C1tK7pcWxoOHOu9W/qtzOvq/
....
2018-12-16 19:52:00.117 25974-26622/org.atalk.android D/SMACK: SENT (0): <iq to='leopard@atalk.org/atalk' id='3YU3s-137' type='result'></iq><r xmlns='urn:xmpp:sm:3'/>

....
....

2018-12-16 19:52:01.426 25974-26623/org.atalk.android D/SMACK: RECV (0): <iq xml:lang='en' to='swordfish@atalk.org/atalk' from='leopard@atalk.org/atalk' type='set' id='3YU3s-155'><data xmlns='http://jabber.org/protocol/ibb' seq='9' sid='jsi_1240632326'>eKm4QMKdb4B5zbRMbU8z+eLQJ8Bu8gcKf8Tu7SbTSi5CvpXvVSp4yH9AJ94V9Y2/GXeV14nL1i5xMvzDs4vyOOInSQ/wmRQyCphVuZ20nk3AoWYy51tyNoGfvJW9m5izCYq1wGTIFPR2rOBdhTrhLq88ClMDjpcM/LPCPEhozzDlu/B30pSUtBj3HLZ1cyJ7Z1GfP4CfdSrYyue7444MGmkdaSGUOGuUgjZQfvkeCuGqoyAcvx/R4VBTI+vrgP1od1l1SMRvjLvpoSWYRGC1Vgs8NH6JiRcKKl9DdCN0zj15jCURDfG85hneXoDiCOFKcZamYPdwGaP3gmxMEDwxEIVMzbrTxx2hVAvVV9KYtU/v/bF48rvjfjmfEw8HG7pPiXWyk1zhS
....
/Y2E8COa7GA3zF3kf2IcBfuwl1EuAt3EeEu3EWEu3AXEe7CXSTiLrJvQe4iTyDC/WnkXyIa3wt49QLVAAAAAElFTkSuQmCC</data></iq>
2018-12-16 19:52:01.433 25974-26622/org.atalk.android D/SMACK: SENT (0): <iq to='leopard@atalk.org/atalk' id='3YU3s-155' type='result'></iq>

2018-12-16 19:52:01.566 25974-26623/org.atalk.android D/SMACK: RECV (0): <iq xml:lang='en' to='swordfish@atalk.org/atalk' from='leopard@atalk.org/atalk' type='set' id='3YU3s-157'><close xmlns='http://jabber.org/protocol/ibb' sid='jsi_1240632326'/></iq>
2018-12-16 19:52:01.571 25974-26622/org.atalk.android D/SMACK: SENT (0): <iq to='leopard@atalk.org/atalk' id='3YU3s-157' type='result'></iq><r xmlns='urn:xmpp:sm:3'/>

#4

Thanks for your contribution. :slight_smile:

Are those patches the same that can be found in

?


#5

Yes, the patches here are exactly the same as in the PR.