mail.communication.inet
Class InetCommunicator

java.lang.Object
  extended by mail.communication.Communicator
      extended by mail.communication.inet.InetCommunicator
All Implemented Interfaces:
java.lang.Runnable

public class InetCommunicator
extends Communicator
implements java.lang.Runnable

Author:
Arne Müller

Field Summary
private  java.util.Collection<InetAddress> addr
          this communicators address
private  java.io.File basedir
          directory in which comm-properties are stored
static int BOOT_TIMEOUT
           
private  java.util.Properties bootstrap
           
private static java.lang.String BOOTSTRAP_ADDR
           
static int CONNECTION_TIMEOUT
          the time after which a connection is considered dead.
(package private)  java.util.Hashtable<InetAddress,java.lang.Long> connections
          map of connections to their last response time
private  javax.xml.parsers.DocumentBuilderFactory docfactory
          used to build the XML documents needed to send packages
(package private)  boolean ip_answer
          indicates if this communicators ip address was updated
private  LocalNode local
          the local node this communicator is attached to
private static int MAX_BOOTSTRAP_TRIES
           
static int PING_INTERVAL
          the interval PING packages get send to neighbor nodes, to keep the UDP connection alive, because if the UDP connection collapse it might be hard to rebuild it (UDP hole punching)
(package private)  java.util.Hashtable<InetAddress,java.util.Vector<UDP>> received
          contains received, unfinished packets
(package private)  java.util.Hashtable<InetAddress,java.lang.Integer> responses
          list of received elementar response packets
private  java.util.Properties settings
           
private static java.lang.String SETTINGS
           
private  java.net.DatagramSocket socket
          the socket all packets are send and received with.
static int TIMEOUT
          If TIMEOUT ms have passed after an request, the package is believed of have gotten lost
private  javax.xml.transform.TransformerFactory transFactory
          used to transform XML documents into OutputStreams
(package private)  java.util.Hashtable<Node,InetAddress> useableAddresses
          maps Nodes to InetAddresses of the Node, that work
 
Constructor Summary
InetCommunicator()
          creates a new InetCommunicator.
InetCommunicator(java.io.File basedir)
           
InetCommunicator(int port)
          creates a new InetCommunicator.
 
Method Summary
 void attachNode(LocalNode l)
           
 void bootstrap()
           
 void close()
           
private  boolean connectionEstablished(InetAddress address)
          looks up the time, when the last package was received.
private  void establishConnection(InetAddress address)
          establishes a connection.
 void findMyAddress(Address apeer)
           
 java.util.Collection<Address> getAddress()
          returns the Address this Communicator uses to send Packets
 javax.xml.parsers.DocumentBuilder getDocumentBuilder()
           
 boolean isOpen()
           
 boolean open()
           
 void open(int port)
           
 InetAddress parseAddress(java.lang.String addr)
           
private  void print_debug(org.w3c.dom.Document d)
          print a Document to System.out.
private  void punch_hole(InetAddress action)
          sends PING packets to punch a UDP hole into the NAT router this peer is hidden behind
private  void receivePackage(java.io.InputStream in, InetAddress sender)
          builds a CPackage out of the InputStream.
private  void request_hole_punch(InetAddress action, InetAddress sender)
          sends a node a request to punch a UDP hole for another node
private  void reset(InetAddress address, int reply)
          resets the specified entry at adress in the response list
 void run()
          this methods listens for Packets send to this peer and handles them appropriately.
 void sendPackage(CPackage p, Address to)
           
 void sendPackage(CPackage p, RemoteNode to)
           
private  void startConnectionHolder()
          starts the mechanism to keep UDP connections alive.
private  int waitForEcho(InetAddress address)
          waits until any reply came from address.
private  int waitForEcho(InetAddress address, int reply)
          waits until the specified reply came from address.
 void write(org.w3c.dom.Document d, java.io.File out)
           
 
