OOB data when implementing Telnet protocol server in Java - java

I'm writing a little text-based game server in Java. The telnet protocol is surprising more complex than it expected, and in particular, they make use of "Urgent" or "OOB" data.
I'm struggling to understand what might be lost if I either ignore OOB data, or if using "setOOBInline(true)" will lose context and cause ambiguity.

It's a difficult problem.
If you set OOB inlining to false, you lose the notification.
If you set OOB inlining to true, they potentially get injected in the middle of something else.
One possible solution is a lead provided by this answer:
Java sockets with out of band data
Apparently, the Tomcat 6.0 codebase has a JNI implementation of sockets that handles OOB differently. It looks like you could use atMark(...) to test whether the socket has just received an OOB marker.
UPDATE - After reviewing the telnet protocol spec, it seems that the effect of losing the OOB notification would not be a show-stopper. Telnet's "synch" mechanism entails sending an OOB notification, and adding a "DATA MARK" command to the regular stream. It tells the receiving end that it can throw away data (but not telnet commands) until it sees the "DATA MARK".
If the receiving end misses (or ignores) the OOB marker, then the net effect is that it doesn't ignore the data. That is "mostly harmless" behaviour. Not ideal ... but it doesn't stop telnet from working.
Fortunately (as #EJP noted) the TCP OOB notification mechanism is rarely used these days. So Java's limited support for it hardly matters.
It is also worth noting that handling OOB notifications is not just a Java problem. Apparently, different implementations of the (native / C) socket APIs handle it in incompatible ways.
Reference: Protocol-Independent Out-of-Band Data.
The best advice is to avoid OOB entirely if possible. Certainly don't design it into new protocols.

Related

Preventing connections from illegitimate clients

I've got a client/server setup in Java. The client currently transmits a calculated value to the server (via socket, in addition to login/password) in order to authenticate.
However, there is currently nothing preventing a maliciously decompiled and refactored client from connecting, because all it would need to do is send the same authentication data.
Given that decompilation reveals everything my client is doing, is there really any way to reasonably prevent connections from modified clients? It seems to me that the only way to accomplish this is to generate a unique token that a modified client (with identical token-generation logic) would, somehow, be incapable of generating.
You cannot really avoid fake clients (look at how proprietary softwares/protocols get reverse-engineered), but that's no problem because you should never trust the client: check every request he makes so that he cannot cause problems. If you do so, even a fake client will have to respect your rules and will not be a problem at all.
Anyway, another way is to make the protocol you use obfuscated so it cannot be easily decompiled and the protocol cannot be reverse-engineered, but you would be amazed by the ability of certain people to break what you do anyway. Making your code obscure is rarely a benefit and makes you loose time most of the time.

How can I implement a good Client-Server approach?

I'm developing a distributed application, and I need to connect a client Java based to a server C++ based. Both of them will need to send information to each other, but I need them to be able to do things while waiting for the information, and they don't know when they are gonna get new information, or send information.
How can I achieve this? Now I'm trying to implement a basic communication with Sockets, but I don't really get to communicate them. I have read that using sockets + threads is usually a good approach for client-server apps.
Could you please recommend me some web or book to read about this, or send me some example code to learn?
Do you think that i should use other approach, better than sockets? maybe a higher level library (i would need it for c++ and java) or a totally different way?
EDIT:
I will add some extra information.
What I would love to achieve is the following:
My C++ program has a main loop, where I would like to have a call like GetUpdatedDataFromRemoteDevice() where I read the new values of some numerical variables that previously got updated from the net (the socket, for example).
Eventually, the C++ program will need to send a message to the remote device, to tell him to send other kind of data, and after that, keep getting the updated values.
From the Java program (remote device) the application running is an interactive touchable screen, that cant get blocked by the network transmissions, because it must keep working for the user, so all the networking should be done in a separated thread.
That thread, should connect to the server, and when a button is pushed, start to send the data (4 changing numerical values) in a loop until another event happens.
It would be nice also to be easily re-connectable to the server.
ICE is a modern and good library for distributed applications:
many languages as C++ and Java
many platforms
GNU GPL
good performance
easy to use
First, you define the messages you want to exchange between server and client.
Then, you implement the C++ and Java source code to handle these messages.
More info at http://zeroc.com/ice.html
Have fun ;-)
EDIT: I have to use ACE in some projects. I can tell ACE is very old, maybe mature, but uses outdated C++ coding rules :-(
Therefore ACE is not as easy to use as STL or BOOST. Moreover, ACE is not really efficient... I prefer ICE ;-)
I don't know what your application is but robust client server socket programming is pretty hairy task to do properly. Hardware byte order, String encoding, Network errors, retries, duplicate messages, acks etc.. require lots of good design and careful programming. You need to get it work well as single-threaded before even thinking using multiple threads.
Unless you need instant notifications from server to client I suggest that you use HTTP as protocol between client and server. Client can poll server occasionally for new messages.
Anyway the problem has been solved multiple times already.
http://activemq.apache.org/
http://www.rabbitmq.com/devtools.html
http://www.cs.wustl.edu/~schmidt/ACE-overview.html
I did something of this sort once. In my case it was easier to connect my C++ app to a local Java app using JNI and then have the two Java apps talk to each other.

