[an error occurred while processing this directive]
Logo IMMD
Department of Computer Science 4
Institut für Informatik  >  Informatik 4  >  Projects  >  JX  >  Misc

Bearbeiter: Torsten Ehlers, Christian Fiermann, Stefan Winkler

JX Betriebssystem

JX ist ein bis auf den Mikrokernel vollständig in Java geschriebenes Betriebssystem. Die Speicherverwaltung im Mikrokernel ist in C geschrieben, um JX einen direkten Zugriff auf den Hauptspeicher zu ermöglichen. JX zeichnet sich durch folgende Eigenschaften aus:

  • Einfache und robuste Architektur
  • Dynamische Betriebssystemerweiterung mit nicht vertrauenswürdigen Komponenten
  • Wiederverwendung von Code
  • Sicherheit durch Domain-Konzept
  • Einfache Speicherverwaltung durch Garbage Collection

Aufgabenstellung

Erweiterung des Netzwerkprotokollstacks des JX-Betriebssystems um TCP. Die Protokolle der unteren Schichten waren schon als Ergebnis einer früheren Studienarbeit implementiert. Sie mussten im Rahmen unserer Implementierung teilweise angepasst werden.
Bereitstellung einer Socket-Schnittstelle wie im JDK, um beliebigen Java-Programmen die Nutzung des Netzwerks zu ermöglichen.

Paketzirkulation im Netzwerkstack von JX

Um den Speicherverbrauch einzelner Anwendungen zu begrenzen und um das ständige Erzeugen und Verwerfen von Objekten zu vermeiden, existiert im Netzwerkstack von JX ein Mechanismus zur Paketzirkulation. Das bedeutet, dass beim Empfangen eines Pakets ein leeres übergegeben werden muss und beim Senden ein leeres zurückgegeben wird.
Die TCP-Implementierung muss an diesen Mechanismus entsprechend angepasst werden.

TCP Protokoll

Das Tranmission Control Protocol stellt den darüberliegenden Schichten einen zuverlässigen reihenfolgeerhaltenden Datentransport zur Verfügung. Die oberen Schichten lesen und schreiben dabei in Streams. Das Protokoll zerlegt die Daten vor dem Senden in einzelne Pakete und baut sie nach dem Empfangen wieder zu einem Stream zusammen.
Die Abbildung der eingehenden Pakete auf die jeweilige Verbindung erfolgt über Ports. Jede Verbindung wird durch einen Socket repräsentiert. Dieser ist eindeutig charakterisiert durch das 4-Tupel (Lokale Addresse, Lokaler Port, Zieladdresse, Zielport).

TCP/IP Header

Da die Quell- und Zieladdresse nur im IP- und nicht erneut im TCP-Header gespeichert werden, muss die TCP-Schicht diese Daten aus dem IP-Header erhalten. Darüber hinaus wird zur Berechnung der Checksumme der TCP-Pakete ein Pseudo-Header gebaut, der ebenfalls einige Felder des IP-Headers enthält.

Anhand des Protokolltyps im IP-Header ordnet die IP-Schicht die Pakete den oberen Schichten, also auch TCP, zu.

IP Header

Durch Source- und Destination Port werden die kommunizierenden Anwendungen identifiziert. Um Reihenfolgeerhaltung und Zuverlässigkeit zu gewährleisten benutzt TCP Sequenznummern. Beim Verbindungsaufbau wählt jede Seite eine zufällige initiale Sequenznummer. Bei der Datenübertragung wird die Sequenznummer immer um die Zahl der übertragenen Datenbytes erhöht. Anhand der Sequenznummer ist es der Gegenstelle möglich, die Pakete in der richtigen Reihenfolge zusammenzufügen. Mit der Acknowledgement Number wird der Gegenstelle mitgeteilt, bis zu welcher Sequenznummer sämtliche Daten empfangen wurden. Bleibt die Bestätigung für versandte Pakete bis zu einem vorgegebenen Timeout aus, geht TCP davon aus, dass das Paket verloren gegangen ist und sendet es erneut.
Die Semantik des TCP-Pakets wird durch Flags charakterisert.

TCP Header

Beispielverbindung zwischen Client und Server

Client: telnet (Linux, 192.168.34.2)
Server: JX 192.168.34.26

