tcp

Server bully test

Well, not exactly crashed the server, but I stopped it from running which is a proof of concept.

With a simple Java program which sends legitimate requests from a legitimate device, the server failed after a few minutes. A quick manual restart over ssh got it up and running immediately.

public class BullyServerTest {
    
    public static BullyServerTest bst;

    public static void main(String[] args) {
        bst = new BullyServerTest();
    }
    
    boolean quit = false;
    
    private final String server_host = "SOMEWEBADDRESS"; // LOL
    private final int server_port = SOMESECRETNUMBER;
    
    private final String home = System.getProperty("user.home") + "/";
    
    public BullyServerTest() {
        Runtime.getRuntime().addShutdownHook(new Thread() {
            public void run() {
                quit = true;
                try { Thread.sleep(1000); } catch (InterruptedException ex) {}
            }
        });
        
        while (!quit) {
            try { Thread.sleep(randInt(10, 250)); } catch (InterruptedException ex) {}
            do_hello_world_bully();
        }
    }
    
    Random rand = new Random();
    
    private int randInt(int min, int max) {
        return rand.nextInt((max - min) + 1) + min;
    }
    
    private static final int COMMAND_HELLO = 1234;
    
    private void do_hello_world_bully() {
        int count = randInt(10, 100);
        System.out.println("HELLO WORLD BULLY at " + count + " times");
        
        while (count-- != 0) { // a shed load of threads at once
            new Thread(runnable_HW).start();
        }
        
        System.out.println("Completed...");
    }
    
    Runnable runnable_HW = new Runnable() {
        @Override
        public void run() {
            try {
                WLSocket socket = new WLSocket(server_host, server_port);

                socket.out.writeInt(COMMAND_HELLO);
                String hello = socket.in.readUTF();
                
            } catch (IOException ex) {
                System.out.println("Server failed with HELLO WORLD response");
            }
        }
    };
}

So the next step is to implement a thread pool so that the server will not hang on too many requests. It ran for less than a minute. The above program kept running until my 12Gb RAM ran out which was a bit longer. The current server does only have 4Gb RAM and couldn’t handle the amount of connections at once. I’ve also had to keep the sudden bandwidth usage down as I was hitting my upload and download limits.

Eventually the server and client code will all be rewritten in C++ and handle such things as low latency timeouts.

This has been a very interesting test. I’ll be leaving the hello world server command in for future testing to simulate fake requests.

Devices unique identifier

Now I could have just got the MAC address and used that to communicate with the server, but I wanted to take it to the extremes. Mainly because I wanted to obscure the communication with the previous methods of encryption so the server can identify which device is making a request.

For this I create a string using the devices host name and all the network interfaces connected to it with their MAC addresses. Although I might change this in the near future, at the moment, this gives a good length string for the server to identify the device.

Below is the code used to create this identity string.

    public String host;
    
    private void testMACAddress() {
        try {
            InetAddress ip = InetAddress.getLocalHost();
            
            host = ip.getHostName();

            Enumeration&ltNetworkInterface&gt networks = NetworkInterface.getNetworkInterfaces();
            while (networks.hasMoreElements()) {
                NetworkInterface network = networks.nextElement();
                byte[] mac = network.getHardwareAddress();

                if (mac != null) {
                    StringBuilder sb = new StringBuilder();
                    
                    for (int i = 0; i &lt mac.length; i++) {
                        sb.append(String.format("%02X%s", mac[i], (i &lt mac.length - 1) ? "-" : ""));
                    }
                    
                    host += " " + network.getDisplayName() + " " +  sb.toString();
                }
            }
        } catch (UnknownHostException | SocketException e) {
            System.out.println(e.getMessage());
        }
    }

As mentioned above, this identity string will then be encrypted and sent to the server. Further communication will commence if the server accepts it.

TCP Encryption

Tonight I grabbed an old class that uses a pseudo random number generator and implemented it into the TCP client server encryption test. Both the client and server create a new Object of the class and both set the same seed. Both the client and server will grab the next byte and add the next random number to it on a read, on a write, it will subtract the next random byte.

