forward.server
Class DefaultProtocolHandler

java.lang.Object
  extended by forward.server.DefaultProtocolHandler
All Implemented Interfaces:
IProtocolHandler

public class DefaultProtocolHandler
extends java.lang.Object
implements IProtocolHandler

This is the implementation for the first version of the JAP routing protocol.


Field Summary
private  int m_currentState
          This stores the current protocol state.
private  java.io.ByteArrayOutputStream m_incomingMessageBuffer
          This buffer stores the parts of a incoming protocol message until we received the full message.
private  int m_incomingMessageLength
          This stores the net length of a incoming message in the incoming message buffer.
private  java.io.ByteArrayInputStream m_outgoingMessageBuffer
          This is the for outgoing protocol messages to the client.
private  ForwardConnection m_parentConnection
          This stores the client connection this protocol handler belongs to.
private  java.net.Socket m_serverConnection
          This stores the connection to the selected mixcascade.
private static int MAXIMUM_PROTOCOLMESSAGE_SIZE
          This is the maximum net size of a protocol message in bytes.
private static byte[] MESSAGE_END_SIGNATURE
          This is the end signature of every protocol message.
private static byte[] MESSAGE_START_SIGNATURE
          This is the start signature of every protocol message.
private static int PROTOCOL_VERSION
          This is the version of the current protocol implementation.
private static int STATE_CONNECTED_TO_MIX
          This is the state after we received the cascade selection from the client and built a connection ton the selected cascade.
private static int STATE_CONNECTION_CLOSED
          This is the state after the connection was closed (because of connection termination by client or an error on the connection).
private static int STATE_WAIT_FOR_CASCADE_SELECTION
          This is the state after we have gotten the connection request from a forwarding client (not an infoservice) and sent the connection offer back to the client.
private static int STATE_WAIT_FOR_CLIENT_REQUEST
          This is the state after establishing the connection.
private static int STATE_WAIT_FOR_INFOSERVICE_CLOSE
          This is the state after sending the acknowledgement for the verify message of the infoservice.
 
Constructor Summary
DefaultProtocolHandler(ForwardConnection a_parentConnection)
          Generates a new DefaultProtocolHandler.
 
Method Summary
 int available()
          Returns the number of bytes which are ready for sending to the client without blocking by the next call of read().
private  boolean checkSignature(byte[] a_signature1, byte[] a_signature2)
          This method checks, whether to byte arrays have identical content or not.
 void close()
          Closes the connection to the server and stops handling of protocol messages.
private  boolean connectTo(MixCascade a_selectedCascade)
          This method tries to get a connection to a mixcascade (by probing all ListenerInterfaces).
private  byte[] createProtocolPacket(byte[] a_data)
          Creates a protocol packet from byte array with data.
private  void emptyBuffers()
          This method sends all data in our incoming message buffer to the server.
private  org.w3c.dom.Document generateConnectionAcknowledgement()
          Creates an acknowledge message for the verify request of the infoservice.
private  org.w3c.dom.Document generateConnectionOfferXml()
          Creates the connection offer XML structure.
private  void handleClientCascadeSelectMessage(org.w3c.dom.Element a_japRoutingNode)
          This method handles the cascade select message from a forwarding client.
private  void handleInitialRequestMessage(org.w3c.dom.Element a_japRoutingNode)
          This method handles the initial request messages from a client or an infoservice.
private  void handleProtocol(org.w3c.dom.Element a_japRoutingNode)
          This method handles the incoming XML messages.
private  void messageHandler(byte[] a_newData)
          This method handles all data packets received from the client.
private  void messageReceived(byte[] a_newMessage)
          This method handles and evaluates a whole message.
 int read(byte[] a_buffer)
          Read a_buffer.length bytes from the server in the buffer a_buffer.
private  void sendProtocolDataToClient(byte[] a_data)
          Put the specified data in the buffer for outgoing protocol messages to the client.
 void write(byte[] a_buffer)
          Writes the bytes in a_buffer to the server or the protocol handler.
private  byte[] xmlToProtocolPacket(org.w3c.dom.Document a_doc)
          Creates a protocol packet from an XML structure.
 
Methods inherited from class java.lang.Object
clone, equals, finalize, getClass, hashCode, notify, notifyAll, toString, wait, wait, wait
 

Field Detail

PROTOCOL_VERSION

private static final int PROTOCOL_VERSION
This is the version of the current protocol implementation. Interaction is only possible with clients, which use the same protocol version.

See Also:
Constant Field Values

MAXIMUM_PROTOCOLMESSAGE_SIZE

private static final int MAXIMUM_PROTOCOLMESSAGE_SIZE
This is the maximum net size of a protocol message in bytes. Bigger messages are not accepted and causes an exception.

See Also:
Constant Field Values

MESSAGE_START_SIGNATURE

private static final byte[] MESSAGE_START_SIGNATURE
This is the start signature of every protocol message.


