Index: branches/network/src/lib/network/Makefile.am
===================================================================
--- branches/network/src/lib/network/Makefile.am	(revision 6041)
+++ branches/network/src/lib/network/Makefile.am	(revision 6043)
@@ -11,5 +11,6 @@
                       data_stream.cc \
                       network_protocol.cc \
-		      server_socket.cc
+		      server_socket.cc \
+		      handshake.cc
 
 
@@ -22,4 +23,5 @@
                  data_stream.h \
                  network_protocol.h \
-		 server_socket.h
+		 server_socket.h \
+		 handshake.h
 
Index: branches/network/src/lib/network/handshake.cc
===================================================================
--- branches/network/src/lib/network/handshake.cc	(revision 6043)
+++ branches/network/src/lib/network/handshake.cc	(revision 6043)
@@ -0,0 +1,160 @@
+/*
+   orxonox - the future of 3D-vertical-scrollers
+
+   Copyright (C) 2004 orx
+
+   This program is free software; you can redistribute it and/or modify
+   it under the terms of the GNU General Public License as published by
+   the Free Software Foundation; either version 2, or (at your option)
+   any later version.
+
+### File Specific:
+   main-programmer: christoph
+   co-programmer:
+*/
+
+
+/* this is for debug output. It just says, that all calls to PRINT() belong to the DEBUG_MODULE_NETWORK module
+   For more information refere to https://www.orxonox.net/cgi-bin/trac.cgi/wiki/DebugOutput
+*/
+#define DEBUG_MODULE_NETWORK
+
+#include "handshake.h"
+
+Handshake::Handshake( bool server, int clientId )
+{
+  /* set the class id for the base object */
+  this->setClassID(CL_HANDSHAKE, "Handshake");
+
+  this->server = server;
+  this->clientId = clientId;
+  this->state = HS_SEND_INIT;
+  this->isOk = false;
+}
+
+void Handshake::writeBytes( const byte * data, int length )
+{
+  if ( state == HS_RECV_INIT )
+  {
+    if ( length != _INITIAL_DATA_LENGTH )
+    {
+      PRINTF(1)("initial packet has wrong size %d instead of %d\n", length, _INITIAL_DATA_LENGTH);
+      state = HS_COMPLETED;
+      return;
+    }
+
+    if ( strncmp((char*)data, _INITIAL_DATA, length) )
+    {
+      PRINTF(1)("initial packed does not match\n");
+      state = HS_COMPLETED;
+      return;
+    }
+
+    state = HS_SEND_VERSION;
+    PRINTF(0)("got valid initial packet from client %d\n", clientId);
+    return;
+  }
+
+  if ( state == HS_RECV_VERSION )
+  {
+    if ( length != _ORXONOX_VERSION_LENGTH )
+    {
+      PRINTF(1)("version number packet has wrong size %d instead of %d\n", length, _ORXONOX_VERSION_LENGTH);
+      state = HS_COMPLETED;
+      return;
+    }
+
+    if ( strncmp((char*)data, _ORXONOX_VERSION, length) )
+    {
+      PRINTF(1)("versions do not match\n");
+      state = HS_COMPLETED;
+      return;
+    }
+
+    if ( this->isServer() )
+      state = HS_SEND_ID;
+    else
+      state = HS_RECV_ID;
+
+    PRINTF(0)("client %d's version does match\n", clientId);
+    return;
+  }
+
+  if ( state == HS_RECV_ID )
+  {
+    if ( length != _ORXONOX_VERSION_LENGTH )
+    {
+      PRINTF(1)("hostID packet has wrong size %d instead of %d\n", length, 4);
+      state = HS_COMPLETED;
+      return;
+    }
+
+    this->state = HS_COMPLETED;
+    this->isOk = true;
+    memcpy(&(this->newHostId), data, 4);
+    PRINTF(0)("got my hostID: %d\n", newHostId);
+    return;
+  }
+
+}
+
+int Handshake::readBytes( byte * data, int maxLength, int & reciever )
+{
+  if ( state == HS_SEND_INIT )
+  {
+    if ( maxLength < _INITIAL_DATA_LENGTH )
+    {
+      PRINTF(1)("buffer too small for _INITIAL_DATA");
+      state = HS_COMPLETED;
+      return 0;
+    }
+
+    state = HS_RECV_INIT;
+    memcpy(data, _INITIAL_DATA, _INITIAL_DATA_LENGTH);
+    if ( this->isServer() )
+      reciever = clientId;
+    return _INITIAL_DATA_LENGTH;
+  }
+
+  if ( state == HS_SEND_VERSION )
+  {
+    if ( maxLength < _ORXONOX_VERSION_LENGTH )
+    {
+      PRINTF(1)("buffer too small for version number");
+      state = HS_COMPLETED;
+      return 0;
+    }
+
+    state = HS_RECV_VERSION;
+    memcpy(data, _ORXONOX_VERSION, _ORXONOX_VERSION_LENGTH);
+    if ( this->isServer() )
+      reciever = clientId;
+    return _ORXONOX_VERSION_LENGTH;
+  }
+
+  if ( state == HS_SEND_ID )
+  {
+    if ( maxLength < 4 )
+    {
+      PRINTF(1)("buffer too small for ID");
+      state = HS_COMPLETED;
+      return 0;
+    }
+
+    state = HS_COMPLETED;
+    memcpy(data, (byte*)&clientId, 4);
+    if ( this->isServer() )
+      reciever = clientId;
+    return 4;
+  }
+
+  return 0;
+}
+
+void Handshake::writeDebug( ) const
+{
+}
+
+void Handshake::readDebug( ) const
+{
+}
Index: branches/network/src/lib/network/handshake.h
===================================================================
--- branches/network/src/lib/network/handshake.h	(revision 6043)
+++ branches/network/src/lib/network/handshake.h	(revision 6043)
@@ -0,0 +1,53 @@
+/*!
+ * @file network_stream.h
+ *  implementation of a network pipe
+ */
+
+#ifndef _HANDSHAKE
+#define _HANDSHAKE
+
+#include "base_object.h"
+#include "synchronizeable.h"
+
+#define _INITIAL_DATA "orxonox"
+#define _INITIAL_DATA_LENGTH 7
+
+#define _ORXONOX_VERSION "\x00\x00\x00\x01"
+#define _ORXONOX_VERSION_LENGTH 4
+
+typedef enum HandshakeState {
+  HS_SEND_INIT = 0,
+  HS_RECV_INIT,
+  HS_SEND_VERSION,
+  HS_RECV_VERSION,
+  HS_SEND_ID,
+  HS_RECV_ID,
+  HS_COMPLETED,
+
+  NUM_STATES
+};
+
+class Handshake : public Synchronizeable
+{
+  public:
+    Handshake(bool server, int clientId = 0);
+    inline bool       completed(){ return state == HS_COMPLETED; }
+    inline bool       ok(){ return isOk; }
+    inline int        getHostId(){ return newHostId; }
+
+    virtual void      writeBytes(const byte* data, int length);
+    virtual int       readBytes(byte* data, int maxLength, int& reciever);
+    virtual void      writeDebug() const;
+    virtual void      readDebug() const;
+
+  private:
+    int               state;
+    int               server;
+    int               clientId;
+    int               newHostId;
+    bool              isOk;
+
+};
+
+
+#endif
Index: branches/network/src/lib/network/network_protocol.cc
===================================================================
--- branches/network/src/lib/network/network_protocol.cc	(revision 6041)
+++ branches/network/src/lib/network/network_protocol.cc	(revision 6043)
@@ -57,11 +57,10 @@
     * @arg bufferLength: the length of the internal buffer
     * @arg source: reference to the source Synchronizeable object
