fix open ssl bug

This commit is contained in:
lxsang 2018-10-07 01:03:05 +02:00
parent 1cfb69691f
commit 04fec05b70
6 changed files with 101 additions and 20 deletions

View File

@ -125,12 +125,7 @@ void load_config(const char* file)
}
init_file_system();
}
void set_nonblock(int socket) {
int flags;
flags = fcntl(socket,F_GETFL,0);
//assert(flags != -1);
fcntl(socket, F_SETFL, flags | O_NONBLOCK);
}
void* accept_request(void* data)
{
@ -144,28 +139,68 @@ void* accept_request(void* data)
task = antd_create_task(NULL,(void*)rq,NULL);
task->priority++;
server_config.connection++;
fd_set read_flags;
fd_set read_flags, write_flags;
// first verify if the socket is ready
antd_client_t* client = (antd_client_t*) rq->client;
FD_ZERO(&read_flags);
FD_SET(rq->client->sock, &read_flags);
FD_ZERO(&write_flags);
FD_SET(rq->client->sock, &write_flags);
struct timeval timeout;
timeout.tv_sec = 0;
timeout.tv_usec = 500;
// select
int sel = select(client->sock+1, &read_flags, NULL, (fd_set*)0, &timeout);
int sel = select(client->sock+1, &read_flags, &write_flags, (fd_set*)0, &timeout);
if(sel == -1)
{
unknow(rq->client);
return task;
}
if(sel == 0 || !FD_ISSET(client->sock, &read_flags) )
if(sel == 0 || (!FD_ISSET(client->sock, &read_flags) && !FD_ISSET(client->sock, &write_flags)))
{
// retry it later
server_config.connection--;
task->handle = accept_request;
return task;
}
// perform the ssl handshake if enabled
#ifdef USE_OPENSSL
int ret,stat;
if(server_config.usessl == 1 && client->status == 0)
{
if (SSL_accept((SSL*)client->ssl) == -1) {
stat = SSL_get_error((SSL*)client->ssl, ret);
switch(stat)
{
case SSL_ERROR_WANT_READ:
case SSL_ERROR_WANT_WRITE:
case SSL_ERROR_NONE:
//LOG("RECALL %d\n", stat);
task->handle = accept_request;
task->priority = HIGH_PRIORITY;
server_config.connection--;
return task;
default:
LOG("ERRRRRRRRROR accept %d %d %d\n", stat, ret, ERR_get_error());
ERR_print_errors_fp(stderr);
return task;
}
}
client->status = 1;
server_config.connection--;
task->handle = accept_request;
return task;
}
else
{
if(!FD_ISSET(client->sock, &read_flags))
{
task->handle = accept_request;
server_config.connection--;
return task;
}
}
#endif
count = read_buf(rq->client, buf, sizeof(buf));
//LOG("count is %d\n", count);
line = buf;
@ -831,6 +866,8 @@ void* decode_multi_part_request_data(void* data)
{
int totalsize=0,len=0;
//read until the next boundary
// TODO: this is not efficient for big file
// need a solution
while((len = read_buf(rq->client,buf,sizeof(buf))) > 0 && strstr(buf,boundary) <= 0)
{
fwrite(buf, len, 1, fp);
@ -927,12 +964,16 @@ void decode_url_request(const char* query, dictionary dic)
char* post_data_decode(void* client,int len)
{
char *query = (char*) malloc((len+1)*sizeof(char));
for (int i = 0; i < len; i++) {
antd_recv(client, (query+i), 1);
}
char* ptr = query;
int readlen = len > BUFFLEN?BUFFLEN:len;
int read = 0;
while(readlen > 0)
{
read += antd_recv(client, query+read, readlen);
LOG("READ %d/%d\n", read, len);
readlen = (len - read) > BUFFLEN?BUFFLEN:(len-read);
}
query[len]='\0';
//query = url_decode(query);
//LOG("JSON Query %s\n", query);
return query;
}

View File

@ -8,7 +8,6 @@
#include <signal.h>
#include <sys/socket.h>
#include <sys/select.h>
#include <fcntl.h>
#include "libs/handle.h"
#include "libs/scheduler.h"
#include "plugin_manager.h"

View File

@ -167,17 +167,19 @@ int main(int argc, char* argv[])
//LOG("Unclosed connection: %d\n", server_config->connection);
#ifdef USE_OPENSSL
client->ssl = NULL;
client->status = 0;
if(config()->usessl == 1)
{
client->ssl = (void*)SSL_new(ctx);
if(!client->ssl) continue;
SSL_set_fd((SSL*)client->ssl, client_sock);
SSL_set_fd((SSL*)client->ssl, client->sock);
if (SSL_accept((SSL*)client->ssl) <= 0) {
/*if (SSL_accept((SSL*)client->ssl) <= 0) {
LOG("EROOR accept\n");
ERR_print_errors_fp(stderr);
antd_close(client);
continue;
}
}*/
}
#endif
// create callback for the server

View File

@ -100,8 +100,28 @@ int antd_recv(void *src, void* data, int len)
#ifdef USE_OPENSSL
if(usessl())
{
//LOG("SSL READ\n");
// TODO: blocking is not good, need a workaround
set_nonblock(source->sock);
ret = SSL_read((SSL*) source->ssl, data, len);
set_nonblock(source->sock);
/*
int stat, r, st;
do{
ret = SSL_read((SSL*) source->ssl, data, len);
stat = SSL_get_error((SSL*)source->ssl, r);
} while(ret == -1 &&
(
stat == SSL_ERROR_WANT_READ ||
stat == SSL_ERROR_WANT_WRITE ||
stat == SSL_ERROR_NONE ||
(stat == SSL_ERROR_SYSCALL && r== 0 && !ERR_get_error())
));
if(ret == -1)
{
LOG("Problem reading %d %d %d\n", ret, stat, r);
}
//set_nonblock(source->sock);
*/
}
else
{
@ -116,6 +136,19 @@ int antd_recv(void *src, void* data, int len)
}*/
return ret;
}
void set_nonblock(int socket) {
int flags;
flags = fcntl(socket,F_GETFL,0);
//assert(flags != -1);
fcntl(socket, F_SETFL, flags | O_NONBLOCK);
}
void set_block()
{
int flags;
flags = fcntl(socket,F_GETFL,0);
//assert(flags != -1);
fcntl(socket, F_SETFL, flags & (~O_NONBLOCK));
}
int antd_close(void* src)
{
if(!src) return -1;

View File

@ -11,6 +11,7 @@
#ifdef USE_DB
#include "dbhelper.h"
#endif
#include <fcntl.h>
#include "dictionary.h"
#include "list.h"
#include "ini.h"
@ -33,6 +34,9 @@ typedef struct{
int sock;
void* ssl;
char* ip;
#ifdef USE_OPENSSL
int status;
#endif
} antd_client_t;
typedef struct {
@ -60,7 +64,8 @@ typedef struct {
char* sslkey;
#endif
}config_t;
void set_nonblock(int socket);
void set_block(int socket);
int response(void*, const char*);
void ctype(void*,const char*);
void redirect(void*,const char*);

View File

@ -195,6 +195,7 @@ void antd_add_task(antd_scheduler_t* scheduler, antd_task_t* task)
{
// check if task is exist
int prio = task->priority>N_PRIORITY-1?N_PRIORITY-1:task->priority;
//LOG("Prio is %d\n", prio);
pthread_mutex_lock(&scheduler->scheduler_lock);
enqueue(&scheduler->task_queue[prio], task);
pthread_mutex_unlock(&scheduler->scheduler_lock);