MESSAGE_END_SIGNATURE

private static final byte[] MESSAGE_END_SIGNATURE
This is the end signature of every protocol message.


STATE_WAIT_FOR_CLIENT_REQUEST

private static final int STATE_WAIT_FOR_CLIENT_REQUEST
This is the state after establishing the connection. In this state the protocol waits for the request message from the client (or the infoservice validation request).

See Also:
Constant Field Values

STATE_WAIT_FOR_CASCADE_SELECTION

private static final int STATE_WAIT_FOR_CASCADE_SELECTION
This is the state after we have gotten the connection request from a forwarding client (not an infoservice) and sent the connection offer back to the client. In this state the protocol waits for the answer (cascade selection) from the client.

See Also:
Constant Field Values

STATE_CONNECTED_TO_MIX

private static final int STATE_CONNECTED_TO_MIX
This is the state after we received the cascade selection from the client and built a connection ton the selected cascade. We are forwarading all received packets between client and cascade in this state.

See Also:
Constant Field Values

STATE_CONNECTION_CLOSED

private static final int STATE_CONNECTION_CLOSED
This is the state after the connection was closed (because of connection termination by client or an error on the connection). In this state we wait for the removing from the forwarding scheduler.

See Also:
Constant Field Values

STATE_WAIT_FOR_INFOSERVICE_CLOSE

private static final int STATE_WAIT_FOR_INFOSERVICE_CLOSE
This is the state after sending the acknowledgement for the verify message of the infoservice. We can't close the connection immediately because we have to wait until all data is sent to the infoservice. The infoservice will close the connection after receiving the acknowledgement message (no problem if the infoservice doesn't close the connection, because we are not accepting any more messages, we will close the connection after the timeout).

See Also:
Constant Field Values

m_serverConnection

private java.net.Socket m_serverConnection
This stores the connection to the selected mixcascade. If this value is null, there is no connection to a cascade and the protocol handles all incoming packets. If this value is not null, all incoming packets are forwarded on this connection.


m_incomingMessageBuffer

private java.io.ByteArrayOutputStream m_incomingMessageBuffer
This buffer stores the parts of a incoming protocol message until we received the full message. If we have finished the protocol phase, all packets are directly forwarded, so we only need this buffer while doing the protocol stuff before the forwarding process.


m_incomingMessageLength

private int m_incomingMessageLength
This stores the net length of a incoming message in the incoming message buffer. We get the value from evaluating the message header.


m_outgoingMessageBuffer

private java.io.ByteArrayInputStream m_outgoingMessageBuffer
This is the for outgoing protocol messages to the client. The connection handler will read the data from this buffer and sends them to the client. If we have finished the protocol phase, all packets are read directly from the buffer of the mixcascade connection, so we only need this buffer while doing the protocol stuff before the forwarding process.


m_currentState

private int m_currentState
This stores the current protocol state. This state decides what to do with incoming messages. Look at the constants in this class.


m_parentConnection

private ForwardConnection m_parentConnection
This stores the client connection this protocol handler belongs to.

Constructor Detail

DefaultProtocolHandler

public DefaultProtocolHandler(ForwardConnection a_parentConnection)
                       throws java.lang.Exception
Generates a new DefaultProtocolHandler.

Parameters:
a_parentConnection - This is the client connection for which we are doing the protocol stuff.
Throws:
java.lang.Exception
Method Detail

available

public int available()
              throws java.lang.Exception
Returns the number of bytes which are ready for sending to the client without blocking by the next call of read(). This call throws an exception, if there is something wrong with the connection to the server. If no connection to the server is established, we look in the buffer for protocol messages.

Specified by:
available in interface IProtocolHandler
Returns:
The number of bytes which can be read.
Throws:
java.lang.Exception

read

public int read(byte[] a_buffer)
         throws java.lang.Exception
Read a_buffer.length bytes from the server in the buffer a_buffer. This call blocks until a_buffer.length bytes could be read. This call throws an exception, if there is something wrong with the connection to the server. If no connection to the server is established, we look in the buffer for protocol messages.

Specified by:
read in interface IProtocolHandler
Parameters:
a_buffer - A buffer for the read bytes.
Returns:
The bytes read into the buffer or -1, if the end of the stream is reached.
Throws:
java.lang.Exception

write

public void write(byte[] a_buffer)
           throws java.lang.Exception
Writes the bytes in a_buffer to the server or the protocol handler. This call blocks until the bytes could be written in the send queue. This call throws an exception, if there is something wrong with the connection to the server.

Specified by:
write in interface IProtocolHandler
Parameters:
a_buffer - A buffer with the bytes to write.
Throws:
java.lang.Exception

close

public void close()
Closes the connection to the server and stops handling of protocol messages. All later calls of available(), read(), write() will throw an exception.

Specified by:
close in interface IProtocolHandler

checkSignature