-    * @arg remoteID: id number of the remote Synchronizeable object
     * @return: the new data length with header (the header data is included into byte* data)
     *          -1 if there isn't enough space in the buffer for the header
 */
-int NetworkProtocol::createHeader(byte* data, int length, int bufferLength, const Synchronizeable& source, unsigned int remoteID)
+int NetworkProtocol::createHeader(byte* data, int length, int bufferLength, const Synchronizeable& source)
 {
-  printf("NetworkProtocol: create header length = %i, bufferLength = %i\n", length, bufferLength);
+  PRINTF(0)("create header length = %i, bufferLength = %i\n", length, bufferLength);
   //If there isn't enough space for the header return -1
   if (length + this->headerLength > bufferLength)
@@ -82,9 +81,7 @@
   data[1] = 0;
   /* sender ID: FIXME: there will be a better ID (for example unique:D)*/
-  data[2] = (byte)source.getClassID();
-  /* receiver ID */
-  data[3] = remoteID;
+  data[2] = (byte)(source.getUniqueID());
   /* data length*/
-  data[4] = length;
+  data[3] = length;
 
 
@@ -104,5 +101,5 @@
   if (length < headerLength)
   {
-    PRINTF(0)("Received data is to short; it can't contain a header!");
+    PRINTF(0)("Received data is to short; it can't contain a header!\n");
     Header h;
     h.protocol = 0;
@@ -117,10 +114,8 @@
   /* version number */
   h.version = data[1];
-  /* sender ID: FIXME: there will be a better ID (for example unique:D)*/
-  h.senderID = data[2];
-  /* receiver ID */
-  h.receiverID = data[3];
+  /* unique ID */
+  h.uniqueID = data[2];
   /* data length*/
-  h.length = data[4];
+  h.length = data[3];
 
 
Index: branches/network/src/lib/network/network_protocol.h
===================================================================
--- branches/network/src/lib/network/network_protocol.h	(revision 6041)
+++ branches/network/src/lib/network/network_protocol.h	(revision 6043)
@@ -17,6 +17,5 @@
   byte protocol;
   byte version;
-  byte senderID;
-  byte receiverID;
+  byte uniqueID;
   byte length;
 };
@@ -33,5 +32,5 @@
     ~NetworkProtocol();
 
-    int createHeader(byte* data, int length, int bufferLength, const Synchronizeable& source, unsigned int remoteID);
+    int createHeader(byte* data, int length, int bufferLength, const Synchronizeable& source);
     Header extractHeader(byte* data, int length);
 
Index: branches/network/src/lib/network/network_stream.cc
===================================================================
--- branches/network/src/lib/network/network_stream.cc	(revision 6041)
+++ branches/network/src/lib/network/network_stream.cc	(revision 6043)
@@ -26,4 +26,5 @@
 #include "connection_monitor.h"
 #include "synchronizeable.h"
+#include "network_manager.h"
 #include "list.h"
 #include "debug.h"
@@ -56,4 +57,9 @@
   this->networkProtocol = new NetworkProtocol();
   this->connectionMonitor = new ConnectionMonitor();
+
+  Handshake* hs = new Handshake(false);
+  this->handshakes.push_back(hs);
+  this->connectSynchronizeable(*hs);
+  PRINTF(0)("NetworkStream: %s\n", hs->getName());
 }
 
