December 02, 2010

TcpDump

Introduction
A project I was working on required me to verify network traffic activity over specific ports.  I have not had much experience doing this but I knew Linux tcpdump would be my tool of choice.  Unfortunately, I was working in a Windows environment but it was easy enough to find a port of tcpdump for Windows.

Download
I found MicroOlap had an easy to use port of tcpdump available for download.
http://www.microolap.com/products/network/tcpdump/

Installation
Installation is simple, just unzip it.

Find Your Network Interface (Device)
Your computer may have more than one network interface.  A laptop will have an Ethernet card for a network cable but it will also have a wireless Ethernet card.  You need to know which one you are using and tell tcpdump to listen for network traffic on the device.  To get a list of devices on your computer, use the -D switch.

C:\Apps\tcpdump>tcpdump -D

*******************************************************************
**                                                               **
**        Tcpdump v4.0.0 (October 27, 2008) for Windows          **
**          Win 98/ME/NT4/2000/XP/2003/Vista/2008/Win7           **
**                                                               **
**      built with MicroOLAP Packet Sniffer SDK v4.2 and         **
**   MicroOLAP WinPCap to Packet Sniffer SDK migration module.   **
**                                                               **
**     Copyright (c) 1997 - 2009 MicroOLAP Technologies LTD,     **
**                  Khalturin A.P. & Naumov D.A.                 **
**                   http://www.microolap.com                    **
**                                                               **
**                         Trial license.                        **
**                                                               **
*******************************************************************

1.\Device\PssdkLoopback (PSSDK Loopback Ethernet Emulation Adapter)
2.\Device\{8C8A81C7-D190-4A6D-88D9-7C83CF11BD1F} (VMware Virtual Ethernet Adapter for VMnet1)
3.\Device\{9AA64137-DCCD-4292-802D-7568D75004AA} (DW1520 Wireless-N WLAN Half-Mini Card)
4.\Device\{B58EA48A-BD5C-400D-94FD-02659C8B659A} (Intel(R) 82577LM Gigabit Network Connection)
5.\Device\{F61893D4-5284-48ED-960D-27A777C4D1DC} (Check Point Virtual Network Adapter For SecureClient)
6.\Device\{952066E8-9363-4AB5-8E8F-20F64C7DB32F} (VMware Virtual Ethernet Adapter for VMnet8)

Listen for Incoming Traffic on a Specific Port
After determining your interface, run the following command to listen for incoming traffic on a specific port.

C:\Apps\tcpdump>tcpdump -i 5 -nnvvXSs 1514 port %PORT_NUMBER%

-i 5  Specifies to which interface to use, which in this example is #5 above.
%PORT_NUMBER% Is replaced with the port number to listen for incoming traffic.

There is a lot more to tcpdump, but that is enough for now.

November 12, 2010

Running Vuze (Azureus) BitTorrent Client From Command Line (SSH Terminal)

Introduction
Finding command line BitTorrent clients has been a challenge.  My challenge is finding one which passes the 5 minute rule.  If I want a GUI based BitTorrent client I can download and install uTorrent, click on the torrent's link, and be downloading within 5 minutes.  For command line clients, I have run into python errors, C library version issues, and other problems which are not resolved in 5 minutes and not worth the effort to.
      
Vuze (Azureus) is a major Java based GUI BitTorrent client however a little searching online revealed it can also be run from a command line.  Getting it up and running and being able to monitor the torrent download was not too painful.  It required searching to solve some problems so it did not pass the 5 minute rule but it was not too bad.  I document my research here so it is all in one place.

Download Vuze (Azureus) and supporting libraries
You need to download 3 files.  Put them all in the same directory

Vuze_<version>.jar
Select to download the "Jar" from the download page or try downloading directly.

log4j.jar 
Search and download log4j.jar or try downloading directly.

commons-cli.jar
Search and download commons-cli.jar or try downloading directly.
Running Vuze (Azureus) from the command line
To run Vuze (Azureus) from the command line, execute the following command (Linux assumed)

$ screen java -jar Vuze_4510.jar --ui=console