private boolean checkSignature(byte[] a_signature1,
                               byte[] a_signature2)
This method checks, whether to byte arrays have identical content or not.

Parameters:
a_signature1 - The first byte array.
a_signature2 - The second byte array.
Returns:
True, if both byte arrays are not null and have the same content, else the result is false.

messageHandler

private void messageHandler(byte[] a_newData)
                     throws java.lang.Exception
This method handles all data packets received from the client. We evaluate the message header, put the data in the incoming message buffer and call messageReceived() method, if we received the full message. If we find a protocol error (wrong header/trailer, message to long, wrong message content, ...) this method throws an exception.

Parameters:
a_newData - The data packet received from the client.
Throws:
java.lang.Exception

messageReceived

private void messageReceived(byte[] a_newMessage)
                      throws java.lang.Exception
This method handles and evaluates a whole message. The handleProtocol() method is called after parsing the message. This method throws an exception, if there is an error while parsing the message.

Parameters:
a_newMessage - A whole message received from the client.
Throws:
java.lang.Exception

handleProtocol

private void handleProtocol(org.w3c.dom.Element a_japRoutingNode)
                     throws java.lang.Exception
This method handles the incoming XML messages. Dependent of the current prototcol state, it calls the method needed for handling the expected message. This method throws an exception, if there is something wrong with the received message or if there is an error while calling the method for handling the associated event.

Parameters:
a_japRoutingNode - The JAPRouting node, which is the root node of every protocol message.
Throws:
java.lang.Exception

handleInitialRequestMessage

private void handleInitialRequestMessage(org.w3c.dom.Element a_japRoutingNode)
                                  throws java.lang.Exception
This method handles the initial request messages from a client or an infoservice. The request is parsed and if the request was from a client, we send the connection offer back. I the request was the verify message from the infoservice, we send an acknowledgement. This method throws an exception, if there is something wrong with the received message or if there is an error while creating the answer.

Parameters:
a_japRoutingNode - The JAPRouting node of the connection request message.
Throws:
java.lang.Exception

handleClientCascadeSelectMessage

private void handleClientCascadeSelectMessage(org.w3c.dom.Element a_japRoutingNode)
                                       throws java.lang.Exception
This method handles the cascade select message from a forwarding client. If everything is ok, it connects to the selected cascade, so forwarding can start. This method throws an exception, if there is something wrong with the received message or if there is an error while connecting to the specified mixcascade.

Parameters:
a_japRoutingNode - The JAPRouting node of the cascade select message.
Throws:
java.lang.Exception

connectTo

private boolean connectTo(MixCascade a_selectedCascade)
This method tries to get a connection to a mixcascade (by probing all ListenerInterfaces). The connection is made by calling the createConnection() method of ForwardUtils, which knows the current proxy settings.

Parameters:
a_selectedCascade - The mixcascade to build a connection to.
Returns:
True, if we got the connection (stored in m_serverConnection). False, if we couldn't make the connection.

emptyBuffers

private void emptyBuffers()
                   throws java.lang.Exception
This method sends all data in our incoming message buffer to the server. This method is called after we made a connection to a mixcascade to send the already received data to the first mix.

Throws:
java.lang.Exception

generateConnectionOfferXml

private org.w3c.dom.Document generateConnectionOfferXml()
                                                 throws java.lang.Exception
Creates the connection offer XML structure. This structure is sent directly after the connection request from the client. The client will find information about the used routing protocol verison, all available MixCascades, our quality of service and whether we need dummy traffic for holding connections.

Returns:
The connection offer XML structure.
Throws:
java.lang.Exception

generateConnectionAcknowledgement

private org.w3c.dom.Document generateConnectionAcknowledgement()
                                                        throws java.lang.Exception
Creates an acknowledge message for the verify request of the infoservice. So the infoservice knows, that verifying the forwarder was successful. The infoservice will close the connection immediately after receiving this acknowledgement (no problem if the infoservice doesn't close the connection, because we are not accepting any more messages, we will close the connection after the timeout).

Returns:
The verify acknowledge XML structure.
Throws:
java.lang.Exception

sendProtocolDataToClient

private void sendProtocolDataToClient(byte[] a_data)
Put the specified data in the buffer for outgoing protocol messages to the client.

Parameters:
a_data - The data to put into the buffer.

xmlToProtocolPacket

private byte[] xmlToProtocolPacket(org.w3c.dom.Document a_doc)
                            throws java.lang.Exception
Creates a protocol packet from an XML structure.

Parameters:
doc - The XML structure which shall be transformed in a protocol packet.
Returns:
The protocol packet with the XML structure inside.
Throws:
java.lang.Exception

createProtocolPacket

private byte[] createProtocolPacket(byte[] a_data)
Creates a protocol packet from byte array with data. This method adds header and trailer to the data and returns the whole packet.

Parameters:
a_data - The bytes to put in the protocol packet.
Returns:
The protocol packet with data, header and trailer.