Verbindungsaufbau

  1. Der Client schickt ein Paket mit gesetztem SYN-Flag und einer zufälligen Sequenznummer.
  2. Der Server antwortet darauf mit einem SYN-ACK-Paket, wählt selbst eine initiale Sequenznummer und bestätigt die Sequenznummer des Clients in seinem ACK-Feld.
  3. Der Client bestätigt den erhalt des SYN-ACK-Pakets durch ein weiteres ACK-Paket mit entsprechender Acknowledgment Number.
13:26:38.056818 192.168.34.2.32774 > 192.168.34.26.3012: S 2972432675:2972432675(0)
13:26:38.074686 192.168.34.26.3012 > 192.168.34.2.32774: S 24:24(0) ack 2972432676
13:26:38.075310 192.168.34.2.32774 > 192.168.34.26.3012: . ack 25

Datenübertragung

Im Beispiel übertragen beide Seiten hintereinander ein Datenpaket mit der Länge von 12 bzw. 4 Bytes. Das Paket wird jeweils von der Gegenseite bestätigt.

13:26:38.137537 192.168.34.26.3012 > 192.168.34.2.32774: P 25:37(12) ack 2972432676
13:26:38.138154 192.168.34.2.32774 > 192.168.34.26.3012: . ack 37
13:26:40.773416 192.168.34.2.32774 > 192.168.34.26.3012: P 2972432676:2972432680(4) ack 37
13:26:40.788656 192.168.34.26.3012 > 192.168.34.2.32774: . ack 2972432680

Verbindungsabbau

  1. Der Client schickt ein Paket mit gesetztem FIN-Flag und signalisiert damit dem Server, dass er die Verbindung abbauen möchte.
  2. Der Server antwortet mit einem FIN-ACK-Paket.
  3. Der Client bestätigt den Erhalt durch ein ACK-Paket.
13:26:44.109015 192.168.34.2.32774 > 192.168.34.26.3012: F 2972432680:2972432680(0) ack 37
13:26:44.123220 192.168.34.26.3012 > 192.168.34.2.32774: F 37:37(0) ack 2972432681
13:26:44.123845 192.168.34.2.32774 > 192.168.34.26.3012: . ack 38

TCP Zustandsdiagramm

Der Verbindungsauf- und abbau wird durch folgenden Zustandsautomaten dargestellt:

TCP State Transition Diagram

Probleme bei der Implementierung

  • Verteilung der eingehenden TCP-Pakete

    Nach der Registrierung als TCP-Consumer bei IP werden alle TCP-Pakete an einen TCP-Dispatcher (Klasse TCP) gereicht. Dieser muss unterscheiden, ob die Pakete für einen Client- oder Serversocket bestimmt sind und sie entsprechend weiterreichen. Hierzu müssen sich die Sockets vorher beim Dispatcher registrieren.

  • Implementierung des Zustandsautomaten

    Der Zustansautomat wird durch die Klasse TCPSocket dargestellt. Jeder Zustand wird durch eine eigene Methode repräsentiert. Die einzelnen Zustände warten auf eingehende Pakete und blockieren sich dabei an der Eingangswarteschlange. Wird die Anwendung während dessen geschlossen, so muss es möglich sein, die Deblockierung von aussen anzustossen.

  • Bereitstellung von Client- und Serversockets als Anwendungsschnittstellen

    Durch Einführung der Klassen Socket und ServerSocket wird den Anwendungen eine Abstraktionsebene gegeben, die den Socketschnittstellen in anderen Betriebssystemen entspricht. Jedes Socket-Objekt beinhaltet auch einen Input- und Outputstream, die die Anwendung zum Lesen und Schreiben von bzw. in den Socket nutzt.

  • Erneutes Senden nicht bestätigter Pakete

    Die Implementierung stellt einen Mechanismus zum erneuten Senden bereit. Da hierzu die gesendeten Pakete gepuffert werden müssen, dies aber aufgrund der Paketzirkulation von JX zur Zeit nicht möglich ist, ist das erneute Übertragen nicht aktiviert.


Erlangen, 01.03.2002
Torsten Ehlers, Christian Fiermann, Stefan Winkler
[an error occurred while processing this directive]