Time sur socket en C

yohan49 Messages postés 380 Date d'inscription samedi 22 janvier 2005 Statut Membre Dernière intervention 13 août 2011 - 2 mai 2007 à 13:09
emmatopiak Messages postés 149 Date d'inscription mercredi 28 mars 2007 Statut Membre Dernière intervention 17 mai 2007 - 3 mai 2007 à 23:11
Salut les gars , je suis entrain de faire une scanner de proxy pour irc, donc j'utilise des socket lol

je cherche a savoir comment mettre un timeout sur la fonction connect du socket en C , car 3 minutes de timeout sur cahque ports scanné , en cas d'attaque , 7 ports * 3 minutes !! lol

une demi heure de scan !!

donc si quelqu'un sait comment faire !!

merci d'avance

11 réponses

rudybaka Messages postés 8 Date d'inscription vendredi 10 février 2006 Statut Membre Dernière intervention 24 mai 2007
2 mai 2007 à 16:41
Essaye d'envoyer un signal préalablement rédirigé juste avant ta fonction

signal(SIGALRM, sigalarm); // sigalarm est une fonction que tu defini toi meme
alarm(10); // en secondes
connect() ...

je pense que sa fonctionne mais je ne suis pas sur a 100% désolé
En esperant t'aider un peu
0
yohan49 Messages postés 380 Date d'inscription samedi 22 janvier 2005 Statut Membre Dernière intervention 13 août 2011 7
2 mai 2007 à 18:14
y'a pas a dire c vraiment chiant c trois minutes

la fonction alarm dans un thread , ou je dois tester plusieur ports , quand l'alarm se produit , j'ai l'impression que mon thread se termine

grrrr
0
rudybaka Messages postés 8 Date d'inscription vendredi 10 février 2006 Statut Membre Dernière intervention 24 mai 2007
2 mai 2007 à 18:34
La fonction sigalarm n'est pas très importante, elle peut etre vide ou afficher un message d'erreur, c'est comme tu veux. elle sert juste a être appelé a la fin du timeout et ansi debloqué la fonction connect()
0
emmatopiak Messages postés 149 Date d'inscription mercredi 28 mars 2007 Statut Membre Dernière intervention 17 mai 2007 2
2 mai 2007 à 23:12
Salut,

Y'a setsockopt avec parametre SO_RCVTIMEO ou SO_SNDTIMEO,  mais suis pas sur :p

Donc essaye de voir si tu peux pas utiliser setsockopt, et notamment les parametres SO_RCVTIMEO et SO_SNDTIMEO, ou bien rendre ta socket non bloquante, sinon.

Ensuite.

la methode que te conseillait rudybaka c'etait de lancer ton connect dans un autre processus et quand tu recois l'alarme, tu killes ce processus.

@++
0

Vous n’avez pas trouvé la réponse que vous recherchez ?

Posez votre question
yohan49 Messages postés 380 Date d'inscription samedi 22 janvier 2005 Statut Membre Dernière intervention 13 août 2011 7
2 mai 2007 à 23:20
jmp_buf timeout_jump ;

void timeout(int sig)
{
    printf("timeou\n");
    longjmp( timeout_jump, 1 ) ;
}

int check_connect(char *iphost,int port)
{
    struct hostent *serverHostEnt;
    struct sockaddr_in serverSockAddr;
    long hostAddr;
    int s = -1;
    int ret = 0;
    if ((s socket(PF_INET, SOCK_STREAM, 0)) SOCKET_ERROR)
        return 0;

    memset(&serverSockAddr, 0, sizeof(struct sockaddr_in));

    memset(&serverSockAddr, 0, sizeof(serverSockAddr));
    hostAddr = inet_addr(iphost);
    if ( (long)hostAddr != (long)-1)
        memcpy(&serverSockAddr.sin_addr, &hostAddr, sizeof(hostAddr));
    else
    {
        serverHostEnt = gethostbyname(iphost);
        if(!serverHostEnt)
            return 0;

        memcpy(&serverSockAddr.sin_addr, serverHostEnt->h_addr, serverHostEnt->h_length);
    }

    setsockopt(s, SOL_SOCKET, SO_LINGER, 0, 0);
    setsockopt(s, SOL_SOCKET, SO_REUSEADDR, 0, 0);
    setsockopt(s, SOL_SOCKET, SO_KEEPALIVE, 0, 0);

    serverSockAddr.sin_family = AF_INET;
    serverSockAddr.sin_port = htons(port);

    // on arme le timeout
    signal( SIGALRM, timeout ) ;
    alarm( 1 ) ;
    if ( setjmp( timeout_jump ) == 1 ) // c'est un timeout
    {
        printf( "C'est un timeout : %s sur port %d\n",iphost,port ) ;
        close(s);
        return 0;
    }
    else
    {
        ret = connect(s,(struct sockaddr *)&serverSockAddr,sizeof(struct sockaddr_in)) ;
        if ( ret == -1 )
        {
            perror( "connect()" );
            alarm(0);
            close(s);
            return 0;
        }
    }

    alarm(0) ;
    printf( "Connect reussi : %s sur port %d\n",iphost,port ) ;
    return s ;
}

