2010-07-29 7 views
0

Je suis en train de reproduire un exemple de Network Security avec OpenSSL (par Chandra et al). Le programme se compose de client.cserver.ccommon.h et common.c. client.c crée simplement une connexion au serveur sur le port 6012 et lit les données de stdin, puis envoie ces données au serveur. Le server.c lit les données de la socket et les réécrit à stdout.pthread_create a échoué et renvoyé -1 (ou 4294967295)

Le problème est que server.c toujours se coincer dans if(BIO_do_accept(acc) <= 0) à la ligne 62 et ne fait jamais les données envoyées par client.c, qui fonctionne parfaitement bien. J'ai trouvé plus tard, le problème est que pthread_create(...) à la ligne 66 (qui est définie comme THREAD_CREATE(...) dans common.h) a échoué et il est revenu 4294967295. Parce que THREAD_CREATE(...) a échoué, le programme n'obtient jamais une chance d'exécuter do_server_loop dans server_thread(...), ce qui explique pourquoi le serveur n'a jamais reçu les données du client.

Comment dois-je interpréter les valeurs de retour de pthread_create et comment dois-je résoudre ce problème? PS. J'ai utilisé plus tard strerror pour convertir 4294967295 et il a renvoyé "Erreur inconnue".

Toute aide sera très appréciée!

////////////////////////////////////////////// ////

Voici server.c:

#include "common.h" 
void do_server_loop(BIO *conn) 
{ 
    int err, nread; 
    char buf[80]; 

    do 
    { 
     fprintf(stderr, "server_loop executed.\n"); 
     for(nread = 0; nread < sizeof(buf); nread += err) 
     { 
      err = BIO_read(conn, buf + nread, sizeof(buf) - nread); 
      if(err <= 0){ 
       break; 
      } 
     } 
     fwrite(buf, 1, nread, stdout); 
    } 
    while (err > 0); 
} 

void THREAD_CC server_thread(void *arg) 
{ 
    fprintf(stderr, "server_thread(void *arg) executed.\n"); 
    BIO *client = (BIO *)arg; 
#ifndef WIN32 
    pthread_detach(pthread_self()); 
#endif 
    fprintf(stderr, "Connection opened.\n"); 
    do_server_loop(client); 
    fprintf(stderr, "Connection closed.\n"); 

    BIO_free(client); 
    ERR_remove_state(0); 
#ifdef WIN32 
    _endthread(); 
#else 
    return 0; 
#endif 
} 


int main(int argc, char *argv[]) 
{ 
    BIO  *acc, *client; 
    int thread_create_result; 
    THREAD_TYPE tid; 

    init_OpenSSL(); 

    acc = BIO_new_accept(PORT); 
    if(!acc){ 
     int_error("Error creating server socket"); 
    } 

    if(BIO_do_accept(acc) <= 0){ 
     int_error("Error binding server socket"); 
    } 
    for(;;) 
    { 
     if(BIO_do_accept(acc) <= 0){ 
      int_error("Error accepting connection"); 
     } 
     client = BIO_pop(acc); 
     thread_create_result = THREAD_CREATE(tid, server_thread, client); 
     if(thread_create_result != 0){ 
      fprintf(stderr, "THREAD_CREATE failed! returns: %s.\n", \ 
              strerror(thread_create_result)); 
      fprintf(stderr, "thread_create_result has the value: %u.\n", \ 
              thread_create_result); 
      exit(-1); 
     } 
    } 

    BIO_free(acc); 
    return 0; 
} 

Voici common.h

#include <errno.h> 
#include <fcntl.h> 
#include <netdb.h> 
#include <netinet/in.h> 
#include <netinet/tcp.h> 
#include <openssl/bio.h> 
#include <openssl/err.h> 
#include <openssl/hmac.h> 
#include <openssl/objects.h> 
#include <openssl/rand.h> 
#include <openssl/ssl.h> 
#include <openssl/x509.h> 
#include <openssl/x509v3.h> 
#include <signal.h> 
#include <stdio.h> 
#include <stdlib.h> 
#include <strings.h> 
#include <sys/socket.h> 
#include <sys/time.h> 
#include <sys/types.h> 
#include <unistd.h> 


