Ist es möglich, eine Verbindung zu TCP-Port 0 herzustellen?

59

Beim Abhören von TCP-Port 0 wird mir eine freie Portnummer auf dem System zugewiesen.

Aber was passiert, wenn ich versuche, eine Verbindung zu TCP-Port 0 herzustellen? Die offensichtliche Antwort lautet: "Es funktioniert nicht":

$ nc localhost 0                 
nc: port number too small: 0

Wo im System wird das gehandhabt? Im TCP-Stack des Betriebssystemkerns? Gibt es Unixe, bei denen die Verbindung zu TCP-Port 0 funktionieren würde?

nh2
quelle
2
Theoretisch könnten Sie einen benutzerdefinierten TCP-Stack erstellen, in dem das Abhören oder Verbinden von Port 0 funktioniert.
Joshua,

Antworten:

60

Nur um sicherzustellen, dass wir uns auf derselben Seite befinden (Ihre Frage ist auf diese Weise nicht eindeutig), weist die Aufforderung, TCP an Port 0 zu binden, auf die Anforderung hin, dynamisch eine nicht verwendete Portnummer zu generieren. Mit anderen Worten, die Portnummer, die Sie nach dieser Anforderung tatsächlich abhören, ist nicht Null. Es gibt einen Kommentar zu diesem in [linux kernel source]/net/ipv4/inet_connection_sock.can inet_csk_get_port():

/* Obtain a reference to a local port for the given sock,
 * if snum is zero it means select any available local port.
 */

Welches ist eine Standard-Unix-Konvention. Es könnte Systeme geben, die tatsächlich die Verwendung von Port 0 zulassen, dies wird jedoch als schlechte Praxis angesehen. Dieses Verhalten wird jedoch nicht offiziell von POSIX, IANA oder dem TCP-Protokoll angegeben. 1 Das könnte Sie interessieren .

Aus diesem Grund können Sie keine sinnvolle TCP-Verbindung zu Port Null herstellen. Vermutlich ncist sich dessen bewusst und informiert Sie, dass Sie eine unsinnige Anfrage stellen. Wenn Sie dies im nativen Code versuchen:

int fd = socket(AF_INET, SOCK_STREAM, 0);
struct sockaddr_in addr;
addr.sin_family = AF_INET;
addr.sin_port = 0;
inet_aton("127.0.0.1", &addr.sin_addr);
if (connect(fd, (const struct sockaddr*)&addr, sizeof(addr)) == -1) {
    fprintf(stderr,"%s", strerror(errno));
}    

Sie erhalten den gleichen Fehler, den Sie beim Versuch, eine Verbindung zu einem anderen nicht verfügbaren Port herzustellen, erhalten: ECONNREFUSED"Verbindung abgelehnt". Also als Antwort auf:

Wo im System wird das gehandhabt? Im TCP-Stack des Betriebssystemkerns?

Wahrscheinlich nicht; es bedarf keiner besonderen Behandlung. Dh, wenn Sie ein System finden, das das Binden und Abhören von Port 0 ermöglicht, könnten Sie vermutlich eine Verbindung dazu herstellen.


1. IANA spricht jedoch von "Reserved" ( siehe hier ). Dies bedeutet, dass dieser Port nicht online verwendet werden sollte. Das macht es in Bezug auf die dynamische Zuweisungskonvention in Ordnung (da es eigentlich nicht verwendet wird). Es würde wahrscheinlich den Rahmen der IANA sprengen, dies ausdrücklich als Zweck festzulegen. Im Grunde genommen können Betriebssysteme damit tun, was sie wollen, auch nichts.

Goldlöckchen
quelle
Es sieht aus wie die gleiche Idee wie die Adresse 0.0.0.0 in ipv4. Ein reservierter Wert, der vom Betriebssystem und von den Programmen für einen bestimmten Zweck verwendet wird. Analog dazu gibt es im Radio reservierte Frequenzen, die niemand für Übertragungen verwendet, sondern die intern in Geräten verwendet werden.
ctrl-alt-delor
1
@richard nein, 0.0.0.0 hat eine andere Bedeutung;) es wird verwendet, um ein ungültiges, unbekanntes oder nicht zutreffendes Ziel zu
kennzeichnen
2
@AndreaCi wurde nicht gesendet 255.255.255.255?
Ratschenfreak
4
@ratchetfreak 255.255.255.255 wird gesendet. 0.0.0.0 hat je nach Kontext zwei Bedeutungen. Bei der Programmierung ist es auch w / INADDR_ANY, worauf sich Richard bezieht (das System ersetzt es durch eine Standardeinstellung). Aber tatsächlich in einem Netzwerk unter Verwendung der Adresse scheint die Auswirkungen haben Andrea erwähnt ( mit Ausnahme nicht so klar , dass es gilt als „broadcast“): en.wikipedia.org/wiki/0.0.0.0
Goldilocks
5

Die Verwendung von Port 0 veranlasst das Betriebssystem, nach dem nächsten verfügbaren Port zu suchen und diesen zuzuweisen. Dies vermeidet, dass Sie einen bestimmten Port fest codieren oder nach einem verfügbaren Port suchen müssen. Mein Mint Linux-System kehrt zurück

nc: port range not valid

zu

nc localhost 0 
MichaelJohn
quelle
2

nc -l 0wird das Betriebssystem auffordern, Port 0 abzuhören. Wie oben erwähnt, werden die meisten Betriebssysteme jedoch die 0 sehen und ihre speziellen Gepflogenheiten aufrufen, um einen positiv nummerierten Port für Ihre Anwendung zu wählen, sodass ncsie einen Port wie 56514 abhören.

MC17
quelle
Die meisten Betriebssysteme funktionieren, ok, welche nicht?
Barlop