summaryrefslogtreecommitdiffstats
AgeCommit message (Collapse)Author
2018-03-21Ensure JavaTimer.stop() cleans up any unresolved eventsAlex Clayton
The code for stop() in JavaTimer read: @Override public void stop() { timer_.stop(); //FIXME: This needs to clear any remaining events out of the EventLoop queue. } Where as the equivalent swiften code in BoostTimer was: void BoostTimer::stop() { { std::unique_lock<std::mutex> lockTimer(timerMutex); shuttingDown = true; timer->cancel(); eventLoop->removeEventsFromOwner(shared_from_this()); } } This patch updates the java code to bring it inline with the swiften code. In short to make sure it removes any remaining events from the event loop when it is stopped. Test-information: Code Inspection. Unit test still pass. Ran update stroke against M-Link Console it ran ok. Change-Id: Idf92e92d002b8404547702d1c34738165e331810
2016-09-13Fix cut-n-paste typoAlan Young
Change-Id: Ie57f18aee639d6ba911cd95ac6b45d048462c105
2016-07-15Stop HostAddress constructor running DNS lookup.Alex Clayton
When running the latest stroke against harrier android a NetworkOnMainThread exception was encountered. This was traced to the new constructor HostAddress(String) that was been called by Connector.start() method. The issue was dues to difference between the java code in stroke and the c++ code in swiften. In swiften the equivalent conde calls boost::asio::ip::address::from_string, which parses a string that may be an ipv4 or ipv6 address into an IP address object. If the string is not one of these then the object is left invalid. In the java code InetAddress.getByName(String name) is used instead. If this is an ipv4 or ipv6 address then it parses it into an InetAddress object. However if is not one of these it does a DNS lookup on the address. This was what was causing the error. To match the C++ the java code should only create an InetAddress if the input is an IP address, if not it should be left null. This was done by copying the IPv4 and IPv6 regexes in the Regex class in isode lib. The input to HostAddress(String) is checked against these if it matches InetAddress.getByName is called, otherwise address is set to null. Test-information: Ran unit tests in stroke they all pass. Ran code against android harrier, no longer fails. Ran against MLC (with updates for other changes in stroke api) it still passes. Change-Id: I1945c7c3cdfece8feb45b9196483131c0d9c4e7c
2016-04-20Remove use of Java 7 SocketChannel.getRemoteAddress()Alan Young
Not supported on Android. Change-Id: I55551ceeed06ab1ff4ce9e5995f809466d0e69bd
2016-03-22Try to fix possible race condition in Connector and ProxiedConnection.Alex Clayton
As per patch 'Fix possible race condition between Connection and Connectors' (7eec2000d72f8fa597398704121d0b73a84ca284). The issue occurs with ProxiedConnection that started connecting but do not have an external reference anymore. As soon as the handlers of the ProxiedConnection are disconnected from the signals of the connection_ object, the remaining references to a shared ProxiedConnection vanish and the ProxiedConnection is deleted, while it still requires access to its members in ProxiedConnection::handleConnectFinished(). Test-information: Unit tests pass ok. Change-Id: I6c81009262dd51cda17b1b93a15edf968f40e464
2016-03-15Add getRemoteAddress() method to Connection.Alex Clayton
Added a getRemoteAddress() method to connection as per patch 'Listen to IPv6 any address instead of only IPv4' (13801557b6664426cac26384441ab0b19ff9abb5). Also some modifications to SOCKS5BytestreamServerManager to use IPv6 address. Test-information: Unit tests pass ok. Change-Id: Ic0536745db9052ec1c5fc0832ed90eb5ec609429
2016-03-14Add getter for TLSContext in TLSConnection.Alex Clayton
As per patch 4a6950af0f324091553f7ab7271de45721b8667f (Rest of patch is for implementing TLS on OSX so no need to port). Test-information: Code inspection. Unit tests still all pass ok. Change-Id: I62b2f32f3cba0caa7db84f2806cd49b1a7a202e4
2016-02-29Finish porting on Network PackageAlex Clayton
As per PortingProgress.txt finsh porting all the classes I can from the network package. This involved some updates as the tests and code had changed since they existing classes had been imported. I have added notes for the classes I did not port in PortingProgress explaining why they were not ported. Test-information: All unit tests pass. Change-Id: Ibb52ae409f1da9b72a4c1e590cd22835a1be95eb
2016-02-29Add sort method for ServiceQuery and add TestsAlex Clayton
Add the sortResult static method to the DomainNameServiceQuery class. This required adding a few equivalances for C++ std library methods to the class. And add a test for the new method too. Test-information: All unit tests pass ok. Change-Id: Idee0888f7ea140d35a971414fc2fd3cbcdfc337f
2016-02-29Add Network Bosh ClassesAlex Clayton
Add the missing Bosh classes to the network packages (BoshConnection and BoshConnectionPool), plus tests for the classes and any other classes required by the new classes. Test-information: Units tests all pass ok. Change-Id: I5c2e05bae9e678ac10d2601c7fdbdccd68d66b71
2016-02-16Add the FileTransfer testsAlex Clayton
Add the missing FileTransfer tests to stroke. When porting the tests I found some of them were failing and required changes to the classes being tested to fix. Had to add a DummyNetworkEnvironment as well for the OutgoingJingleFileTransferTest. Test-information: All unit tests pass. Change-Id: Id511a556ef3a5d66e0e107f36f736db3bbb3a437
2016-01-14More Changes to NetworksAlex Clayton
Some more changes to the Networks classes. Based on comments on the last patch. Test-information: No longer see crash I was seeing when I ran the updated Stroke against MLC. Ran unit tests. Change-Id: Id577e5322bab0ec48f0353907f82e72bc93b848a
2016-01-12Make Networks equivalent with Swiften.Tarun Gupta
Adds ProxyProviders, DomainNameResolvers and DummyConnection. License: This patch is BSD-licensed, see Documentation/Licenses/BSD-simplified.txt for details. Test-Information: Tests added for ChainedConnector, Connector and HostAddress. Test also added for ComponentConnector, which needed bits of Network. Five assertions are commented in ConnectorTest, which fails and will be updated after review. Change-Id: I8a62841eb2f9c109bc3a94865b7a003b33493e11
2015-09-11Add JavaConnection.ActivityWatcher for watching connection activity.Alan Young
If a JavaConnection is supplied with a JavaConnection.ActivityWatcher at creation time, then each of its Worker threads will signal when they become active and when they potentially go to sleep (on select()). This allows clients to manage a device's power state or any other suitable subsystem. Change-Id: I3c83cb8ce5a087dd6fc5d402c75f830f5deca282
2015-09-11Improve efficiency of JavaConnection reads.Alan Young
Given that doRead() ends up populating a SafeByteArray as part of the result is is more efficient to pass an empty SafeByteArray to doRead() and push each chunk of data read directly to the it rather than use an intermediate ByteArrayOutputStream. SafeByteArray.getData() will do any concatenation necessary. It is unnecessarily inefficient to use a class instance to return the connection status from doRead. Remove JavaConnection.ReadResult. Change-Id: I6c8dc000d9030d3929c71444eb5b489df93f1987
2015-09-11Make JavaConnection fully event driven - no 100ms spinAlan Young
Refactor JavaConnection to make it fully event-driven via select for both reads and writes. Remove the 100ms spin when there are pending writes. Encapslate all the management of the select mask and the write queue within Worker and protect via a common lock. Change-Id: I1a709f9b12a949448923f51c2d434746c9190c9d
2015-07-28Fixed CancelledKeyException in JavaConnectionPeter Ballard
If synchroniseReads was enabled then if was possible for CancelledKeyExceptions to occur if the channel closed, whilst data was being procsessed on the event loop. I have also made the selectorKey_ reference volatile as this is used by both threads since my previous change 1afab8c1f2c417b08371bc12569e03171851d785 Change-Id: I48edcab9ef090b8a4561331d6aecc7f95cb8924d
2015-07-28Complete StreamStack and add tests.Tarun Gupta
TLSLayer could not be updated because it requires TLS to be ported first. Updates other classes, only for having compatibility with SafeByteArray because of updates in Stream Stack. License: This patch is BSD-licensed, see Documentation/Licenses/BSD-simplified.txt for details. Test-Information: Tests added for StreamStack and XMPPLayer, which passes. Change-Id: I8707fc1f16d622d2a90f6f39f671b7e7c46aa170
2015-07-08Add option to only read from TCP socket when previous read has been processedPeter Ballard
By default this option is disabled, existing usages will function as normal. This option stops the JavaConnection from reading data if the previous read has not been processed by the event loop. Previously constrained devices were seeing OutOfMemoryErrors, if they were not able to process the incoming data quick enough. This change does not affect the write behavour. Change-Id: I47bc0eafba32336f5bf250ccb1fea530f51d328e
2015-06-18Adds Jingle Elements.Tarun Gupta
Adds: JinglePayload, its Parser and Serializer and JingleReasonParser. JingleContentPayload Element, its Parser and Serializer. JingleDesciption Element. JingleFileTransferDescription Element, its Parser and Serializer. JingleFileTransferFileInfo Element, its Parser and Serializer. JingleFileTransferHash Element, its Parser and Serializer. JingleIBBTransportPayload Element, its Parser and Serializer. JingleS5BTransportPayload Element, its Parser and Serializer. JingleTransportPayload Element and HashElement. Updates HostAddress access specifier for getInetAddress(). License: This patch is BSD-licensed, see Documentation/Licenses/BSD-simplified.txt for details. Test-Information: Tests added for: JingleParser JingleContentPayload Parser and Serializer. JingleFileTransferHash Parser and Serializer. JingleFileTranferFileInfo Parser and Serializer. JingleFileTransferDescription Parser and Serializer. JingleIBBTransportPayload Parser and Serializer. JingleS5BTransportPayload Parser and Serializer. All tests passes. Change-Id: Ife1b7fef00efc57d8d0d4290f3280327439abbb6
2015-06-14Add support for Crypto-functions.Tarun Gupta
Completes the JavaCryptoProvider providing functionalities for SHA-1 Hash, MD5 Hash and HMACSHA1 Hash. Also updates reference for JavaCryptoProvider in JavaNetworkFactories. License: This patch is BSD-licensed, see Documentation/Licenses/BSD-simplified.txt for details. Test-Information: Tests are added for JavaCryptoProvider, which passes. Change-Id: I2439e5fd76a23e9b5c4e9132a9856543a7ca53fd
2015-05-13Make sure Stroke clears write buffer before disconnectingAlex Clayton
There was a bug with stroke where if I sent a large amount of messgaes (cica 1000) and then disconnected, not all the messages would be sent before storke handled the disconnect. It seems it did not fully lear the write buffer before closing the stream. This patch shoudl fix the error. It now only closses if the disconnecting flag is closed and the write buffer is closed. This should bring it into line with Swiften behaviour. Test-information: I had a simple stroke application that sent 1000 messages and then disconnected. Before the patch it would only send abut 80 or so of the messages before it got disconnected. After the patch it now sends all the messages before disconnecting. Change-Id: I6f56b25dcbabd16ee860dbf353f39559a77d6830 Signed-off-by: Alex Clayton <alex.clayton@isode.com>
2015-05-01Revisit handling of JavaConnection race conditions.Alan Young
JavaConnection.disconnect() can be called at any time when opening or using the connection. Its use can interfere with tests for selector_.isOpen(). Protect relevant code by synchronization blocks. This should not cause any contended synchronization issue as contention can only occur while disconnecting. This reverts the relevant part of 7d2101b9. Move selector_.select() call to end of Worker.run() while loop so that any write that is done while still connecting (if that is permitted and possible), and before selector_ first become non-null, is still picked up. Remove redundant checks on disconnecting_ and calls to handleDisconnected(null). Move a couple of fields which are only used in Worker nested class into Worker. Update copyright. Change-Id: I2eabad79c69fe4e9206942c8025e0ac012bffdb0
2015-04-10Checkpoint - A bunch of initial stuff for AndroidAlan Young
MemoryStorages, Storages NickManager, NickResolver CryptoProvider, Hash, SafeByteArray, JavaCryptoProvider CapsInfoGenerator, CapsManager, CapsMemoryStorage, CapsProvider, CapsStorage, CapsInfo CapsInfoSerializer, CapsInfoParser ClientDiscoManager, DiscoInfoResponder, EntityCapsManager, EntityCapsProvider GetDiscoInfoRequest ChatState, Idle Presence, PayloadAddingPresenceSender, PresenceOracle, SubscriptionManager StatusSerializer, StatusShowSerializer, StatusParser, StatusShowParser, Replace, ReplaceParser, ReplaceSerializer SecurityLabel, SecurityLabelsCatalog, GetSecurityLabelsCatalogRequest VCard, GetVCardRequest, SetVCardRequest, VCardManager, VCardMemoryStorage, VCardStorage RosterMemoryStorage, RosterPushResponder, RosterStorage, SetRosterRequest XMPPRoster, XMPPRosterController, XMPPRosterImpl, XMPPRosterItem GetRosterRequest, SetResponder Add parsers and serializers for Idle, VCard, PrivateStorage & Stroage. Add parser for Subject. Add impromptu flag to MUCInvitation. Update copyrights. Change-Id: I9949f506b70e60b3a64f1dadde8f9b235b322e1d
2015-01-13Don't call wakeup on closed selectorsNick Hudson
This operation should be valid according to Javadocs, but triggers a crash on Android Lollipop: https://code.google.com/p/android/issues/detail?id=80785 This workaround avoids the crash, and should not affect behaviour for all other versions. Test-information: Forced disconnect on Lollipop, didn't see crash. Tested MLC with deliberately dropped connections; seems to work as expected. Change-Id: Ia08476266dd92c40bea04076b3c3d8750737c309 Reviewer: Nick Hudson <nick.hudson@isode.com>
2014-10-24Don't disregard data that arrives on network just prior to socket closingNick Hudson
The JavaConnection code which reads from a socket detects a socket closure and emits a disconnected signal. It was noticed that on some occasions, data was arriving on the socket just before it was closed, and this data was never passed to the application. This happens when the server writes e.g. a "BYE" message and closes the socket straight away: when JavaConnection is woken to read the message, it does so and then goes on to notice that the connection has been closed and throws an IOException without passing the message back to the application. This patch fixes the problem by making sure that any data read prior to the close being noticed is sent to the application before the closed signal is emitted Test-information: It was possible to provoke the problem by deliberately breaking socket connections - if you do this often enough you see cases where data read from the socket is lost. After this patch, such cases do not result in data loss. Also tested with email client and verified that connections to icloud.com which previously had provoked this problem when authentication failed now seem to return all data reliably. Change-Id: Ieba0f4186b7c91e55f5f1a4b3b64bc923006b933
2014-10-24Fix JavaConnection to emit onDataWritten when it writes data to the socketNick Hudson
The java code was never emitting the onDataWritten signal, although the corresponding C++ code in Swiften does do this. This change causes the signal to be emitted whenever a data is successfully written to the socket. Test-information: Tested using an application which was registering for the signal; previously it never saw "onDataWritten"; now it does. Tested using an application which doesn't register for the signal; it works as before. Change-Id: I1399af0721ef8226c0c4d2420bbe23f53ad3494f
2014-07-24Apply a Connector timeout even if not using SRV lookupsNick Hudson
Corresponds to the Swiften change of the same name, d949d1638c Test-information: Unit tests pass. Verified that the new code works as expected in a test application that previously would never see timeouts. Change-Id: I95cc73a81e42d6ac00c79f74531e8dd6c67882f3
2014-04-22Move hardcoded XMPP SRV information from Connector into CoreClientNick Hudson
The Connector class had "_xmpp-client._tcp." hard-coded in it, which meant that it was not suitable for non XMPP clients. This change means that Connector could now be used by clients who are interested in arbitrary SRV records; the CoreClient class is updated accordingly. Test-information: Built and tested using MLC. Also tested with a client that is interested in IMAP SRV records Change-Id: Ia23c148fd8afdd7b3271c47b1c96d086d57a44bd
2013-11-09Allow /etc/hosts to override DNS host lookupsAlex Clayton
A recent change made Stroke use the dnsjava library instead of JNDI for domain service queries, because JNDI had problems with IPv6 addresses. The change also replaced the use of Java's standard InetAddress class for name resolution with the Address class inside dnsjava - this change was not neccessary, and is problematic because although the documentation for "Address" says that it "Includes functions similar to those in the java.net.InetAddress class", it does not provide equivalent functionality. Specifically, whereas InetAddress.getAllByName() will use the local system's "host" file when attempting to resolve hostnames, the corresponding Address.getAllByName() method in dnsjava does not do this. This means that if a user inserts values into /etc/hosts, they will be ignored by the Address.getAllByName(). As a result, users who had expected stroke to honour values in /etc/hosts (which is something you might want to do just for testing purposes) will be surprised when it stops doing this. So this patch reverts the code in question to use InetAddress instead of dnsjava's Address class. Test Information I added the following lines to my /etc/hosts file. 127.0.0.1 alexmac.com 127.0.0.1 alexmac.clayton.com At time of the testing there already existed an external domain with name alexmac.com but none corresponding to alexmac.clayton.com. I then ran the 'Check DNS for a domain...' dialog in the MLC Help Menu. Before the patch this would give me the the details for the external domain for 'alexmac.com' and say no DNS could be found for 'alexmac.clayton.com'. After the patch the correct details (i.e 127.0.0.1) were returned for both domains. Also, before the patch I could not connect to the local xmpp server 'alexmac.com'. After the patch I connected correctly. Change-Id: If7f15b8aa98313278a1892eb27a5f73aaea8802b
2013-10-30Re-implement DNS lookup to use dnsjava rather than JNDINick Hudson
There are limitations when using JNDI for DNS lookups, including that it does not properly handle the situation when resolv.conf contains IPv6 addresses (Isode bug #44832) - see e.g. http://java.net/jira/browse/JITSI-295 JNDI is also not readily available on Android, which makes it slightly more awkward to use Stroke on that platform. This patch changes the PlatformDomainName classes so that they use classes from dnsjava rather than JNDI. The patch also updates the build scripts so that dnsjava.jar is fetched (if necessary) and included in the build. Indentation in build.xml has been tidied up Test-information: Ran unit tests - ok Ran MLC - works OK and no longer throws NumberFormatExceptions when resolve.conf contains "nameserver 2001:470:f052::2" Change-Id: Iacf1105c52c281f9e59b60ea6caa011914b588dc
2013-10-15Revert "synchronized" patch and fix use of ByteArray inside JavaConnectionNick Hudson
Some discussion followed the "Fix synchronization problem in ByteArray" patch, and that led us to believe that it would be better to change the JavaConnection class so that it does not rely on being able to pass ByteArrays around in a way that makes them vulnerable to the problems that had been seen. The JavaConnection class accepts a ByteArray in its "write()" method, and emits a ByteArray when it has read data. ByteArrays are not the ideal way for the JavaConnection class to manipulate data and so this patch changes the implementation so that: a) the "write()" method extracts the byte[] from the supplied ByteArray and uses these objects, rather than keeping references to the ByteArray objects (which might lead to synchronisation issues). b) the "doRead()" method uses a ByteArrayOutputStream to hold incoming data, and only constructs a ByteArray out of it when it is ready to return the data to the application. These changes make the class more efficient, since in the case of (a), the need to create temporary ByteArrays is removed, and in (b) the code no longer creates ByteArrays by iterating through the network data one byte at a time and appending it to a ByteArray. It also means that the "synchronized" patch (which would fix the problem) is no longer necessary, and so that code is reverted. Test-information: I patched the code to emulate the situation that would occur when a buffer is only partially written, and verified that in this case it correctly re-inserted the unwritten portion of the buffer at the front of the pending queue. Ran MLC to various servers, all seems to work OK. Tested in Harrier, seems to work OK, and does not exhibit problems that we had seen previously which led us to investigate this issue. Change-Id: Ifcda547402430c87da45ba7d692518b5af285763 Signed-off-by: Nick Hudson <nick.hudson@isode.com>
2013-09-19Fix PlatformDomainNameResolve DomainNameAddressQueryAlex Clayton
In the PlatformDomainNameResolver class there is a DomainNameAddressQuery class (accesible via DomainNameResolver->createAddressQuery()) for performing a DNS lookup on a given domainname. This should have been returing the set of all HostAddress associated with a given domain, but instead was only returning a singleton set (or empty if there was no dns). This patch fixes this by changing the method call from InetAddress.getByName() to InetAddress.getAllByName(). Test-information: Tested on top of my MLC Diagnose SRV patch. For 'google.com' we now see a full list of ip addresses associated with it, rather then just the one. Change-Id: I6e57c16bb64f76048f16bcff8ee9c1924049a051
2013-09-18Update NetworkFactories to own TLSContextFactory as per SwiftenNick Hudson
This change moves responsibility for creating the TLSContextFactory from CoreClient into NetworkFactories, which is in line with the Swiften implementation. This means that a caller may now provide his own concrete TLSContextFactory using code of the form: NetworkFactories myNetworkFactories; . . myNetworkFactories = new JavaNetworkFactories(eventLoop()) { @Override public TLSContextFactory getTLSContextFactory() { return new MyTLSContextFactory(); } }; Test-information: I implemented separate TLSContextFactory and TLSContext classes that used OpenSSL via JNI) to provide SSL functionality. I was able to switch to using these with the mechanism that this patch provides. I also verified that existing code which doesn't try to provide its own NetworkFactories subclass still works as before (i.e. this patch doesn't break existing applications). Change-Id: Ibf07ddbbb4a4d39e4bb30a28be9aa0c43afe005f Signed-off-by: Nick Hudson <nick.hudson@isode.com>
2013-08-12Null check for selector before trying to close itGurmeen Bindra
It is possible to have a null selector if socketchannel open failed so adding a null check in this patch. Test-information: sanity tested on linux by connecting/reconnecting on an xmpp service on linux Change-Id: Idee180ca4aefd1f743705da674b486dd8acc4922 Reviewer: Nick Hudson <nick.hudson@isode.com> Reviewer: Kevin Smith <kevin.smith@isode.com>
2013-08-09Close selector with socketchannelGurmeen Bindra
I left MLC which is an XMPP Client running overnight and noticed "Too many open files" error when trying to stop/start xmpp server. On doing an "lsof | grep java", I noticed a large number of open sockets which was presumably the cause of this error. After this patch, the lsof command shows a constant number of open sockets. Test-information: tested on centos vm by doing "lsof | grep java " wc-l"-open sockets do not increase. Change-Id: I7ddff78a1efb005177427fda21f1d0b92d8ed7cc Reviewer: Kevin Smith <kevin.smith@isode.com>
2013-07-26Re-implement JavaConnection to use SelectorNick Hudson
When investigating problems on Solaris, attention focused on the JavaConnection class, whose implementation appeared to be non-optimal. The original implementation had a loop which operated on a non-blocking socket, and looked something like this: while (!disconnecting) { while (something to write) { write data to socket; if write failed { sleep(100); // and try again } } try reading data from socket if (any data was read) { process data from socket; } sleep(100); } Because the socket is non-blocking, the reads/writes return straight away. This means that even when no data is being transferred, the loop is executing around ten times a second checking for any data to read/write. In one case (Solaris client talking to Solaris server on the same VM) we were consistently able to get into a state where a write fails to write any data, so that the "something to write" subloop never exits. This in turn means that the "try reading data" section of the main loop is never reached. Investigation failed to uncover why this problem occurs. The underlying socket appears to be returning EAGAIN (equivalent to EWOULDBLOCK), suggesting that the write fails because the client's local buffer is full. This in turn implies that the server isn't reading data quickly enough, leading to the buffers on the client side being full up. But this doesn't explain why, once things have got into this state, they never free up. At any rate, it was felt that the implementation above is not ideal because it is relying on a polling mechanism that is not efficient, rather than being event driven. So this change re-implements JavaConnection to use a Selector, which means that the main loop is event-driven. The new implementation looks like this while (!disconnected) { wait for selector if (disconnected) { break; } if something to write { try to write data; } if something to read { try to read data; } if still something to write { sleep(100); post wake event; // so that next wait completes straight away } } Test-information: Testing appears to show that the problems we saw on Solaris are no longer seen with this patch (Solaris tests still fail, but later on, which appears to be due to a separate problem). Testing shows that this leads to the thread spending much more time idle, and only being active when data is being read/written (unlike the original implementation which was looping ten times a second regardless of whether any data was being read/written). Testing using MLC seems to show the new implementation works OK. I was unable to provoke the "write buffer not completely written" case, so faked it by making the doWrite() method constrain its maximum write size to 200 bytes. By doing this I verified that the "leftOver" section of code was working properly (and incidentally fixed a problem with the the initial implementation of the patch that had been passing the wrong parameter to System.arrayCopy). Change-Id: I5a6191567ba7e9afdb9a26febf00eae72b00f6eb Signed-off-by: Nick Hudson <nick.hudson@isode.com>
2012-10-02Don't crash when overriding the connect hostKevin Smith
2012-09-21Update some interfaces for consistency with Swiften.Kevin Smith
Makes ClientOptions do more.
2012-08-20Close socketChannel in finally blockGurmeen Bindra
In one of my testing scenario, socket was not getting closed. This was happening when an XMPP client was connecting to a domain which was different from the domain in the jabber ID of the connection user. Moving the close call to a finally block ensures that socket gets closed in all scenarios. Test-information: I created an IM domain j.com on my XMPP Server and then added a user with that domain (user@j.com). Then I tried connecting to my Primary domain using this new user. After removing j.com, I could an increase in number of sockets after every poll (coreclient.connect()) but not after this patch.
2012-08-16Close DirectoryContext after receiving resultsGurmeen Bindra
If I leave an Application using Stroke running for a few hours(making periodic connection attempts), the JVM would throw an Exception saying "Too Many Open Files". On doing an "lsof -p <pid_of_jvm>", I noticed that there were number of open sockets in CLOSE_WAIT state and these went up after every attempt to do a connect on CoreClient object. Closing of DirContext object fixes this bug and the number of open sockets does not increase. Test-information: Ran MLC and kept on monitoring the result of "lsof -p <pid>". It would not increase after this patch.
2012-07-17Move DNS resolution into a thread to make the API asyncronous.Kevin Smith
2012-04-20Also emit onDisconnected after a manual disconnectKevin Smith
2012-03-13Fix up mistakes in previous patchNick Hudson
I broke the "getLocalAddress()" method. This fixes it. Test-information: By debugging and looking at "JavaConnection.toString()" output
2012-03-13Update JavaConnection to use SocketChannel rather than SocketNick Hudson
The initial implementation of JavaConnection used the "Socket" class, from which it derived InputStream and OutputStream objects to read/write data. In order to avoid blocking, the "read" loop would only attempt to read data if the InputStream.available() method indicated that there was data ready to be read. However, in order to determine that an InputStream has been closed, you have to read from it and have it return -1 to indicate "end-of-stream". There was no explicit test for a -1 return, but even if there had been, it wouldn't have tripped, because of the "available()" test. So this change makes JavaConnection use "SocketChannel" rather than Socket, which allows (when you configure the SocketChannel to be non-blocking) you to issue non-blocking reads which *can* return -1 when the input stream has finished. Test-information: Tested with test program and MLC, using both TLS and non-TLS connections. Applications still work as expected. Observed that when I deliberately stop the server, or break the socket connection, the client almost immediately gets a "disconnected" signal. Prior to this change, stopping the server results in the client getting a disconnected signal only when it next tries to write something.
2012-02-23Allow non-standard ports on internal interface methodKevin Smith
2012-02-13Tidying up based on feedback from patch for initial TLS implementationNick Hudson
Hopefully the changes speak for themselves. Some feedback relating to JavaCertificate has not been addressed; that will be done in a separate patch Test-information: Can still establish sessions with / without TLS
2012-02-13Initial implementation of TLS supportNick Hudson
Note that TLS won't be enabled with this patch unless you uncomment the change in PlatformTLSFactories. With that comment removed, then a new CoreClient session will attempt to negotiate TLS if the server supports it. Further changes are required to support this properly, as there appears not to be comprehensive support in the CoreClient class for dealing with situations when the server's certificate is not acceptable. There's also no support yet for setting up client certificates. Further changes will also be needed (see below) to support full parsing of subjectAltNames from server certificates. Significant changes are as follows - TLSProceed - FIXME comments removed - JavaConnection - changed so that it reads bytes from the socket's InputStream, rather than reading chars and then constructing a String out of them from which a byte array is then extracted. While this seemed to work for non-binary data (e.g. non-encrypted XMPP sessions), it breaks when you start sending binary (i.e. TLS) data. - JavaTLSConnectionFactory - implemented - PlatformTLSFactories - By having this return a JSSEContextFactory, then this will cause the client to try TLS if possible. But because other changes are needed to make this work properly, the current code still returns null. - JSSEContext - new class which uses an SSLEngine to handle TLS handshake and subsequent encryption/decryption. This is the main substance of the SSL implementation Note the "hack" in here to cope with SSLEngine requiring that some data be sent from the application before it will do a TLS handshake - JSSEContextFactory - just creates JSSEContexts - JavaCertificate - this wraps an X509Certificate and does *some* of the parsing of a certificate to look for stuff that is expected when verifying an XMPP server certificate (RFC 6120 and RFC 6125). Note that the JDK classes for parsing certificates don't provide an easy way to decode "OTHER" subjectAltNames, and so this implementation does not find XMPP or SRV subjectaltnames from the server certificate. This will need extra work. - JavaTrustManager - obtains the server certificate from the TLS handshake and verifies it. Currently the only verification done is to check that it's in date. More work will be needed to perform proper validation - Where necessary, Remko's copyright comments were changed from GNU to "All rights reserved". Isode copyright notices updated to "2012" Test-information: Set up XMPP server with its own certificate, and checked that TLS gets negotiated and starts OK (provided the server cert contains e.g. a DNS subjectAltName matching its own name). Subsequent operation appears to be as expected.
2012-01-18Add toString to some more classesNick Hudson
Also made "Stanza" be an abstract class and had its ".toString()" include the name of the subclass which is involved, so that the subclasses don't have to do that themselves. Also added null check to existing HostAddress.toString() method Also fixed Remko copyright in Connector class Test-information: Stuff is displayed as expected in debugger.
2012-01-16Update JavaTimer class to guard against premature timer expirationNick Hudson
The JavaTimer class uses Thead.sleep() to wait a specified number of milliseconds. Thread.sleep() requires the caller catch InterruptedException, but in the original implementation, such an exception would result in the code assuming that the specified time had been reached. So as things stood, if you e.g. set a timer for 60 seconds, then the timer might generate its "onTick" signal before that 60 seconds had elapsed. This patch changes the code so that the method will wait until the specified time has been reached. The "milliseconds" parameters are also changed to "long", which is the type used by the rest of the java library for millisecond values. Added a bit of javadoc and a toString() method as well. Note there is still a "FIXME" in the code which I've not addressed. Test-information: Tested in debugging setup; things seem to be working as expected.