Problème de fonctionnement d'un serveur sur le port 25

Hello !

J’ai un petit programme dont le code est ci-dessous et qui me pose quelques problèmes sur le port 25 (smtp).

[code]#include <stdio.h>
#include <stdlib.h>
#include <string.h>
#include <netdb.h>
#include <netinet/in.h>
#include <unistd.h>
#include <arpa/inet.h>

int main() {
struct sockaddr_in SockLocale;

int sock = socket(AF_INET, SOCK_STREAM, 0);
if(sock==-1) exit(-1);

memset(&SockLocale,0,sizeof(struct sockaddr_in));
SockLocale.sin_family = AF_INET;
SockLocale.sin_addr.s_addr = htonl(INADDR_ANY);
SockLocale.sin_port = htons(25);

if(bind(sock,(struct sockaddr*)&SockLocale,sizeof(struct sockaddr_in)) != -1) {
	if(listen(sock, 100)<0) {
		printf("Echec de Listen()\n");
		exit(-1);
	}
}
else {
	printf("echec de bind()\n");
	exit(-1);
}

while(1) {
	struct sockaddr_in SockDistant;
	char buffer[512];
	
	socklen_t TailleSock = sizeof(SockDistant);
	memset(&SockDistant,0,sizeof(struct sockaddr_in));
	int s_distant = accept(sock,(struct sockaddr*)&SockDistant,&TailleSock);
	if(s_distant!=-1) {
		printf("CONNEXION ETABLIE\r\n");
		strcpy(buffer,"Hello world !\r\n");
		write(s_distant,buffer,strlen(buffer));
		printf("Chaine \"Hello world !\" envoyée\r\n");
		close(s_distant);
	}
}

}
[/code]

Ce programme fait juste l’envoi de la chaine “Hello world !” et ferme la connexion aussitot. Il affiche en même temps “CONNEXION ETABLIE Chaine “Hello world” envoyée !” coté serveur.

Sur le port 2525 tout marche parfaitement :
Si je fais un telnet à partir de linux sur le port 25, j’obtiens le résultat suivant sur l’écran de la machine sur laquelle tourne le programme :

CONNEXION ETABLIE Chaine "Hello world" envoyée !

mais le problème survient sur le port 25 (le programme final devra tourner sur le port 25) : Si je fais un telnet depuis Windows, j’obtiens la chaine en double cette fois :

CONNEXION ETABLIE Chaine "Hello world" envoyée ! CONNEXION ETABLIE Chaine "Hello world" envoyée !

C’est à dire que windows fait systématiquement 2 connexions consécutives, la première semblant échouer.

Je ne sais pas si le problème vient du code (il ne me semble pas…) ou si ca vient de la configuration linux.

Avez-vous une idée ?

pourrais tu faire un test en mettant la valeur de s_distant dans le message (juste pour voir si c’est le même fd).
Sinon, as tu essayé sur deux machines differentes ?
et finalement, est ce que le doublage arrive systêmatiquement, ou est ce que chaque connection successive rajoute un msg ? Il n’y aurait pas une accumulation dans un buffer non flushé ?

Sais tu aussi que si ton dialogue client serveur est simple, tu peux simplifier ton codage C, en faisant dialoguer ton interface avec stdin/stdout au lieu d’un socket, puis en lançant un netcat ou socat pour piper les io du socket que tu veux (port 2525 ou 25 ou autre) vers les io de ton appli ?
Juste je ne sais pas si netcat/socat font du bidirectionnel, mais ça simplifierait le debuguage et la prog, non ?

Si je mets la valeur de s_distant dans le message, j’obtiens toujours la même valeur (4). Mais comme la socket est refermée à chaque fois, je pense que c’est normal non ?

Le problème arrive quelle que soit la machine : mon pc ou bien un serveur distant toujours sous débian.

Le doublage est systématique lorsque le client est sous windows. Si il est sous linux tout fonctionne. En tracant un client sous windows, j’ai remarqué qu’il y avait un seul appel de connect() qui effectue systématiquement 2 connections.

Ce n’est pas une histoire de buffer car il y a doublage dès le premier lancement et tout marche sur un autre port.

Le problème n’arrive que sur le port 25, et l’appli finale sera sur le port 25 (serveur smtp). Alors je me demande si c’est pas debian qui fait foirer la connexion sur ce port pour une raison que j’ignore. (il n’y a pourtant pas de serveur smtp qui tourne).

:laughing:
Debian n’est pas windows: pour quelquechose d’aussi specifique, ca serait documenté. Si il se passe quelquechose sur le port 25, c’est toi qui l’a mis en place.
Donc, je ne vois pas comment iptables pourrait provoquer ça, et j’imagine que tu n’as pas installé de snort ou de detection d’intrusion sur les machines ou tu as testé ?