int scan_proxy_http(char *ip)
{
    int i = 0;
    char *port[] = { "80" , "8080" , "3128" , "8001" , "8002" , NULL};

    /* Scan for HTTP proxy */
    while(port[i])
    {
        printf("tentative sur %s %s\n",ip,port[i]);
        int s = check_connect(ip,atoi(port[i++]));
        if(s > 0)
                printf("connecté\n");
    }
}

le timeout fonctionne sur le ports 80 ,  ne fonctionne pas sur le 8080 , et fonctionne sur les trois suivant

y'a rien a comprendre
lol
0
emmatopiak Messages postés 149 Date d'inscription mercredi 28 mars 2007 Statut Membre Dernière intervention 17 mai 2007 2
3 mai 2007 à 12:29
Salut, 

 Deja ton code est tres bien fait c'est tres agreable a lire, maintenant pour ton probleme je ne sais pas pour le moment.
 -Peux-tu me dire :
1) l'etat de tous les ports que tu testes
2) ce que renvoie connect quand il marche
3) ce que tu entends par 'le timeout ne marche pas' => est-ce que tu veux dire que tu dois attendre les trois minutes ?

@++
0
yohan49 Messages postés 380 Date d'inscription samedi 22 janvier 2005 Statut Membre Dernière intervention 13 août 2011 7
3 mai 2007 à 14:18
je vais te pondre un petit prog separe pour tester tout cela et afficher les duree avant timeout

je vous l'afficherais apres

a dans une heure
0
yohan49 Messages postés 380 Date d'inscription samedi 22 janvier 2005 Statut Membre Dernière intervention 13 août 2011 7
3 mai 2007 à 16:08
#include <sys/types.h>
#include <sys/socket.h>
#include <sys/select.h>
#include <sys/time.h>
#include <netinet/in.h>
#include <netdb.h>
#include <stdio.h>
#include <string.h>
#include
#include <stdlib.h>
#include <fcntl.h>
#include
#include <signal.h>
#include <errno.h>
#include <setjmp.h>
#include <time.h>

/* ip a tester */
char *ip_test = "86.204.130.181";

/* variable d'enregistrement de l'environnement pour restauration de l'environnement apres un timeout **/
jmp_buf timeout_jump ;

/* fonction a traiter sur SIGALRM */
void timeout(int sig)
{
    printf("dans la fonction timeout , restauration de l'environnement\n");
    longjmp( timeout_jump, 1 ) ;
    return;
}

/* return 0 si erreur ou superrieur a 0 si reussi **/
int creat_socket()
{
    int s = -1;
    if ((s socket(PF_INET, SOCK_STREAM, 0)) -1)
        return 0;

    setsockopt(s, SOL_SOCKET, SO_LINGER, 0, 0);
    setsockopt(s, SOL_SOCKET, SO_REUSEADDR, 0, 0);
    setsockopt(s, SOL_SOCKET, SO_KEEPALIVE, 0, 0);

    return s ;
}