This worked as expected. The following code is an example of a complex random number generator.

public class WLPRNG {
    
    long seed;
    
    public WLPRNG(long seed) { this.seed = seed; }
    
    public int nextInt() {
        long result = seed + 0x123defca;
        result = Long.rotateLeft(result, 19);
        result += 0xbead6789;
        result *= 0x1234567c;
        
        int temp = (int)result;
        
        result ^= 0x5ecdab73;
        result = Long.rotateLeft(result, 48);
        
        if (temp % 4 == 0) result *= 0x87650027;
        
        result += 13;
        seed = result;
        
        return (int)result;
    }

    public byte nextByte() {
        return (byte)nextInt();
    }
}

The next step for me to try out is to use and encrypted message from the client which sends the MAC address of the client using encryption, and then both the client and server will communicate using the MAC address as a key for another pseudo random number generator.

Over time, the server can update the encryption methods used by the clients.

Cryptography Secure TCP Sockets in Java

Well, I finally got round to testing out a basic encryption over TCP sockets.

First off, the main() entry looks very familiar and is easy to understand. I simply create the listening server (doesn’t spawn thread for simplicity), with the ability to safely shut it down.

Then I use the DataInputStream and DataOutputStream to send data back and forth. In this test case I sent a string which both the client and server will print to the console.

Once that was working, I extended the OutputStream and InputStream and override the read() and write() methods (shown in the code examples below). Notice that I manipulate the byte in two different ways, one by adding and subtracting and the other by XOR’ing (commented out but works). If these manipulations match up whilst data is being sent back and forth then there’s no errors.

Main class

The main class and entry point to the test which spawns the server and then runs a couple of tests:

package com.wlgfx.cryptotest;

public class CryptoServer {

    public static void main(String[] args) {
        WLCryptoServer server_run = new WLCryptoServer();
        Thread server = new Thread(server_run);
        server.start();
        
        System.out.println("Server thread started");
        
        new Thread(new WLCryptoClient("Hello world!")).start();
        
        try { Thread.sleep(500); } catch (InterruptedException ex) {}
        
        new Thread(new WLCryptoClient("Jump around and stomp your feet!")).start();
        
        try { Thread.sleep(500); } catch (InterruptedException ex) {}
        
        server_run.quitServer();
    }
}

Server class

The server code which take the input and output streams and creates new subclasses of the encryption layer classes and then creates the usual DataInputStream and DataOutputStream for the rest of the normal IO. This matched in the following code for the client.

package com.wlgfx.cryptotest;

import com.wlgfx.cryptotest.WLC.WLInputStream;
import com.wlgfx.cryptotest.WLC.WLOutputStream;
import java.io.DataInputStream;
import java.io.DataOutputStream;
import java.io.IOException;
import java.net.ServerSocket;
import java.net.Socket;

public class WLCryptoServer implements Runnable {
    
    private final int port = 1999;
    private boolean quit = false;

    @Override
    public void run() {
        try {
            ServerSocket socket =  new ServerSocket(port);
            socket.setSoTimeout(1000);
            
            while (!quit) {
                Socket client = socket.accept();
                
                WLOutputStream wlout = new WLOutputStream(client.getOutputStream());
                DataOutputStream out = new DataOutputStream(wlout);
            
                WLInputStream wlin = new WLInputStream(client.getInputStream());
                DataInputStream in = new DataInputStream(wlin);
                
                String text = in.readUTF();
                System.out.println("SERVER: " + text);
                out.writeUTF(text);
                
                client.close();
            }
        } catch (IOException ex) {
            System.out.println("SERVER: " + ex.getLocalizedMessage());
        }
    }
    
    public void quitServer() {
        quit = true;
    }
}

Client class

The client code is just the same as the server class code.

package com.wlgfx.cryptotest;

import com.wlgfx.cryptotest.WLC.WLInputStream;
import com.wlgfx.cryptotest.WLC.WLOutputStream;
import java.io.DataInputStream;
import java.io.DataOutputStream;
import java.io.IOException;
import java.net.Socket;

