NitroNet - New, High-Level Networking Library

The myths in this thread are trivial to debunk.


Socket s = new Socket(...);
OutputStream os = s.getOutputStream();
os.write(new byte[414 * 1024]);
os.flush();
os.close();
s.close();

No exception is thrown, all data is sent, there is no need to split your data into tcp-packets by yourself, the TCP layer does that for you.

As for checksums: this is (hopefully!) not about information integrity, but about data integrity. Even with TLS your (generated?) private key is on the client’s machine, so it’s all hackable. What actually happens IRL however, is that the IP-packet checksum is merely checking the packet header, not the payload. Adding a checksum to the payload is ensuring that the data that the client sent (however malicious) is verifiable by the server as what the client intended to send. CRC32 is enough for this, as we’re checking for TCP payload-corruption, not an attack of any sort.

Data integrity, information integrity (signatures) and information secrecy (encryption) are entirely different topics. That SSL/TLS incorporates them all does not imply SSL/TLS is the right tool if one merely needs integrity. If you need information integrity, as to prevent a man-in-the-middle from altering your data, there is no need to add encryption to the mix. You can cryptographically sign raw data just fine and send it over the wire. There is just this pesky problem of which public keys you deem trustworthy to verify the signatures. In the end it’s about trusting a session, not a party and especially not a packet.

Anyway, the amount of misinformation on which this library was built, does not bode well for its potential users.

I decided to peek at the sourcecode, starting with Server.java, when I stumbled onto this:

https://github.com/baseball435/NitroNet/blob/master/src/com/jmr/wrapper/server/Server.java#L65


		try {
			tcpSocket = new ServerSocket(tcpPort, 1, InetAddress.getByName("0.0.0.0"));
		} catch (IOException e) {
			e.printStackTrace();
			throw new NNCantStartServer();
		}

A ServerSocket with a [icode]backlog[/icode] of 1. I have never seen this before and hopefully never will again, as it’s a sure way to bounce/drop incoming connections. By default the backlog is 50, I have had busy servers where I had to bump it to 200. A value of one would have gotten me pulled off the project instantly.

Not to meantion line 4 and 5 force log-verbosity, while hiding information (the true cause of the IOException) from the application, which is exactly the opposite of what one would want in a serious application.

This was obviously a simple mistake, with the backlog, and has been changed to be configurable in the configuration settings. I post my source openly to let others look at the code and point out things like this. So thank you. And my IO exception catch is printed out with a new error thrown after so that you would know the problem.

But that new error doesn’t keep track of what actually caused the error, just that the server can’t start.

Yes it is completely about data integrity and I am indeed using CRC32. It has no function in preventing attacks. I currently don’t have SSL implemented but I am going to try to work on an implementation for it.

There are so many things wrong with this I can’t just ignore it. Run away from this library. Run really fast, and don’t look back.

  • TCP in java is stream-oriented. All underlying primitives such as packets are transparently hidden by the OutputStream and InputStream interfaces. The OpenJDK implementation of this system is open-source, publically available, massively popular, and as a result, well peer-reviewed. It can be reasonably assumed to be error-free. Attempting to do additional disassembly and reassembly over the TCP streaming layer is ignorant and error-prone.
  • IEncryptor is useless. The existing OutputStream and InputStream primitives already have a transformation layer available. Just wrap your InputStream in your preferred subclass of FilterOutputStream, or more specifically a CipherOutputStream if it’s encryption you’re looking for.
  • While the easy part (creating a CipherOutputStream) is treated as if it were hard, the hard part (actually encrypting the data) is treated as if it were easy, offering no user-friendly primitives for dealing with keys or certificates where Java often drops the ball. Instead the tutorials casually suggest a ROT1 cipher, which is essentially plaintext.
  • Many other places in the code reflect a very basic ignorance of very common java functions. For instance, ComplexObject.java line 118-124 illustrates to me that the author does not know of the existence of System::arraycopy
  • Given these casual mistakes and ignorant design decisions, the likelihood for actual knowledgeable peer review is quite low, except in posts like this advising not to use the library. As such the code quality is also not likely to improve in the forseeable future.