Problem in adapters and sockets remote JVM

Adastra
2012-02-14
2013-01-21
  • Adastra
    Adastra
    2012-02-14

    Hi guys…
    I have a problem….
    I'm trying every netlib Adapter and works fine using TCPIP and TOR Netlayers, I have an application in a JVM and every "remote" request  works using any of the adapters that specific but in my application I need to create objects and then they must be delivered to other applications (using another JVM) when it is required. Typically in Java this is usually done using raw sockets or RMI and this is where I have problems, because after "registering" any adpater (socketglobal, jvm, nameadapter, etc.) the InputStream of the Socket is always Null, so there's no data transfer, I don't no what happens, but if I remove the adapter, everything works fine (Using NetLib NetSockets or Java Raw Sockets). I use Adapters and Netlib direct usage because I need everything inside the JVM (ServerSocket JVM) is handled by the NetLib NetLayer and also need that same virtual machine can accept connections from another virtual machine (using sockets for example) to transfer objects or byte streams.
    In this message I've included two classes "client" and "server" explaining my problem, the "server" class executed from the JVM1 start the SocketGlobal Adapter (I've tried all with the same results) and the "client" class executed from the JVM2 connects with the "server" in the port 30000, the server accepts the connection but when try to get the InputStream from the "client" socket, the object is Null. If I remove the method "setDefaultLayer()" from the "server" class, everything works, but the JVM is not handled by the NetLib NetLayer..
    What can I do?

    Server:
    http://pastebin.com/4m97x3yZ

    Client:
    http://pastebin.com/FhEic3Mq

    Thank you for your help

     
  • Hi,

    unfortunately, I don't understand you actual requirements. Which system (server or client) do you want to connect to Tor? This system/JVM then could use Netlib and an Adapter to communicate to Tor, and in parallel you could use the TcpipNetLayer for classical TCP/IP communication without Tor. The second system/JVM, which does not want to communicate to Tor, can work completely without silvertunnel.org Netlib.

    Cheers,

    Christian

     
  • Adastra
    Adastra
    2012-02-15

    Hi!
    Thanks for the reply and sorry for being so unclear message I'll try to explain my problem in a way much more clear :)

    From the JVM1 (server) I need to use Silvertunnel Netlib to connect with TOR, so from the JVM1 (server) I use an Netlib Adapter (JVM Adapter, NameService, SocketGlobal, wherever etc.) It works fine :)
    Now, the problem:
    From the same machine (JVM1, the server) I need to start a "ServerSocket" to accept connections from other machines inside the LAN (sockets TCP with or without NetLib) to share objects between those machines, using simple and plain TCP connection, so the steps that I'm following in my classes are:

    1. JVM1(Server): Start the NetLib Adapter (works fine, I see a log indicating that "Tor is Started using NetLib").
    2. JVM1(Server): Start a new ServerSocket (Using ServerSocket class or NetServerSocket Netlib class, I've tried both) using a port (like 3000).
    3. JVM1(Server): Start a Thread for each new connection from a client.
    4. JVM2 (Client): Create a new Socket or NetSocket (I've tried with both) to communicate with the server (JVM1) using the specified port (like 3000).
    5. JVM2 (Client): Create a serialized object and send it to the Server (JVM1), example:

    ObjectOutputStream oos = null;
    ObjectInputStream ois = null;
    // open a socket connection
    //  socket = new Socket("192.168.1.11", 3000); //I've tried this too.
    TcpipNetAddress remoteAddress = new TcpipNetAddress("192.168.1.11", 3000);
    NetLayer netLayer = NetFactory.getInstance().getNetLayerById(NetLayerIDs.TCPIP);
    NetSocket netSocket = netLayer.createNetSocket(null, null, remoteAddress);
    // open I/O streams for objects
    oos = new ObjectOutputStream(netSocket.getOutputStream());
    ois = new ObjectInputStream(netSocket.getInputStream());
    oos.writeObject(new SerializedObject); //Sends the Serialized object to the remote JVM.
    oos.flush();
    // read an object from the server
    SerializedObject serialized = (SerializedObject) ois.readObject();
    oos.close();
    ois.close();
    netSocket.close();
    

    6. JVM1 (Server): Accepts the connection and get the Socket, example:

    NetSocket socketClient = objectServer.accept();
    Connect c = new Connect(client);
    c.start
    

    where "Connect" is a Thread.

    6. JVM1 (Server) In the method "run()": I need the Input and OuputStream from the client socket:

    private NetSocket client = null;  // Same result if I use Socket class
    private ObjectInputStream ois = null;
    private ObjectOutputStream oos = null;
    public Connect(NetSocket clientSocket) {
                         client = clientSocket;
                 try {
                                ois = new ObjectInputStream(client.getInputStream()); //HERE I GET NULLPOINTER EXCEPTION CAUSE THE INPUTSTREAM IS NULL.
                                oos = new ObjectOutputStream(client.getOutputStream());
                 } catch(Exception e) {
    ..........................................
                 }
    

    In the client socket the InputStream is Null, so…. here I got a problem. :(

    OK, Now if I remove the "step 1" It works fine using NetSocketServer/NetSocket or the standard SocketServer/Socket.
    So, this is my problem using Silvertunnel Netlib…
    I should also note that it is exactly the same if I use an NetLib Adapter with a NetLayer TCPIP or TOR. If I use any Netlib Adapter, the InputStream from the socket client, is always Null as explained above…

    I'm doing something wrong using this API?

    Thank for your help!

     
  • Adastra
    Adastra
    2012-02-15

    To clarify:
    In the "step 6" the code is:

    NetSocket socketClient = objectServer.accept(); 
    Connect c = new Connect(socketClient); 
    c.start
    

    The "socketClient" never comes null, but the socketClient.getInputStream() is always Null if I use any NetLib Adapter.

    Thanks!

     
  • Hi,

    to handle non-Tor connections on JVM1 you must do this:

    TcpipNetAddress localListenAddress = new TcpipNetAddress("0.0.0.0", LISTEN_PORT);
    server = NetFactory.getInstance().getNetLayerById(NetLayerIDs.TCPIP).
            createNetServerSocket(null, localListenAddress);
    NetSocket s = server.accept();
    ...
    

    And: forget Netlib on JVM2.

    I hope this helps,

    Christian

     
  • Adastra
    Adastra
    2012-02-16

    Hi!
    Doing what you have said, (leaving NetLib use in the client JVM2 and using TcpIpNetAddress in JVM1 on "0.0.0.0" address) I'm still having the same problem …. : (
    I guess this a problem in the Library, this is the trace I get (JVM1 Server):

    java.lang.NullPointerException
        at org.silvertunnel.netlib.api.impl.NetSocket2SocketImpl.getInputStream(NetSocket2SocketImpl.java:176)
        at java.net.Socket$2.run(Socket.java:799)
        at java.security.AccessController.doPrivileged(Native Method)
        at java.net.Socket.getInputStream(Socket.java:796)
        at org.silvertunnel.netlib.api.impl.Socket2NetSocket.getInputStream(Socket2NetSocket.java:37)
        at test.ServerSocketTest$Connect.<init>(ServerSocketTest.java:94)
        at test.ServerSocketTest.run(ServerSocketTest.java:78)
    16-feb-2012 10:55:30 org.silvertunnel.netlib.api.impl.NetSocket2SocketImpl close
    INFO: close() with netSocket=null
    java.lang.Throwable: Just to dump a trace
        at org.silvertunnel.netlib.api.impl.NetSocket2SocketImpl.close(NetSocket2SocketImpl.java:107)
        at java.net.Socket.close(Socket.java:1352)
        at org.silvertunnel.netlib.api.impl.Socket2NetSocket.close(Socket2NetSocket.java:46)
        at test.ServerSocketTest$Connect.<init>(ServerSocketTest.java:99)
        at test.ServerSocketTest.run(ServerSocketTest.java:78)
    

    Again, If I remove the Netlib Adapter, the Socket's InputStream is not Null.

    Maybe I'm using wrong the adapter's. I use this code to init the JVM Netlib Adapter. (I think it's correct )

                JvmGlobalUtil.init();
                NetLayer torNetLayer = NetFactory.getInstance().getNetLayerById(NetLayerIDs.TOR);
                torNetLayer.waitUntilReady();
                JvmGlobalUtil.setNetLayerAndNetAddressNameService(torNetLayer, true);
    

    This piece of code is executed at program startup (JVM1 Server) and then run the other instructions that I have indicated in previous messages. If I remove these 4 lines the program works correctly, if I include them fails.

     
  • Please, could reduce the full and running code of JVM1 to its minimum (but still with the NPE problem) so that I can copy the code 1:1 into a main() method to execute and reproduce the problem.

    Thanks,

    Christian

     
  • Adastra
    Adastra
    2012-02-16

    Ok,
    I've reduce de source code to the minimum in a main method, so you can reproduce the problem:

    In JVM1 (Server):

    import java.io.ObjectInputStream;
    import java.io.ObjectOutputStream;
    import org.silvertunnel.netlib.adapter.java.JvmGlobalUtil;
    import org.silvertunnel.netlib.api.NetFactory;
    import org.silvertunnel.netlib.api.NetLayer;
    import org.silvertunnel.netlib.api.NetLayerIDs;
    import org.silvertunnel.netlib.api.NetServerSocket;
    import org.silvertunnel.netlib.api.NetSocket;
    import org.silvertunnel.netlib.api.util.TcpipNetAddress;
    public class ServerSocketTest extends Thread {
        private NetServerSocket objectServer;
         public static void main(String ... s) throws Exception{
             setDefaultLayer();
             ServerSocketTest ts = new ServerSocketTest(3000);
             ts.start();
         }
    
         public static void setDefaultLayer() {
                JvmGlobalUtil.init();
                NetLayer torNetLayer = NetFactory.getInstance().getNetLayerById(NetLayerIDs.TOR);
                torNetLayer.waitUntilReady();
                JvmGlobalUtil.setNetLayerAndNetAddressNameService(torNetLayer, true);
         }
    
           public ServerSocketTest(int port) throws Exception {
               TcpipNetAddress localListenAddress = new TcpipNetAddress("0.0.0.0", 3000);
               objectServer = NetFactory.getInstance().getNetLayerById(NetLayerIDs.TCPIP). createNetServerSocket(null, localListenAddress);
               System.out.println("Server listening on port "+port);
           } 
           public void run() {
               while(true) {
                   try {
                       System.out.println("Waiting for connections.");
                       NetSocket client = objectServer.accept();
                       System.out.println("Accepted a connection from: "+client);
                       Connect c = new Connect(client);
                       c.start();
                   } catch(Exception e) {}
               }
           }
           
           class Connect extends Thread {
               private NetSocket client = null;
               public Connect(NetSocket clientSocket) {
                   client = clientSocket;
                   try {
                       ObjectInputStream ois = new ObjectInputStream(client.getInputStream()); //HERE THE INPUTSTREAM IS NULL...
                       ObjectOutputStream oos = new ObjectOutputStream(client.getOutputStream());
                   } catch(Exception e1) {
                       e1.printStackTrace();
                     return;
                 }
                 this.start();
               }
              
               public void run() {
               }
            }      
    }
    

    Now, in JVM2 (Client) just executing something like this:

    import java.io.ObjectInputStream;
    import java.io.ObjectOutputStream;
    import java.net.Socket;
    import java.util.ArrayList;
    public class ClientTest {
        public static void main(String ... s) throws Exception {
                    Socket socket = new Socket("127.0.0.1", 3000);
            oos = new ObjectOutputStream(socket.getOutputStream());
            ois = new ObjectInputStream(socket.getInputStream());
            oos.writeObject(new ArrayList());
            oos.flush();
            }
    }
    

    Using this code, I'm reproducing the error…
    Now I've forget to comment, I'm using the last version available of Silvertunnel Netlib.

    Thanks a lot for your quick response, I'll try to check the code of the library, although I do not know how this implemented, I probably will cost a little effort, but I'll try :)

     
  • Hi,

    I could reproduce the problem - it is a bug in Netlib. Unfortunately, it is not easy to fix so we cannot provide a fast patch. I created a ticket that will document the details and the progress: https://sourceforge.net/apps/trac/silvertunnel/ticket/142

    Possible workarounds are maybe acceptable:
    * connect to Tor without JvmGlobalUtil/Netlib Socket Adapter (https://silvertunnel.org/doc/netlib-direct-api-usage.html / Netlib Direct API Usage)
    * you only create client connections (but with plain IP address because of a 2nd/DNS bug in this context), i.e. you replace TcpipNetLayer server sockets by client sockets if possible:

    NetSocket netSocket = NetFactory.getInstance().getNetLayerById(NetLayerIDs.TCPIP).
                     createNetSocket(null, null, new TcpipNetAddress("1.2.3.4:80"));
    ...
    

    Good luck

    Christian

     
  • Adastra
    Adastra
    2012-02-16

    Ok,
    Replacing the Netlib Adapter with something like this:

            NetLayer torNetLayer = NetFactory.getInstance().getNetLayerById(NetLayerIDs.TOR);
            NetFactory.getInstance().registerNetLayer(NetLayerIDs.TOR, torNetLayer);
    

    After that, the sockets works fine, well for me this solution it's ok, in the JVM1 (Server) I wil create a new NetSocket For each connection in the need to use TOR.

    you are doing a great job.
    thank you very much