2010-12-31 9 views
1

Ich schreibe ein C/C++ - Client-Server-Programm unter Linux. Angenommen, eine Nachricht m soll vom Client an den Server gesendet werden.Lesen der TCP-Sequenznummer vor dem Senden eines Pakets

Ist es möglich, dass der Client die TCP-Sequenznummer des Pakets liest, das m trägt, bevor m gesendet wird?

In der Tat, würde Ich mag an append diese Sequenznummer m, und das resultierende Paket senden. (Na ja, sind die Dinge komplizierter, aber wir halten es so einfach. In der Tat, ich möchte Authentifizierungs-Info dieser Sequenznummer beantragen, und es dann zu m anhängen.)

Außerdem

ist es für den Server möglich, die TCP-Sequenznummer des Pakets zu lesen, das m?

+1

Warum auf der Erde tun Sie dies tun wollen? – Omnifarious

+0

@Onmifarious: Ich benötigte "Sequenznummern" in einem Sicherheitsprotokoll. Da das Implementieren von ihnen erfordert, ein Fenster zu halten (wie in TCP), was wiederum viel Codierung erfordert, dachte ich, dass es leichter sein könnte, das Rad nicht neu zu erfinden und die zugrundeliegenden TCP-Sequenznummern zu verwenden. Aus den Antworten unten scheint die Idee unmöglich zu sein. Haben Sie eine Idee, die Implementierung von "Sequenznummern" zu erleichtern? –

+2

Ihr Sicherheitsprotokoll sollte nicht von der zugrunde liegenden Paketierung des TCP-Datenstroms abhängen. Die Art, wie TLS und andere strombasierte kryptografische Protokolle dies handhaben, besteht darin, die Daten zu chunken. Jedem Datenelement wird eine Länge vorangestellt und ein MAC als Suffix hinzugefügt. Sie stellen also eine Datensatzstruktur innerhalb des Streams bereit. – Omnifarious

Antwort

4

nein, kann man das nicht - zumindest nicht mit dem erwarteten Ergebnis

Dies liegt daran:

  • TCP-Stream basiert , nicht paketbasiert.
  • TCP Sequenznummer ist in Byte, nicht Paket.
  • Die zugrunde liegende TCP-Schicht führt die Segmentierung für Sie durch.
  • TCP-Fenstergröße/Paketgröße ist dynamisch

Dies bedeutet, dass Sie vielleicht ein „Paket“ mit der Sequenznummer am Ende des „Pakets“ senden. Es stellt sich heraus, dass die zugrunde liegende Magie dein Paket neu segmentiert.

Was Sie wollen:

1 2 3 4 
    +---+---+---+---+   
    | A | B | C |"1"| packet 1, seq=1, len=4 
    +---+---+---+---+   

    5 6 7 8 
    +---+---+---+---+   
    | A | B | C |"5"| packet 2, seq=5, len=4 
    +---+---+---+---+   

Was Sie vielleicht bekommen:

1 2 3 4   
    +---+---+---+---+ 
    | A | B | C |"1"| packet 1 (seq=1, len=4) 
    +---+---+---+---+ 

(packet 1 got lost) 

    1 2 3 4 5 6 
    +---+---+---+---+---+---+ 
    | A | B | C |"1"| A | B | packet 1, resent, seq=1, len=6 
    +---+---+---+---+---+---+ 

    7 8 
    +---+---+ 
    | C |"5"| packet 2, seq=7, len=2 
    +---+---+ 
+0

Auch TCP-Offload neigt dazu, es unmöglich zu machen, da selbst der Kernel keine Ahnung von Segmentierung hat. –

+0

Clevere ASCII Kunst FTW! :-) – Omnifarious

6

Sie können etwas sehr Ähnliches tun. Sie können alle von Ihnen gesendeten Bytes zählen und alle Bytes, die vor der Nachricht am Ende Ihrer Nachricht gesendet wurden, zählen.

Ich werde wirklich nervös, wenn jemand über 'Pakete' mit TCP spricht. Denn wenn Sie gleichzeitig über Pakete und TCP sprechen, mischen Sie Protokollebenen, die nicht gemischt werden sollten. Es gibt keine sinnvolle Entsprechung zwischen den Daten, die Sie in TCP senden, und den Paketen, die über IP gesendet werden.

Ja, es gibt Sequenznummern in IP-Paketen, die zum Senden von TCP-Informationen verwendet werden. Bei diesen Sequenznummern handelt es sich um die Anzahl der bisher gesendeten Bytes (aka Oktetts). Sie identifizieren, wo im Stream die Bytes in dem Paket gehören, aber sie sind ansonsten nicht mit dem Paket verbunden.

Wenn ein erneutes Senden stattfindet oder wenn Sie den Nagle-Algorithmus verwenden oder wenn sich der TCP-Stack an diesem Tag anfühlt, können zwei Sendevorgänge im selben Paket enden. Oder Sie enden mit der Hälfte einer Sendeoperation, die in einem Paket endet, und der Hälfte in einem anderen Paket. Und jedes dieser Pakete hat seine eigenen Sequenznummern.

Wie gesagt, es gibt absolut keine sinnvolle Beziehung zwischen Sendeoperationen, die Sie auf der Transportschicht durchführen, und den Paketen, die auf der Netzwerkschicht gesendet werden. Ich rede auch nicht theoretisch. Es sind nicht wirklich alle Pakete darunter und das Senden im Allgemeinen, abgesehen von einem seltsamen Zustand, setzt alle Bytes in ein einziges Paket. Nein, die oben skizzierten Szenarien, bei denen die Bytes einer einzelnen Sendeoperation auf mehrere Pakete verteilt werden, treten häufig und unter unvorhersehbaren Bedingungen auf.

Also, ich weiß nicht, warum Sie etwas über die Sequenznummern in Paketen wissen wollen. Aber wenn Sie die Sequenznummer als Proxy für die Anzahl der gesendeten Bytes verwenden, können Sie diese Zählung selbst behalten und sie einfach selbst in den Stream stopfen. Und vergiss nicht, auch diese Bytes zu zählen.

1

TCP/IP-Stack erledigt alle Dinge für Sie. Sie erhalten nur Payload. Stack entfernt alle Header und stellt Nutzdaten im Benutzerbereich bereit.

Wenn Sie wirklich auf Paketkopfebene hinzufügen oder ändern möchten, probieren Sie RAW sockets aus. RAW-Sockets empfangen/senden Pakete unabhängig von der Transportart (TCP oder UDP) direkt von der Netzwerkkarte. In diesem Fall müssen Sie alle Header (TCP/UDP Header, IP Header and Ethernet Header) mit Ihrer Payload entfernen/entfernen.

Kasse eine sehr gute Video-Tutorial auf RAW Sockets

Verwandte Themen