1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 76 77 78 79 80 81 82 83 84 85 86 87 88 89 90 91 92 93 94 95 96 97 98 99 100 101 102 103 104 105 106 107 108 109 110 111 112 113 114 115 116 117 118 119 120 121 122 123 124 125 126 127 128 129 130 131 132 133 134 135 136 137 138 139 140 141 142 143 144 145 146 147 148 149 150 151 152 153 154 155 156
|
#include <stdio.h>
#include <stdlib.h>
#include <unistd.h>
#include <sys/types.h>
#include <sys/socket.h>
#include <netinet/in.h>
#include <arpa/inet.h>
#include <netdb.h>
#include <string.h>
#include <pthread.h>
#include "socketFunction.h"
#define MAX_RECV_TIMEOUT 10000 //ms
void traitement_client(int);
int doProxy(int ,int,unsigned long ,int ,char * );
int main(int argc,char *argv[]){
int port;
unsigned int lenAccept;
int sckListen,sckAccept;
struct sockaddr_in adrAccept;
pthread_t th;
pthread_attr_t attr;
//Sélection du port
if(argc == 2){
port = atoi(argv[1]);
}else
port = 3125;
//sem_init()
//On détache le serveur de la console
#ifndef DEBUG
if(fork()!=0)
exit(1);
if(setsid()==-1)
exit(2);
#endif
//On créer la structure d'attribut qui créer un thread détaché automatiquement
pthread_attr_init(&attr);
pthread_attr_setdetachstate(&attr,PTHREAD_CREATE_DETACHED);
if((sckListen=createSocketListener(port))<0){
exit(3);
}
while(1){
//Réinitialisation de la longueur (sinon accept peut planter)
lenAccept = sizeof(adrAccept);
//sem_wait
//Et on attend les clients
if((sckAccept = accept(sckListen,(struct sockaddr*)&adrAccept,&lenAccept))==-1){
exit(4);
}
//On traite chaque client dans un thread séparé
if(pthread_create(&th,&attr,(void*)traitement_client,(void*)sckAccept)!=0){
exit(5);
}
}
}
void traitement_client(int sck){
char * header,*host;
int method,port;
unsigned long ip;
printf("DEBUT THREAD\n");
//Récupérer le header
if((header=recvHeader(sck))!=NULL){
//On récupére le champ host
if((host=getField(header,"Host"))!=NULL){
if(getIpPortFromHost(host,&ip,&port)>0){
setField(&header,"Connection","Close");
rmField(&header,"Proxy-Connection");
rmField(&header,"Keep-Alive");
setField(&header,"user-agent","super pingouin le gros sexuel");
//On récupére le type de requète
switch(method=getMethod(header)){
case GET :
case HEAD :
doProxy(sck,method,ip,port,header);
break;
default :
// methode inconnue ou non implemen
//send501();
break;
}
}
free(host);
}
free(header);
}
close(sck);
//sem_post()
printf("FIN THREAD\n");
}
int doProxy(int sck,int method,unsigned long ip,int port,char * header){
struct sockaddr_in server;
int sckServer,len;
char * headerServer;
char c;
// Connexion au serveur
if((sckServer = socket(AF_INET,SOCK_STREAM,0))==SOCKET_ERROR){
printf("SOCKET\n");
return -1;
}
server.sin_addr.s_addr = ip;
server.sin_family = AF_INET;
server.sin_port = htons(port);
len=sizeof(server);
//Remplacer par myconnect avec timeout
if(connect(sckServer,(struct sockaddr*)&server,len)==SOCKET_ERROR){
perror("CONNECT\n");
return -1;
}
//Envoie du header client au serveur
send(sckServer,header,strlen(header),0);
//POST [...]
//reception et envoie du header serveur au client
if((headerServer = recvHeader(sckServer))!=NULL){
if(send(sck,headerServer,strlen(headerServer),0) == strlen(headerServer)){
while((len=myrecv(sckServer,&c,1,0,TIMEOUT))>0) {
printf("RECV %c\n",c);
if((len=send(sck,&c,1,0))<=0)
printf("! SEND\n");//Quitte la boucle
printf("SEND %d\n",len);
}
}
free(headerServer);
}
close(sckServer);
return 1;
} |
Partager