Yes, you will want to use the
screen command to run it.  Why you want to use screen will become apparent soon.
Console commands
The available console commands are easy enough.  Type "help" to get a list of available commands:
> -----
help
> -----
Available console commands (use help <command> for more details):

  [] xml   [#] hack   [a] add   [c] check   [q] queue   [r] remove
  [s] start   [h] stop   [] host   [] publish   [] forcestart   [tl] tlog
  [l] log   [m] move   [] share   [+] set   [sh] show   [u] ui   [] logout
  [] quit   [?] help   [] alias   [] prio   [] plugin
> -----


Type "help <command>" to get help for a specific command.  To get help for the "add" command, type "help add"
> -----
help add
add [addoptions] [.torrent path|url]            a       Add a download from the given .torrent file path or url. Example: 'add /path/to/the.torrent' or 'add http://www.url.com/to/the.torrent'
> -----
add [addoptions] [.torrent path|url]            a       Add a download from the given .torrent file path or url. Example: 'add /path/to/the.torrent' or 'add http://www.url.com/to/the.torrent'
    -r,--recurse               recurse sub-directories.
    -f,--find                  only find files, don't add.
    -h,--help                  display help about this command
    -l,--list                  list previous find results
    -o,--output <outputDir>    override default download directory
> -----

Adding a Torrent
Adding a torrent is easy.  Use the "add" command combined with either the URL or file system path to the torrent.
> -----
add http://url/of/the/file.torrent


> -----
add /path/of/the/file.torrent

Checking Progress of a Torrent
To see if a torrent is finished, use the "show torrents" command

> -----
show torrents
> -----
 1 [>] 078.2%   Something being downloaded (3.27 GB) ETA: 21h 26m
                Speed: 9.7 kB/s / 4.8 kB/s      Amount: 2.56 GB ( 1.76 MB discarded ) / 515.76 MB       Connections: 4(8) / 2(9)

 2 [>] 071.7%   Another thing being downloaded (3.49 GB) ETA: 12h 36m
                Speed: 23.8 kB/s / 5.6 kB/s     Amount: 2.51 GB ( 1.45 MB discarded ) / 270.24 MB       Connections: 5(8) / 2(8)

Total Speed (down/up): 33.5 kB/s / 10.5 kB/s
Transferred Volume (down/up/discarded): 5.08 GB / 786.01 MB / 3.21 MB
Total Connected Peers (seeds/peers): 9 / 4
> -----

Logging out of Your SSH Session and Coming Back
After you added torrent(s), you want Vuze (Azureus) to continue running in the background until it is finished but you also want to be able to come back to it to check on the progress.  So how do you do this?

Well, because the
screen command was used to start the application, to leave and let Vuze (Azureus) to continue running in the background all you need to do is close your console window or exit your Putty screen.  Basically just end your connection without exiting or logging out.
To come back and check on the progress of your torrent download is just as easy.  SSH to you account then execute the following command
$ screen -ls
There is a screen on:
        31432.pts-0.server      (Attached)
1 Socket in /var/run/screen/S-michael.
You should see a screen listed.  Now execute the following command  to return to the screen.
$ screen –x 31432

And there you have it, you are back at the Vuze (Azureus) console interface!

References
http://wiki.vuze.com/w/ConsoleUI
http://wiki.vuze.com/w/Commandline_options
http://azureus.sourceforge.net/download.php
http://sourceforge.net/projects/azureus/files/vuze/Vuze_4510/Vuze_4510.jar/download
http://svn.vuze.com/public/client/trunk/uis/lib/log4j.jar
http://svn.vuze.com/public/client/trunk/uis/lib/commons-cli.jar

March 06, 2003

Distributed Notification with Java RMI

Abstract

Java’s implementation of Remote Method Invocation (RMI) is very easy to use and very power. Java makes the task of setting up an RMI server an almost trivial one. Once running, connecting client applications to the RMI server is also a breeze. There are examples and how-tos for client to server communication everywhere. But what about the other way, server to client communication? Is it possible for an RMI server to actively communicate with all the clients that are connected to it without the client initiating the conversation? In other words, is distributed notification possible? The purpose of this post is to demonstrate that yes, it is possible.

Disclaimer

This post is solely informative. Critically think before using any information presented. Learn from it but ultimately make your own decisions at your own risk.

Problem

Consider development of a small test application that demonstrates an RMI server notifying its clients of events. A very simple example is an RMI “time server”. Clients register with the server (client to server communication) and then every second all registered clients are notified of an event, the new date and time (server to client communication). The client implements some kind of listener and that listener can be used to handle the event any way the client sees fit.

Proposed Solution

The difficulty that I have with implementing distributed notification is that the server has to have some knowledge of the client application. Just as the client needs an Xxx_Stub.class to talk to the server, the server needs a similar Xxx_Stub.class to talk to the client.

The first, and most obvious (to me anyway) solution was for the client to develop its own remote class, generate an Xxx_Stub.class for it, then give that Xxx_Stub.class file to the server. Not a very attractive solution.

After struggling with the problem for a while I narrowed down the root of the problem. On the server side, I had interfaces and objects like listing 1 and listing 2.

Listing 1 - ClientCallback interface

public interface ClientCallback extends Remote {
    public void informClient(String msg)
    throws RemoteException;
}

Listing 2 - Remote service allowing clients to register

class SomeServiceImpl extends UnicastRemoteObject implements SomeService {
    public void registerWithService(ClientCallback cc)
    throws RemoteException {
        //...
    }
}

Continuing with the root of the problem, on the client side I want to make a remote call that looks something like listing 3.

Listing 3 - What client wants to do

serverObject.registerWithService(this);

The root of the problems caused by this code is that the client would then have to become a ‘server’ itself, generating Xxx_Stub.class files for the classes that implement ClientCallback and somehow getting those Xxx_Stub classes to the server. Not very pretty.

When considering a solution to this problem, realization struck. The server would have no problems if the class that implemented ClientCallback was a class that the server had created! For example, let us say that the server gives to the client the class in listing 4.

Listing 4 - Server gives client this class

class ServerListener implements ClientCallback {
   /**
    * constructor
    */
   public ServerListener(String serverName, int port)
   throws Exception {
      UnicastRemoteObject.exportObject( this );

      SomeService ss = (SomeService)Naming.lookup("rmi://<server>:<port>/SomeService");

      ss.registerWithService(this);
   }


   /**
    * MyCustomListener interface method
    */
   public void informClient(String msg) {
     // do something
   }
}

When the code for the RMI server is compiled, a ServerListener_Stub.class is also created and bundled in the jar file for the client to use. Basically, this is an object that a client can create an instance of just like any other Java object.

ServerListener ls = new ServerListener("localhost", 1099);

This object knows how to contact the RMI server, do the appropriate lookup, and register itself with the server. And because of the line:

UnicastRemoteObject.exportObject(this); 

The server is able to call the informClient() method on the client’s machine! Bingo! that’s exactly what I wanted!

Well not quite. The server can now inform the client of something, but that code is buried inside the ServerListener object that the client really has no access to. Extending the ServerListener object won’t work because that gets you back to the previous problem of the server having to know what the client classes are. Here’s my solution, another listener interface provided by the server!

Let’s say the ClientCallback interface had an analogous, non-remote interface called ClientListener. Also let’s say that the ServerListener class that the server provides as an additional method that looks like listing 5.

Listing 5 - Method to register client-side listener

Vector listeners = new Vector();

public void addClientListener(ClientListener cl) {
    if (!listeners.contains(cl)) {
        listeners.add(cl);
    }
}

Now let ClientListener be just a simple, non-remote interface as in listing 6.

Listing 6 - Non-remote, client-side interface

public interface ClientListener() {
    public void statusChanged(String s);
}

Now the client side code just falls into place as in listing 7.

Listing 7 - Client code

// create an object that can "listen" for events on the server
ServerListener sl = new ServerListener("localhost", 1099);

// add as many classes as you want to handle those events
sl.addClientListener(new ClientListenerA());
sl.addClientListener(new ClientListenerB());
sl.addClientListener(new ClientListenerC());
sl.addClientListener(new ClientListenerD());

The implementation of the ServerListener.informClient() object is nothing more than looping over the list of ClientListener objects and calling the changeStatus() method on each.