Soweit ich weiß, passiert Folgendes, wenn ein Client eine Verbindungsanfrage stellt:
- Der Server wird an eine bestimmte Portnummer gebunden. Die Portnummer ist immer an einen Abhörvorgang gebunden. Da nur der Server auf eingehende Verbindungen wartet, müssen wir keine Bindung auf der Clientseite herstellen
- Der Server überwacht diese Portnummer weiterhin.
- Der Client sendet eine
connect()
Anfrage. - Der Server akzeptiert die Anfrage mit
accept()
. Sobald der Server die Client - Anforderung, das Kernel - allocates eine zufällige Portnummer für den Server zum weiteren akzeptiertsend()
undreceive()
, da die gleichen Portnummer auf dem Server für das Senden als auch Hören nicht verwendet werden kann, und der vorherigen Hafen ist immer noch neue Verbindungen suchen
Wie kann der Server angesichts all dessen herausfinden, auf welchem Port der Client empfängt? Ich weiß, dass der Client TCP-Segmente mit einem Quell- und einem Zielport sendet, sodass der Server den Quellport dieses Segments als Zielport verwendet. Welche Funktion ruft der Server jedoch auf, um diesen Port zu ermitteln? Ist es accept()
?
Antworten:
Es ist Teil des TCP-Headers (oder UDP-Headers usw.) im Paket. Der Server findet es heraus, weil der Client es ihm sagt. Dies ähnelt dem Ermitteln der IP-Adresse des Clients (die Teil des IP-Headers ist).
Beispielsweise enthält jedes TCP-Paket einen IP-Header (mindestens mit Quell-IP, Ziel-IP und Protokoll [TCP]). Dann gibt es einen TCP-Header (mit Quell- und Zielport und mehr).
Wenn der Kernel ein SYN-Paket (den Start einer TCP-Verbindung) mit einer Remote-IP von 10.11.12.13 (im IP-Header) und einem Remote-Port von 12345 (im TCP-Header) empfängt, kennt er die Remote-IP und den Remote-Port . Es sendet ein SYN | ACK zurück. Wenn es eine Bestätigung zurückerhält, gibt der
listen
Anruf einen neuen Socket zurück, der für diese Verbindung eingerichtet wurde.Ein TCP-Socket wird durch die vier Werte (Remote-IP, lokale IP, Remote-Port, lokaler Port) eindeutig identifiziert. Sie können mehrere Anschlüsse / Sockets haben, sofern sich mindestens einer davon unterscheidet.
In der Regel sind der lokale Port und die lokale IP für alle Verbindungen zu einem Serverprozess gleich (z. B. alle Verbindungen zu sshd erfolgen über die lokale IP: 22). Wenn ein Remote-Computer mehrere Verbindungen herstellt, verwendet jeder einen anderen Remote-Port. Alles außer dem Remote-Port ist also gleich, aber das ist in Ordnung - nur einer der vier muss sich unterscheiden.
Sie können z. B. wirehsark verwenden, um das Paket zu sehen, und es kennzeichnet alle Daten für Sie. Hier ist der Quellport hervorgehoben (beachten Sie, dass er im dekodierten Paket hervorgehoben ist, sowie der hexadezimale Speicherauszug unten):
quelle
write
(usw.) erhalten, an die richtige Stelle gelangen.Die "Verbindungsanforderung" (
connect()
normalerweise der Systemaufruf des Client-Programms ) bewirkt einen Drei-Wege-Handshake . Das erste Paket des Drei-Wege -Handshakes (vom Client zum Server) enthält das SYN-Flag und die TCP-Port-Nummer des Client-Programms Kernel weist es zu.Sie können dies in einem Artikel über Nmap vs Natural SYN-Pakete sehen . Die Nmap-SYN-Paketdecodierung hat den Ausdruck "source.60058> dest.22". Die Dekodierung des "legitimen SYN-Pakets" enthält den Ausdruck "source.35970> dest.80". Die beiden SYN-Pakete teilen dem Remote-Kernel mit, dass die Pakete vom TCP-Port 60058 bzw. vom Port 35970 stammen.
quelle
getpeername()
sollte dies an jedem offenen Socket ermöglichen. Deraccept()
Systemaufruf, den der Servercode verwenden muss, um einen Socket-Dateideskriptor für die Kommunikation mit dem Client zu erhalten, enthält einen Parameter ("sockaddr" in meinen Manpages), der die IP-Adresse und die TCP-Portnummer des potenziellen Clients enthält.TCP-Socket ist ein stream-orientierter Socket. Die beiden Socket-Deskriptoren (im Besitz von Ihnen und Ihrem Peer) sind zuverlässig verbunden. Sie müssen sich also keine Sorgen um den Port des Clients machen - schreiben Sie einfach Ihren Socket-Deskriptor!
Fühlen Sie sich auch frei, getsockname (2) zu verwenden, wenn Sie das wirklich wissen möchten (zum Protokollieren vielleicht).
quelle
Die Verbindung wird durch ein Tupel definiert (Quell-IP, Quell-Port, Ziel-IP, Ziel-Port). Die Antworten gehen in die umgekehrte Richtung.
quelle