/* fonction de test de connection iphost / port */
int is_con_possible(int s,char *iphost,int port)
{
    struct hostent *serverHostEnt;
    struct sockaddr_in serverSockAddr;
    long hostAddr;
    int ret = 0;

    memset(&serverSockAddr, 0, sizeof(struct sockaddr_in));

    memset(&serverSockAddr, 0, sizeof(serverSockAddr));
    hostAddr = inet_addr(iphost);
    if ( (long)hostAddr != (long)-1)
        memcpy(&serverSockAddr.sin_addr, &hostAddr, sizeof(hostAddr));
    else
    {
        serverHostEnt = gethostbyname(iphost);
        if(!serverHostEnt)
        return 0;

        memcpy(&serverSockAddr.sin_addr, serverHostEnt->h_addr, serverHostEnt->h_length);
    }
    serverSockAddr.sin_family = AF_INET;
    serverSockAddr.sin_port = htons(port);

    // on arme le timeout
    signal( SIGALRM, timeout ) ;
    alarm( 5 ) ;

    if ( setjmp( timeout_jump ) == 1 )
    {
        printf( "C'est un timeout\n") ;
        close(s);
        alarm(0);
        return 0;
    }
    else
    {
        ret = connect(s,(struct sockaddr *)&serverSockAddr,sizeof(struct sockaddr_in)) ;
        if ( ret == -1 )
        {
            perror( "connect()" );
            alarm(0);
            close(s);
            return 0;
        }
    }
    alarm(0) ;
    printf( "Connect reussi\n") ;
    return 1;
}

int scan_proxy_http(char *ip)
{
    int i = 0;
    char *port[] = { "8080" , "80" , "3128" , "8001" , "8002" , NULL};

    time_t d,f;

    /* Scan for HTTP proxy */
    while(port[i])
    {
        
        time(&d);

        printf("\n\ntentative sur %s %s\n",ip,port[i]);

        /* creation de la socket */
        int s = creat_socket();
        if(s > 0)
        {
            printf("socket cree\n");

            // on arme le timeout
            if(is_con_possible(s,ip,atoi(port[i++])))
            {
                printf("la connection a reussi\n");

                /* fermeture du socket */
                close(s);
            }
        }

        time(&f);
        printf("temps ecoule %ld seconde(s)\n",f-d);
    }
    return 0;
}

int main(void)
{
    printf("Lancement du test sur l'ip : %s!\n",ip_test);
    scan_proxy_http(ip_test);
    return 0;
}

ET LE RESULTAT :

Lancement du test sur l'ip : 86.204.130.181!

tentative sur 86.204.130.181 8080
socket cree
dans la fonction timeout , restauration de l'environnement
C'est un timeout
temps ecoule 5 seconde(s)

tentative sur 86.204.130.181 80
socket cree
connect(): Connection timed out
temps ecoule 189 seconde(s)

tentative sur 86.204.130.181 3128
socket cree
connect(): Connection refused
temps ecoule 1 seconde(s)

tentative sur 86.204.130.181 8001
socket cree
connect(): Connection timed out
temps ecoule 189 seconde(s)

tentative sur 86.204.130.181 8002
socket cree
connect(): Connection timed out
temps ecoule 189 seconde(s)

Mon time out ne fonctionne qu'une seul fois :///

bien bizard ca quand meme

je pense que je vais devoir passer en non-bloquant , les stocker dans une liste chainée , puis creer une liste de timer qui ira toute les secondes voir si un socket est dispo en lecture
0
yohan49 Messages postés 380 Date d'inscription samedi 22 janvier 2005 Statut Membre Dernière intervention 13 août 2011 7
3 mai 2007 à 18:00
voici maintenant en socket non bloquand ! fonctionne bien mieu

#include <sys/types.h>
#include <sys/socket.h>
#include <sys/select.h>
#include <sys/time.h>
#include <netinet/in.h>
#include <netdb.h>
#include <stdio.h>
#include <string.h>
#include
#include <stdlib.h>
#include <fcntl.h>
#include
#include <signal.h>
#include <errno.h>
#include <time.h>

/* ip a tester */
char *ip_test = "86.204.130.181";

int Sock_SetBlockMode (int sock, int blocking)
{
    int flags;
    int r;
   
    flags = fcntl (sock, F_GETFL);
   
    if (blocking == 1)
        r = fcntl (sock, F_SETFL, flags & ~O_NONBLOCK);   
    else
        r = fcntl (sock, F_SETFL, flags | O_NONBLOCK);   
    return r;
}

/* return 0 si erreur ou superrieur a 0 si reussi **/
int creat_socket()
{
    int s = -1;
    if ((s socket(PF_INET, SOCK_STREAM, 0)) -1)
        return 0;

    setsockopt(s, SOL_SOCKET, SO_LINGER, 0, 0);
    setsockopt(s, SOL_SOCKET, SO_REUSEADDR, 0, 0);
    setsockopt(s, SOL_SOCKET, SO_KEEPALIVE, 0, 0);

    return s ;
}