public class WLCryptoClient implements Runnable {
    
    private String text;
    private Socket socket;
    
    private final int port = 1999;
    
    public WLCryptoClient(String test) {
        text = test;
    }
    
    @Override
    public void run() {
        try {
            socket = new Socket("localhost", port);
            
            WLOutputStream wlout = new WLOutputStream(socket.getOutputStream());
            DataOutputStream out = new DataOutputStream(wlout);
            
            WLInputStream wlin = new WLInputStream(socket.getInputStream());
            DataInputStream in = new DataInputStream(wlin);
            
            out.writeUTF(text);
            text = in.readUTF();
            System.out.println("CLIENT: " + text);
            
            socket.close();
        } catch (IOException ex) {
            System.out.println("CLIENT: " + ex.getLocalizedMessage());
        }
    }
    
}

The encryption class

This is where you can see exactly how easy it is to manipulate the data being sent back and forth.Ā  Here I am showing you two methods, XOR and add and subtract. It’s very simple, but for heavier encryption you could look further at CSPRNG, or Crypto Secure Pseudo Random Number Generator. PRNG’s are ten a penny, from simple ones to hefty things. Take your pick. The Crypto and Secure layers are the ones you really need for truly undecipherable data communication.

package com.wlgfx.cryptotest;

import java.io.IOException;
import java.io.InputStream;
import java.io.OutputStream;

public class WLC {

    // NB: short inner classes are static to avoid errors
    
    public static class WLInputStream extends InputStream {

        private InputStream in;

        public WLInputStream(InputStream input) {
            in = input;
        }

        @Override
        public int read() throws IOException {
            byte a = (byte) in.read();
            a--;
            return (int) a;

            //return in.read() ^ 255; // WORKS TOO
        }
    }

    public static class WLOutputStream extends OutputStream {

        private OutputStream out;

        public WLOutputStream(OutputStream output) {
            out = output;
        }

        @Override
        public void write(int b) throws IOException {
            byte a = (byte) b;
            a++;
            out.write((int) a);

            //out.write(b ^ 255); // WORKS TOO
        }
    }
}
Console output:
run:
Server thread started
SERVER: Hello world!
CLIENT: Hello world!
SERVER: Jump around and stomp your feet!
CLIENT: Jump around and stomp your feet!
SERVER: Accept timed out
BUILD SUCCESSFUL (total time: 1 second)

Until next time

šŸ˜›

A day spent programming

Yep, a day of blitzing code.

There’s a total of four pieces of software I’m writing for this project. The server. The media manager. The device manager. And the device player. All four of them are now well on the way to being tested out soon enough.

So far the server works flawlessly with the media manager which can run on any OS, ie Linux, Windows or Mac.

The player is for embedded Linux only and also has some in built security layers.

The device manager runs on Android which makes it so much easier when setting up the devices.

The next step is to get the device player software to handle communication with the server and retrieve its playlist and it’s all ready for the big demo.

Once the demo setup has been produced I can move on to adding all the security layers in which will include encrypted communications over the internet.

Server media management

I’m glad to announce that my media server manager is very almost completed. The files upload to their respective categories and the Java application handles the media library perfectly.

It took a bit of learning Swing in Java but that wasn’t hard at all.

There’s a couple of things to do in the media manager before it is completed. Remove media and categories from the server. And add descriptions to the media files. And that’s it.

The next step is the Android application to manage devices so that I can set them up on the go without the need to get back to my PC.

Unknown devices (those that are ready to be set up) will be stored in the root directory of the media server. The Android application will then assign it a category and a playlist.

All looking good now.

(I’m having a bit of difficulty with WordPress Code Snippets so I’ve been unable to add any snippets recently)

Only a minor update

After work today I was zapped, but I got the file structure tested and confirmed on the server side for the initial testing. Everything is using Linux so it is easy to set up the testing grounds. I’m trying to make the device installation as quick as possible with minimal fussing about.

