Patch: Improve Socks5 bytestream

Hi,

I created a patch to improve the support of the Socks5 bytestream feature of XMPP for Smack. With this patch comes a new API to establish Socks5 bytestreams. This can be useful for applications that exchange data not only via XMPP messages but also via streams. Socks5 bytestreams can also be a good fallback if Jingle doesn’t work.

Here is a list of changes:

  • full implementation of XEP-0065 (except the optional UDP Support)
    • Smack now replies with error message “not_acceptable” if an unexpected Socks5 bytestream request is received
    • if target fails to connect to all Socks5 proxies it replies with “remote_server_not_found” error (before: “not_acceptable”)
  • extracted API for Socks5 bytestreams from file transfer API
    • Socks5 bytestream feature can now be used detached from the file transfer API
    • file transfer API is now based on that extracted Socks5 bytestream API
    • use Socks5ByteStreamManager#establishConnection() to initiate a Socks5 bytestream
    • use Socks5ByteStreamManager#addIncomingByteStreamListener() to listen for incoming Socks5 bytestream requests
    • use Socks5ByteStreamRequest#accept() to accept incoming Socks5 bytestream
  • improved timeout behavior for Socks5 bytestreams
    • response timeout to a Socks5 bytestream request is now configurable through Socks5ByteStreamManager#setTargetResponseTimeout() (was a constant)
    • timeout for target to connect to Socks5 proxies is now configurable through Socks5ByteStreamRequest#setTotalConnectTimeout() and Socks5ByteStreamRequest#setMinimumConnectTimeout()
    • every connection attempt to a Socks5 proxy now has a timeout so that connecting to an unreachable Socks5 proxy doesn’t consume the whole timeout for answering the Socks5 bytestream request
  • improved prioritizing of Socks5 proxies
    • Socks5 bytestream manager will set the last working Socks5 proxy to the top of the list of Socks5 proxies when establishing a new Socks5 bytestream
  • Socks5 bytestream feature can now be enabled/disabled
  • improved local Socks5 proxy server
    • port of the local Socks5 proxy server can now be configured by editing the smack-config.xml file or by SmackConfiguration#setLocalSocks5ProxyPort()
    • local Socks5 proxy can now be enabled/disabled by editing the smack-config.xml file or by SmackConfiguration#setLocalSocks5ProxyEnabled()
    • local Socks5 proxy replies to some bad Socks5 request with appropriate error messages to be more client-friendly
  • improved documentation of the implementation for maintainability
  • added about 40 tests with almost 100% code coverage of the changed code
    • added testing utilities to be able to test the code without using an XMPP server by mocking the XMPPConnection class

The patch is based on the current trunk of the Smack svn repository (rev 11621).

To run the tests the mocking libraries mockito and PowerMock are required.

Download the libraries here:
http://powermock.googlecode.com/files/powermock-mockito-junit-1.3.5.zip

Copy all files from the archive except the junit-4.7.jar and the *.pom files to Smacks “build” directory.

Note: The support of Socks5 bytestreams depends on the XMPP server (respectively the Socks5 proxy server) implementation. For example Openfire only supports Socks5 bytestreams within the scope of a file transfer by default. You can change this behavior by setting the “xmpp.proxy.transfer.required” flag to false. Additionally not all Socks5 proxy implementations support bidirectional Socks5 bytestream. Openfire only supports a directed Socks5 bytestream from the initiator to the target.

I hope you like the patch.

Best regards,
Henning
socks5bytestream.patch.zip (46638 Bytes)

1 Like

Hi Henning,

Thanks for your work and sharing it with the community! You should have a look on For Code Contributors Document to include your patch within our official release. Maybe you want continue to work with the community and join the mentorship program to get commit access for the sources?

Hi Guenther,

I just faxed the copyright assignment to Jive Software.

I would really like to join the mentorship program and maybe get commit access for the sources.

I am working on some more patches for Smack within the scope of my diploma theses at the Freie Universität Berlin and that would be very helpful.

Best regards,

Henning

Do you have already a Jira account? Please ping Daryl Herzmann with your account name, he can grant you the privileges to create an issue for tracking and documenting your patches.

Howdy,

Let me know your Jira account and I’ll get you all setup.

daryl

Hi Henning,

it’s exhausting to review your patch, because it includes many unnecessary formating changes (e.g. indentation changes, line breaks, brace changes). Could you cleanup and maybe split your patch? This would be great and make reviews a lot easier.

Regards

Guenther

With splitting I mean, it would be great if you can create Jira issues, e.g. add local socks 5 proxy configuration, support network address requests from proxy according XEP-0065: Initiator Discovers Network Address of StreamHost,… and assign these issues to me.

Ok, thanks for the hint.

I will split it in some smaller patches which should be easier to review.

Also I’m currently working on a document containing some code style guides for creating patches for smack. This could avoid the problem that patches contain unnecessary formating changes.

I couldn’t find anything like that and just choosed one of the codestyles I found in Smack and formatted everything the same way.

Maybe it would be a good idea to have this styleguide and format all the source in Smack the same way to avoid that problem.

Best regards,

Henning

Hi,

here is a new version of the SOCKS5 Bytestream patch. I fixed a few bugs I found and made the changes requested by Guenther Niess review.

The test cases are now separated into the unit tests and smack tests. I’ve also added a shutdown listener for the Socks5BytestreamManager.

Additionally I moved the classes Bytestream and BytestreamsProvider into subpackages of the socks5bytestream package according to our new code guideline.

The patch is now splitted in four parts:

The first adds a convenience class for the ConnectionListener which contains empty implementations for all methods of the ConnectionListener. This is useful if you only want to implement some of the methods and it makes the code look much nicer.

The second patch is the improved implementation of the Socks5 bytestream feature.

The third patch contains Utility classes for unit testing. These require the mockito and powermock libraries.

The last patch contains the test cases for the improved Socks5 bytestream implementation.

Best regards,

Henning
convenience_class_for_connection_listener.patch.zip (602 Bytes)
improved_socks5_bytestream.patch.zip (30322 Bytes)
unit_test_utilities.patch.zip (3564 Bytes)
improved_socks5_bytestream_tests.patch.zip (14064 Bytes)

Hi,

I’ve added some improvements to the Socks5 bytestream patch.

You can now add multiple local network addresses to the local Socks5 proxy. This might be useful if your application runs on a machine with multiple network interfaces or is behind a NAT und has a public IP that differs from the local IP.

I also fixed the strange behaviour that so socket returned by Socks5ByteStreamManager#establishConnection() had a fixed timeout of 10 seconds. It is now set to an indefinitely timeout so that calls to InputStream#read() won’t timeout anymore.

The JavaDoc for the adding the IncomingByteStreamListeners is updated and now states that these listeners won’t be informed on incoming Socks5 bytestream requests created in the context of a file transfer.

There are also some new unit tests to check the imrovements.

Greets,

Henning
convenience_class_for_connection_listener.patch.zip (602 Bytes)
improved_socks5_bytestream_v2.patch.zip (32288 Bytes)
unit_test_utilities.patch.zip (3568 Bytes)
improved_socks5_bytestream_tests_v2.patch.zip (14833 Bytes)