add support to reverse proxy (alpha)

This commit is contained in:
lxsang
2021-01-22 01:12:26 +01:00
parent 5d1998ef1f
commit 520b99f94b
12 changed files with 381 additions and 117 deletions

View File

@ -24,35 +24,37 @@ THE SOFTWARE.
#ifndef DICTIONARY_H
#define DICTIONARY_H
#define DHASHSIZE 16
#define for_each_assoc(assoc, dic) \
for(unsigned int i = 0; i < dic->cap; i++) \
for(assoc = dic->map[i];assoc!= NULL; assoc = assoc->next)
#define DHASHSIZE 16
#define for_each_assoc(assoc, dic) \
for (unsigned int i = 0; i < dic->cap; i++) \
for (assoc = dic->map[i]; assoc != NULL; assoc = assoc->next)
/**
* Dictionary for header
*/
typedef struct __assoc{
struct __assoc *next;
char *key;
void* value;
typedef struct __assoc
{
struct __assoc *next;
char *key;
void *value;
//char *value;
} * chain_t;
typedef chain_t* map_t;
typedef chain_t *map_t;
typedef struct __dict{
typedef struct __dict
{
unsigned int cap;
map_t map;
unsigned int size;
}* dictionary_t;
} * dictionary_t;
dictionary_t dict();
dictionary_t dict_n(unsigned int n);
chain_t dlookup(dictionary_t,const char*);
void* dvalue(dictionary_t, const char*);
chain_t dput(dictionary_t,const char*, void*);
chain_t dremove(dictionary_t, const char*);
chain_t dlookup(dictionary_t, const char *);
void *dvalue(dictionary_t, const char *);
chain_t dput(dictionary_t, const char *, void *);
chain_t dremove(dictionary_t, const char *);
void freedict(dictionary_t);
#endif

View File

@ -107,8 +107,8 @@ int compressable(char *ctype)
void htdocs(antd_request_t *rq, char *dest)
{
dictionary_t xheader = (dictionary_t)dvalue(rq->request, "REQUEST_HEADER");
char *www = (char *)dvalue(xheader, "SERVER_WWW_ROOT");
//dictionary_t xheader = (dictionary_t)dvalue(rq->request, "REQUEST_HEADER");
char *www = (char *)dvalue(rq->request, "SERVER_WWW_ROOT");
if (www)
{
strcpy(dest, www);
@ -527,7 +527,7 @@ int antd_send(void *src, const void *data_in, int len_in)
writelen = (len - written) > BUFFLEN ? BUFFLEN : (len - written);
time(&source->last_io);
}
else if (difftime(time(NULL), source->last_io) > MAX_IO_WAIT_TIME || (count == -1 && errno != EAGAIN && errno != EWOULDBLOCK))
else if ((difftime(time(NULL), source->last_io) > MAX_IO_WAIT_TIME) || (count == -1 && errno != EAGAIN && errno != EWOULDBLOCK))
{
if (written == 0)
written = count;
@ -542,6 +542,76 @@ int antd_send(void *src, const void *data_in, int len_in)
return written;
}
/**
* Read up to n bytes, not guaranty to have exactly nbytes
* - return -1 if false
* */
int antd_recv_upto(void *src, void *data, int len)
{
if (!src)
return -1;
int received = 0;
antd_client_t *source = (antd_client_t *)src;
#ifdef USE_OPENSSL
if (source->ssl)
{
ERR_clear_error();
received = SSL_read(source->ssl, data, len);
int err = SSL_get_error(source->ssl, received);
if (received > 0)
{
time(&source->last_io);
return received;
}
else
{
switch (err)
{
case SSL_ERROR_NONE:
{
return 0;
}
case SSL_ERROR_ZERO_RETURN:
{
// peer disconnected...
return -1;
}
case SSL_ERROR_WANT_READ:
{
return 0;
}
case SSL_ERROR_WANT_WRITE:
{
return 0;
}
default:
return -1;
}
}
}
else
{
#endif
received = recv(((int)source->sock), data, len, 0);
//LOG("Read : %c\n", *ptr);
if (received > 0)
{
time(&source->last_io);
return received;
}
if (received == 0 || (errno != EAGAIN && errno != EWOULDBLOCK))
{
return -1;
}
return 0;
#ifdef USE_OPENSSL
}
#endif
}
int antd_recv(void *src, void *data, int len)
{
if (!src)
@ -688,7 +758,8 @@ int antd_recv(void *src, void *data, int len)
time(&source->last_io);
//LOG("Read len is %d\n", readlen);
}
else if (difftime(time(NULL), source->last_io) > MAX_IO_WAIT_TIME || (errno != EAGAIN && errno != EWOULDBLOCK))
else if ((read == 0) ||
difftime(time(NULL), source->last_io) > MAX_IO_WAIT_TIME || (errno != EAGAIN && errno != EWOULDBLOCK))
{
//ERROR("Error while reading: %s", strerror(errno));
if (read == 0)

View File

@ -132,6 +132,7 @@ int ws_enable(dictionary_t);
int read_buf(void *sock, char *buf, int i);
int antd_send(void *source, const void *data, int len);
int antd_recv(void *source, void *data, int len);
int antd_recv_upto(void* src, void* data, int len);
int antd_close(void *source);
void destroy_request(void *data);
#endif

View File

@ -694,7 +694,7 @@ void *antd_scheduler_wait(void *ptr)
antd_queue_item_t it = NULL;
antd_queue_item_t curr = NULL;
antd_task_evt_item_t *eit = NULL;
bst_node_t* node = NULL;
bst_node_t* node, *task_node = NULL;
struct pollfd *pfds = NULL;
antd_scheduler_t *scheduler = (antd_scheduler_t *)ptr;
@ -745,6 +745,7 @@ void *antd_scheduler_wait(void *ptr)
for (int i = 0; i < pollsize; i++)
{
// find the event
task_node = NULL;
node = bst_find(poll_list,i);
if(node)
eit = (antd_task_evt_item_t *)node->data;
@ -755,9 +756,12 @@ void *antd_scheduler_wait(void *ptr)
) {
// event triggered schedule the task
pthread_mutex_lock(&scheduler->scheduler_lock);
scheduler->task_queue = bst_delete(scheduler->task_queue, eit->task->id);
task_node = bst_find(scheduler->task_queue, eit->task->id);
if(task_node)
scheduler->task_queue = bst_delete(scheduler->task_queue, eit->task->id);
pthread_mutex_unlock(&scheduler->scheduler_lock);
antd_task_schedule(scheduler, eit->task);
if(task_node)
antd_task_schedule(scheduler, eit->task);
}
else if( (pfds[i].revents & POLLERR) || (pfds[i].revents & POLLHUP) ) {
// task is no longer available
@ -782,6 +786,8 @@ void *antd_scheduler_wait(void *ptr)
if (!scheduler->task_queue)
{
// reset id allocator
//scheduler->id_allocator=0;
// no task found, go to idle state
sem_wait(scheduler->scheduler_sem);
}
@ -805,6 +811,7 @@ int antd_scheduler_next_id(antd_scheduler_t *sched, int input)
while (bst_find(sched->task_queue, id) != NULL)
{
sched->id_allocator++;
id = sched->id_allocator;
}
pthread_mutex_unlock(&sched->scheduler_lock);

View File

@ -34,6 +34,8 @@ THE SOFTWARE.
#include <stdio.h>
#include <stdint.h>
#include <ctype.h>
#include <arpa/inet.h>
#include <netdb.h> //hostent
#ifdef USE_OPENSSL
#include <openssl/sha.h>
@ -594,4 +596,60 @@ int guard_write(int fd, void* buffer, size_t size)
n += st;
}
return n;
}
/*
send a request
*/
int request_socket(const char *ip, int port)
{
int sockfd;
struct sockaddr_in dest;
if ((sockfd = socket(AF_INET, SOCK_STREAM, 0)) < 0)
{
ERROR("Socket: %s", strerror(errno));
return -1;
}
/*struct linger lingerStruct;
lingerStruct.l_onoff = 0; // turn lingering off for sockets
setsockopt(sockfd, SOL_SOCKET, SO_LINGER, &lingerStruct, sizeof(lingerStruct));*/
bzero(&dest, sizeof(dest));
dest.sin_family = AF_INET;
dest.sin_port = htons(port);
if (inet_aton(ip, &dest.sin_addr) == 0)
{
perror(ip);
close(sockfd);
return -1;
}
if (connect(sockfd, (struct sockaddr *)&dest, sizeof(dest)) != 0)
{
close(sockfd);
ERROR("Connect:%s", strerror(errno));
return -1;
}
return sockfd;
}
char* ip_from_hostname(const char *hostname)
{
struct hostent *he;
struct in_addr **addr_list;
int i;
if ((he = gethostbyname(hostname)) == NULL)
{
// get the host info
ERROR("gethostbyname:%s", strerror(errno));
return NULL;
}
addr_list = (struct in_addr **)he->h_addr_list;
for (i = 0; addr_list[i] != NULL; i++)
{
//Return the first one;
return inet_ntoa(*addr_list[i]);
}
return NULL;
}

View File

@ -96,4 +96,6 @@ void digest_to_hex(const uint8_t *, char *);
void verify_header(char* k);
int guard_read(int fd, void* buffer, size_t size);
int guard_write(int fd, void* buffer, size_t size);
int request_socket(const char *ip, int port);
char* ip_from_hostname(const char *hostname);
#endif

View File

@ -3,7 +3,6 @@
#include <unistd.h>
#include <string.h>
#include <errno.h>
#include <netdb.h> //hostent
#ifdef USE_OPENSSL
#include <openssl/ssl.h>
#include <openssl/err.h>
@ -348,71 +347,6 @@ int ws_send_close(void *client, unsigned int status, int mask)
//_send_header(client, header);
//send(client,bytes,2,0);
}
int ip_from_hostname(const char *hostname, char *ip)
{
struct hostent *he;
struct in_addr **addr_list;
int i;
if ((he = gethostbyname(hostname)) == NULL)
{
// get the host info
ERROR("gethostbyname:%s", strerror(errno));
return -1;
}
addr_list = (struct in_addr **)he->h_addr_list;
for (i = 0; addr_list[i] != NULL; i++)
{
//Return the first one;
strcpy(ip, inet_ntoa(*addr_list[i]));
return 0;
}
return -1;
}
/*
send a request
*/
int request_socket(const char *ip, int port)
{
int sockfd;
struct sockaddr_in dest;
// time out setting
struct timeval timeout;
timeout.tv_sec = CONN_TIME_OUT_S;
timeout.tv_usec = 0; //3 s
if ((sockfd = socket(AF_INET, SOCK_STREAM, 0)) < 0)
{
ERROR("Socket: %s", strerror(errno));
return -1;
}
if (setsockopt(sockfd, SOL_SOCKET, SO_RCVTIMEO, (char *)&timeout, sizeof(timeout)) < 0)
ERROR("setsockopt failed:%s", strerror(errno));
if (setsockopt(sockfd, SOL_SOCKET, SO_SNDTIMEO, (char *)&timeout, sizeof(timeout)) < 0)
ERROR("setsockopt failed:%s", strerror(errno));
/*struct linger lingerStruct;
lingerStruct.l_onoff = 0; // turn lingering off for sockets
setsockopt(sockfd, SOL_SOCKET, SO_LINGER, &lingerStruct, sizeof(lingerStruct));*/
bzero(&dest, sizeof(dest));
dest.sin_family = AF_INET;
dest.sin_port = htons(port);
if (inet_aton(ip, &dest.sin_addr) == 0)
{
perror(ip);
close(sockfd);
return -1;
}
if (connect(sockfd, (struct sockaddr *)&dest, sizeof(dest)) != 0)
{
close(sockfd);
ERROR("Connect:%s", strerror(errno));
return -1;
}
return sockfd;
}
void ws_client_close(ws_client_t *wsclient)
{
@ -437,9 +371,8 @@ void ws_client_close(ws_client_t *wsclient)
//this is for the client side, not use for now
int ws_client_connect(ws_client_t *wsclient, port_config_t pcnf)
{
char ip[100];
int stat = ip_from_hostname(wsclient->host, ip);
if (stat == -1)
char* ip = ip_from_hostname(wsclient->host);
if (ip == NULL)
return -1;
int sock = request_socket(ip, pcnf.port);
if (sock <= 0)
@ -447,6 +380,16 @@ int ws_client_connect(ws_client_t *wsclient, port_config_t pcnf)
ERROR("Cannot request socket");
return -1;
}
// time out setting
struct timeval timeout;
timeout.tv_sec = CONN_TIME_OUT_S;
timeout.tv_usec = 0; //3 s
if (setsockopt(sock, SOL_SOCKET, SO_RCVTIMEO, (char *)&timeout, sizeof(timeout)) < 0)
ERROR("setsockopt failed:%s", strerror(errno));
if (setsockopt(sock, SOL_SOCKET, SO_SNDTIMEO, (char *)&timeout, sizeof(timeout)) < 0)
ERROR("setsockopt failed:%s", strerror(errno));
// will be free
wsclient->antdsock->sock = sock;
wsclient->antdsock->z_status = 0;

View File

@ -57,8 +57,6 @@ int ws_send_file(void *client, const char *file, int mask);
int ws_send_binary(void *client, uint8_t *data, int l, int mask);
int ws_read_data(void *, ws_msg_header_t *, int, uint8_t *);
int request_socket(const char *ip, int port);
int ip_from_hostname(const char *hostname, char *ip);
//int ws_open_hand_shake(const char* host, int port, const char* resource);
char *get_ip_address();