Oh and I also fixed a bug with the ‘~’ (home) location in java. Using ‘user.home’ gives me the home directory (actually on Windows too I found out but not tested, no need).

Eventually all of this will be in C++ so I’m 0% stressing at the moment. The servers will need to be C++ because of the JVM overhead.

I also fixed my PC in Linux which was not connecting to many websites. I had set up the fixed IP for testing without setting the routers gateway correctly. Chrome seems to mask this by loading up some websites but the rest it couldn’t find. The fix was done by assigning the fixed IP on the routers side. Eventually a VPS will cause me a few headaches.

I think tomorrow I will get back down to using Blender because that is the main source for this project. Royalty free 3D models/animations I want to test out.

More progress towards my project

I’ve been doing odds and sods today.

  1. Play a list of videos on a continuous loop full screen. By using libvlc and the Java wrapper I’ve finally got a full screen player working in less than 60 lines of code which plays a list of video files.
  2. Write a server and test over the internet. Using just a Java server, the initial test worked which was to accept a connection and send “Hello world!” back. Now that it is running I can expand the server with all the functionality I require. This will be handling the back-end database, media and installations.
  3. Define a KISS (Keep It Simple Stupid) database for handling devices and media.

To do:

  1. Write a mobile Android app to manage the setup of devices and assigning play lists. This is going to be a big one and a lot of work and I need to be on site when setting up devices and getting them playing without glitches.
  2. Expand on the software for the media player so that it can update itself from the server with not only media updates, but also software updates.
  3. Run an outside test live over the internet and update the playlist.
  4. Get more experience with Blender and video creation. For the most part, I’m more than capable of producing the videos in approximately an hour for everything I need. The more I get familiar with Blender then I can add more effects to the videos which will be a bonus.
  5. Bully test the server. I already have someone on hand that can test the servers integrity and stability. Pen-testing the server will give me some good pointers to how to make it more secure. I’m also considering the 2 way login.

That’s the plan for the next couple of weeks. Just so long as I get some free time I can move along quite quickly with this with the exception of the bully testing and updating.

Right now, things are looking almost bullet proof. Fingers crossed.

EDIT:

I forgot to add the VPS (Virtual Private Server)

It’s been a while

Yes, most definitely it has been some time since I last posted anything on my blog. That’s because this last month I have hardly had any real chill time to myself. Well, I have had some, but it never lasts for long enough.

Anyway, I’ve still been faffing about. I recently purchased CopperCubeĀ so that I could delve deeper into WebGL. Plus I’m familiar with Irrlicht, and CopperLicht makes working with 3D graphics a doddle.

I’ve also found that I can actually call myself a full-stack developer considering recent projects I’ve been working on. One project involves a C/C++ TCP/UDP server for communications, A Java TCP server to use Java AWT graphics, GWT for a web interface instead of installing software. The server does many things, too many to mention, but I’m well chuffed with it.

Setting up the server involves freshly installing Linux. Then installing Apache Tomcat. Making a few modifications to the system and then installing the software.

Device connect on the network via ethernet or wifi and will automatically detect the location of the server because of the UDP heart beat. Clever stuff really. Probably not, but all the same, it works great.

I’ve also played around with having a home TCP server which can be made use of from my mobile phone while I am out, my tablet or a PC, as well as a GWT web interface.

After playing around with all of this, there’s lot’s more I want to play with. Maybe Vaadin or similar. Move on to desktop 3D graphics again instead of openGLES 2.

I’ve also finally got myself an i7 laptop with nVidia graphics. Cheap off eBay! So I can develop on the go. That’s if the battery is good in it.

There’s other things over this last month that have tickled my fancy, but I won’t mentioned that here. Tempting though.

Hopefully this weekend I will have a long one as I’m booking Friday and Monday off because I seriously need to relax a little.

Until next time…

Android client TCP server image request

Well, I finally finished off the initial test where I can run an app on my phone or tablet anywhere, click something and it fetches a random image from my PC at home.

The updated sources can be found HERE.

android-tcp-client-server-app