Est-ce que bind () socket à l’adresse distante?

Avec l’instantané suivant du code C, je comprends que l’adresse à laquelle l’appel bind() se lie à listfd est l’adresse logique de la machine locale sur laquelle ce programme serveur est exécuté. Par la suite, le serveur écoute sur le socket listfd de la même machine.

 struct sockaddr_in serv_addr; listfd = socket(AF_INET, SOCK_STREAM, 0); bzero(&serv_addr, sizeof(serv_addr)); serv_addr.sin_family = AF_INET; serv_addr.sin_addr.s_addr = htonl(INADDR_ANY); serv_addr.sin_port = htons(8000); retval = bind(listfd, (struct sockaddr*)&serv_addr, sizeof(serv_addr)); listen(listfd) 

J’ai appris à coursera — que, l’appel bind() vous permet également de lier socket à une adresse distante et à un port.

entrez la description de l'image ici Je voudrais comprendre ce point.

Je veux dire, listfd = socket(AF_INET, SOCK_STREAM, 0); fournit un descripteur de fichier à partir du processus de programme où ce programme est exécuté (ordinateur local).

Ma question:

Si l’appel bind () lie ce socket local listfd à une adresse distante au lieu de INADDR_ANY , quelle machine écoute réellement? Parce que listfd est une entrée de la table de descripteur de fichier de processus local de la machine locale sur laquelle ce programme est exécuté et que ce socket listfd est listfd à l’adresse IP de la machine distante? Comment puis-je interpréter cela? Comment ça marche sous le capot?

Vous ne pouvez pas bind() à une adresse distante, du moins pas dans la famille AF_INET . Selon la page de manuel de bind , vous obtiendrez une erreur EADDRNOTAVAIL , indiquant que l’adresse à laquelle vous souhaitez vous EADDRNOTAVAIL n’est pas locale.

Edit: bind() peut fonctionner pour les adresses distantes, mais pas dans la famille AF_INET . S’il vous plaît noter qu’il y a plus que cela. Certaines familles prennent en charge la liaison à des adresses distantes, probablement des protocoles de clustering. Même s’il n’y en a pas, bind() peut fonctionner théoriquement sur ceux-ci au cas où certains protocoles émergeraient là où cela aurait du sens.

Edit2: Comme l’ a souligné Thuovila , il existe en réalité un cas où la liaison sur des adresses distantes dans AF_INET fonctionne. C’est-à-dire que vous définissez l’option de socket IP_TRANSPARENT avant la liaison. La page de manuel de ip (7) nous dit:

  IP_TRANSPARENT (since Linux 2.6.24) Setting this boolean option enables transparent proxying on this socket. This socket option allows the calling application to bind to a nonlocal IP address and operate both as a client and a server with the foreign address as the local endpoint. NOTE: this requires that routing be set up in a way that packets going to the foreign address are routed through the TProxy box (ie, the system hosting the application that employs the IP_TRANSPARENT socket option). Enabling this socket option requires superuser privileges (the CAP_NET_ADMIN capability). TProxy redirection with the iptables TPROXY target also requires that this option be set on the redirected socket. 

Donc, avec beaucoup de travail supplémentaire, vous pouvez créer un proxy transparent en liant un socket local et un socket distant avec ce jeu d’options de socket (si je comprends bien).

Je conviens que le matériel de Coursera est probablement faux ou au moins trompeur pour un apprentissage de base de la programmation réseau.

Cependant, je ne peux pas supprimer un commentaire pédant. Il est possible (sous Linux) de se lier à une adresse IP non locale. Veuillez consulter l’option IP_TRANSPARENT à l’ adresse http://man7.org/linux/man-pages/man7/ip.7.html . Cela a probablement très peu à voir avec le problème en question, cependant. Aussi j’apprécie la question est étiquetée bsd.

Plus sur le sujet, bind() n’a rien à voir avec l’écoute. Il associe simplement le fd à une adresse. C’est l’appel à listen() qui permet “l’écoute”. Il est possible de bind() un socket utilisé pour les connexions sortantes.