IMMORTAL SOCKETS


DESCRIPTION


Do you have an application (such as scp or unison file synchronize) that cannot recover from broken tcp connections, and you hate that?!! this tool is for you!!

ImmortalSockets is a standalone application that creates a TCP tunnel for unreliable TCP connections. It can also be used as a library to create a TCP socket that does not die.

That is, according to man sockets, "The communications protocols which implement a SOCK_STREAM ensure that data is not lost or duplicated. If a piece of data for which the peer protocol has buffer space cannot be successfully transmitted within a reasonable length of time, then the connection is considered to be dead.". Thus, it happens often that the connection dies (or the connection breaks) if you have an unreliable Internet connection. This is a problem with software (such as scp or unison file synchronizer) that it is not designed to reconnect when the connection dies and resume its operation.

ImmortalSockets can help you in these cases where you need to prevent the connection to die under an unreliable Internet connection (hence the name, Immortal Sockets).
Suppose you need to copy a file using scp. You would do something like this:


Without ImmortalSockets:
computer1> scp myfile.zip computer2:myfile.zip

This copies a file. However, if the connection between computer1 and computer2 is broken, the copy needs to be restarted from the beginning.

Using ImmortalSockets:
computer2T> java -cp ImmortalSockets.jar org.ImmortalSockets.tunnel.TunnelServer 2000 computer2 22
computer1T> java -cp ImmortalSockets.jar org.ImmortalSockets.tunnel.TunnelClient 2001 computer2T 2000
computer1> scp -P 2001 myfile.zip computer1T:myfile.zip

This copies a file. If the connection between computer1T and computer2T is broken, TunnelServer/TunnelClient will reconnect, and scp will keep copying as if nothing happened.
Of course, you can avoid needing two extra computers (Computer1T and Computer2T) by running TunnelClient in Computer1 and TunnelServer in Computer2.



The tunnel works very much as "ssh -f -N -L 2222:computer2T:3333 computer2".
This specifies that port 2222 on the local (client) host is to be forwarded to computer2:3333 via computer2T using ssh. This works by allocating a socket to listen to port 2222 on the local side. Whenever a connection is made to this port, the connection is forwarded over the secure channel, and a connection is made to myremotemachine.com:3333 from myremotemachine.com.

The difference is that ImmortalSockets "transparently reconnects" whenever the tunnel connection is broken. By "transparently reconnecting" we mean that when the tunnel connection is broken, the connection of the local application to localhost:2222 is not closed, nor is the connection from computer2T to computer2:3333, and thus the application does not even notice that the tunnel connection was broken.


Note: to run this software, you need to:
  1. install Java if you don't already have it
  2. download ImmortalSockets_0.2.zip, unzip it and get the ImmortalSockets.jar file.


Note: you don't need 4 computers to use this software.
For the sake of understanding, the example above shows 4 computers: Computer1, Computer1T, computer2T and computer2;
but Computer1 and Computer1T can be the same computer,
and Computer2 and Computer2T can be the same computer.


Note: you will get a log4j warning when running the software. You can ignore it.
otherwise, you can take the log4j.properties file from the ImmortalSockets_0.2.zip, and run:
computer2T> java -cp ImmortalSockets.jar -Dlog4j.configuration=file:log4j.properties org.ImmortalSockets.tunnel.TunnelServer 2000 computer2 22


Currently ImmortalSockets is implemented in Java. If you wish to contribute, you can port it to other languages (C/C++, C#, VisualBasic, perl, python, PHP, javascript...).


Technical details

IMMORTAL SOCKETS
++++++++++++++++++++++++++++++++++++++++++++++++++++++++++
package org.ImmortalSockets;
public class ImmortalSocket {
    /*  Creates a stream socket and connects it to the specified port number at the specified IP address. 
     *  At the other end, there should be a ImmortalServerSocket listening at this port 
     */
    public
ImmortalSocket(InetAddress address, int port) throws IOException;
    

    /* Returns the input stream of this ImmortalSocket.
     * Closing the returned input stream will close the associated socket.
    
* Throws an IOException if the socket is closed
     */
  
    public InputStream getInputStream() throws IOException;

    /* Returns the output stream of this ImmortalSocket.
     * Closing the returned output stream will close the associated socket.
     * Throws an IOException if the socket is closed
     */

    public OutputStream getOutputStream() throws IOException;

    /* Close the ImmortalSocket
     */

    public void close();
}


package org.ImmortalSockets;
public class ImmortalServerSocket {
    /* Creates a server socket, bound to the specified port. A port of 0 creates a socket on any free port.
     * At the other end, there should be a
Immortal Socket connecting to this port.
     */
    public
ImmortalServerSocket(int port) throws IOException;


    /* Listens for a connection to be made to this socket and accepts it. The method blocks until a connection is made.
     * The connection has to be made by an ImmortalSocket.
     */
    public
ImmortalSocket accept() throws IOException;

    /* Close the ImmortalServerSocket
     */

    public void close() throws IOException;
}




TUNNEL. BASIC APPLICATION USING IMMORTAL SOCKET
++++++++++++++++++++++++++++++++++++++++++++++++++++++++++
packa
ge org.ImmortalSockets.tunnel;
public class TunnelClient implements Runnable{
   
   
/* This creates the TunnelClient.
     * When running, it will be
using a common java.net.ServerSocket to listen at the specified port for connection from a client who wants to use the tunnel.
     * Each connection will be then forwarded to the TunnelServer at the specified TunnelServerHost and port using an ImmortalSocket.
     */
    public TunnelClient(int listenPort, String serverHost, int serverPort);
    public void run();
   
    /* args[0]: port listening the connections of the client who want to use the tunnel.
     * args[1]: host name or IP address of the TunnelServer we want the TunnelClient to be connected to.
     * args[2]: port
of the TunnelServer we want the TunnelClient to be connected to.
     */
    public static void main(String[] args) {
        TunnelClient app = new TunnelClient(Integer.parseInt(args[0]), args[1], Integer.parseInt(args[0]));
        new Thread(app).start();
    }
}

package org.ImmortalSockets.tunnel;
public class TunnelServer implements Runnable{

    /* This creates the TunnelServer.

     * When running, it will using an ImmortalServerSocket to listen at the specified port for connection from a TunnelClient 

     * Each connection will be then forwarded to the specified forwardHost and port using a common java.net.Socket.

     */

    public TunnelServer(int listenPort, String forwardHost, int forwardPort);
    public void run();
   
    /* args[0]: port listening the connections from the TunnelClient.
     * args[1]: host name or IP address of the server we have to forward the connection to.
     * args[2]: port of the server we forward the connection to.
     */

    public static void main(String[] args) {
        TunnelServer app = new TunnelServer(Integer.parseInt(args[0]), args[1], Integer.parseInt(args[0]));
        new Thread(app).start();
    }
}



Download


Download the project at sourceforge.





Alternative names to this project are Immortal Sockets, Undying Sockets, Lasting Sockets, Permanent Sockets and Steady Sockets.

Contact us at "David Portabella" <david.portabella@gmail.com> and "Pierre Tholence" <pierre.tholence@gmail.com>.