Smack 4.1.3 cannot properly handle Sock5ByteStreamSession with multiple <streamhost/>

Attached below is a log of the file transfer between Pidgin client and an xmpp client uses smack 4.1.3

When pidgin reply with multiple ,

file transfer process aborted with exceptions when the first connection cannot be established.

Following changes to the file resolve the problem:

org.jivesoftware.smackx.bytestreams.socks5.Socks5BytestreamRequest.java#accept()

========== Socks5BytestreamSession accept() modifications =================

public Socks5BytestreamSession accept()

throws InterruptedException, XMPPErrorException, SmackException

{

Collection streamHosts = this.bytestreamRequest.getStreamHosts();

// throw exceptions if request contains no stream hosts

if (streamHosts.size() == 0) {

cancelRequest();

}

StreamHost selectedHost = null;

Socket socket = null;

String digest = Socks5Utils.createDigest(this.bytestreamRequest.getSessionID(), this.bytestreamRequest.getFrom(), this.manager.getConnection().getUser());

/*

  • determine timeout for each connection attempt; each SOCKS5 proxy has the same amount of time so that the first does not consume

  • the whole timeout

*/

int timeout = Math.max(getTotalConnectTimeout() / streamHosts.size(), getMinimumConnectTimeout());

for (StreamHost streamHost : streamHosts) {

String address = streamHost.getAddress() + “:” + streamHost.getPort();

// check to see if this address has been blacklisted

int failures = getConnectionFailures(address);

if ((CONNECTION_FAILURE_THRESHOLD <= 0) || (failures < CONNECTION_FAILURE_THRESHOLD)) {

// try establish socket connection

try {

// build SOCKS5 client

final Socks5Client socks5Client = new Socks5Client(streamHost, digest);

// connect to SOCKS5 Proxy with a timeout

socket = socks5Client.getSocket(timeout);

// set selected host only if socket connection is OK; Otherwise loop exit with exception

if (socket != null) {

selectedHost = streamHost;

break;

}

else {

incrementConnectionFailures(address);

}

}

catch (TimeoutException e) {

incrementConnectionFailures(address);

}

catch (IOException e) {

incrementConnectionFailures(address);

}

catch (XMPPException e) {

incrementConnectionFailures(address);

}

}

}

// throw exception if connecting to all SOCKS5 proxies failed

if (selectedHost == null || socket == null) {

cancelRequest();

}

// send used-host confirmation

Bytestream response = createUsedHostResponse(selectedHost);

this.manager.getConnection().sendStanza(response);

return new Socks5BytestreamSession(socket, selectedHost.getJID().equals(this.bytestreamRequest.getFrom()));

}

=================== File Transfer Log =======================

09-05 22:46:02.836: D/SMACK(32726): RECV (0):

http://jabber.org/protocol/bytestreams http://jabber.org/protocol/ibb

09-05 22:46:02.876: D/SMACK(32726): SENT (0):

09-05 22:46:23.926: D/ViewRootImpl(32726): ViewPostImeInputStage ACTION_DOWN

09-05 22:46:24.066: D/SMACK(32726): SENT (0):

http://jabber.org/protocol/bytestreams

http://jabber.org/protocol/ibb

09-05 22:46:24.116: D/SMACK(32726): RECV (0):

09-05 22:46:24.116: D/SMACK(32726): SENT (0):

Could you show use the modification in unified diff format? It’s hard to spot the changes otherwise. And please describe what you have changed and why.

I am running eclipse on Windows 7, not that easy to generate diff format.

The only changes in the routine is as below in Bold: it checks for attempted connection socket for null and loop to next streamhost until a valid connection socket is found. Otherwise if a streamHost with (socket == null) is returned, the application will exit with exception, causing the whole file transfer to fail.

=====================

