 Hallo und willkommen zu meinem Vortrag. Mein Name ist Felix Schiller. Ich möchte euch heute Packet Capturing auf Android OS vorstellen und zwar ohne Ruhzugriff. Das ist ein kleines Projekt, das bei mir abgefallen ist. Es gibt auch ein paar Apps, die das bereits machen und ich würde jetzt gerne mal erörtern, wie man das macht und was man dafür alles beachten muss. Jetzt ist der Bildschirm ausgegangen. Also sind eure Technik zu tun oder mit meiner Technik zu tun? So, wenn man neue Präsentationstools verwendet, dann scheint das wohl dazu zu gehören. Einmal noch. Ervorragend, okay. Was sind die Voraussetzungen, um von diesem Beitrag sich was mitzunehmen heute, grundlegendes Verständnis von OSI-Schichtenmodell und grundlegendes Verständnis vom TCP-IP-Stack, was man wahrscheinlich von den meisten Besuchern einer CCC-Veranstaltung durchaus erwarten kann, wenn man sich so im Raum umschaut. Also easy, machbar für uns. Kleine Wiederholung, was ist Packet Capturing laut Technopedia intercepting a data packet that is crossing or moving over a specific computer network? Also wir fangen Datenpakete, die in unserem Computernetzwerk an unsere Netzwerkschnittstelle vorbeifliegen, greifen wir auf, um dort Informationen auszuwerten. Normalerweise macht das unser, ein Programm für uns im TCP-Dump beispielsweise. Und auf einem normalen Computersystem sieht das so aus. Pakete kommen an unsere Hardware vorbei, werden von unserer Netzwerkkarte aufgefangen und der Kartentreiber übergibt die aufgefangenen Netzwerkkakete an unseren Protocol-Stack oder TCP-IP-Stack wertet die Ethernet-Pakete Layer 2-Pakete aus und sendet den Inhalt an unsere Applications. Der Kernel nimmt auch die Daten des Kartdrivers, die Netzwerkkakete, die gesendet und die empfangen werden und schickt die in ein Paketfilter. Dort kann ein Netzwerkmonitor-Protool wie beispielsweise TCP-Dump die Daten abgreifen. Okay, und warum funktioniert das jetzt auf Android nicht? Android ist ja Linux und so. Wir haben bei Android keinen Zugriff auf Systemfunktionen. Wir haben bei Android keinen Zugriff von unseren Apps auf das Kernel Layer ohne dass wir unsere Kiste routen. Und unser Permission-Model in Android erlaubt nur vorgefertigte Rechte oder Rechte, die sicher sind, die von Apps definiert werden. Das heißt, wir können uns auch nicht einfach recht erstellen. Du bist jetzt unser Admin-User, du darfst jetzt auf Kernel Space zugreifen und Netzwerk-Pakete mitlesen. Okay, ganz kurz zur Einführung. Wie sieht das Android-Security-Model aus? Diejenigen, die sich genau damit auskennen, bitte nageln mich nicht darauf fest. Das ist nur eine große Übersicht. Unser Android ist ein Software-Stack auf einem Linux-Kernel. Wir haben ein Hardware-Access-Layer und die Runtime, indem unsere Apps laufen, das Framework, in das uns die Java-Umgebung bereitstellt und wir haben unsere Apps, die da oben drin laufen. Jedes Software-Layer, das übereinander auf dem Stack liegt, erfordert Zugriff auf das darunter liegende Software-Stack an. Wenn also unsere Taschenlampen-App, unsere persönlichen Benutzerdaten an die Cloud senden möchte, dann muss sie dieses Recht Permission Internet vorher am Android-Framework anmelden. Wir müssen das bei der Installation der App bestätigen und dann vermitteln das Framework über die Runtime auf das Hardware-Access-Layer unseren Zugriff. Oder am Beispiel mit einer Kamera-App. Wir haben die Kamera-App, die App meldet die Android-Permission-Kamera am Android-Framework an und das Android-Framework vermittelt unser Zugriff auf hardware, auf unsere Hardware-App, die dann wiederum erst den Linux-Curnal-Triber, den Treiber, der quasi auf der Linux Software-Stack-Ebene, kernel Software-Stack-Ebene, vermittelt ist. Jetzt zur Vervollständigung, was ist Routing? Beim Routing ändern wir die System-Partition und fügen eine Super-User-Binary auf System-Layer zu die uns erlaubt, privilegierte Shell-Commands abzusenden. Also wir haben einfach eine SU-Shell, die ist schon in der Android-Debug-Bit bei default drin, mit dieser App, die wir uns auf die System-Platte installieren. Dazu müssen wir die System-Partition ändern, das ist das Routing. Und dadurch bohren wir uns einen Loch für eine neue Kommand mit unserer SU-App. Wir haben also eine Super-User-App und wir haben eine binary auf der Platte. Die Super-User-App vermittelt uns den Zugriff auf das Framework, das Framework sagt, ja, die App darf das, weil ich habe diesen Zugriff auf meinem Hardware-Access-Layer und unser Super-User setzt unsere Shell-Command, unsere App ab. Somit könnten wir Netzwerkpakete abgreifen, indem wir unsere TCP-Dump-Binary auf ein Android-Linux-Curnal kompellieren, den auf unserer Platte installieren und mit Super-User per Shell starten, dann die Daten irgendwo auf eine PCRP-Pile speichern und diese auslesen. So machen das die meisten Capturing-Apps. Wir wollen das ohne Systemzugriff machen. Wir wollen das ohne ein gutes System machen, einfach dadurch, dass wir dann auf jeden beliebigen Android-System Pakete Capturen und auch Injecten können. Das kann man machen über die VPN-Service API, die das Android Framework bereitstellt. Es gibt bereits, ich habe zwei Apps gefunden, die das können, das ist SSL-Packet Capture und T-Packet Capture. Das Problem an den beiden ist, es ist closed doors. Das heißt, wir können nicht einfach das Capturing-System dieser App benutzen und unsere eigene schöne, unsere eigene schöne, netzwerkfähige App, die dann tolle Sachen macht mit Packet Capturing. Da lasse ich eure fantasiefreien Lauf, was man damit machen kann, machen. Okay, was ist also das Ziel? Das Ziel ist eine Open Source Implementierung dieses VPN Capture-Mechanismus als Capture, als Inject-Service, den wir an unsere App anmelden können, starten können und dann bekommen wir da einfach Netzwerk-Packete raus und können auch welche reinschreiben. Und das ganze Projekt wurde angeregt durch ein Artikel auf theGeekstuff.com ist auch schon ein bisschen älter, aber bisher gibt es leider immer noch keine Open Source Implementierung, deswegen habe ich einfach einmal angefangen. Okay, VPN auf Android. Wie ich schon erwähnt, ist es eine AP, die uns das Framework zur Verfügung stellt. Die VPN Service-AP, davon darf es genau eine aktive geben oder keine aktive, nicht mehrere. Das heißt, die Benutzung eines VPN-Services schließt einen anderen aus. Wir können also nicht gleichzeitig VPN Capture und gleichzeitig VPN benutzen. Und das normale, das Szenario sieht so aus, wir haben einen VPN Service, der hat Zugriff auf ein Tunnel-Interface namens TUN und an dieses Tunnel-Interface werden alle Ethernet-Packete geleitet, sorry, alle IP-Packete, alle Layer-3-Packete, werden an die Tunn-Schnittstelle geroutet an unserem Service, wo wir sie abgreifen können. In einem normalen VPN-Client-Szenario, wir schreiben uns eine App für Android, die uns VPN Zugang zur Verfügung stellt, sieht das dann so aus. Wir haben hier unseren Android-Framework, unseren TCP-IP-Stack und unsere Apps, die produzieren Netzwerk-Packete, Layer-3 auf IP-Ebene und geben sie an unser Tun-Interface. Das Tun-Interface können wir in unserem selbstprogrammierten Service abgreifen und zwar Output und Input. Wir haben zwei Input-Streams, wir haben File-Input-Stream und wir haben File-Output-Stream. Von dem lesen wir Daten, lesen wir Pakete, das sind Layer-3-Packete, IPv4, IPv6, da ist TCP oder UDP normalerweise drin und dann irgendein Payload. Auf der anderen Seite öffnen wir dann einen Socket-Channel zu einem Ziel-VPN-Server. Diesen Channel markieren wir als Protected, weil sonst würde der ja ja wieder irgendwie in unseren Netzwerksdeck geroutet werden und kommt hinten am Pune-Interface wieder aus. Also markieren wir den der darf raus. Das ist eine Funktion, die das VPN-Server AB unterstützt und dann bauen wir Verbindung zum VPN-Server auf und wir geben dem einfach die Layer-3-Packete. Wir schicken die Layer-3-Packete an unseren VPN-Servers, wie wir VPN-Server, wie wir diese Verbindung händeln, ist uns in unserer App vollkommen freigestellt. Und der VPN-Server macht irgendwas damit, vermittelt die Pakete dann weiter. Wir wollen keinen Server haben, weil dann bräuchten wir diese App ja nicht. Ja, das könnte man jetzt schon machen. Wir machen VPN-Server und auf dem VPN-Server oder beim Proxy, wie jetzt auch am letzten Beitrag schon gesagt, können wir die Pakete abgreifen. Wir wollen ja die Pakete direkt am Gerät abgreifen und dazu verändern wir den VPN-Server. Erstmal wir Capturen alles, was durch das Tun-Interface rein- und rausgeht, weil wir wollen ja Capturen. Oder injecten, je nachdem. Wir können Raw-Sockets generieren. Raw-Sockets können wir mal IP-Packete reinschicken, die protekten wir und dann schicken wir die enden Target Host. Wir schicken da die Netzwerk-Packete direkt an das Ziel ohne VPN-Server. Das ist so eine tolle Idee. Es ist ziemlich einfach, kann man schnell programmieren. Ja, nee. Können wir nicht. Raw-Sockets sind Sockets, die IP-Packete fressen. Das ist Kernel-Level. Kernel-Level dürfen wir nicht. Einzige Sachen, die wir dürfen, sind Application-Layer-Sockets. Das heißt, wir dürfen nur Application-Payload haben und den in einen Socket, entweder Socket-Channel für TCP oder Datacromps-Channel für UDP rein schicken, die wir zu einer spezifischen Adresse verbinden. Okay. Also, machen wir es halt. Wir lesen aus unserem Paket und aus unserem UDP-Packet. Beispiel, UDP ist einfacher, weil es dateless. Wir lesen die Ziel-IP und den Port aus. Wir eröffnen eine Datadatagramm-Channel zu unserem Ziel-Host und dann schicken wir den Payload, den wir aus unserem UDP-Packet entpacken, schicken wir in den Channel rein und das wird dann zum Ziel-Server generiert. Irgendwann kommt eine Antwort zurück und die Antwort, da packen wir wieder die Ziel-IP und den Ziel-Port außen rum, gehen wir generieren den Header. Den haben wir uns gemerkt, als wir den Channel geöffnet haben, haben sie an dem Channel hinterlegt und generieren das Paket. Checkstum berechnet können wir selber machen. Wir haben ja Computer. Das sieht ungefähr so aus. Wir haben jetzt wieder unser Tunnel-Interface. Davon lesen wir die einzelnen Pakete. Hier ist unser Layer 3-Paket. Beispiel mit IPv4. Wir lesen die IP-Version aus. Wir lesen die Source- and Destination-IPs aus. Adressen, wir geben den Timestamp zu, das wir wissen, in welche Reihenfolge. Wir dinge rein und raus gelesen haben und aus dem UDP-Packet lesen wir Ziel- und Quell-Port aus. Das Ganze nenne ich UDP-Flow. Hinterleg es an ein Datagramm-Channel. Den Datagramm-Channel öffne ich zu Target Host mit meiner Ziel-IP und mit meinem Source-Port. Also das Socket-Pair zum Target Host wird aufgemacht. Dort schiebe ich den Payload rein. Der Target Host antwortet mir, beispielsweise in den S-Request, wo ist ccc.de und er antwortet mir mal mit der IP von ccc.de. Ich lese also, was aus dem Datagramm-Channel rauskommt. Lese aus meinen Flow-Daten mit der IP und Port-Information aus. Generiere die Hater dafür und schiebe das an mein Interface zurück. Das wird von meinem Stack wieder ausgewertet. Von meinem Software-Stack ausgewertet. Der Payload wird an meine Application korrekt ausgesandt. Und es funktioniert. Und das ist da drin. Puh, ja, es ist gar nicht so einfach. Aber UDP geht. Ja, wir haben TCP, wir haben Handshakes und wir haben Handshakes zum Aufbauen und wir haben Handshakes zum Abbauen. Wir haben Sequenznummern, wir haben Agnummern, die wir korrekt befehligen müssen. Und wir haben natürlich checksum und die auch alle stimmen müssen. Und das ist nur ein Teil der ganzen Liste, die man dafür beachten muss. Aber davon lassen wir uns nicht entmutigen. Wir machen weiter. Wenn wir also ein TCP-Paket fälschen und ein paar Module in unserem Service drinnen, die uns Aufgaben abnehmen. Zum Beispiel haben wir hier einen Packet-Händler gebaut, der die Kontrollflex aus unserem TCP-Paket Synn zum Verbindungsaufbau und Reset zum Verbindungsabbau erkennt. Also nehmen wir mal den normalen Pfeil einer TCP-Verbindung zu der Homepage von ccc.de an. Wir bekommen also ein Synnflag in unserem Handshake Verbindungsaufbau. Wir erkennen, es ist ein Synnflag. Also schicken wir an unserem Paketgenerator die Anweisung Handshake. Wir verwenden uns einen Synn-Ack mit korrekter Acknowledgement-Nummern des ursprünglichen Pakets zurück. Unser Interface vermittelt das an unsere Applikation bzw. an unseren TCP-IP-Stack im Kernel, der akzeptiert dieses Paket idealerweise selbst haben. Und er gibt ein Akk zurück, das wir wiederum wegwerfen, weil wir sind ja unser eigener Stack jetzt. Also alles mit payload0 wird hier vom Packet-Händler aussortiert und die Flex ausgelesen gegebenenfalls für Verbindungsaufbau und Abbau bzw. für Paketduplicate etc. Kontrollen an den Paketgenerator geschickt. Gut, die Synn- und Akkflags unsere Sequenznummern, Acknowledgement-Nummern aus unserem TCP-State-Verkehr legen wir zusammen wie auch beim WDP-Szenario ab in unserem Flow-Element zusammen mit Quell und Ziel-IP und den Source-Ports. Und ebenfalls dazu öffnen wir einen Socket-Channel Socket-Channel für TCP-Bakete und dann schicken wir die payload auf den Socket-Channel raus. Der Socket-Channel verbindet sich zum Ziel-Server, macht selber einen Handshake übernimmt den Payload fragmentiert den Payload, schickt ihn irgendwie durch den Ether was auch immer, interessiert uns nicht. Leindet beim Ziel-Host der Ziel-Hoster idealerweise antwortet darauf was wir gesendet haben. CCC sendet die Dateien von ihrer Index-HTML und ihre schönen Bilder zurück. Diese lesen wir auf dem Socket-Channel herunter nehmen wieder die Daten aus dem TCP-Flip Flow-Element und generieren wieder ein Paket mit berechneten Acnolishment und Sequenznummern. Das ist übrigens falsch, da soll das SEQ sehen. Und generieren unsere Header und unsere Gefälschepakete schreiben wir zurück ans Tune-Interface. Puh! Es ist da schon ein bisschen mehr jetzt. Da wird noch mehr. Okay. Soweit so gut, das können wir gerade programmiert technisch noch bewältigen. Das kriegen wir hin in Java. Ja. Okay, also wir haben ja nicht nur eine Verbindung, wir haben mehrere simultane Verbindungen und da gibt es noch das Punkt der Paketfragmentierung. Bloß weil wir IP-Pakete bekommen, heißt es ja nicht, dass die nicht fragmentiert sein können. Maximale Maximum-Touch-Mission Unit bei TCP4 ist 65 Kilobyte, glaube ich. Also jede Datei, die größer als 65 Kilobyte ist, wird fragmentiert. Das müssen wir beachten. Das sind wir wohl auf dem Hinweg als auf dem Rückweg. Und wir haben natürlich multiple Verbindungen zu multiple hosts. Die multiple Verbindungen können wir mit einer netten Java Implementierung namens NIO Network Input Output Selektor lösen. Und zwar können wir mit dem Selektor einzelne Channel, also Datacamp Channel und Socket Channel an diesem Selektor registrieren und können aus einem Thread heraus multiple Channel verwalten. Also da nimmt uns die Implementierung die Java Implementierung das Problem ab. Wir können unseren eingebauten VPN-Server aus einem Thread betreiben, aus einem Service Thread betreiben. Und für die Paketfragmentierung also das Zeilen und Zusammensetzen der Pakete auf dem Hinweg und auf dem Rückweg, da müssen wir die Sequenz und Agnomen in entsprechenden Teilpakete neu berechnen und da hilft nur fieses Algorithmen Design. Das war interessanterweise der erste Punkt meiner Programmiererlaufbahn, an dem ich dann wirklich auf Pseudocode zurückgreifen musste, weil ich es nicht mehr geblickt habe. Whiteboard und Pseudocode weg vom PC. Einen Tag später hatte ich dann so was. Es ist jetzt ein Fragment aus dem Packet Generator der mir die Fragmentierung ankommt, der Pakete ankommt, der unser Socket Channel bringt mir meine Datei und ich muss sie wieder neu zerstückeln, bevor ich sie an mein Toon Interface gebe, damit mein Netzwerkstack, mein echter Netzwerkstack, die erneut wieder zusammensetzen kann, um meine Applikation zu geben. Also wenn meine Chunk Size größer ist, also meine Maximum to the Minute Mission Unit, dann fragmentiert er mir sie, setzt mir das Fragment Bit, damit mein Steak auch weiß, dass es fragmentiert ist und er ruft die Sub-Routine zum Acknowledgement-Nummern aufrufen. Ich habe eine Acknowledgement-Nummerköhe von Paketen, die ich noch aus diesem Flow Channel bestätigen muss, et cetera, et cetera, et cetera. Ja. Und das Ganze sieht dann so aus, wenn es zusammengebaut ist. Wir haben wieder unser Toon Interface, von dem wir bei Bites lesen. Die Bites lesen wir jetzt praktischerweise in unser Dekoder ein. Wir haben das Stream Framework entschieden. Das ist ein Packet Framework, das Stream basiert und Java basiert ist. Also ich muss keine Native Libraries einbinden in meiner Android-Applikation. Und ich kann mit Datastreams umgehen, was mir für diese Implementierung als Service sehr brauchbar ist. Alle Dekodierten Pakete kopiere ich weg auf mein Packetbuffer. Da können dann von meiner Applikation abgegriffen werden. Meine Pakete kommen in meinen Packethandler. Ich extrahiere die Header-Information. Ich baue einen Channel auf. Ich hinterlege das Flow Element zu diesem Channel, sei es TCP, sei es UDP und registriere den Channel am Selektor oder, wenn bereits geöffnet, hole mir den Channel vom Selektor. Und das bin payload, schicke ich raus. Auf der Rückseite hole ich mir check, lauf ich meine Channels durch, die registriert sind. Schau, ob an den Daten anliegen und lese die Daten. Nehmen wir das Flow Element heraus, baue mir meine Pakete wieder zusammen. Refragmentiere, also quasi Defragmentiere, meine Pakete. Update entsprechend das Flow Element mit Sequenz und Acknowledgement-Nummern. Nun generiere ich wieder die Header- und Kontrollpakete. Ich habe ein gültiges Pakete, wenn alles gut gelaufen ist. Und das schicke ich an's Tuning interface. Und that's it. So funktioniert Paket Capturing ohne Route auf enddeutend über die VPN- Schnittstelle in der Theorie. Aktueller Stand ist, ich möchte eine Open Source Implementierung für diesen Service bereitstellen. Für meine und für andere beliebige Security Apps Security Enforcing oder Security Apps, wie er auch möchte oder wer auch immer möchte. Ich habe eine Proof-of-Konzept-Implementierung durchgeführt. Es funktioniert tatsächlich. Es ist nicht nur eine Theorie, es funktioniert auch wirklich. Was noch getun werden muss, sind die Paketfragmentierungs- Algorithmen einpflegen. Ich kann bisher nur Dateien kleiner als 65k bedienen. Und aus dem Ganzen muss natürlich aus dem Test ein Release gemacht werden, dass man dann als Alpha in die Gegend streuen kann, womit dann alle netten Programmierer testen und jede Menge Bug Reports schreiben, im Idealfall. Und an dieser Stelle führt man immer eine Demo durch, habe ich gesehen, bei der DEVCON im Video. Und dann sagt man, may the Demo gods be with me. Da der Android-Immulator keine VPN-Schnittstelle unterstützt, mache ich das auf meinem Gerät und schaue mir die entsprechenden Log-Information ADB Log-Cad und dann starten wir den VPN ja und wir Browsen auf ccc.de Hier sieht man schon, jede Menge gedammte Nachrichten. Ich lasse das gerade mal kurz durchlaufen und dann können wir das ansehen. Das ist der Output aus dem Programm TLS-Metric. Die Schriftart ist natürlich jetzt super groß. Das stelle ich kurz ein. Die dammte Information eine Auswertung aus dem Framework Source-Port, Destination-Port, Acknowledgement-Nummer und Sequence-Nummer, Deflex und sehen immer, an welchem Interface was anlegt. Also Tunel-Interface ist das Tunel-Interface, an dem wir unsere Daten bekommen. Und wir suchen jetzt mal ein UDP-Packet, ein DNS-Request. Beziehungsweise bitte glaubt mir, es funktioniert. Da kommen Daten rein. Ich habe da mal den Stream ein wenig aufgehübscht dass die Demo nicht funktioniert. Wenn man den Log-Output ansieht, dann kann man so Beispiel solche Elemente sehen. Wir haben 52 bytes auf dem Tunel-Interface gelesen. Wir haben 52 bytes gedammt. Source 1021, das ist meine Internet-Schnittstelle meines Telefonanbieters meine Source-Port, wenn ich überhaupt meinen Telefonvertrag surfe und das ist meine Ziel-IP. Das ist mein DNS-Server, DNS-Standard-Cray-Re Ich eröffne eine Datacram-Channel mit der ID-Dissource-Ports zum Ziel und ich habe 24 von 24 Payload-Bytes des DNS-Requests gesendet. Wir warten kurze Zeit und irgendwann meldet der Channel-ID 5303 40 bytes konnten gelesen werden. Das dampfen wir und hier haben wir unsere DNS-Antwort. UDP von unserem DNS-Server waren uns 43 bytes. Dann generieren wir ein Header und den Header schicken wir weiter. Jetzt haben wir der IP. Das ist der Mitschnitt aus einem TCP-Request auf die CCC-Homepage. Hier sehen wir 60 bytes an Tunel-Interface angelegt. Wir dampfen dieses Paket. Das ist ein TCP-Paket. Die entsprechenden Dumping-Frame wir machen einen Soccer-Channel aufgemacht mit dem Port zur IP. Wir senden das Paket nicht, weil es keinen Payload besitzt. Das war ein Control-Flag. Synflags haben wir geteckt. Wir generieren ein Handshake. Den Handshake dampfen wir wieder und schicken das an unsere Tunel-Interface. Der Handshake wird akzeptiert. Wir bekommen ein Acknowledgement-Paket mit dem Source und dem Term-Ziel Port. Unser Channel ist noch nicht schreibbar, weil er noch aufgebaut wird. Das Paket wird nicht rausgeschickt. Wir haben 498 bytes von ccc.e an unserem TCP-Request. Den schicken wir raus an unseren Channel. Wir warten, bis unser Channel writable ist und schicken den raus. Dann kommt die Antwort von unserem Channel. Wir haben 3.807 bytes gelesen und aus den generieren wir ein IP-Paket. Das IP-Paket wird gedammt und wird auf unser Tunel-Interface geschrieben. Das ist der Lockoutput eines TCP-Verbindungsaufbaus zum ccc.e in der Testimplementierung. Ich hoffe, es funktioniert wirklich. Was gibt es noch zu tun? Die Entwicklung stagniert leider, weil ich Koden für Geld machen muss und nicht mehr Koden für Uni. Die Zeit, die ich am Computer an Quellcode verbringe, ist die Zeit, mit der ich mir meine Brötchen verdiene. Deswegen stagniert die Entwicklung leider kurz vor Ende, was sehr schade ist. Wenn hier kundige Android-Entwickler sind, die Lust haben sich um die Phasen des VPN-Captures zu beteiligen, bitte meldet euch. Ich bin Altschrepp, meine E-Mail. Mein Name at posteo.de Und an dieser Stelle möchte ich meinen Vortrag beenden und fragen von euch beantworten. Ja, bitte. Latence ist kein Problem. Die größte Last ist das Analyse-Framework, die den Output generiert auf der Diba-Konsole. Das ist tatsächlich das größte. Wenn ich den ausschalte, dann habe ich genug Kapazität, den Service betreiben zu können. Was aber ein Problem ist, das sind Racing-Conditions. Zum Beispiel, meine Applikation macht ein Resent von einem TCP-Anfrage auf meiner Homepage, bevor mein Socket-Channel geöffnet ist in dem Fall muss man vorab schon Pakete in meinem Service bestätigen mit gefälschen Acknowledgement-Paketen und diese Pakete muss ich puh von bis mein Channel bereit ist. Racing-Conditions ist ein Problem und Latence-Zeiten, Recent-Zeiten, beidseitige Verbindungsabbau mit Wartezeiten bis ich den Channel wieder schließe. Ich habe ja wirklich ein altes Smartphone, das ist ein altes Experial, das ist kein Problem. Ja, bitte. Dann wird der Channel, den ich geöffnet habe, nicht aufgemacht. Und ich habe eine Routine drin, die die auf Timeouts killt. Das heißt, wenn mein Zielserver nicht verfügbar ist, dann ist er einfach nicht verfügbar. Da ändert sich dann für meine App, die hinter dem Tunnelinterface steht, wenig, weil die irgendwann merken, es wird dreimal, das Paketen wird normal gesendet und dann terminiert der Client die Verbindung, also der Client, der Stack nach dreimal Recent, nach 2,8 Sekunden ist die Recent-Zeit killt die Verbindung von sich aus ab und versucht dann auf je nach Programmierung der Beabligation oder nach Usereingabe das nochmal erneut. Ich habe jetzt noch nichts mit zurückgemacht, aber was ist das? Ist das ein Sockel oder was kommt da an? Da kommt ein IP-Paket an. Also an diesem Interface bekomme ich ein File-Descriptor auf einfach ein Bytebuffer, dort kann ich paketweise die IP-Pakete von der Schnittstelle ablesen, habe die in meinem Puffer und kann die auf den operieren. Beantwortet das die Frage? Ja. Du klingst zögerlich. Darfst gerne nachfragen. Weitere Fragen. Okay. Ja, bitte. Wenn die Pakete reinkommen, kann man da nicht die einfach annehmen und einfach so weiterschicken, also eigentlich einen neuen Server aufmachen, so gewissermaßen eine neue Verbindung von diesem Zeug aufmachen und den Inhalt weiter schicken und später die Antwort wieder zurück? Ja, das passiert ja, auch. Wenn ich dich korrekt verstanden habe. Ja, ich mein, ohne den Heter nachzubauen und so, war es einfach eine neue Verbindung aufmachen und das Zeug selber verschicken. Nein, das funktioniert deswegen nicht, weil wir nicht die Verbindung auf RawSockets haben. RawSockets nehmen IP-Pakete an. Ach so. Und wir haben nur, in Android haben wir wegen der Berechtigung der jungen jungen jungen jungen Internet, haben wir nur Application-Layer-Sockets zur Verfügung. Sonst wäre es relativ einfach. Das ist richtig. Wir können einfach einen IP-Socket nehmen, einen Raw-Socket nehmen und dann können wir die Pakete einfach reinschieben. Layer 3 Pakete reinschieben, Layer 3 Pakete rausbekommen, die könnten wir etwas durchreichen. Das können wir wegen dem Berechtigungsmodell nicht ohne die Kistefolgeroute zu haben. Beziehungsweise wir können es auch mit der Kiste nicht. Okay. Genau. Dann möchte ich mich zur letzten Folie durchblicken. Für eure Aufmerksamkeit danken. Und wirklich, wäre echt toll, wenn da sich jemand meldet, das kurz vor Ende AP fertigzustellen mit mir, würde mich sehr freuen. Ansonsten bin ich noch verfügbar an der Bar für weitere Fragen oder Gespräche und danke, dass ich hier beim CCC sein durfte. Ciao.