Título: Servidor SSL con Pthreads Publicado por: alcatraz en 11 Junio 2010, 15:35 pm Hola, estaba haciendo un pequeño servidor SSL que pudiese atender a multiples clientes a la vez. Cogí un ejemplo que encontre por internet y trabaje sobre el:
Código: #define NUM_THREADS 5 //−−− S e r v i d o r −−−−−−−−−− −−−−−−−−−−−−−−−−−−−−−−−−−− // R e a l i z a r e l p r o c e d i m i e n t o s e r v i c i o −−−−−−−−−−−−−−− void *Servidor(void *threadarg){ char buf[1024]; char reply[1024]; int sd, bytes; const char* HTMLecho="Esto solo es el mensaje de mi servidor SSL multihilo"; // Estructura donde se guardan los parametros de los threads struct thread_data *my_data; int taskid; // Parser de los datos de la estructura a variables my_data=(struct thread_data*)threadarg; taskid=my_data->thread_id; SSL *ssl=my_data->message; HTMLecho=my_data->reto; printf("Inicia Servidor\n"); if(SSL_accept(ssl)==FAIL){ printf("Hubo un error en el SSL accept\n"); ERR_print_errors_fp(stderr); } else{ printf("SSL accept fue exitoso\n"); //MostrarCertificados(ssl); bytes=SSL_read(ssl,buf,sizeof(buf)); if(bytes>0){ buf[bytes]=0; printf("Mensaje cliente [%d]: %s\n", taskid,buf); sprintf(reply,HTMLecho,buf); sleep (30); //SSL_write(ssl,reply,strlen(reply)); SSL_write(ssl,reply,20); } else ERR_print_errors_fp(stderr); } sd=SSL_get_fd(ssl); SSL_free(ssl); close(sd); } //−−− Main −−−−−−−−−−−−−−−−−−−−−−−−−−−−−−−−−−−−−−−−− // Se e n c a r g a de c r e a r e l s e r v i d o r int main(int count, char *strings[]){ //Arreglo de hilos pthread_t threads[NUM_THREADS]; struct thread_data thread_data_array[NUM_THREADS]; int t=0; int rc; SSL_CTX *ctx; int server; char *portnum; SSL_library_init(); if(count!= 2){ printf("Uso : %s <portnum>\n", strings[0]); exit(0); } //Genero el reto printf("Generando reto...\n"); /* Longitud del reto */ unsigned short int length = 20; char reto[20]; /* Seed number for rand() */ srand((unsigned int) time(0) + getpid()); /* ASCII characters 33 to 126 */ int aux=0; while(length--) { reto[aux]=putchar(rand() % 94 + 33); srand(rand()); aux++; } reto[aux]='\0'; printf("\n"); //imprimirReto(reto); const char* HTMLecho; HTMLecho=reto; portnum = strings [1]; ctx=IniciarCTXServidor(); CargarCertificados(ctx,"/home/xabi/Escritorio/examples/ssl/proyecto/certificados/servidor/server.crt","/home/xabi/Escritorio/examples/ssl/proyecto/certificados/servidor/server.key");//Certificado y clave server=CrearSocket(atoi(portnum)); printf("Esperando por conexiones[%d]\n", server); printf("Inicia a aceptar conexiones\n"); while(1){ struct sockaddr_in addr; SSL *ssl; int len=sizeof(addr); int client=accept(server,(struct sockaddr*)&addr,&len); printf("Connection: %d %d\n",inet_ntoa(addr.sin_addr),ntohs(addr.sin_port)); ssl=SSL_new(ctx); // Se crea contexto SSL_set_fd(ssl,client); t++; // Se da numero de pthread thread_data_array[t].thread_id=t; // Se le da el id del thread al thread thread_data_array[t].message=ssl; // Se le da el asigna el contexto de la conexion al thread thread_data_array[t].reto=(char *)HTMLecho; rc=pthread_create(&threads[t],NULL,Servidor,(void *)&thread_data_array[t]); // Se crea el hilo y se le manda la estructura llenada previamente if(t==NUM_THREADS){ //DUDA!!!!!!!!! sleep(5); t=0; } } close(server); SSL_CTX_free(ctx); } Como veis para cada peticion que llega crea un hilo que atiende esta petición y tengo definido un máximo de 5 peticiones. De esta forma funcionaba, pero después de la 5 petcion , al llegar la 6 lógicaente da un error de segmentacion. Así que decidi poner, si llega a la 5 petición pongo el contador a 0 y que siga creando hilos, perono estoy seguro de que este bien ya que vuelvo a crear un hilo con id=0 por ejemplo igual que el otro hilo id=0 que no se si acabo o no y supongo que puede darme problemas de concurrecia en el futuro. Alguna idea de como mejorar esto? Gracias |