Methods inherited from class mail.communication.Communicator
getReplyList
 
Methods inherited from class java.lang.Object
clone, equals, finalize, getClass, hashCode, notify, notifyAll, toString, wait, wait, wait
 

Field Detail

BOOTSTRAP_ADDR

private static final java.lang.String BOOTSTRAP_ADDR
See Also:
Constant Field Values

SETTINGS

private static final java.lang.String SETTINGS
See Also:
Constant Field Values

MAX_BOOTSTRAP_TRIES

private static final int MAX_BOOTSTRAP_TRIES
See Also:
Constant Field Values

basedir

private java.io.File basedir
directory in which comm-properties are stored


bootstrap

private java.util.Properties bootstrap

settings

private java.util.Properties settings

BOOT_TIMEOUT

public static final int BOOT_TIMEOUT
See Also:
Constant Field Values

TIMEOUT

public static final int TIMEOUT
If TIMEOUT ms have passed after an request, the package is believed of have gotten lost

See Also:
Constant Field Values

PING_INTERVAL

public static final int PING_INTERVAL
the interval PING packages get send to neighbor nodes, to keep the UDP connection alive, because if the UDP connection collapse it might be hard to rebuild it (UDP hole punching)

See Also:
Constant Field Values

CONNECTION_TIMEOUT

public static final int CONNECTION_TIMEOUT
the time after which a connection is considered dead.

See Also:
Constant Field Values

local

private LocalNode local
the local node this communicator is attached to


addr

private java.util.Collection<InetAddress> addr
this communicators address


docfactory

private javax.xml.parsers.DocumentBuilderFactory docfactory
used to build the XML documents needed to send packages


transFactory

private javax.xml.transform.TransformerFactory transFactory
used to transform XML documents into OutputStreams


socket

private java.net.DatagramSocket socket
the socket all packets are send and received with. On a local machine this socket will stay at the same port, but over NAT?


received

java.util.Hashtable<InetAddress,java.util.Vector<UDP>> received
contains received, unfinished packets


responses

java.util.Hashtable<InetAddress,java.lang.Integer> responses
list of received elementar response packets


connections

java.util.Hashtable<InetAddress,java.lang.Long> connections
map of connections to their last response time


useableAddresses

java.util.Hashtable<Node,InetAddress> useableAddresses
maps Nodes to InetAddresses of the Node, that work


ip_answer

boolean ip_answer
indicates if this communicators ip address was updated

Constructor Detail

InetCommunicator

public InetCommunicator()
creates a new InetCommunicator.


InetCommunicator

public InetCommunicator(java.io.File basedir)

InetCommunicator

public InetCommunicator(int port)
                 throws java.io.IOException
creates a new InetCommunicator. The socket will be created. Package receiving and other necessary methods to keep a communication running are established.

Throws:
java.io.IOException
Method Detail

open

public boolean open()
             throws java.io.IOException
Throws:
java.io.IOException

bootstrap

public void bootstrap()
               throws BootstrapException
Throws:
BootstrapException

isOpen

public boolean isOpen()
Specified by:
isOpen in class Communicator

open

public void open(int port)
          throws java.io.IOException
Throws:
java.io.IOException

close

public void close()
Specified by:
close in class Communicator

attachNode

public void attachNode(LocalNode l)
Specified by:
attachNode in class Communicator

getAddress

public java.util.Collection<Address> getAddress()
Description copied from class: Communicator
returns the Address this Communicator uses to send Packets

Specified by:
getAddress in class Communicator
Returns:

findMyAddress

public void findMyAddress(Address apeer)
                   throws java.io.IOException
Specified by:
findMyAddress in class Communicator
Throws:
java.io.IOException

getDocumentBuilder

public javax.xml.parsers.DocumentBuilder getDocumentBuilder()
Specified by:
getDocumentBuilder in class Communicator

parseAddress

public InetAddress parseAddress(java.lang.String addr)
                         throws IncompatibleAddressException