if ((CONNECTION_FAILURE_THRESHOLD <= 0) || (failures < CONNECTION_FAILURE_THRESHOLD)) {

// try establish socket connection

try {

// build SOCKS5 client

final Socks5Client socks5Client = new Socks5Client(streamHost, digest);

** // connect to SOCKS5 Proxy with a timeout**

** socket = socks5Client.getSocket(timeout);**

** // set selected host only if socket connection is OK; Otherwise loop exit with exception**

** if (socket != null) {**

** selectedHost = streamHost;**

** break;**

** }**

** else {**

** incrementConnectionFailures(address);**

** }**

}

catch (TimeoutException e) {

incrementConnectionFailures(address);

Thanks, but I don’t see how getSocket() could ever return null. Do you have an explanation how this could happen? I’m unable to apply the patch without one.

Following on the last example when sending file from Pidgin to and XMPP cleint with Smack 4.1.3: The Pidgin client is installed on Windows communicating to an Android XMPP client.

On tracing into socks5Client.getSocket(timeout) ===>** res = establish(socket);**



It is found that (res = false) when it tries to establish(socket) with a given but unavailable (possibly due to windows firewall blocking the connection) is attempted; hence it executes

** socket.close();**

** throw new SmackException(“SOCKS5 negotiation failed”);**

and no socket is being returned.

Actually the file transfer failed between pidgin and the xmpp client with smack 4.1.3 on my android application (ported from Jitsi-android).

The solution given is the exact solution that I have implemented to resolve the issue.

You may try to install both pidgin and gajim client on a system, and then send a file from pidgin to gajim (with xmpp console turned on).

The file transfer failed in the test. I believe gajim is also using a version of smack but personally did not verify this.

Note: Current Jitsi supports only ibb file transfer, with bytestream option disabled.

================ getSocket Routine) =============

FutureTask futureTask = new FutureTask(new Callable() {

public Socket call() throws IOException, SmackException {

// initialize socket

Socket socket = new Socket();

SocketAddress socketAddress = new InetSocketAddress(streamHost.getAddress(),

streamHost.getPort());

socket.connect(socketAddress);

boolean res;

// initialize connection to SOCKS5 proxy

try {

res = establish(socket);

}

catch (SmackException e) {

socket.close();

throw e;

}

if (res) {

return socket;

}

else {

** socket.close();**

** throw new SmackException(“SOCKS5 negotiation failed”);**

}

}

  });

Did further tracing, found that it can also failed at

socket.connect(socketAddress);

Timeout with the following error exception message

failed to connect to /192.168.56.1 (port 65533): connect failed: ETIMEDOUT (Connection timed out)

After more testings, now I have the same doubt as you why socket can be null.

I also spotted there is a mistake in the my loop test condition i.e.

if ((CONNECTION_FAILURE_THRESHOLD <= 0) || (failures < CONNECTION_FAILURE_THRESHOLD))

Look like I need more time to investigate and understand why the file transfer works after the modifications.

In fact the exact same fix was applied to asmack 3.3 then to smack 4.1.3 after the asmack to smack migration; in order to make file transfer work with Pidgin client.

Will return to you once I found the reason.

Sorry for the confusion.

You are absolute correct that ‘socket’ can never be null. It was my mistake. After further testing and investigation, I found that instead it should include an additional ‘catch’ statement as below. This is to disallow throwing the SmackException upstream as this will cause the application to abort file transfer process. The SmackException was thrown when res = false:

     catch (SmackException e) {

            incrementConnectionFailures(address);

      }

Below is the proposed final code implementation to resolve the problem that I have experienced.

Attached below also contain the log messages for the types of Exceptions that may occur when socket = socks5Client.getSocket(timeout); is being executed. The log message is captured using a modified code with log methods (attached below).

Sorry for the earlier confusion created.

===================== Final proposed code implementation ==========

public Socks5BytestreamSession accept() throws InterruptedException, XMPPErrorException, SmackException

{

    Collection<StreamHost> streamHosts = this.bytestreamRequest.getStreamHosts();

   // throw exceptions if request contains no stream hosts

   if (streamHosts.size() == 0) {

       cancelRequest();

    }

    StreamHost selectedHost = null;

    Socket socket = null;

    String digest = Socks5Utils.createDigest(this.bytestreamRequest.getSessionID(), this.bytestreamRequest.getFrom(), this.manager.getConnection().getUser());

    /*

     * determine timeout for each connection attempt; each SOCKS5 proxy has the same amount of time so that the first does not consume

     * the whole timeout

     */

    int timeout = Math.max(getTotalConnectTimeout() / streamHosts.size(), getMinimumConnectTimeout());

    for (StreamHost streamHost : streamHosts) {

         String address = streamHost.getAddress() + ":" + streamHost.getPort();

    // check to see if this address has been blacklisted

    int failures = getConnectionFailures(address);

    if ((CONNECTION_FAILURE_THRESHOLD > 0) && (failures < CONNECTION_FAILURE_THRESHOLD)) {

        // try establish socket connection

        try {

            // build SOCKS5 client

            final Socks5Client socks5Client = new Socks5Client(streamHost, digest);

            // connect to SOCKS5 Proxy with a timeout

            socket = socks5Client.getSocket(timeout);

             selectedHost = streamHost;

              break;

         }

          catch (TimeoutException e) {

               incrementConnectionFailures(address);

           }

           catch (SmackException e) {

                 incrementConnectionFailures(address);

           }

           catch (IOException e) {

                incrementConnectionFailures(address);

           }

           catch (XMPPException e) {

               incrementConnectionFailures(address);

           }

       }

  }

    // throw exception if connecting to all SOCKS5 proxies failed

    if (selectedHost == null || socket == null) {

           cancelRequest();

    }

    // send used-host confirmation

    Bytestream response = createUsedHostResponse(selectedHost);

    this.manager.getConnection().sendStanza(response);

    return new Socks5BytestreamSession(socket, selectedHost.getJID().equals(this.bytestreamRequest.getFrom()));

}

================================ End of solution code ===================================

For testing and verification, I captured the log message to trace the problem with the modified code below:

--------------- Test code ---------------------------

if ((CONNECTION_FAILURE_THRESHOLD > 0) && (failures < CONNECTION_FAILURE_THRESHOLD)) {

// try establish socket connection

try {

// build SOCKS5 client

final Socks5Client socks5Client = new Socks5Client(streamHost, digest);

// connect to SOCKS5 Proxy with a timeout

socket = socks5Client.getSocket(timeout);

selectedHost = streamHost;

logger.info("Found streamHost for transfering file with failture Count: " + Integer.toString(failures) + " at addrees: " + address.toString());

break;

}

catch (TimeoutException e) {

logger.error("TimeoutException while transfering file with failture Count: " + Integer.toString(failures) + " at addrees: " + address.toString() + " Exception: ", e);

incrementConnectionFailures(address);

}

catch (SmackException e) {

logger.error("SmackException while transfering file with failture Count: " + Integer.toString(failures) + " at addrees: " + address.toString() + " Exception: ", e);

incrementConnectionFailures(address);

}

catch (IOException e) {

logger.error("IOException while transfering file with failture Count: " + Integer.toString(failures) + " at addrees: " + address.toString() + " Exception: ", e);

incrementConnectionFailures(address);

}

catch (XMPPException e) {

** logger.error("XMPPException while transfering file with failture Count: " + Integer.toString(failures) + " at addrees: " + address.toString() + " Exception: ", e);**

incrementConnectionFailures(address);

}

}


Below is the trace log of the whole file transfer process

---------------- Trace log -----------------------

09-10 11:21:19.579: D/SMACK(12093): SENT (0):

http://jabber.org/protocol/bytestreamshttp://jabber.org/protocol/ ibb

09-10 11:21:20.029: D/SMACK(12093): RECV (0):

09-10 11:21:20.039: D/SMACK(12093): SENT (0):

09-10 11:21:20.129: E/Jitsi(12093): [10] org.jivesoftware.smackx.bytestreams.socks5.Socks5BytestreamRequest.accept().246

SmackException while transfering file with failture Count: 0 at addrees: 192.168.1.109:51006 Exception:

09-10 11:21:20.129: E/Jitsi(12093): org.jivesoftware.smack.SmackException: SOCKS5 negotiation failed

09-10 11:21:20.129: E/Jitsi(12093): at org.jivesoftware.smackx.bytestreams.socks5.Socks5Client$1.call(Socks5Client.jav a:105)

09-10 11:21:20.129: E/Jitsi(12093): at org.jivesoftware.smackx.bytestreams.socks5.Socks5Client$1.call(Socks5Client.jav a:80)

09-10 11:21:20.129: E/Jitsi(12093): at java.util.concurrent.FutureTask.run(FutureTask.java:237)

09-10 11:21:20.129: E/Jitsi(12093): at java.lang.Thread.run(Thread.java:818)

09-10 11:21:22.129: E/Jitsi(12093): [10] org.jivesoftware.smackx.bytestreams.socks5.Socks5BytestreamRequest.accept().242

TimeoutException while transfering file with failture Count: 0 at addrees: 192.168.56.1:51006 Exception:

09-10 11:21:22.129: E/Jitsi(12093): java.util.concurrent.TimeoutException

09-10 11:21:22.129: E/Jitsi(12093): at java.util.concurrent.FutureTask.get(FutureTask.java:176)

09-10 11:21:22.129: E/Jitsi(12093): at org.jivesoftware.smackx.bytestreams.socks5.Socks5Client.getSocket(Socks5Client. java:115)

09-10 11:21:22.129: E/Jitsi(12093): at org.jivesoftware.smackx.bytestreams.socks5.Socks5BytestreamRequest.accept(Socks 5BytestreamRequest.java:236)

09-10 11:21:22.129: E/Jitsi(12093): at org.jivesoftware.smackx.filetransfer.Socks5TransferNegotiator.negotiateIncoming Stream(Socks5TransferNegotiator.java:104)

09-10 11:21:22.129: E/Jitsi(12093): at org.jivesoftware.smackx.filetransfer.FaultTolerantNegotiator.createIncomingStre am(FaultTolerantNegotiator.java:68)

09-10 11:21:22.129: E/Jitsi(12093): at org.jivesoftware.smackx.filetransfer.IncomingFileTransfer$2.call(IncomingFileTr ansfer.java:186)

09-10 11:21:22.129: E/Jitsi(12093): at org.jivesoftware.smackx.filetransfer.IncomingFileTransfer$2.call(IncomingFileTr ansfer.java:183)

09-10 11:21:22.129: E/Jitsi(12093): at java.util.concurrent.FutureTask.run(FutureTask.java:237)

09-10 11:21:22.129: E/Jitsi(12093): at org.jivesoftware.smackx.filetransfer.IncomingFileTransfer.negotiateStream(Incom ingFileTransfer.java:190)

09-10 11:21:22.129: E/Jitsi(12093): at org.jivesoftware.smackx.filetransfer.IncomingFileTransfer.access$100(IncomingFi leTransfer.java:57)

09-10 11:21:22.129: E/Jitsi(12093): at org.jivesoftware.smackx.filetransfer.IncomingFileTransfer$1.run(IncomingFileTra nsfer.java:129)

09-10 11:21:22.129: E/Jitsi(12093): at java.lang.Thread.run(Thread.java:818)

09-10 11:21:22.169: E/Jitsi(12093): [10] org.jivesoftware.smackx.bytestreams.socks5.Socks5BytestreamRequest.accept().250

IOException while transfering file with failture Count: 0 at addrees: 0.0.0.0:51006 Exception:

09-10 11:21:22.169: E/Jitsi(12093): java.net.ConnectException: failed to connect to localhost/127.0.0.1 (port 51006): connect failed: ECONNREFUSED (Connection refused)

09-10 11:21:22.169: E/Jitsi(12093): at libcore.io.IoBridge.connect(IoBridge.java:124)

09-10 11:21:22.169: E/Jitsi(12093): at java.net.PlainSocketImpl.connect(PlainSocketImpl.java:183)

09-10 11:21:22.169: E/Jitsi(12093): at java.net.PlainSocketImpl.connect(PlainSocketImpl.java:456)

09-10 11:21:22.169: E/Jitsi(12093): at java.net.Socket.connect(Socket.java:882)

09-10 11:21:22.169: E/Jitsi(12093): at java.net.Socket.connect(Socket.java:825)

09-10 11:21:22.169: E/Jitsi(12093): at org.jivesoftware.smackx.bytestreams.socks5.Socks5Client$1.call(Socks5Client.jav a:88)

09-10 11:21:22.169: E/Jitsi(12093): at org.jivesoftware.smackx.bytestreams.socks5.Socks5Client$1.call(Socks5Client.jav a:80)

09-10 11:21:22.169: E/Jitsi(12093): at java.util.concurrent.FutureTask.run(FutureTask.java:237)

09-10 11:21:22.169: E/Jitsi(12093): at java.lang.Thread.run(Thread.java:818)

09-10 11:21:22.169: E/Jitsi(12093): Caused by: android.system.ErrnoException: connect failed: ECONNREFUSED (Connection refused)

09-10 11:21:22.169: E/Jitsi(12093): at libcore.io.Posix.connect(Native Method)

09-10 11:21:22.169: E/Jitsi(12093): at libcore.io.BlockGuardOs.connect(BlockGuardOs.java:111)

09-10 11:21:22.169: E/Jitsi(12093): at libcore.io.IoBridge.connectErrno(IoBridge.java:137)

09-10 11:21:22.169: E/Jitsi(12093): at libcore.io.IoBridge.connect(IoBridge.java:122)

09-10 11:21:22.169: E/Jitsi(12093): … 8 more

09-10 11:21:24.179: E/Jitsi(12093): [10] org.jivesoftware.smackx.bytestreams.socks5.Socks5BytestreamRequest.accept().242

TimeoutException while transfering file with failture Count: 0 at addrees: 118.200.189.88:51006 Exception:

09-10 11:21:24.179: E/Jitsi(12093): java.util.concurrent.TimeoutException

09-10 11:21:24.179: E/Jitsi(12093): at java.util.concurrent.FutureTask.get(FutureTask.java:176)

09-10 11:21:24.179: E/Jitsi(12093): at org.jivesoftware.smackx.bytestreams.socks5.Socks5Client.getSocket(Socks5Client. java:115)

09-10 11:21:24.179: E/Jitsi(12093): at org.jivesoftware.smackx.bytestreams.socks5.Socks5BytestreamRequest.accept(Socks 5BytestreamRequest.java:236)

09-10 11:21:24.179: E/Jitsi(12093): at org.jivesoftware.smackx.filetransfer.Socks5TransferNegotiator.negotiateIncoming Stream(Socks5TransferNegotiator.java:104)

09-10 11:21:24.179: E/Jitsi(12093): at org.jivesoftware.smackx.filetransfer.FaultTolerantNegotiator.createIncomingStre am(FaultTolerantNegotiator.java:68)

09-10 11:21:24.179: E/Jitsi(12093): at org.jivesoftware.smackx.filetransfer.IncomingFileTransfer$2.call(IncomingFileTr ansfer.java:186)

09-10 11:21:24.179: E/Jitsi(12093): at org.jivesoftware.smackx.filetransfer.IncomingFileTransfer$2.call(IncomingFileTr ansfer.java:183)

09-10 11:21:24.179: E/Jitsi(12093): at java.util.concurrent.FutureTask.run(FutureTask.java:237)

09-10 11:21:24.179: E/Jitsi(12093): at org.jivesoftware.smackx.filetransfer.IncomingFileTransfer.negotiateStream(Incom ingFileTransfer.java:190)

09-10 11:21:24.179: E/Jitsi(12093): at org.jivesoftware.smackx.filetransfer.IncomingFileTransfer.access$100(IncomingFi leTransfer.java:57)

09-10 11:21:24.179: E/Jitsi(12093): at org.jivesoftware.smackx.filetransfer.IncomingFileTransfer$1.run(IncomingFileTra nsfer.java:129)

09-10 11:21:24.179: E/Jitsi(12093): at java.lang.Thread.run(Thread.java:818)

09-10 11:21:24.219: I/Jitsi(12093): [10] org.jivesoftware.smackx.bytestreams.socks5.Socks5BytestreamRequest.accept().238

Found streamHost for transfering file with failture Count: 0 at addrees: 118.200.189.88:7777

09-10 11:21:24.219: D/SMACK(12093): SENT (0):

I have the similar question with you.

When I get streamhost-used and I send an iq to set up Socket5,

it return an error with 405(not-allowed).

var iq = $iq({
id :“Nhie4aJteJrxfytQ”,
from : "sender@xxx.com.cn/Spark",
to : “proxy.xxx.com.cn”,
type : ‘set’
}).c(‘query’, {
xmlns : “http://jabber.org/protocol/bytestreams”,
sid :“iTh6jGrTfsPwiKPEp7xN25KsHKia6GeY”
}).c(‘activate’).t("receiver@xxx.com.cn/Spark");

It equal to behind:

android@192.168.1.113/Spark 2.6.3

Can anyone help me???

I see there is a in your "android@192.168.1.113/Spark 2.6.3" resource name. Can this be the cause?

Try to use "android@192.168.1.113/Spark%202.6.3" to see it works

android@192.168.1.113/Spark 2.6.3 is the example on InterNet not me

my is receiver@xxx.com.cn/Spark , there is no space
and my iq turn to xml is :

<query sid="6fZPGZD6GimZQGPRGKf5A6bpbtAhxtY5" xmlns="http://jabber.org/protocol/bytestreams">

    <activate>liuxinqi@try.techexcel.com.cn/Spark</activate>

id and sid created myself ,I send file from web to Spark.

According to the example and xep-0065,I could’t find any error

can you find something wrong ,

sorry for my terrible English

As you only give the activate packet that lead to the problem. It is not easy for someone to identify where the problem lies.

I recommend you refer to the XEP-0065: SOCK5 ByteStreams document online. Then you can understand the whole protocol requirements as described in Section 6.

One thing you need to know if the streamhost that you try to connect to in fact support and allow proxy connection from "zhangjunrui@try.techexcel.com.cn/7c01bc09" .

Also “sid” must remains consistent through the whole process during Sock5 communication, and it is actually given by the target (Example 21. Target Notifies Reqeuster of ByteStream) and not self generated as mentioned in your last message.

You said it’s not easy to find problem for the message I gave was not complete.
So I will give the whole message behind(all the id and sid are made myself):

first

<si id="rFihK6HDajZajjHFECBimR4Zb8GECmjy" xmlns="http://jabber.org/protocol/si" profile="http://jabber.org/protocol/si/profile/file-transfer" mime-type="text/plain">

    <file xmlns="http://jabber.org/protocol/si/profile/file-transfer" name="test.txt" size="335"/>

    <feature xmlns="http://jabber.org/protocol/feature-neg">
                <option><value>http://jabber.org/protocol/bytestreams</value></option>

                <option><value>http://jabber.org/protocol/ibb</value></option>

second

<query xmlns="http://jabber.org/protocol/disco#items"/>

third

<query xmlns="http://jabber.org/protocol/bytestreams"/>

forth

<query mode="tcp" sid="rFihK6HDajZajjHFECBimR4Zb8GECmjy" xmlns="http://jabber.org/protocol/bytestreams">

fifth

<query sid="rFihK6HDajZajjHFECBimR4Zb8GECmjy" xmlns="http://jabber.org/protocol/bytestreams">

    <activate>liuxinqi@try.techexcel.com.cn/Spark</activate>

from first to forth,return result.But fifth return error:

can you find what’s wrong.

You said sid should’t create myself,could you give me the URL to the example,I didn’t find any example on Internet.

thanks a lot.

and I find log on server

2015.09.14 08:55:24 org.jivesoftware.openfire.filetransfer.proxy.FileTransferProxy - Error activating connection

java.lang.IllegalArgumentException: Transfer doesn’t exist or is missing parameters

at org.jivesoftware.openfire.filetransfer.proxy.ProxyConnectionManager.activate(Pr oxyConnectionManager.java:297)

at org.jivesoftware.openfire.filetransfer.proxy.FileTransferProxy.handleIQ(FileTra nsferProxy.java:153)

at org.jivesoftware.openfire.filetransfer.proxy.FileTransferProxy.process(FileTran sferProxy.java:356)

at org.jivesoftware.openfire.spi.RoutingTableImpl.routeToComponent(RoutingTableImp l.java:401)

at org.jivesoftware.openfire.spi.RoutingTableImpl.routePacket(RoutingTableImpl.jav a:243)

at org.jivesoftware.openfire.IQRouter.handle(IQRouter.java:331)

at org.jivesoftware.openfire.IQRouter.route(IQRouter.java:123)

at org.jivesoftware.openfire.spi.PacketRouterImpl.route(PacketRouterImpl.java:76)

at org.jivesoftware.openfire.SessionPacketRouter.route(SessionPacketRouter.java:10 8)

at org.jivesoftware.openfire.SessionPacketRouter.route(SessionPacketRouter.java:69 )

at org.jivesoftware.openfire.http.HttpSession.sendPendingPackets(HttpSession.java: 655)

at org.jivesoftware.openfire.http.HttpSession$HttpPacketSender.run(HttpSession.jav a:1279)

at java.util.concurrent.ThreadPoolExecutor.runWorker(Unknown Source)

at java.util.concurrent.ThreadPoolExecutor$Worker.run(Unknown Source)

at java.lang.Thread.run(Unknown Source)

can it help to find the problem?

I proposed you refer to the following link for the actual operation as specified in Section 6. Mediated Connection of

XEP-0065: SOCKS5 Bytestreams

I see that in your protocol flow, you are intermixed the id and sid i.e.

<si id=“rFihK6HDajZajjHFECBimR4Zb8GECmjy” xmlns="http://jabber.org/protocol/si

<query sid=“rFihK6HDajZajjHFECBimR4Zb8GECmjy” xmlns=“http://jabber.org/protocol/bytestreams”>

Actually id and sid have different roles in the file transfer connection setup. If you refer to the XEP-0065 document

Example 21. Target Notifies Requester of Bytestream

<iq from='target@example.org/bar'
    id='npq71g53'
    to='requester@example.com/foo'
    type='result'>
  <query xmlns='http://jabber.org/protocol/bytestreams'
         sid='vxf9n471bn46'>
    <streamhost-used jid='streamer.example.com'/>
  </query></iq>

Where sid is actually sent by target and I see this <streamhost-used... is missing from you protocol exchange between the Requester and Target.

When file transfer uses a proxy, the target will actually try the <streamhost/> provided by the requester until a successful socket connection is found. Then the target sends this info to the requester, with a defined sid in which the requester must use. I believe this sid is also used by the proxy server. When the request <activate/> the connection, the server must know which target the requester is trying to send file to, by the matching sid. Without this matching sid, the server does not know how to pair the the requester and target.

In your case, as I do not see the sid being sent by the target, I suspect the target has failed to make connection to the given <streamhost/> or never attempted??. In this case the requester should not have even proceed to <activate/> the connection. I believe this is the problem you are facing.

I send streamhost but I forget to show you ,now Ishow you it:

<query mode="tcp" sid="cCX4MdtsCTpXQ8ekMpBw45n5xHSZdkHn" xmlns="http://jabber.org/protocol/bytestreams">

you said it will return result with sid but I coudn’t find anywhere

<query xmlns="http://jabber.org/protocol/bytestreams">

     <streamhost-used jid="proxy.try.techexcel.com.cn"/>

</query>

I coudn’t find sid, why ? It’s my streamhost something wrong