Non, AMA, ca vient de ce put{|[ de telnet de windows qui est bugué à la moëlle.
Depuis windows, essayes avec l’hypertermial pour voir si tu répètes le prob.
Tu peux aussi essayer avec un autre telnet tournant sous windows, si tu en as un (un telnet linux tournant dans cygwin cygwin.com , par exemple).

Déja,
comme disait MattOTop, jette telnet , prend netcat et utilise l’option -v ou -vv (me rappele plus si on peut doubler). Socat c’est l’usine à gaz :slightly_smiling: et je sais pas si c’est dispo sous zin
Ensuite tu pourra comparer…

Ah, si je fais un netcat j’obtiens un “invalid connection” lorsque j’essaye de me connecter depuis n’importe quel client windows (telnet, putty, programme en c).

Je me demande si c’est pas winsock qui est buggé ?

tu n’as pas un vieux 98 qui traine, pour voir si c’est la pile NT qui se comporte bizarrement (ne commençons pas à dire du mal en appelant ça un bug, c’est peut être un “feature” microsoft :mrgreen: ) ?

Bon, sinon, peut être un suivi du traffic réseau avec ethereal ?
Ca permet de loguer les transactions de manière trés verbeuse, et on peut même sniffer ce qui se passe sur le client et sur le serveur dans le même log.
non ?

sinon, je pensais au netcat coté serveur:
tu délègues la gestion du socket à netcat, et tu fais un script qui lance le netcat avec ses io redirigées dans/depuis ton appli. Reste juste à tester les transactions que tu veux faire avec ton appli en la lançant en ligne de commande (sans l’accrocher au socket, juste en stdin/stdout).

Bon, mais rien ne dit que les clients vingt doses ne continueront pas le double connect, et que ça ne mettra pas quand même la zouille dans tes transactions.

AMA, il faut blinder: par exemple considèrer que tu peux avoir des clients “bugués” qui font un double connect, les identifier pour voir à chaque connect si le client ne dispose pas d’un canal qui fonctionne, et n’en garder qu’un des deux.

Ce qui ne dispense pas d’essayer de comprendre plus précisément les causes du double connect :wink:

Bien l’idée de ethereal :wink: mais je ne sais pas comment analyser les données. :blush:
Enfin, je vois qu’il y a bien 2 connexions, que “hello world” est envoyé 2 fois. Mais comment savoir pourquoi ?

[quote=“luckynut”]Ah, si je fais un netcat j’obtiens un “invalid connection” lorsque j’essaye de me connecter depuis n’importe quel client windows (telnet, putty, programme en c).
Je me demande si c’est pas winsock qui est buggé ?[/quote]
netcat -t ?
et sinon, que dit le client sur lequel se fait le double connect ? il reçoit et receptionne bien deux hello world ?

nc -l -p 25 -v localhost
:question:

Grace à ethereal, je vois que le réseau recoit 2 fois la chaine hello mais le client semble faire la chose suivante :

  1. Connexion
  2. Déconnexion
  3. Connexion
  4. réception et affichage d’hello world

Apparemment, le client coupe la connexion une première fois avant de lire les données.

MattOTop, merci pour ton aide ! :wink:
Mais je crois que ca ne sert à rien d’aller plus loin : lorsque je sniffe les connexions windows, je remarque que les connexions internet pop et smtp sont toutes doublées quel que soit le serveur !

Je ne sais pas d’ou vien le problème, certainement de windows (ou de ma version qui chie je ne sais pas pourquoi…)

Par contre si quelqu’un ici qui a ethereal peut vérifier si ca lui fait la même chose avec son windows, ca m’intéresse !

Merci

Pour ceux qui seraient curieux de connaitre l’explication finale : c’est mon antivirus BITDEFENDER 8 qui met la pagaille !!

:confused: :confused:

de toutes manières, j’imagine que le connect ne va pas suffire au final pour entamer la transaction que tu souhaites mettre en place, donc seule le deuxiême connect qui peut causer pourra entamer le protocole.

Non la pile winsock marche, j’ai fait pas mal de dev réseau windows/linux pas de probleme. C’est une pile BSD en fait…

BitDefender? Rolala je suis content de plus ^etre sous windows avec ces antivirus qui marchent à moitié…

Bon, j’ai mis l’antivirus à jour (version 9) et ca marche maintenant…

Coté client le problème était transparent puisque il n’y avait pas d’echec connection au niveau de l’appel connect qui se chargeait tout seul de rétablir la connexion en 2 fois.

Par contre coté serveur j’ai remarqué des fins de connexions prématurées systématiques pour des clients windows, et ca m’a fait tourner en bourique :open_mouth: :open_mouth:

Windoze n’est pas une science exacte :confused:

Pas de médisance: c’est bitdefender le problême.

D’ailleurs j’adooore les programmes qui se disent antivirus et qui en fait font aussi firewall.
Sous windows j’avais kerio 2.15 (eh oui pour emule) et pas d’antivirus.
Le plus important c’est l’interface chaise-clavier.
Bitdefender je sais pas si c’est SI au top que ca…

Bon je m’eloigne du sujet initial, j’arrete …

Non bitdefender c’est pas mal du tout ! C’est roumain !

Et puis sous linux on est pas à l’abris… L’autre jour j’ai recu le virus :

[quote]Vous venez d’être contaminé par un virus !!

Veuillez s’il vous plait envoyer cet email à toute votre liste de contact et effecer vos fichiers système ![/quote]

Et ben j’avais 150 emails dans la liste de contacts, ca m’a pris la journée !!
Au moins sous windows les virus sont automatisés :laughing:

Boris: AMA, bit defender ne fait pas firewall, mais il doit intercepter les communications pop/imap et smtp (d’ou le symptome n’arrivant que sur le port 25), pour filtrer les circulation de mail.
Ca ne me parait pas illogique pour un antivirus, même si ça necessite un peu de boulot de firewallage.

Tiens, d’ailleurs, ça merite d’etre verifié, mais si ça se trouve, le double connect doit se produire aussi sur les ports 110, 143, 993, et 995 .