@@ -77,4 +83,5 @@
   this->bActive = false;
   this->serverSocket = NULL;
+  myHostId = 0;
 }
 
@@ -94,4 +101,12 @@
       (*i)->disconnectServer();
       (*i)->destroy();
+    }
+  }
+
+  for (HandshakeVector::iterator i = handshakes.begin(); i!=handshakes.end(); i++)
+  {
+    if ( *i )
+    {
+      delete (*i);
     }
   }
@@ -116,4 +131,113 @@
   if ( this->type == NET_SERVER )
     this->updateConnectionList();
+
+  for (HandshakeVector::iterator it = handshakes.begin(); it!=handshakes.end(); it++)
+  {
+    if ( *it )
+    {
+      if ( (*it)->completed() )
+      {
+        if ( (*it)->ok() )
+        {
+          NetworkManager::getInstance()->setHostID( (*it)->getHostId() );
+          myHostId = NetworkManager::getInstance()->getHostID();
+          delete *it;
+          *it = NULL;
+          PRINT(0)("handshake finished\n");
+        }
+        else
+        {
+          PRINT(1)("handshake failed!\n");
+          delete *it;
+          *it = NULL;
+          //TODO: handle error
+        }
+      }
+    }
+  }
+
+
+  /* DOWNSTREAM */
+
+  int dataLength;
+  int reciever;
+  Header header;
+  for (SynchronizeableList::iterator it = synchronizeables.begin(); it!=synchronizeables.end(); it++)
+  {
+    if ( (*it)->getOwner() == myHostId )
+    {
+      PRINTF(0)("sync: %s\n", (*it)->getName());
+      reciever = 0;
+      do {
+        dataLength = (*it)->readBytes(downBuffer, DATA_STREAM_BUFFER_SIZE, reciever);
+
+        if ( dataLength<=0 ){
+          reciever = 0;
+          continue;
+        }
+
+        PRINTF(0)("read %d bytes\n", dataLength);
+
+        dataLength = networkProtocol->createHeader((byte*)downBuffer, dataLength, DATA_STREAM_BUFFER_SIZE, static_cast<const Synchronizeable&>(*(*it)));
+
+        if ( dataLength<=0 )
+          continue;
+
+        if ( reciever!=0 )
+        {
+          if ( networkSockets[reciever] )
+          {
+            PRINTF(0)("write %d bytes to socket\n", dataLength);
+            networkSockets[reciever]->writePacket(downBuffer, dataLength);
+          }
+          else
+          {
+            PRINTF(1)("networkSockets[reciever] == NULL\n");
+          }
+        }
+        else
+        {
+          for ( int i = 1; i<networkSockets.size(); i++)
+          {
+            if ( networkSockets[i] )
+              networkSockets[i]->writePacket(downBuffer, dataLength);
+          }
+        }
+
+      } while( reciever!=0 );
+    }
+  }
+
+  /* UPSTREAM */
+
+  for ( int i = 1; i<networkSockets.size(); i++)
+  {
+    if ( networkSockets[i] )
+    {
+      do {
+        dataLength = networkSockets[i]->readPacket(upBuffer, DATA_STREAM_BUFFER_SIZE);
+
+        if ( dataLength<=0 )
+          continue;
+
+        PRINTF(0)("read %d bytes from socket\n", dataLength);
+        header = networkProtocol->extractHeader(upBuffer, dataLength);
+        dataLength -= sizeof(header);
+
+        if ( dataLength != header.length )
+        {
+          PRINTF(1)("packetsize in header and real packetsize do not match! %d:%d\n", dataLength, header.length);
+          continue;
+        }
+
+        for (SynchronizeableList::iterator it = synchronizeables.begin(); it!=synchronizeables.end(); it++)
+        {
+          if ( *it && (*it)->getUniqueID()==header.uniqueID )
+            (*it)->writeBytes(upBuffer+sizeof(header), dataLength);
+        }
+
+      } while ( dataLength>0 );
+    }
+  }
 
 #if 0