/* fonction de connection iphost / port */
int connection(int s,char *iphost,int port)
{
    struct hostent *serverHostEnt;
    struct sockaddr_in serverSockAddr;
    long hostAddr;

    memset(&serverSockAddr, 0, sizeof(struct sockaddr_in));

    memset(&serverSockAddr, 0, sizeof(serverSockAddr));
    hostAddr = inet_addr(iphost);
    if ( (long)hostAddr != (long)-1)
        memcpy(&serverSockAddr.sin_addr, &hostAddr, sizeof(hostAddr));
    else
    {
        serverHostEnt = gethostbyname(iphost);
        if(!serverHostEnt)
        return 0;

        memcpy(&serverSockAddr.sin_addr, serverHostEnt->h_addr, serverHostEnt->h_length);
    }
    serverSockAddr.sin_family = AF_INET;
    serverSockAddr.sin_port = htons(port);

    Sock_SetBlockMode(s,0);

    connect(s,(struct sockaddr *)&serverSockAddr,sizeof(struct sockaddr_in)) ;

    return s;
}

/* test si le socket est pret en lecture */
int proxy_test(int s)
{
    fd_set fds;
    struct timeval tv;

    FD_ZERO(&fds);
    FD_SET(s, &fds);

    tv.tv_sec = 5;
    tv.tv_usec = 0;

    if(select(s+1, &fds, NULL, NULL, &tv) > 0)
        return s;
   
        return -1;
}

/* reception des donnees */
int proxy_read(int s, char *buf, size_t buflen)
{
    fd_set fds;
    struct timeval tv;

    FD_ZERO(&fds);
    FD_SET(s, &fds);

    tv.tv_sec = 5;
    tv.tv_usec = 0;

    if(select(s+1, &fds, NULL, NULL, &tv) > 0)
        return recv(s, buf, buflen, 0);
   
        return -1;
}

int scan_proxy_http(char *ip)
{
    int i = 0;
    char *port[] = { "8080" , "80" , "3128" , "8001" , "8002" , NULL};

    time_t d,f;

    /* Scan for HTTP proxy */
    while(port[i])
    {
       
        time(&d);

        printf("\n\ntentative sur %s %s\n",ip,port[i]);

        /* creation de la socket */
        int s = creat_socket();
        if(s > 0)
        {
            connection(s,ip,atoi(port[i++]));
           
            /** test si le socket est pret **/
            if(proxy_test(s) != -1)
            {
                char buf[256];

                printf("la connection a reussi\n");
                proxy_read(s, buf, 256);

                printf("recus :%s\n",buf);
            }
            else
            {
                printf("la connection a echoue\n");
            }
            /* fermeture du socket */
            close(s);
        }

        time(&f);
        printf("temps ecoule %ld seconde(s)\n",f-d);
    }
    return 0;
}

int main(void)
{
    printf("Lancement du test sur l'ip : %s!\n",ip_test);
    scan_proxy_http(ip_test);
    return 0;
}

ET LE RESULTAT :

Lancement du test sur l'ip : 86.204.130.181!

tentative sur 86.204.130.181 8080
la connection a echoue
temps ecoule 5 seconde(s)

tentative sur 86.204.130.181 80
la connection a echoue
temps ecoule 5 seconde(s)

tentative sur 86.204.130.181 3128
la connection a reussi
recus :
temps ecoule 0 seconde(s)

tentative sur 86.204.130.181 8001
la connection a echoue
temps ecoule 5 seconde(s)

tentative sur 86.204.130.181 8002
la connection a echoue
temps ecoule 5 seconde(s)
0
emmatopiak Messages postés 149 Date d'inscription mercredi 28 mars 2007 Statut Membre Dernière intervention 17 mai 2007 2
3 mai 2007 à 23:10
ok:p
0
emmatopiak Messages postés 149 Date d'inscription mercredi 28 mars 2007 Statut Membre Dernière intervention 17 mai 2007 2
3 mai 2007 à 23:11
Salut,

En fait, j'essaierais de me souvenir qu'avec un select ca a l'air de passer..
Et tu utilises longjmp.

C'est à noter.
@++
0
Rejoignez-nous