Specified by:
parseAddress in class Communicator
Throws:
IncompatibleAddressException

print_debug

private void print_debug(org.w3c.dom.Document d)
print a Document to System.out. For debugging

Parameters:
d - the document to print

write

public void write(org.w3c.dom.Document d,
                  java.io.File out)
           throws javax.xml.transform.TransformerException,
                  java.io.IOException
Specified by:
write in class Communicator
Throws:
javax.xml.transform.TransformerException
java.io.IOException

startConnectionHolder

private void startConnectionHolder()
starts the mechanism to keep UDP connections alive. This is necessary, because some UDP connections might have been established via UDP hole punching. This means, that neither communication partner is able to reastablish the connection once it is dead, because each others NAT routers are blocking unknown packets from the outside. If packets are send on regular intervals the router will expect packets and thus keep the connection.


connectionEstablished

private boolean connectionEstablished(InetAddress address)
looks up the time, when the last package was received. If that's to long ago, the connection is considered dead

Parameters:
address - the address the connection belongs to
Returns:
true, if the connection is alive

establishConnection

private void establishConnection(InetAddress address)
                          throws UDP.UDPException,
                                 java.io.IOException
establishes a connection. First a simple ping is tried to test, if the other peer might be able to answer directly. If this is not the case, the other peer is probably behind a NAT router, so UDP hole punching is tried. In UDP hole punching the peer gets told of the connection request from a third peer, who already has got a connection, and then answers (even if he didn't get the packet). The NAT Router thinks, he established the connection and thus now allows also the other packets in.

Parameters:
address - the address to connect to
Throws:
java.io.IOException - if no connection could be established
UDP.UDPException

waitForEcho

private int waitForEcho(InetAddress address)
waits until any reply came from address. Only ECHO replies are marked received

Parameters:
address - the address to listen at
Returns:
the reply, or UDP.NO_REPLY, if TIMEOUT ms no message came

waitForEcho

private int waitForEcho(InetAddress address,
                        int reply)
waits until the specified reply came from address. The reply is marked received

Parameters:
address - the Address to listen at
reply - the reply to wait for
Returns:
the reply, or UDP.NO_REPLY, if TIMEOUT ms no reply came

reset

private void reset(InetAddress address,
                   int reply)
resets the specified entry at adress in the response list

Parameters:
address - the address to reset
reply - the reply to reset at the address

punch_hole

private void punch_hole(InetAddress action)
sends PING packets to punch a UDP hole into the NAT router this peer is hidden behind

Parameters:
action - the address to enable the communication to

request_hole_punch

private void request_hole_punch(InetAddress action,
                                InetAddress sender)
sends a node a request to punch a UDP hole for another node

Parameters:
action - the node to send the request to
sender - the node to punch the UDP hole for

run

public void run()
this methods listens for Packets send to this peer and handles them appropriately. If a complete Package is received receivePackage(InputStream, InetAddress) is executed

Specified by:
run in interface java.lang.Runnable

receivePackage

private void receivePackage(java.io.InputStream in,
                            InetAddress sender)
builds a CPackage out of the InputStream. reads the InputStream and builds a XML Document. The XML Document is used to build the Package.

Parameters:
in - the InputStream containing the data
sender - the address of the sender of the package (might not be usable if the sender used tor)

sendPackage

public void sendPackage(CPackage p,
                        RemoteNode to)
                 throws IncompatibleAddressException,
                        NotReachableException,
                        PackageBuildException
Specified by:
sendPackage in class Communicator
Throws:
IncompatibleAddressException
NotReachableException
PackageBuildException

sendPackage

public void sendPackage(CPackage p,
                        Address to)
                 throws IncompatibleAddressException,
                        java.io.IOException,
                        PackageBuildException
Specified by:
sendPackage in class Communicator
Throws:
IncompatibleAddressException
java.io.IOException
PackageBuildException