@@ -199,13 +323,15 @@
       freeSocketSlots.pop_back();
       networkSockets[clientId] = tempNetworkSocket;
+      handshakes[clientId] = new Handshake(true, clientId);
     } else
     {
       clientId = networkSockets.size();
       networkSockets.push_back(tempNetworkSocket);
+      handshakes.push_back(new Handshake(true, clientId));
     }
 
     PRINTF(0)("New Client: %d\n", clientId);
-    //TODO: start handshake
-    //new Handshake(true, clientId);
+
+    this->connectSynchronizeable(*handshakes[clientId]);
   }
 
@@ -223,8 +349,11 @@
       networkSockets[i]->destroy();
       networkSockets[i] = NULL;
+      delete handshakes[i];
+      handshakes[i] = NULL;
 
       if ( i == networkSockets.size()-1 )
       {
         networkSockets.pop_back();
+        handshakes.pop_back();
       }
       else
@@ -237,2 +366,4 @@
 
 }
+
+
Index: branches/network/src/lib/network/network_stream.h
===================================================================
--- branches/network/src/lib/network/network_stream.h	(revision 6041)
+++ branches/network/src/lib/network/network_stream.h	(revision 6043)
@@ -13,4 +13,5 @@
 #include "network_protocol.h"
 #include "server_socket.h"
