Je suis en train de reproduire un exemple de Network Security avec OpenSSL (par Chandra et al). Le programme se compose de client.c
server.c
common.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
Ê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. –
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 ... –