Create network errors for testing a distributed system

I am developing a Java library for communication via HTTP, and I want to test its reliability and performance in case of network problems such as packet loss, high latency, low bandwidth, and congestion. I'm using Apache's httpclient library for doing connections from client side, and Java's own com.sun.net.httpserver.HttpServer for starting up HTTP servers.
Are there libraries available that do that kind of thing, or should I roll my own? I guess I could try to plug my own org.apache.http.conn.scheme.SchemeSocketFactory into the client side, and simulate several of the problems mentioned above with that, but I'd prefer to use something that works already :-)
This is similar to question Creating TCP network errors for unit testing, but I'm looking for solutions involving Java on Linux. I've looked at click, which was suggested for that question, but I'm not sure it can provide what I'm looking for.
Since Java API's do not have access to the low level network API's, emulating it would be challenging.
Alternatively The Apache HTTP Core components library may have something to help you simulate latency and data loss and possibly bandwidth issues. The library has the feature to inject your own session input and output buffers. You can find the documentation at Advanced Features of HTTP Core
By injecting your own buffer
Latency can be a small delay injected into the read and writes
Data loss is some bytes thrown away. It is not packet loss in the true sense, since there is no resending of duplicates.
Bandwidth can be limited by tuning the read/write and flush operations.
Traffic is hard to simulate except as an over all slowdown of reading and writing to the buffer.
You can also look at TCPProxy available in the Grinder project. I haven't looked at it in detail. The documentation shows EchoFilter as an example but I believe it should be possible to extend the filters to delay the sending and receiving of bytes within the stream. But it makes sense to use a proxy to simulate network issues. This way your client and server remain blissfully ignorant of the testing going on.
In both cases simulation of the network issues seems to be the best effort possible in Java.
Or else you can setup a local firewall and have it configured to intercept and play with the packets it receives.
Hope this was helpfull.
If you are not integration testing the system, I.E running the full stack with external servers and so on, then using mocking tools is what you are looking for. They allow you to record the behaviour of the library you are working against. This save you running the library code, which should not need verification.
Using something like mockito, or if needed PowerMock, you can tell the library to throw exceptions when a method you invoke is invoked.
Example:
import static org.mockito.Mockito.mock
import static org.mockito.Mockito.when
...
#Test(expected=HttpException.class)
public void invockationThrowsHttpException() {
...
HttpClient httpClient = mock(HttpClient.class)
when(httpClient).executeMethod(args...).thenThrow(HttpException...)
underTest.invokeCodeUnderTest(args...)
...
}
The above example assumes JUnit4. There is a pretty good tutorial on the Mockito website. PowerMock is used if you need to mock things that mockito does not mock (for example static or final methods).
As an aside I noticed that Apache's HTTP Client is on End of Life and that they recommend switching to Apache HTTP Components instead. If your project is still in early stages it may well be worth switching now.
Instead of trying to implement network errors (in your case it could mean to modify the httpclient library or simulating errors and delays in the Server), you should consider to use a WAN Emulator like WANEM. It would be a simpler and more feasible solution, in my opinion.