+#include "handshake.h"
 
 class Synchronizeable;
@@ -21,5 +22,6 @@
 
 typedef std::list<Synchronizeable*>  SynchronizeableList;
-typedef std::vector<NetworkSocket*> NetworkSocketVector;
+typedef std::vector<NetworkSocket*>  NetworkSocketVector;
+typedef std::vector<Handshake*>      HandshakeVector;
 
 
@@ -47,4 +49,5 @@
     SynchronizeableList    synchronizeables;
     NetworkSocketVector    networkSockets;
+    HandshakeVector        handshakes;
     ServerSocket*          serverSocket;
     int                    type;
@@ -53,4 +56,6 @@
     std::list<int>         freeSocketSlots;
 
+    int                    myHostId;
+
     void updateConnectionList();
 };
Index: branches/network/src/lib/network/synchronizeable.cc
===================================================================
--- branches/network/src/lib/network/synchronizeable.cc	(revision 6041)
+++ branches/network/src/lib/network/synchronizeable.cc	(revision 6043)
@@ -17,4 +17,5 @@
 #include "synchronizeable.h"
 #include "netdefs.h"
+#include "network_manager.h"
 
 
@@ -26,5 +27,5 @@
 
   //owner = ?;
-  //hostID = ?;
+  hostID = NetworkManager::getInstance()->getHostID();
   //state = ?;
 
@@ -55,5 +56,5 @@
  *  read data from NetworkStream
  */
-int Synchronizeable::readBytes(byte* data)
+int Synchronizeable::readBytes(byte* data, int maxLength, int& reciever)
 {}
 
@@ -65,7 +66,4 @@
 void Synchronizeable::readDebug() const
 {}
-
-
-
 
 
@@ -111,2 +109,5 @@
   return this->state & STATE_OUTOFSYNC == STATE_OUTOFSYNC;
 }
+
+
+
Index: branches/network/src/lib/network/synchronizeable.h
===================================================================
--- branches/network/src/lib/network/synchronizeable.h	(revision 6041)
+++ branches/network/src/lib/network/synchronizeable.h	(revision 6043)
@@ -29,23 +29,25 @@
 
     virtual void      writeBytes(const byte* data, int length);
-    virtual int       readBytes(byte* data);
+    virtual int       readBytes(byte* data, int maxLength, int& reciever);
     virtual void      writeDebug() const;
     virtual void      readDebug() const;
-    
-    
-    
-    
-    
-    void setIsServer(bool isServer);
-    void setIsOutOfSync(bool outOfSync);
+
+    void setIsServer( bool isServer );
+    void setIsOutOfSync( bool outOfSync );
     bool isServer();
     bool isOutOfSync();
+    void setUniqueId( int id ){ uniqueID = id; }
+    int  getUniqueID() const { return uniqueID; };
+    void requestSync( int hostID ){ this->synchronizeRequests.push_back( hostID ); }
+
+    inline int getOwner(){ return owner; }
+    inline void setOwner(int owner){ this->owner = owner; }
 
   private:
 
     int               uniqueID;
-    
-    
-    
+
+
+
     //static std::vector<Synchronizeable*> classList;
     int owner;