#ifndef WIN32 
#include <pthread.h> 
#define THREAD_CC * 
#define THREAD_TYPE   pthread_t 
#define THREAD_CREATE(tid, entry, arg) pthread_create(&(tid), NULL, \ 
            (entry), (arg)) 
#else 
#include <windows.h> 
#include <process.h> 
#define THREAD_CC    __cdecl 
#define THREAD_TYPE   DWORD 
#define THREAD_CREATE(tid, entry, arg) do { _beginthread((entry), 0, (arg));\ 
         (tid) = GetCurrentThreadId();\ 
         } while (0) 
#endif 

#define PORT "6012"  //port 
#define SERVER "10.1.251.24" //server address 
#define CLIENT "10.1.21.46" //client address 

#define int_error(msg) handle_error(__FILE__, __LINE__, msg) 
void handle_error(const char *file, int lineno, const char *msg); 

void init_OpenSSL(void); 

Makefile:

CC = gcc 
OPENSSLDIR = /usr/local/ssl 
#CFLAGS = -g -Wall -W -I${OPENSSLDIR}/include -O2 -D_REENTRANT -D__EXTENSIONS__ 
CFLAGS = -g -Wall -W -I${OPENSSLDIR}/include -O2 

RPATH = -R${OPENSSLDIR}/lib 
#LD = ${RPATH} -L${OPENSSLDIR}/lib -lssl -lcrypto -lsocket -lnsl -lpthread 
LD = -L${OPENSSLDIR}/lib -lssl -lcrypto -lsocket -lnsl -pthread 

OBJS = common.o 

PROGS = server 

all: ${PROGS} 

server: server.o ${OBJS} 
     ${CC} server.o ${OBJS} -o server ${LD} 


clean:; 
     ${RM} ${PROGS} *.ln *.BAK *.bak *.o 
+0

Êtes-vous sûr que la valeur de retour est de pthread_create? Je veux savoir si vous avez compilé avec -DWIN32 comme sous #ifndef. –

+0

Oui, je suis sûr que le 4294967295 est retourné par pthread_create et j'ai ensuite utilisé strerror pour convertir le numéro d'erreur et j'ai juste "Erreur inconnue". Je ne pense pas avoir compilé avec -DWIN32 ... –

Répondre

0

ajouter -D_REENTRANT sur les lignes de commande de compilation et -lpthread sur la ligne de commande de liaison. -D_REENTRANT racontera C/C++ bibliothèques que votre programme est en mode multithread et -lpthread il suffit de charger le libpthread.so de bibliothèque partagée à l'exécution. J'ai trouvé cela au William Garrison's POSIX threads tutorial et this link.

Voici le Makefile:

CC = gcc 
OPENSSLDIR = /usr/local/ssl 
CFLAGS = -g -Wall -W -I${OPENSSLDIR}/include -O2 -D_REENTRANT -D__EXTENSIONS__ 

RPATH = -R${OPENSSLDIR}/lib 
LD = ${RPATH} -L${OPENSSLDIR}/lib -lssl -lcrypto -lsocket -lnsl -lpthread 

OBJS = common.o 

PROGS = server 

all: ${PROGS} 

server: server.o ${OBJS} 
     ${CC} server.o ${OBJS} -o server ${LD} 


clean:; 
     ${RM} ${PROGS} *.ln *.BAK *.bak *.o 
2

changement

if(thread_create_result = !0){ 

à

if(thread_create_result != 0){ 

De plus, vous pouvez utiliser strerror fonction pour convertir le code d'erreur de forme lisible par l'homme.

+0

@ adf88: merci! J'ai mis à jour mon code et ajouté "fprintf (stderr," THREAD_CREATE a échoué!renvoie:% s. \ n ", strerror (thread_create_result));" à la ligne 68. Voici ce que le programme a renvoyé: THREAD_CREATE a échoué! retourne: Erreur inconnue. thread_create_result a la valeur: 4294967295. –

+0

@ adf88: J'ai vérifié les codes d'erreur listés dans pthread_create mais je n'ai pas pu trouver celui que j'avais. Merci! –

+0

4294967295 est juste la version non signée de -1. –