Is there a request–response networking API for Java?

I'm looking for a simple java library which would enable to write code in the following fashion:
Remote remote = Remote.connect("some_host:1234");
Future<String> response = remote.request("hello");
// do something else
String reply = response.get();
It should be based on tcp/ip and use plain text messages across the network to be language agnostic, so that non-Java servers are also able to send/receive requests/responses.
(Before telling me to use plain sockets, keep in mind that in that case you need to implement wrappers to delimit payload, care about received messages reordering, thread handling... the example is simple, but it is not that trivial to implement well.)
Is there any existing API out there like this?
PS: ...the simpler, the better!
Take a look at JMS.
Use plain sockets :-)
Sockets use TCP, and TCP takes care of payloads, multiple packets and ordering. You'll still need to handle the threading, but java.util.concurrent has all you need for this. Don't forget to decide of a character encoding for your strings.
TCP implementations usually give to the applications only a stream-like interface, with no access to the individual packets. (Also, some routers/firewalls might want to repack the data in the TCP streams, which means that they do not necessarily arrive in the same blocks as sent.)
Thus we really need to use some packaging protocol on top of TCP (or really on top of any stream-pair).
A really simple protocol would be one line for each request/response, but this will work only with small data sizes (or you need to somehow escape embedded newlines).
If you want it more structured, you could use something XML-based (like XMPP): each request/response would be a complete XML element (including subelements, if necessary).
Also, if you want to use the request–response scheme, you will need to either say responses have to come in the same order as the requests were ordered (which disallows or at least complicates parallel processing on the server side for multiple requests on the same connection), or you will have to define request numbers, and the responses then will somehow include the request number they relate to.
As examples, HTTP uses the first approach (from 1.1 - before there was only one request/response pair for each connection), while the X protocol uses the second one.
For HTTP, there are already implementations around (both on client and on server side), and it can be made totally plain text (depending on the data you are sending).
Alternatively, we could build our protocol directly on a packet-based protocol like UDP. But this has the usual reliability problems of UDP, and we also need to use message-numbers (to relate responses to requests) or such - which could mean that we have to re-implement half of TCP again.
So, sorry, no real answer other than use HTTP.
With Apache Mina you're able to develop your own protocol, but it might be overkill.
I am not aware of any library which gives you a layer quite like this over sockets. The IMAP protocol has a framing layer which is quite like this, but i don't know of any way to use it independently of the rest of IMAP. Such a library would be simple enough to write, and potentially quite useful, so if anyone fancies trying it, i encourage them to do so!
The closest thing i can think of to what you want is ZeroMQ in request-reply mode. ZeroMQ is written in C, but there is a Java binding. It's a pretty good library - there are bindings for many languages, so it's practically language agnostic, and it does indeed take care of delimiting payload, caring about received messages reordering, and thread handling. I don't think it's plain-text, though.

Writing a CANopen test utility

How do I listen in (preferably using Java) on a small set of well-defined CANopen messages without a commercial CANopen stack?
There is really nothing special about CANopen in this regard. If you are able to read CAN data from the CAN bus you should be OK. The CAN ID of the messages will identify them, and the interpretation of the data will be given in the data emitting device's documentation.
It's hard to give a generic answer on how to read the data, because everything depends on your hardware situation. However, before you can listen to any CAN messages, you need a CAN interface for your computer. The CAN interface's documentation will probably tell you how to use it.

Categories

Resources