Reformated text.
This commit is contained in:
parent
bcb7c68911
commit
787ece6c01
41
src/acl.c
41
src/acl.c
@ -1,4 +1,4 @@
|
|||||||
/* $Id: acl.c,v 1.10 2001-11-03 06:08:37 rjkaes Exp $
|
/* $Id: acl.c,v 1.11 2001-11-22 00:31:10 rjkaes Exp $
|
||||||
*
|
*
|
||||||
* This system handles Access Control for use of this daemon. A list of
|
* This system handles Access Control for use of this daemon. A list of
|
||||||
* domains, or IP addresses (including IP blocks) are stored in a list
|
* domains, or IP addresses (including IP blocks) are stored in a list
|
||||||
@ -38,7 +38,8 @@ static struct acl_s *access_list = NULL;
|
|||||||
* Take a netmask number (between 0 and 32) and returns a network ordered
|
* Take a netmask number (between 0 and 32) and returns a network ordered
|
||||||
* value for comparison. Somebody please clean this up. :)
|
* value for comparison. Somebody please clean this up. :)
|
||||||
*/
|
*/
|
||||||
static in_addr_t make_netmask(int netmask_num)
|
static in_addr_t
|
||||||
|
make_netmask(int netmask_num)
|
||||||
{
|
{
|
||||||
static in_addr_t netmasks[] = {
|
static in_addr_t netmasks[] = {
|
||||||
0x00000000, 0x80000000, 0xc0000000, 0xe0000000,
|
0x00000000, 0x80000000, 0xc0000000, 0xe0000000,
|
||||||
@ -66,7 +67,8 @@ static in_addr_t make_netmask(int netmask_num)
|
|||||||
* -1 on failure
|
* -1 on failure
|
||||||
* 0 otherwise.
|
* 0 otherwise.
|
||||||
*/
|
*/
|
||||||
int insert_acl(char *location, acl_access_t access_type)
|
int
|
||||||
|
insert_acl(char *location, acl_access_t access_type)
|
||||||
{
|
{
|
||||||
size_t i;
|
size_t i;
|
||||||
struct acl_s **rev_acl_ptr, *acl_ptr, *new_acl_ptr;
|
struct acl_s **rev_acl_ptr, *acl_ptr, *new_acl_ptr;
|
||||||
@ -81,7 +83,7 @@ int insert_acl(char *location, acl_access_t access_type)
|
|||||||
/*
|
/*
|
||||||
* Numeric strings can not contain letters, so test on it.
|
* Numeric strings can not contain letters, so test on it.
|
||||||
*/
|
*/
|
||||||
if (isalpha((unsigned char)location[i])) {
|
if (isalpha((unsigned char) location[i])) {
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@ -99,9 +101,9 @@ int insert_acl(char *location, acl_access_t access_type)
|
|||||||
if (!new_acl_ptr) {
|
if (!new_acl_ptr) {
|
||||||
return -1;
|
return -1;
|
||||||
}
|
}
|
||||||
|
|
||||||
new_acl_ptr->acl_access = access_type;
|
new_acl_ptr->acl_access = access_type;
|
||||||
|
|
||||||
if (location[i] == '\0') {
|
if (location[i] == '\0') {
|
||||||
DEBUG2("ACL \"%s\" is a number.", location);
|
DEBUG2("ACL \"%s\" is a number.", location);
|
||||||
|
|
||||||
@ -115,7 +117,8 @@ int insert_acl(char *location, acl_access_t access_type)
|
|||||||
*nptr++ = '\0';
|
*nptr++ = '\0';
|
||||||
|
|
||||||
new_acl_ptr->netmask = strtol(nptr, NULL, 10);
|
new_acl_ptr->netmask = strtol(nptr, NULL, 10);
|
||||||
if (new_acl_ptr->netmask < 0 || new_acl_ptr->netmask > 32) {
|
if (new_acl_ptr->netmask < 0
|
||||||
|
|| new_acl_ptr->netmask > 32) {
|
||||||
safefree(new_acl_ptr);
|
safefree(new_acl_ptr);
|
||||||
return -1;
|
return -1;
|
||||||
}
|
}
|
||||||
@ -137,7 +140,7 @@ int insert_acl(char *location, acl_access_t access_type)
|
|||||||
|
|
||||||
*rev_acl_ptr = new_acl_ptr;
|
*rev_acl_ptr = new_acl_ptr;
|
||||||
new_acl_ptr->next = acl_ptr;
|
new_acl_ptr->next = acl_ptr;
|
||||||
|
|
||||||
return 0;
|
return 0;
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -149,7 +152,8 @@ int insert_acl(char *location, acl_access_t access_type)
|
|||||||
* 0 if denied
|
* 0 if denied
|
||||||
* -1 if error
|
* -1 if error
|
||||||
*/
|
*/
|
||||||
int check_acl(int fd)
|
int
|
||||||
|
check_acl(int fd)
|
||||||
{
|
{
|
||||||
struct acl_s *aclptr;
|
struct acl_s *aclptr;
|
||||||
char ip_address[PEER_IP_LENGTH];
|
char ip_address[PEER_IP_LENGTH];
|
||||||
@ -180,9 +184,13 @@ int check_acl(int fd)
|
|||||||
continue;
|
continue;
|
||||||
}
|
}
|
||||||
|
|
||||||
if (strcasecmp(string_address + (test_length - match_length), aclptr->location) == 0) {
|
if (strcasecmp
|
||||||
|
(string_address + (test_length - match_length),
|
||||||
|
aclptr->location) == 0) {
|
||||||
if (aclptr->acl_access == ACL_DENY) {
|
if (aclptr->acl_access == ACL_DENY) {
|
||||||
log_message(LOG_NOTICE, "Unauthorized access from \"%s\"", string_address);
|
log_message(LOG_NOTICE,
|
||||||
|
"Unauthorized access from \"%s\"",
|
||||||
|
string_address);
|
||||||
return 0;
|
return 0;
|
||||||
} else {
|
} else {
|
||||||
return 1;
|
return 1;
|
||||||
@ -202,9 +210,12 @@ int check_acl(int fd)
|
|||||||
|
|
||||||
netmask_addr = make_netmask(aclptr->netmask);
|
netmask_addr = make_netmask(aclptr->netmask);
|
||||||
|
|
||||||
if ((test_addr.s_addr & netmask_addr) == (match_addr.s_addr & netmask_addr)) {
|
if ((test_addr.s_addr & netmask_addr) ==
|
||||||
|
(match_addr.s_addr & netmask_addr)) {
|
||||||
if (aclptr->acl_access == ACL_DENY) {
|
if (aclptr->acl_access == ACL_DENY) {
|
||||||
log_message(LOG_NOTICE, "Unauthorized access from [%s].", ip_address);
|
log_message(LOG_NOTICE,
|
||||||
|
"Unauthorized access from [%s].",
|
||||||
|
ip_address);
|
||||||
return 0;
|
return 0;
|
||||||
} else {
|
} else {
|
||||||
return 1;
|
return 1;
|
||||||
@ -218,10 +229,10 @@ int check_acl(int fd)
|
|||||||
aclptr = aclptr->next;
|
aclptr = aclptr->next;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
/*
|
/*
|
||||||
* Deny all connections by default.
|
* Deny all connections by default.
|
||||||
*/
|
*/
|
||||||
log_message(LOG_NOTICE, "Unauthorized connection from \"%s\" [%s].", string_address, ip_address);
|
log_message(LOG_NOTICE, "Unauthorized connection from \"%s\" [%s].",
|
||||||
|
string_address, ip_address);
|
||||||
return 0;
|
return 0;
|
||||||
}
|
}
|
||||||
|
@ -1,4 +1,4 @@
|
|||||||
/* $Id: anonymous.c,v 1.8 2001-11-05 15:24:42 rjkaes Exp $
|
/* $Id: anonymous.c,v 1.9 2001-11-22 00:31:10 rjkaes Exp $
|
||||||
*
|
*
|
||||||
* Handles insertion and searches for headers which should be let through when
|
* Handles insertion and searches for headers which should be let through when
|
||||||
* the anonymous feature is turned on. The headers are stored in a Ternary
|
* the anonymous feature is turned on. The headers are stored in a Ternary
|
||||||
@ -32,12 +32,14 @@ static TERNARY anonymous_tree = 0;
|
|||||||
*/
|
*/
|
||||||
static short int anonymous_is_enabled = 0;
|
static short int anonymous_is_enabled = 0;
|
||||||
|
|
||||||
inline short int is_anonymous_enabled(void)
|
inline short int
|
||||||
|
is_anonymous_enabled(void)
|
||||||
{
|
{
|
||||||
return anonymous_is_enabled;
|
return anonymous_is_enabled;
|
||||||
}
|
}
|
||||||
|
|
||||||
int anonymous_search(char *s)
|
int
|
||||||
|
anonymous_search(char *s)
|
||||||
{
|
{
|
||||||
assert(s != NULL);
|
assert(s != NULL);
|
||||||
assert(anonymous_is_enabled == 1);
|
assert(anonymous_is_enabled == 1);
|
||||||
@ -46,7 +48,8 @@ int anonymous_search(char *s)
|
|||||||
return ternary_search(anonymous_tree, s, NULL);
|
return ternary_search(anonymous_tree, s, NULL);
|
||||||
}
|
}
|
||||||
|
|
||||||
int anonymous_insert(char *s)
|
int
|
||||||
|
anonymous_insert(char *s)
|
||||||
{
|
{
|
||||||
assert(s != NULL);
|
assert(s != NULL);
|
||||||
|
|
||||||
|
49
src/buffer.c
49
src/buffer.c
@ -1,4 +1,4 @@
|
|||||||
/* $Id: buffer.c,v 1.15 2001-11-05 15:23:05 rjkaes Exp $
|
/* $Id: buffer.c,v 1.16 2001-11-22 00:31:10 rjkaes Exp $
|
||||||
*
|
*
|
||||||
* The buffer used in each connection is a linked list of lines. As the lines
|
* The buffer used in each connection is a linked list of lines. As the lines
|
||||||
* are read in and written out the buffer expands and contracts. Basically,
|
* are read in and written out the buffer expands and contracts. Basically,
|
||||||
@ -33,8 +33,8 @@
|
|||||||
struct bufline_s {
|
struct bufline_s {
|
||||||
unsigned char *string; /* the actual string of data */
|
unsigned char *string; /* the actual string of data */
|
||||||
struct bufline_s *next; /* pointer to next in linked list */
|
struct bufline_s *next; /* pointer to next in linked list */
|
||||||
size_t length; /* length of the string of data */
|
size_t length; /* length of the string of data */
|
||||||
size_t pos; /* start sending from this offset */
|
size_t pos; /* start sending from this offset */
|
||||||
};
|
};
|
||||||
|
|
||||||
/*
|
/*
|
||||||
@ -43,7 +43,8 @@ struct bufline_s {
|
|||||||
* pointer into the structure. In other words, when you insert data into the
|
* pointer into the structure. In other words, when you insert data into the
|
||||||
* buffer, the buffer becomes responsible for freeing it.
|
* buffer, the buffer becomes responsible for freeing it.
|
||||||
*/
|
*/
|
||||||
static struct bufline_s *makenewline(unsigned char *data, size_t length)
|
static struct bufline_s *
|
||||||
|
makenewline(unsigned char *data, size_t length)
|
||||||
{
|
{
|
||||||
struct bufline_s *newline;
|
struct bufline_s *newline;
|
||||||
|
|
||||||
@ -66,7 +67,8 @@ static struct bufline_s *makenewline(unsigned char *data, size_t length)
|
|||||||
/*
|
/*
|
||||||
* Free the allocated buffer line
|
* Free the allocated buffer line
|
||||||
*/
|
*/
|
||||||
static void free_line(struct bufline_s *line)
|
static void
|
||||||
|
free_line(struct bufline_s *line)
|
||||||
{
|
{
|
||||||
assert(line != NULL);
|
assert(line != NULL);
|
||||||
|
|
||||||
@ -82,7 +84,8 @@ static void free_line(struct bufline_s *line)
|
|||||||
/*
|
/*
|
||||||
* Create a new buffer
|
* Create a new buffer
|
||||||
*/
|
*/
|
||||||
struct buffer_s *new_buffer(void)
|
struct buffer_s *
|
||||||
|
new_buffer(void)
|
||||||
{
|
{
|
||||||
struct buffer_s *buffptr;
|
struct buffer_s *buffptr;
|
||||||
|
|
||||||
@ -103,7 +106,8 @@ struct buffer_s *new_buffer(void)
|
|||||||
/*
|
/*
|
||||||
* Delete all the lines in the buffer and the buffer itself
|
* Delete all the lines in the buffer and the buffer itself
|
||||||
*/
|
*/
|
||||||
void delete_buffer(struct buffer_s *buffptr)
|
void
|
||||||
|
delete_buffer(struct buffer_s *buffptr)
|
||||||
{
|
{
|
||||||
struct bufline_s *next;
|
struct bufline_s *next;
|
||||||
|
|
||||||
@ -121,8 +125,8 @@ void delete_buffer(struct buffer_s *buffptr)
|
|||||||
/*
|
/*
|
||||||
* Push a new line on to the end of the buffer
|
* Push a new line on to the end of the buffer
|
||||||
*/
|
*/
|
||||||
static int add_to_buffer(struct buffer_s *buffptr, unsigned char *data,
|
static int
|
||||||
size_t length)
|
add_to_buffer(struct buffer_s *buffptr, unsigned char *data, size_t length)
|
||||||
{
|
{
|
||||||
struct bufline_s *newline;
|
struct bufline_s *newline;
|
||||||
|
|
||||||
@ -158,7 +162,8 @@ static int add_to_buffer(struct buffer_s *buffptr, unsigned char *data,
|
|||||||
/*
|
/*
|
||||||
* Remove the first line from the top of the buffer
|
* Remove the first line from the top of the buffer
|
||||||
*/
|
*/
|
||||||
static struct bufline_s *remove_from_buffer(struct buffer_s *buffptr)
|
static struct bufline_s *
|
||||||
|
remove_from_buffer(struct buffer_s *buffptr)
|
||||||
{
|
{
|
||||||
struct bufline_s *line;
|
struct bufline_s *line;
|
||||||
|
|
||||||
@ -178,7 +183,8 @@ static struct bufline_s *remove_from_buffer(struct buffer_s *buffptr)
|
|||||||
* Takes a connection and returns the number of bytes read.
|
* Takes a connection and returns the number of bytes read.
|
||||||
*/
|
*/
|
||||||
#define READ_BUFFER_SIZE (1024 * 2)
|
#define READ_BUFFER_SIZE (1024 * 2)
|
||||||
ssize_t readbuff(int fd, struct buffer_s *buffptr)
|
ssize_t
|
||||||
|
readbuff(int fd, struct buffer_s * buffptr)
|
||||||
{
|
{
|
||||||
ssize_t bytesin;
|
ssize_t bytesin;
|
||||||
unsigned char *buffer;
|
unsigned char *buffer;
|
||||||
@ -204,7 +210,8 @@ ssize_t readbuff(int fd, struct buffer_s *buffptr)
|
|||||||
}
|
}
|
||||||
|
|
||||||
if (add_to_buffer(buffptr, newbuffer, bytesin) < 0) {
|
if (add_to_buffer(buffptr, newbuffer, bytesin) < 0) {
|
||||||
log_message(LOG_ERR, "readbuff: add_to_buffer() error.");
|
log_message(LOG_ERR,
|
||||||
|
"readbuff: add_to_buffer() error.");
|
||||||
return -1;
|
return -1;
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -226,7 +233,9 @@ ssize_t readbuff(int fd, struct buffer_s *buffptr)
|
|||||||
case EINTR:
|
case EINTR:
|
||||||
return 0;
|
return 0;
|
||||||
default:
|
default:
|
||||||
log_message(LOG_ERR, "readbuff: recv() error \"%s\" on file descriptor %d", strerror(errno), fd);
|
log_message(LOG_ERR,
|
||||||
|
"readbuff: recv() error \"%s\" on file descriptor %d",
|
||||||
|
strerror(errno), fd);
|
||||||
return -1;
|
return -1;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@ -237,7 +246,8 @@ ssize_t readbuff(int fd, struct buffer_s *buffptr)
|
|||||||
* Write the bytes in the buffer to the socket.
|
* Write the bytes in the buffer to the socket.
|
||||||
* Takes a connection and returns the number of bytes written.
|
* Takes a connection and returns the number of bytes written.
|
||||||
*/
|
*/
|
||||||
ssize_t writebuff(int fd, struct buffer_s *buffptr)
|
ssize_t
|
||||||
|
writebuff(int fd, struct buffer_s * buffptr)
|
||||||
{
|
{
|
||||||
ssize_t bytessent;
|
ssize_t bytessent;
|
||||||
struct bufline_s *line;
|
struct bufline_s *line;
|
||||||
@ -252,7 +262,8 @@ ssize_t writebuff(int fd, struct buffer_s *buffptr)
|
|||||||
assert(BUFFER_HEAD(buffptr) != NULL);
|
assert(BUFFER_HEAD(buffptr) != NULL);
|
||||||
|
|
||||||
line = BUFFER_HEAD(buffptr);
|
line = BUFFER_HEAD(buffptr);
|
||||||
bytessent = write(fd, line->string + line->pos, line->length - line->pos);
|
bytessent =
|
||||||
|
write(fd, line->string + line->pos, line->length - line->pos);
|
||||||
|
|
||||||
if (bytessent >= 0) {
|
if (bytessent >= 0) {
|
||||||
/* bytes sent, adjust buffer */
|
/* bytes sent, adjust buffer */
|
||||||
@ -273,10 +284,14 @@ ssize_t writebuff(int fd, struct buffer_s *buffptr)
|
|||||||
return 0;
|
return 0;
|
||||||
case ENOBUFS:
|
case ENOBUFS:
|
||||||
case ENOMEM:
|
case ENOMEM:
|
||||||
log_message(LOG_ERR, "writebuff: write() error [NOBUFS/NOMEM] \"%s\" on file descriptor %d", strerror(errno), fd);
|
log_message(LOG_ERR,
|
||||||
|
"writebuff: write() error [NOBUFS/NOMEM] \"%s\" on file descriptor %d",
|
||||||
|
strerror(errno), fd);
|
||||||
return 0;
|
return 0;
|
||||||
default:
|
default:
|
||||||
log_message(LOG_ERR, "writebuff: write() error \"%s\" on file descriptor %d", strerror(errno), fd);
|
log_message(LOG_ERR,
|
||||||
|
"writebuff: write() error \"%s\" on file descriptor %d",
|
||||||
|
strerror(errno), fd);
|
||||||
return -1;
|
return -1;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -1,4 +1,4 @@
|
|||||||
/* $Id: buffer.h,v 1.5 2001-11-05 15:23:05 rjkaes Exp $
|
/* $Id: buffer.h,v 1.6 2001-11-22 00:31:10 rjkaes Exp $
|
||||||
*
|
*
|
||||||
* See 'buffer.c' for a detailed description.
|
* See 'buffer.c' for a detailed description.
|
||||||
*
|
*
|
||||||
@ -25,7 +25,7 @@
|
|||||||
struct buffer_s {
|
struct buffer_s {
|
||||||
struct bufline_s *head; /* top of the buffer */
|
struct bufline_s *head; /* top of the buffer */
|
||||||
struct bufline_s *tail; /* bottom of the buffer */
|
struct bufline_s *tail; /* bottom of the buffer */
|
||||||
size_t size; /* total size of the buffer */
|
size_t size; /* total size of the buffer */
|
||||||
};
|
};
|
||||||
|
|
||||||
/*
|
/*
|
||||||
|
@ -1,4 +1,4 @@
|
|||||||
/* $Id: conns.c,v 1.4 2001-11-21 01:00:08 rjkaes Exp $
|
/* $Id: conns.c,v 1.5 2001-11-22 00:31:10 rjkaes Exp $
|
||||||
*
|
*
|
||||||
* Create and free the connection structure. One day there could be
|
* Create and free the connection structure. One day there could be
|
||||||
* other connnection related tasks put here, but for now the header
|
* other connnection related tasks put here, but for now the header
|
||||||
@ -25,7 +25,8 @@
|
|||||||
#include "stats.h"
|
#include "stats.h"
|
||||||
#include "utils.h"
|
#include "utils.h"
|
||||||
|
|
||||||
void initialize_conn(struct conn_s *connptr)
|
void
|
||||||
|
initialize_conn(struct conn_s *connptr)
|
||||||
{
|
{
|
||||||
connptr->client_fd = connptr->server_fd = -1;
|
connptr->client_fd = connptr->server_fd = -1;
|
||||||
connptr->cbuffer = new_buffer();
|
connptr->cbuffer = new_buffer();
|
||||||
@ -42,7 +43,8 @@ void initialize_conn(struct conn_s *connptr)
|
|||||||
update_stats(STAT_OPEN);
|
update_stats(STAT_OPEN);
|
||||||
}
|
}
|
||||||
|
|
||||||
void destroy_conn(struct conn_s *connptr)
|
void
|
||||||
|
destroy_conn(struct conn_s *connptr)
|
||||||
{
|
{
|
||||||
if (connptr->client_fd != -1)
|
if (connptr->client_fd != -1)
|
||||||
close(connptr->client_fd);
|
close(connptr->client_fd);
|
||||||
|
@ -1,4 +1,4 @@
|
|||||||
/* $Id: dnscache.c,v 1.17 2001-10-25 17:27:39 rjkaes Exp $
|
/* $Id: dnscache.c,v 1.18 2001-11-22 00:31:10 rjkaes Exp $
|
||||||
*
|
*
|
||||||
* This is a caching DNS system. When a host name is needed we look it up here
|
* This is a caching DNS system. When a host name is needed we look it up here
|
||||||
* and see if there is already an answer for it. The domains are placed in a
|
* and see if there is already an answer for it. The domains are placed in a
|
||||||
@ -36,7 +36,7 @@ static pthread_mutex_t mutex = PTHREAD_MUTEX_INITIALIZER;
|
|||||||
#define UNLOCK() pthread_mutex_unlock(&mutex);
|
#define UNLOCK() pthread_mutex_unlock(&mutex);
|
||||||
|
|
||||||
#define DNSEXPIRE (5 * 60)
|
#define DNSEXPIRE (5 * 60)
|
||||||
#define DNS_INSERT_LIMIT 10000 /* free the memory after inserts */
|
#define DNS_INSERT_LIMIT 10000 /* free the memory after inserts */
|
||||||
|
|
||||||
struct dnscache_s {
|
struct dnscache_s {
|
||||||
struct in_addr ipaddr;
|
struct in_addr ipaddr;
|
||||||
@ -46,7 +46,8 @@ struct dnscache_s {
|
|||||||
static TERNARY dns_tree = -1;
|
static TERNARY dns_tree = -1;
|
||||||
static unsigned int dns_insertions;
|
static unsigned int dns_insertions;
|
||||||
|
|
||||||
static int dns_lookup(struct in_addr *addr, char *domain)
|
static int
|
||||||
|
dns_lookup(struct in_addr *addr, char *domain)
|
||||||
{
|
{
|
||||||
int ret;
|
int ret;
|
||||||
struct dnscache_s *ptr;
|
struct dnscache_s *ptr;
|
||||||
@ -54,7 +55,7 @@ static int dns_lookup(struct in_addr *addr, char *domain)
|
|||||||
assert(addr != NULL);
|
assert(addr != NULL);
|
||||||
assert(domain != NULL);
|
assert(domain != NULL);
|
||||||
|
|
||||||
ret = ternary_search(dns_tree, domain, (void *)&ptr);
|
ret = ternary_search(dns_tree, domain, (void *) &ptr);
|
||||||
|
|
||||||
if (TE_ISERROR(ret)
|
if (TE_ISERROR(ret)
|
||||||
|| difftime(time(NULL), ptr->expire) > DNSEXPIRE) {
|
|| difftime(time(NULL), ptr->expire) > DNSEXPIRE) {
|
||||||
@ -66,7 +67,8 @@ static int dns_lookup(struct in_addr *addr, char *domain)
|
|||||||
return 0;
|
return 0;
|
||||||
}
|
}
|
||||||
|
|
||||||
static int dns_insert(struct in_addr *addr, char *domain)
|
static int
|
||||||
|
dns_insert(struct in_addr *addr, char *domain)
|
||||||
{
|
{
|
||||||
struct dnscache_s *newptr;
|
struct dnscache_s *newptr;
|
||||||
|
|
||||||
@ -92,7 +94,8 @@ static int dns_insert(struct in_addr *addr, char *domain)
|
|||||||
return 0;
|
return 0;
|
||||||
}
|
}
|
||||||
|
|
||||||
int dnscache(struct in_addr *addr, char *domain)
|
int
|
||||||
|
dnscache(struct in_addr *addr, char *domain)
|
||||||
{
|
{
|
||||||
struct hostent *resolv;
|
struct hostent *resolv;
|
||||||
|
|
||||||
@ -107,7 +110,7 @@ int dnscache(struct in_addr *addr, char *domain)
|
|||||||
dns_insertions = 0;
|
dns_insertions = 0;
|
||||||
}
|
}
|
||||||
|
|
||||||
if (inet_aton(domain, (struct in_addr *)addr) != 0) {
|
if (inet_aton(domain, (struct in_addr *) addr) != 0) {
|
||||||
UNLOCK();
|
UNLOCK();
|
||||||
return 0;
|
return 0;
|
||||||
}
|
}
|
||||||
@ -130,7 +133,9 @@ int dnscache(struct in_addr *addr, char *domain)
|
|||||||
|
|
||||||
dns_insertions++;
|
dns_insertions++;
|
||||||
if (dns_insertions > DNS_INSERT_LIMIT) {
|
if (dns_insertions > DNS_INSERT_LIMIT) {
|
||||||
log_message(LOG_INFO, "DNS Insertion limit reached (%u). Rebuilding cache.", dns_insertions);
|
log_message(LOG_INFO,
|
||||||
|
"DNS Insertion limit reached (%u). Rebuilding cache.",
|
||||||
|
dns_insertions);
|
||||||
ternary_destroy(dns_tree, free);
|
ternary_destroy(dns_tree, free);
|
||||||
dns_tree = ternary_new();
|
dns_tree = ternary_new();
|
||||||
dns_insertions = 0;
|
dns_insertions = 0;
|
||||||
|
31
src/filter.c
31
src/filter.c
@ -1,4 +1,4 @@
|
|||||||
/* $Id: filter.c,v 1.7 2001-10-25 17:27:39 rjkaes Exp $
|
/* $Id: filter.c,v 1.8 2001-11-22 00:31:10 rjkaes Exp $
|
||||||
*
|
*
|
||||||
* Copyright (c) 1999 George Talusan (gstalusan@uwaterloo.ca)
|
* Copyright (c) 1999 George Talusan (gstalusan@uwaterloo.ca)
|
||||||
*
|
*
|
||||||
@ -30,12 +30,12 @@ struct filter_list {
|
|||||||
regex_t *cpat;
|
regex_t *cpat;
|
||||||
};
|
};
|
||||||
|
|
||||||
|
|
||||||
static struct filter_list *fl = NULL;
|
static struct filter_list *fl = NULL;
|
||||||
static int already_init = 0;
|
static int already_init = 0;
|
||||||
|
|
||||||
/* initializes a linked list of strings containing hosts to be filtered */
|
/* initializes a linked list of strings containing hosts to be filtered */
|
||||||
void filter_init(void)
|
void
|
||||||
|
filter_init(void)
|
||||||
{
|
{
|
||||||
FILE *fd;
|
FILE *fd;
|
||||||
struct filter_list *p;
|
struct filter_list *p;
|
||||||
@ -50,22 +50,29 @@ void filter_init(void)
|
|||||||
while (fgets(buf, 255, fd)) {
|
while (fgets(buf, 255, fd)) {
|
||||||
s = buf;
|
s = buf;
|
||||||
if (!p) /* head of list */
|
if (!p) /* head of list */
|
||||||
fl = p = safecalloc(1, sizeof(struct filter_list));
|
fl = p =
|
||||||
|
safecalloc(1,
|
||||||
|
sizeof(struct
|
||||||
|
filter_list));
|
||||||
else { /* next entry */
|
else { /* next entry */
|
||||||
p->next = safecalloc(1, sizeof(struct filter_list));
|
p->next =
|
||||||
|
safecalloc(1,
|
||||||
|
sizeof(struct
|
||||||
|
filter_list));
|
||||||
p = p->next;
|
p = p->next;
|
||||||
}
|
}
|
||||||
|
|
||||||
/* replace first whitespace with \0 */
|
/* replace first whitespace with \0 */
|
||||||
while (*s++)
|
while (*s++)
|
||||||
if (isspace((unsigned char)*s))
|
if (isspace((unsigned char) *s))
|
||||||
*s = '\0';
|
*s = '\0';
|
||||||
|
|
||||||
p->pat = strdup(buf);
|
p->pat = strdup(buf);
|
||||||
p->cpat = safemalloc(sizeof(regex_t));
|
p->cpat = safemalloc(sizeof(regex_t));
|
||||||
if ((err = regcomp(p->cpat, p->pat, REG_NEWLINE | REG_NOSUB)) != 0) {
|
if ((err =
|
||||||
fprintf(stderr,
|
regcomp(p->cpat, p->pat,
|
||||||
"Bad regex in %s: %s\n",
|
REG_NEWLINE | REG_NOSUB)) != 0) {
|
||||||
|
fprintf(stderr, "Bad regex in %s: %s\n",
|
||||||
config.filter, p->pat);
|
config.filter, p->pat);
|
||||||
exit(EX_DATAERR);
|
exit(EX_DATAERR);
|
||||||
}
|
}
|
||||||
@ -77,7 +84,8 @@ void filter_init(void)
|
|||||||
}
|
}
|
||||||
|
|
||||||
/* unlink the list */
|
/* unlink the list */
|
||||||
void filter_destroy(void)
|
void
|
||||||
|
filter_destroy(void)
|
||||||
{
|
{
|
||||||
struct filter_list *p, *q;
|
struct filter_list *p, *q;
|
||||||
|
|
||||||
@ -95,7 +103,8 @@ void filter_destroy(void)
|
|||||||
}
|
}
|
||||||
|
|
||||||
/* returns 0 if host is not an element of filter list, non-zero otherwise */
|
/* returns 0 if host is not an element of filter list, non-zero otherwise */
|
||||||
int filter_url(char *host)
|
int
|
||||||
|
filter_url(char *host)
|
||||||
{
|
{
|
||||||
struct filter_list *p;
|
struct filter_list *p;
|
||||||
char *s, *port;
|
char *s, *port;
|
||||||
|
15
src/log.c
15
src/log.c
@ -1,4 +1,4 @@
|
|||||||
/* $Id: log.c,v 1.15 2001-10-25 17:27:39 rjkaes Exp $
|
/* $Id: log.c,v 1.16 2001-11-22 00:31:10 rjkaes Exp $
|
||||||
*
|
*
|
||||||
* Logs the various messages which tinyproxy produces to either a log file or
|
* Logs the various messages which tinyproxy produces to either a log file or
|
||||||
* the syslog daemon. Not much to it...
|
* the syslog daemon. Not much to it...
|
||||||
@ -44,7 +44,8 @@ static short int log_level = LOG_ERR;
|
|||||||
/*
|
/*
|
||||||
* Set the log level for writing to the log file.
|
* Set the log level for writing to the log file.
|
||||||
*/
|
*/
|
||||||
void set_log_level(short int level)
|
void
|
||||||
|
set_log_level(short int level)
|
||||||
{
|
{
|
||||||
log_level = level;
|
log_level = level;
|
||||||
}
|
}
|
||||||
@ -52,7 +53,8 @@ void set_log_level(short int level)
|
|||||||
/*
|
/*
|
||||||
* This routine logs messages to either the log file or the syslog function.
|
* This routine logs messages to either the log file or the syslog function.
|
||||||
*/
|
*/
|
||||||
void log_message(short int level, char *fmt, ...)
|
void
|
||||||
|
log_message(short int level, char *fmt, ...)
|
||||||
{
|
{
|
||||||
va_list args;
|
va_list args;
|
||||||
time_t nowtime;
|
time_t nowtime;
|
||||||
@ -74,12 +76,11 @@ void log_message(short int level, char *fmt, ...)
|
|||||||
if (level > LOG_INFO && level != LOG_CONN)
|
if (level > LOG_INFO && level != LOG_CONN)
|
||||||
return;
|
return;
|
||||||
} else if (level > log_level)
|
} else if (level > log_level)
|
||||||
return;
|
return;
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
|
|
||||||
#ifdef HAVE_SYSLOG_H
|
#ifdef HAVE_SYSLOG_H
|
||||||
if (config.syslog && level == LOG_CONN)
|
if (config.syslog && level == LOG_CONN)
|
||||||
level = LOG_INFO;
|
level = LOG_INFO;
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
@ -104,7 +105,7 @@ void log_message(short int level, char *fmt, ...)
|
|||||||
cf = stderr;
|
cf = stderr;
|
||||||
|
|
||||||
fprintf(cf, "%-9s %s [%ld]: ", syslog_level[level],
|
fprintf(cf, "%-9s %s [%ld]: ", syslog_level[level],
|
||||||
time_string, (long int)getpid());
|
time_string, (long int) getpid());
|
||||||
vfprintf(cf, fmt, args);
|
vfprintf(cf, fmt, args);
|
||||||
fprintf(cf, "\n");
|
fprintf(cf, "\n");
|
||||||
fflush(cf);
|
fflush(cf);
|
||||||
|
@ -1,4 +1,4 @@
|
|||||||
/* $Id: log.h,v 1.7 2001-08-26 21:10:04 rjkaes Exp $
|
/* $Id: log.h,v 1.8 2001-11-22 00:31:10 rjkaes Exp $
|
||||||
*
|
*
|
||||||
* See 'log.c' for a detailed description.
|
* See 'log.c' for a detailed description.
|
||||||
*
|
*
|
||||||
@ -84,7 +84,7 @@
|
|||||||
# define LOG_DEBUG 7
|
# define LOG_DEBUG 7
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
#define LOG_CONN 8 /* extra to log connections without the INFO stuff */
|
#define LOG_CONN 8 /* extra to log connections without the INFO stuff */
|
||||||
|
|
||||||
/*
|
/*
|
||||||
* Use this for debugging. The format is specific:
|
* Use this for debugging. The format is specific:
|
||||||
|
254
src/reqs.c
254
src/reqs.c
@ -1,4 +1,4 @@
|
|||||||
/* $Id: reqs.c,v 1.40 2001-11-22 00:19:45 rjkaes Exp $
|
/* $Id: reqs.c,v 1.41 2001-11-22 00:31:10 rjkaes Exp $
|
||||||
*
|
*
|
||||||
* This is where all the work in tinyproxy is actually done. Incoming
|
* This is where all the work in tinyproxy is actually done. Incoming
|
||||||
* connections have a new thread created for them. The thread then
|
* connections have a new thread created for them. The thread then
|
||||||
@ -46,7 +46,8 @@
|
|||||||
/*
|
/*
|
||||||
* Remove any new lines or carriage returns from the end of a string.
|
* Remove any new lines or carriage returns from the end of a string.
|
||||||
*/
|
*/
|
||||||
static inline void trim(char *string, unsigned int len)
|
static inline void
|
||||||
|
trim(char *string, unsigned int len)
|
||||||
{
|
{
|
||||||
char *ptr;
|
char *ptr;
|
||||||
|
|
||||||
@ -71,14 +72,17 @@ static inline void trim(char *string, unsigned int len)
|
|||||||
* connections. The request line is allocated from the heap, but it must
|
* connections. The request line is allocated from the heap, but it must
|
||||||
* be freed in another function.
|
* be freed in another function.
|
||||||
*/
|
*/
|
||||||
static char *read_request_line(struct conn_s *connptr)
|
static char *
|
||||||
|
read_request_line(struct conn_s *connptr)
|
||||||
{
|
{
|
||||||
char *request_buffer;
|
char *request_buffer;
|
||||||
size_t len;
|
size_t len;
|
||||||
|
|
||||||
len = readline(connptr->client_fd, &request_buffer);
|
len = readline(connptr->client_fd, &request_buffer);
|
||||||
if (len <= 0) {
|
if (len <= 0) {
|
||||||
log_message(LOG_ERR, "read_request_line: Client (file descriptor: %d) closed socket before read.", connptr->client_fd);
|
log_message(LOG_ERR,
|
||||||
|
"read_request_line: Client (file descriptor: %d) closed socket before read.",
|
||||||
|
connptr->client_fd);
|
||||||
safefree(request_buffer);
|
safefree(request_buffer);
|
||||||
return NULL;
|
return NULL;
|
||||||
}
|
}
|
||||||
@ -106,7 +110,8 @@ struct request_s {
|
|||||||
int port;
|
int port;
|
||||||
};
|
};
|
||||||
|
|
||||||
static void free_request_struct(struct request_s *request)
|
static void
|
||||||
|
free_request_struct(struct request_s *request)
|
||||||
{
|
{
|
||||||
if (!request)
|
if (!request)
|
||||||
return;
|
return;
|
||||||
@ -123,7 +128,8 @@ static void free_request_struct(struct request_s *request)
|
|||||||
/*
|
/*
|
||||||
* Pull the information out of the URL line.
|
* Pull the information out of the URL line.
|
||||||
*/
|
*/
|
||||||
static int extract_http_url(const char *url, struct request_s *request)
|
static int
|
||||||
|
extract_http_url(const char *url, struct request_s *request)
|
||||||
{
|
{
|
||||||
request->host = safemalloc(strlen(url) + 1);
|
request->host = safemalloc(strlen(url) + 1);
|
||||||
request->path = safemalloc(strlen(url) + 1);
|
request->path = safemalloc(strlen(url) + 1);
|
||||||
@ -135,11 +141,14 @@ static int extract_http_url(const char *url, struct request_s *request)
|
|||||||
return -1;
|
return -1;
|
||||||
}
|
}
|
||||||
|
|
||||||
if (sscanf(url, "http://%[^:/]:%d%s", request->host, &request->port, request->path) == 3)
|
if (sscanf
|
||||||
;
|
(url, "http://%[^:/]:%d%s", request->host, &request->port,
|
||||||
else if (sscanf(url, "http://%[^/]%s", request->host, request->path) == 2)
|
request->path) == 3) ;
|
||||||
|
else if (sscanf(url, "http://%[^/]%s", request->host, request->path) ==
|
||||||
|
2)
|
||||||
request->port = 80;
|
request->port = 80;
|
||||||
else if (sscanf(url, "http://%[^:/]:%d", request->host, &request->port) == 2)
|
else if (sscanf(url, "http://%[^:/]:%d", request->host, &request->port)
|
||||||
|
== 2)
|
||||||
strcpy(request->path, "/");
|
strcpy(request->path, "/");
|
||||||
else if (sscanf(url, "http://%[^/]", request->host) == 1) {
|
else if (sscanf(url, "http://%[^/]", request->host) == 1) {
|
||||||
request->port = 80;
|
request->port = 80;
|
||||||
@ -149,7 +158,7 @@ static int extract_http_url(const char *url, struct request_s *request)
|
|||||||
|
|
||||||
safefree(request->host);
|
safefree(request->host);
|
||||||
safefree(request->path);
|
safefree(request->path);
|
||||||
|
|
||||||
return -1;
|
return -1;
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -159,14 +168,14 @@ static int extract_http_url(const char *url, struct request_s *request)
|
|||||||
/*
|
/*
|
||||||
* Extract the URL from a SSL connection.
|
* Extract the URL from a SSL connection.
|
||||||
*/
|
*/
|
||||||
static int extract_ssl_url(const char *url, struct request_s *request)
|
static int
|
||||||
|
extract_ssl_url(const char *url, struct request_s *request)
|
||||||
{
|
{
|
||||||
request->host = safemalloc(strlen(url) + 1);
|
request->host = safemalloc(strlen(url) + 1);
|
||||||
if (!request->host)
|
if (!request->host)
|
||||||
return -1;
|
return -1;
|
||||||
|
|
||||||
if (sscanf(url, "%[^:]:%d", request->host, &request->port) == 2)
|
if (sscanf(url, "%[^:]:%d", request->host, &request->port) == 2) ;
|
||||||
;
|
|
||||||
else if (sscanf(url, "%s", request->host) == 1)
|
else if (sscanf(url, "%s", request->host) == 1)
|
||||||
request->port = 443;
|
request->port = 443;
|
||||||
else {
|
else {
|
||||||
@ -182,17 +191,19 @@ static int extract_ssl_url(const char *url, struct request_s *request)
|
|||||||
/*
|
/*
|
||||||
* Create a connection for HTTP connections.
|
* Create a connection for HTTP connections.
|
||||||
*/
|
*/
|
||||||
static int establish_http_connection(struct conn_s *connptr,
|
static int
|
||||||
struct request_s *request)
|
establish_http_connection(struct conn_s *connptr, struct request_s *request)
|
||||||
{
|
{
|
||||||
/*
|
/*
|
||||||
* Send the request line
|
* Send the request line
|
||||||
*/
|
*/
|
||||||
if (safe_write(connptr->server_fd, request->method, strlen(request->method)) < 0)
|
if (safe_write
|
||||||
|
(connptr->server_fd, request->method, strlen(request->method)) < 0)
|
||||||
return -1;
|
return -1;
|
||||||
if (safe_write(connptr->server_fd, " ", 1) < 0)
|
if (safe_write(connptr->server_fd, " ", 1) < 0)
|
||||||
return -1;
|
return -1;
|
||||||
if (safe_write(connptr->server_fd, request->path, strlen(request->path)) < 0)
|
if (safe_write(connptr->server_fd, request->path, strlen(request->path))
|
||||||
|
< 0)
|
||||||
return -1;
|
return -1;
|
||||||
if (safe_write(connptr->server_fd, " ", 1) < 0)
|
if (safe_write(connptr->server_fd, " ", 1) < 0)
|
||||||
return -1;
|
return -1;
|
||||||
@ -204,7 +215,8 @@ static int establish_http_connection(struct conn_s *connptr,
|
|||||||
*/
|
*/
|
||||||
if (safe_write(connptr->server_fd, "Host: ", 6) < 0)
|
if (safe_write(connptr->server_fd, "Host: ", 6) < 0)
|
||||||
return -1;
|
return -1;
|
||||||
if (safe_write(connptr->server_fd, request->host, strlen(request->host)) < 0)
|
if (safe_write(connptr->server_fd, request->host, strlen(request->host))
|
||||||
|
< 0)
|
||||||
return -1;
|
return -1;
|
||||||
|
|
||||||
if (safe_write(connptr->server_fd, "\r\n", 2) < 0)
|
if (safe_write(connptr->server_fd, "\r\n", 2) < 0)
|
||||||
@ -230,12 +242,16 @@ static int establish_http_connection(struct conn_s *connptr,
|
|||||||
* Send the appropriate response to the client to establish a SSL
|
* Send the appropriate response to the client to establish a SSL
|
||||||
* connection.
|
* connection.
|
||||||
*/
|
*/
|
||||||
static inline int send_ssl_response(struct conn_s *connptr)
|
static inline int
|
||||||
|
send_ssl_response(struct conn_s *connptr)
|
||||||
{
|
{
|
||||||
if (safe_write(connptr->client_fd, SSL_CONNECTION_RESPONSE, strlen(SSL_CONNECTION_RESPONSE)) < 0)
|
if (safe_write
|
||||||
|
(connptr->client_fd, SSL_CONNECTION_RESPONSE,
|
||||||
|
strlen(SSL_CONNECTION_RESPONSE)) < 0)
|
||||||
return -1;
|
return -1;
|
||||||
|
|
||||||
if (safe_write(connptr->client_fd, PROXY_AGENT, strlen(PROXY_AGENT)) < 0)
|
if (safe_write(connptr->client_fd, PROXY_AGENT, strlen(PROXY_AGENT)) <
|
||||||
|
0)
|
||||||
return -1;
|
return -1;
|
||||||
|
|
||||||
if (safe_write(connptr->client_fd, "\r\n", 2) < 0)
|
if (safe_write(connptr->client_fd, "\r\n", 2) < 0)
|
||||||
@ -248,8 +264,8 @@ static inline int send_ssl_response(struct conn_s *connptr)
|
|||||||
* Break the request line apart and figure out where to connect and
|
* Break the request line apart and figure out where to connect and
|
||||||
* build a new request line. Finally connect to the remote server.
|
* build a new request line. Finally connect to the remote server.
|
||||||
*/
|
*/
|
||||||
static struct request_s *process_request(struct conn_s *connptr,
|
static struct request_s *
|
||||||
char *request_line)
|
process_request(struct conn_s *connptr, char *request_line)
|
||||||
{
|
{
|
||||||
char *url;
|
char *url;
|
||||||
struct request_s *request;
|
struct request_s *request;
|
||||||
@ -276,9 +292,13 @@ static struct request_s *process_request(struct conn_s *connptr,
|
|||||||
return NULL;
|
return NULL;
|
||||||
}
|
}
|
||||||
|
|
||||||
ret = sscanf(request_line, "%[^ ] %[^ ] %[^ ]", request->method, url, request->protocol);
|
ret =
|
||||||
|
sscanf(request_line, "%[^ ] %[^ ] %[^ ]", request->method, url,
|
||||||
|
request->protocol);
|
||||||
if (ret < 2) {
|
if (ret < 2) {
|
||||||
log_message(LOG_ERR, "process_request: Bad Request on file descriptor %d", connptr->client_fd);
|
log_message(LOG_ERR,
|
||||||
|
"process_request: Bad Request on file descriptor %d",
|
||||||
|
connptr->client_fd);
|
||||||
httperr(connptr, 400, "Bad Request. No request found.");
|
httperr(connptr, 400, "Bad Request. No request found.");
|
||||||
|
|
||||||
safefree(url);
|
safefree(url);
|
||||||
@ -290,7 +310,9 @@ static struct request_s *process_request(struct conn_s *connptr,
|
|||||||
}
|
}
|
||||||
|
|
||||||
if (!url) {
|
if (!url) {
|
||||||
log_message(LOG_ERR, "process_request: Null URL on file descriptor %d", connptr->client_fd);
|
log_message(LOG_ERR,
|
||||||
|
"process_request: Null URL on file descriptor %d",
|
||||||
|
connptr->client_fd);
|
||||||
httperr(connptr, 400, "Bad Request. Null URL.");
|
httperr(connptr, 400, "Bad Request. Null URL.");
|
||||||
|
|
||||||
safefree(url);
|
safefree(url);
|
||||||
@ -304,8 +326,9 @@ static struct request_s *process_request(struct conn_s *connptr,
|
|||||||
memcpy(url, "http", 4);
|
memcpy(url, "http", 4);
|
||||||
|
|
||||||
if (extract_http_url(url, request) < 0) {
|
if (extract_http_url(url, request) < 0) {
|
||||||
httperr(connptr, 400, "Bad Request. Could not parse URL.");
|
httperr(connptr, 400,
|
||||||
|
"Bad Request. Could not parse URL.");
|
||||||
|
|
||||||
safefree(url);
|
safefree(url);
|
||||||
free_request_struct(request);
|
free_request_struct(request);
|
||||||
|
|
||||||
@ -314,7 +337,8 @@ static struct request_s *process_request(struct conn_s *connptr,
|
|||||||
connptr->ssl = FALSE;
|
connptr->ssl = FALSE;
|
||||||
} else if (strcmp(request->method, "CONNECT") == 0) {
|
} else if (strcmp(request->method, "CONNECT") == 0) {
|
||||||
if (extract_ssl_url(url, request) < 0) {
|
if (extract_ssl_url(url, request) < 0) {
|
||||||
httperr(connptr, 400, "Bad Request. Could not parse URL.");
|
httperr(connptr, 400,
|
||||||
|
"Bad Request. Could not parse URL.");
|
||||||
|
|
||||||
safefree(url);
|
safefree(url);
|
||||||
free_request_struct(request);
|
free_request_struct(request);
|
||||||
@ -323,7 +347,9 @@ static struct request_s *process_request(struct conn_s *connptr,
|
|||||||
}
|
}
|
||||||
connptr->ssl = TRUE;
|
connptr->ssl = TRUE;
|
||||||
} else {
|
} else {
|
||||||
log_message(LOG_ERR, "process_request: Unknown URL type on file descriptor %d", connptr->client_fd);
|
log_message(LOG_ERR,
|
||||||
|
"process_request: Unknown URL type on file descriptor %d",
|
||||||
|
connptr->client_fd);
|
||||||
httperr(connptr, 400, "Bad Request. Unknown URL type.");
|
httperr(connptr, 400, "Bad Request. Unknown URL type.");
|
||||||
|
|
||||||
safefree(url);
|
safefree(url);
|
||||||
@ -342,8 +368,11 @@ static struct request_s *process_request(struct conn_s *connptr,
|
|||||||
if (filter_url(request->host)) {
|
if (filter_url(request->host)) {
|
||||||
update_stats(STAT_DENIED);
|
update_stats(STAT_DENIED);
|
||||||
|
|
||||||
log_message(LOG_NOTICE, "Proxying refused on filtered domain \"%s\"", request->host);
|
log_message(LOG_NOTICE,
|
||||||
httperr(connptr, 404, "Connection to filtered domain is now allowed.");
|
"Proxying refused on filtered domain \"%s\"",
|
||||||
|
request->host);
|
||||||
|
httperr(connptr, 404,
|
||||||
|
"Connection to filtered domain is now allowed.");
|
||||||
|
|
||||||
free_request_struct(request);
|
free_request_struct(request);
|
||||||
|
|
||||||
@ -369,7 +398,8 @@ static struct request_s *process_request(struct conn_s *connptr,
|
|||||||
*/
|
*/
|
||||||
if (strncasecmp(request->protocol, "http", 4) == 0) {
|
if (strncasecmp(request->protocol, "http", 4) == 0) {
|
||||||
memcpy(request->protocol, "HTTP", 4);
|
memcpy(request->protocol, "HTTP", 4);
|
||||||
sscanf(request->protocol, "HTTP/%hu.%hu", &connptr->protocol.major, &connptr->protocol.minor);
|
sscanf(request->protocol, "HTTP/%hu.%hu",
|
||||||
|
&connptr->protocol.major, &connptr->protocol.minor);
|
||||||
}
|
}
|
||||||
|
|
||||||
return request;
|
return request;
|
||||||
@ -380,7 +410,8 @@ static struct request_s *process_request(struct conn_s *connptr,
|
|||||||
* headers which are to be allowed. If the header is found in the
|
* headers which are to be allowed. If the header is found in the
|
||||||
* anonymous list return 0, otherwise return -1.
|
* anonymous list return 0, otherwise return -1.
|
||||||
*/
|
*/
|
||||||
static int compare_header(char *line)
|
static int
|
||||||
|
compare_header(char *line)
|
||||||
{
|
{
|
||||||
char *buffer;
|
char *buffer;
|
||||||
char *ptr;
|
char *ptr;
|
||||||
@ -392,7 +423,7 @@ static int compare_header(char *line)
|
|||||||
if ((buffer = safemalloc(ptr - line + 1)) == NULL)
|
if ((buffer = safemalloc(ptr - line + 1)) == NULL)
|
||||||
return -1;
|
return -1;
|
||||||
|
|
||||||
memcpy(buffer, line, (size_t)(ptr - line));
|
memcpy(buffer, line, (size_t) (ptr - line));
|
||||||
buffer[ptr - line] = '\0';
|
buffer[ptr - line] = '\0';
|
||||||
|
|
||||||
ret = anonymous_search(buffer);
|
ret = anonymous_search(buffer);
|
||||||
@ -407,7 +438,8 @@ static int compare_header(char *line)
|
|||||||
* server headers can be processed.
|
* server headers can be processed.
|
||||||
* - rjkaes
|
* - rjkaes
|
||||||
*/
|
*/
|
||||||
static int pull_client_data(struct conn_s *connptr, unsigned long int length)
|
static int
|
||||||
|
pull_client_data(struct conn_s *connptr, unsigned long int length)
|
||||||
{
|
{
|
||||||
char *buffer;
|
char *buffer;
|
||||||
ssize_t len;
|
ssize_t len;
|
||||||
@ -417,7 +449,9 @@ static int pull_client_data(struct conn_s *connptr, unsigned long int length)
|
|||||||
return -1;
|
return -1;
|
||||||
|
|
||||||
do {
|
do {
|
||||||
len = safe_read(connptr->client_fd, buffer, min(MAXBUFFSIZE, length));
|
len =
|
||||||
|
safe_read(connptr->client_fd, buffer,
|
||||||
|
min(MAXBUFFSIZE, length));
|
||||||
|
|
||||||
if (len <= 0) {
|
if (len <= 0) {
|
||||||
safefree(buffer);
|
safefree(buffer);
|
||||||
@ -444,7 +478,8 @@ static int pull_client_data(struct conn_s *connptr, unsigned long int length)
|
|||||||
* the server.
|
* the server.
|
||||||
* -rjkaes
|
* -rjkaes
|
||||||
*/
|
*/
|
||||||
static int add_xtinyproxy_header(struct conn_s *connptr)
|
static int
|
||||||
|
add_xtinyproxy_header(struct conn_s *connptr)
|
||||||
{
|
{
|
||||||
char ipaddr[PEER_IP_LENGTH];
|
char ipaddr[PEER_IP_LENGTH];
|
||||||
char xtinyproxy[32];
|
char xtinyproxy[32];
|
||||||
@ -464,7 +499,7 @@ static int add_xtinyproxy_header(struct conn_s *connptr)
|
|||||||
|
|
||||||
return 0;
|
return 0;
|
||||||
}
|
}
|
||||||
#endif /* XTINYPROXY */
|
#endif /* XTINYPROXY */
|
||||||
|
|
||||||
/*
|
/*
|
||||||
* Here we loop through all the headers the client is sending. If we
|
* Here we loop through all the headers the client is sending. If we
|
||||||
@ -472,7 +507,8 @@ static int add_xtinyproxy_header(struct conn_s *connptr)
|
|||||||
* (plus a few which are required for various methods).
|
* (plus a few which are required for various methods).
|
||||||
* - rjkaes
|
* - rjkaes
|
||||||
*/
|
*/
|
||||||
static int process_client_headers(struct conn_s *connptr)
|
static int
|
||||||
|
process_client_headers(struct conn_s *connptr)
|
||||||
{
|
{
|
||||||
char *header;
|
char *header;
|
||||||
long content_length = -1;
|
long content_length = -1;
|
||||||
@ -490,9 +526,10 @@ static int process_client_headers(struct conn_s *connptr)
|
|||||||
};
|
};
|
||||||
int i;
|
int i;
|
||||||
|
|
||||||
for ( ; ; ) {
|
for (;;) {
|
||||||
if (readline(connptr->client_fd, &header) <= 0) {
|
if (readline(connptr->client_fd, &header) <= 0) {
|
||||||
DEBUG2("Client (file descriptor %d) closed connection.", connptr->client_fd);
|
DEBUG2("Client (file descriptor %d) closed connection.",
|
||||||
|
connptr->client_fd);
|
||||||
return -1;
|
return -1;
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -514,7 +551,6 @@ static int process_client_headers(struct conn_s *connptr)
|
|||||||
safefree(header);
|
safefree(header);
|
||||||
continue;
|
continue;
|
||||||
}
|
}
|
||||||
|
|
||||||
#if 0
|
#if 0
|
||||||
/*
|
/*
|
||||||
* If we find a Via header we need to append our information
|
* If we find a Via header we need to append our information
|
||||||
@ -527,19 +563,25 @@ static int process_client_headers(struct conn_s *connptr)
|
|||||||
sent_via_header = 1;
|
sent_via_header = 1;
|
||||||
|
|
||||||
gethostname(hostname, sizeof(hostname));
|
gethostname(hostname, sizeof(hostname));
|
||||||
snprintf(via_header_buffer, sizeof(via_header_buffer), ", %hu.%hu %s (%s/%s)\r\n", connptr->protocol.major, connptr->protocol.minor, hostname, PACKAGE, VERSION);
|
snprintf(via_header_buffer, sizeof(via_header_buffer),
|
||||||
|
", %hu.%hu %s (%s/%s)\r\n",
|
||||||
|
connptr->protocol.major,
|
||||||
|
connptr->protocol.minor, hostname, PACKAGE,
|
||||||
|
VERSION);
|
||||||
|
|
||||||
trim(header, strlen(header));
|
trim(header, strlen(header));
|
||||||
|
|
||||||
strlcat(header, via_header_buffer, LINE_LENGTH);
|
strlcat(header, via_header_buffer, LINE_LENGTH);
|
||||||
}
|
}
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
/*
|
/*
|
||||||
* Don't send certain headers.
|
* Don't send certain headers.
|
||||||
*/
|
*/
|
||||||
for (i = 0; i < (sizeof(skipheaders) / sizeof(char *)); i++) {
|
for (i = 0; i < (sizeof(skipheaders) / sizeof(char *)); i++) {
|
||||||
if (strncasecmp(header, skipheaders[i], strlen(skipheaders[i])) == 0) {
|
if (strncasecmp
|
||||||
|
(header, skipheaders[i],
|
||||||
|
strlen(skipheaders[i])) == 0) {
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@ -559,7 +601,9 @@ static int process_client_headers(struct conn_s *connptr)
|
|||||||
content_length = atol(content_ptr);
|
content_length = atol(content_ptr);
|
||||||
}
|
}
|
||||||
|
|
||||||
if ((connptr->server_fd != -1) && safe_write(connptr->server_fd, header, strlen(header)) < 0) {
|
if ((connptr->server_fd != -1)
|
||||||
|
&& safe_write(connptr->server_fd, header,
|
||||||
|
strlen(header)) < 0) {
|
||||||
safefree(header);
|
safefree(header);
|
||||||
return -1;
|
return -1;
|
||||||
}
|
}
|
||||||
@ -576,22 +620,26 @@ static int process_client_headers(struct conn_s *connptr)
|
|||||||
char hostname[128];
|
char hostname[128];
|
||||||
|
|
||||||
gethostname(hostname, sizeof(hostname));
|
gethostname(hostname, sizeof(hostname));
|
||||||
snprintf(via_header_buffer, sizeof(via_header_buffer), "Via: %hu.%hu %s (%s/%s)\r\n", connptr->protocol.major, connptr->protocol.minor, hostname, PACKAGE, VERSION);
|
snprintf(via_header_buffer, sizeof(via_header_buffer),
|
||||||
|
"Via: %hu.%hu %s (%s/%s)\r\n", connptr->protocol.major,
|
||||||
|
connptr->protocol.minor, hostname, PACKAGE, VERSION);
|
||||||
|
|
||||||
safe_write(connptr->server_fd, via_header_buffer, strlen(via_header_buffer));
|
safe_write(connptr->server_fd, via_header_buffer,
|
||||||
|
strlen(via_header_buffer));
|
||||||
}
|
}
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
if (!connptr->send_message && (connptr->upstream || !connptr->ssl)) {
|
if (!connptr->send_message && (connptr->upstream || !connptr->ssl)) {
|
||||||
#ifdef XTINYPROXY_ENABLE
|
#ifdef XTINYPROXY_ENABLE
|
||||||
if (config.my_domain
|
if (config.my_domain && add_xtinyproxy_header(connptr) < 0) {
|
||||||
&& add_xtinyproxy_header(connptr) < 0) {
|
|
||||||
safefree(header);
|
safefree(header);
|
||||||
return -1;
|
return -1;
|
||||||
}
|
}
|
||||||
#endif /* XTINYPROXY */
|
#endif /* XTINYPROXY */
|
||||||
|
|
||||||
if ((connptr->server_fd != -1) && safe_write(connptr->server_fd, header, strlen(header)) < 0) {
|
if ((connptr->server_fd != -1)
|
||||||
|
&& safe_write(connptr->server_fd, header,
|
||||||
|
strlen(header)) < 0) {
|
||||||
safefree(header);
|
safefree(header);
|
||||||
return -1;
|
return -1;
|
||||||
}
|
}
|
||||||
@ -603,7 +651,8 @@ static int process_client_headers(struct conn_s *connptr)
|
|||||||
* Spin here pulling the data from the client.
|
* Spin here pulling the data from the client.
|
||||||
*/
|
*/
|
||||||
if (content_length >= 0)
|
if (content_length >= 0)
|
||||||
return pull_client_data(connptr, (unsigned long int)content_length);
|
return pull_client_data(connptr,
|
||||||
|
(unsigned long int) content_length);
|
||||||
else
|
else
|
||||||
return 0;
|
return 0;
|
||||||
}
|
}
|
||||||
@ -612,13 +661,15 @@ static int process_client_headers(struct conn_s *connptr)
|
|||||||
* Loop through all the headers (including the response code) from the
|
* Loop through all the headers (including the response code) from the
|
||||||
* server.
|
* server.
|
||||||
*/
|
*/
|
||||||
static int process_server_headers(struct conn_s *connptr)
|
static int
|
||||||
|
process_server_headers(struct conn_s *connptr)
|
||||||
{
|
{
|
||||||
char *header;
|
char *header;
|
||||||
|
|
||||||
for ( ; ; ) {
|
for (;;) {
|
||||||
if (readline(connptr->server_fd, &header) <= 0) {
|
if (readline(connptr->server_fd, &header) <= 0) {
|
||||||
DEBUG2("Server (file descriptor %d) closed connection.", connptr->server_fd);
|
DEBUG2("Server (file descriptor %d) closed connection.",
|
||||||
|
connptr->server_fd);
|
||||||
return -1;
|
return -1;
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -628,12 +679,13 @@ static int process_server_headers(struct conn_s *connptr)
|
|||||||
}
|
}
|
||||||
|
|
||||||
if (!connptr->simple_req
|
if (!connptr->simple_req
|
||||||
&& safe_write(connptr->client_fd, header, strlen(header)) < 0) {
|
&& safe_write(connptr->client_fd, header,
|
||||||
|
strlen(header)) < 0) {
|
||||||
safefree(header);
|
safefree(header);
|
||||||
return -1;
|
return -1;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
if (!connptr->simple_req
|
if (!connptr->simple_req
|
||||||
&& safe_write(connptr->client_fd, header, strlen(header)) < 0) {
|
&& safe_write(connptr->client_fd, header, strlen(header)) < 0) {
|
||||||
safefree(header);
|
safefree(header);
|
||||||
@ -652,7 +704,8 @@ static int process_server_headers(struct conn_s *connptr)
|
|||||||
* tinyproxy oh so long ago...)
|
* tinyproxy oh so long ago...)
|
||||||
* - rjkaes
|
* - rjkaes
|
||||||
*/
|
*/
|
||||||
static void relay_connection(struct conn_s *connptr)
|
static void
|
||||||
|
relay_connection(struct conn_s *connptr)
|
||||||
{
|
{
|
||||||
fd_set rset, wset;
|
fd_set rset, wset;
|
||||||
struct timeval tv;
|
struct timeval tv;
|
||||||
@ -666,11 +719,12 @@ static void relay_connection(struct conn_s *connptr)
|
|||||||
|
|
||||||
last_access = time(NULL);
|
last_access = time(NULL);
|
||||||
|
|
||||||
for ( ; ; ) {
|
for (;;) {
|
||||||
FD_ZERO(&rset);
|
FD_ZERO(&rset);
|
||||||
FD_ZERO(&wset);
|
FD_ZERO(&wset);
|
||||||
|
|
||||||
tv.tv_sec = config.idletimeout - difftime(time(NULL), last_access);
|
tv.tv_sec =
|
||||||
|
config.idletimeout - difftime(time(NULL), last_access);
|
||||||
tv.tv_usec = 0;
|
tv.tv_usec = 0;
|
||||||
|
|
||||||
if (BUFFER_SIZE(connptr->sbuffer) > 0)
|
if (BUFFER_SIZE(connptr->sbuffer) > 0)
|
||||||
@ -687,13 +741,18 @@ static void relay_connection(struct conn_s *connptr)
|
|||||||
if (ret == 0) {
|
if (ret == 0) {
|
||||||
tdiff = difftime(time(NULL), last_access);
|
tdiff = difftime(time(NULL), last_access);
|
||||||
if (tdiff > config.idletimeout) {
|
if (tdiff > config.idletimeout) {
|
||||||
log_message(LOG_INFO, "Idle Timeout (after select) as %g > %u.", tdiff, config.idletimeout);
|
log_message(LOG_INFO,
|
||||||
|
"Idle Timeout (after select) as %g > %u.",
|
||||||
|
tdiff, config.idletimeout);
|
||||||
return;
|
return;
|
||||||
} else {
|
} else {
|
||||||
continue;
|
continue;
|
||||||
}
|
}
|
||||||
} else if (ret < 0) {
|
} else if (ret < 0) {
|
||||||
log_message(LOG_ERR, "relay_connection: select() error \"%s\". Closing connection (client_fd:%d, server_fd:%d)", strerror(errno), connptr->client_fd, connptr->server_fd);
|
log_message(LOG_ERR,
|
||||||
|
"relay_connection: select() error \"%s\". Closing connection (client_fd:%d, server_fd:%d)",
|
||||||
|
strerror(errno), connptr->client_fd,
|
||||||
|
connptr->server_fd);
|
||||||
return;
|
return;
|
||||||
} else {
|
} else {
|
||||||
/*
|
/*
|
||||||
@ -701,7 +760,7 @@ static void relay_connection(struct conn_s *connptr)
|
|||||||
*/
|
*/
|
||||||
last_access = time(NULL);
|
last_access = time(NULL);
|
||||||
}
|
}
|
||||||
|
|
||||||
if (FD_ISSET(connptr->server_fd, &rset)
|
if (FD_ISSET(connptr->server_fd, &rset)
|
||||||
&& readbuff(connptr->server_fd, connptr->sbuffer) < 0) {
|
&& readbuff(connptr->server_fd, connptr->sbuffer) < 0) {
|
||||||
break;
|
break;
|
||||||
@ -746,21 +805,25 @@ static void relay_connection(struct conn_s *connptr)
|
|||||||
/*
|
/*
|
||||||
* Establish a connection to the upstream proxy server.
|
* Establish a connection to the upstream proxy server.
|
||||||
*/
|
*/
|
||||||
static int connect_to_upstream(struct conn_s *connptr,
|
static int
|
||||||
struct request_s *request)
|
connect_to_upstream(struct conn_s *connptr, struct request_s *request)
|
||||||
{
|
{
|
||||||
char *combined_string;
|
char *combined_string;
|
||||||
int len;
|
int len;
|
||||||
|
|
||||||
connptr->server_fd = opensock(config.upstream_name, config.upstream_port);
|
connptr->server_fd =
|
||||||
|
opensock(config.upstream_name, config.upstream_port);
|
||||||
|
|
||||||
if (connptr->server_fd < 0) {
|
if (connptr->server_fd < 0) {
|
||||||
log_message(LOG_WARNING, "Could not connect to upstream proxy.");
|
log_message(LOG_WARNING,
|
||||||
|
"Could not connect to upstream proxy.");
|
||||||
httperr(connptr, 404, "Unable to connect to upstream proxy.");
|
httperr(connptr, 404, "Unable to connect to upstream proxy.");
|
||||||
return -1;
|
return -1;
|
||||||
}
|
}
|
||||||
|
|
||||||
log_message(LOG_CONN, "Established connection to upstream proxy \"%s\" using file descriptor %d.", config.upstream_name, connptr->server_fd);
|
log_message(LOG_CONN,
|
||||||
|
"Established connection to upstream proxy \"%s\" using file descriptor %d.",
|
||||||
|
config.upstream_name, connptr->server_fd);
|
||||||
|
|
||||||
/*
|
/*
|
||||||
* We need to re-write the "path" part of the request so that we
|
* We need to re-write the "path" part of the request so that we
|
||||||
@ -775,7 +838,8 @@ static int connect_to_upstream(struct conn_s *connptr,
|
|||||||
return -1;
|
return -1;
|
||||||
}
|
}
|
||||||
|
|
||||||
snprintf(combined_string, len, "%s:%d", request->host, request->port);
|
snprintf(combined_string, len, "%s:%d", request->host,
|
||||||
|
request->port);
|
||||||
} else {
|
} else {
|
||||||
len = strlen(request->host) + strlen(request->path) + 14;
|
len = strlen(request->host) + strlen(request->path) + 14;
|
||||||
combined_string = safemalloc(len + 1);
|
combined_string = safemalloc(len + 1);
|
||||||
@ -783,12 +847,13 @@ static int connect_to_upstream(struct conn_s *connptr,
|
|||||||
return -1;
|
return -1;
|
||||||
}
|
}
|
||||||
|
|
||||||
snprintf(combined_string, len, "http://%s:%d%s", request->host, request->port, request->path);
|
snprintf(combined_string, len, "http://%s:%d%s", request->host,
|
||||||
|
request->port, request->path);
|
||||||
}
|
}
|
||||||
|
|
||||||
safefree(request->path);
|
safefree(request->path);
|
||||||
request->path = combined_string;
|
request->path = combined_string;
|
||||||
|
|
||||||
return establish_http_connection(connptr, request);
|
return establish_http_connection(connptr, request);
|
||||||
}
|
}
|
||||||
#endif
|
#endif
|
||||||
@ -802,7 +867,8 @@ static int connect_to_upstream(struct conn_s *connptr,
|
|||||||
* tinyproxy code, which was confusing, redundant. Hail progress.
|
* tinyproxy code, which was confusing, redundant. Hail progress.
|
||||||
* - rjkaes
|
* - rjkaes
|
||||||
*/
|
*/
|
||||||
void handle_connection(int fd)
|
void
|
||||||
|
handle_connection(int fd)
|
||||||
{
|
{
|
||||||
struct conn_s *connptr;
|
struct conn_s *connptr;
|
||||||
struct request_s *request = NULL;
|
struct request_s *request = NULL;
|
||||||
@ -826,42 +892,46 @@ void handle_connection(int fd)
|
|||||||
|
|
||||||
if (check_acl(fd) <= 0) {
|
if (check_acl(fd) <= 0) {
|
||||||
update_stats(STAT_DENIED);
|
update_stats(STAT_DENIED);
|
||||||
httperr(connptr, 403, "You do not have authorization for using this service.");
|
httperr(connptr, 403,
|
||||||
|
"You do not have authorization for using this service.");
|
||||||
goto send_error;
|
goto send_error;
|
||||||
}
|
}
|
||||||
|
|
||||||
#ifdef TUNNEL_SUPPORT
|
#ifdef TUNNEL_SUPPORT
|
||||||
/*
|
/*
|
||||||
* If tunnel has been configured then redirect any connections to
|
* If tunnel has been configured then redirect any connections to
|
||||||
* it. I know I used GOTOs, but it seems to me to be the best way
|
* it. I know I used GOTOs, but it seems to me to be the best way
|
||||||
* of handling this situations. So sue me. :)
|
* of handling this situations. So sue me. :)
|
||||||
* - rjkaes
|
* - rjkaes
|
||||||
*/
|
*/
|
||||||
if (config.tunnel_name && config.tunnel_port != -1) {
|
if (config.tunnel_name && config.tunnel_port != -1) {
|
||||||
log_message(LOG_INFO, "Redirecting to %s:%d",
|
log_message(LOG_INFO, "Redirecting to %s:%d",
|
||||||
config.tunnel_name, config.tunnel_port);
|
config.tunnel_name, config.tunnel_port);
|
||||||
|
|
||||||
connptr->server_fd = opensock(config.tunnel_name, config.tunnel_port);
|
connptr->server_fd =
|
||||||
|
opensock(config.tunnel_name, config.tunnel_port);
|
||||||
|
|
||||||
if (connptr->server_fd < 0) {
|
if (connptr->server_fd < 0) {
|
||||||
log_message(LOG_WARNING, "Could not connect to tunnel.");
|
log_message(LOG_WARNING,
|
||||||
|
"Could not connect to tunnel.");
|
||||||
httperr(connptr, 404, "Unable to connect to tunnel.");
|
httperr(connptr, 404, "Unable to connect to tunnel.");
|
||||||
|
|
||||||
goto internal_proxy;
|
goto internal_proxy;
|
||||||
}
|
}
|
||||||
|
|
||||||
log_message(LOG_INFO, "Established a connection to the tunnel \"%s\" using file descriptor %d.", config.tunnel_name, connptr->server_fd);
|
log_message(LOG_INFO,
|
||||||
|
"Established a connection to the tunnel \"%s\" using file descriptor %d.",
|
||||||
|
config.tunnel_name, connptr->server_fd);
|
||||||
|
|
||||||
/*
|
/*
|
||||||
* I know GOTOs are evil, but duplicating the code is even
|
* I know GOTOs are evil, but duplicating the code is even
|
||||||
* more evil.
|
* more evil.
|
||||||
* - rjkaes
|
* - rjkaes
|
||||||
*/
|
*/
|
||||||
goto relay_proxy;
|
goto relay_proxy;
|
||||||
}
|
}
|
||||||
#endif /* TUNNEL_SUPPORT */
|
#endif /* TUNNEL_SUPPORT */
|
||||||
|
|
||||||
internal_proxy:
|
internal_proxy:
|
||||||
request_line = read_request_line(connptr);
|
request_line = read_request_line(connptr);
|
||||||
if (!request_line) {
|
if (!request_line) {
|
||||||
update_stats(STAT_BADCONN);
|
update_stats(STAT_BADCONN);
|
||||||
@ -880,7 +950,6 @@ internal_proxy:
|
|||||||
}
|
}
|
||||||
goto send_error;
|
goto send_error;
|
||||||
}
|
}
|
||||||
|
|
||||||
#ifdef UPSTREAM_SUPPORT
|
#ifdef UPSTREAM_SUPPORT
|
||||||
if (config.upstream_name && config.upstream_port != -1) {
|
if (config.upstream_name && config.upstream_port != -1) {
|
||||||
connptr->upstream = TRUE;
|
connptr->upstream = TRUE;
|
||||||
@ -895,7 +964,9 @@ internal_proxy:
|
|||||||
goto send_error;
|
goto send_error;
|
||||||
}
|
}
|
||||||
|
|
||||||
log_message(LOG_CONN, "Established connection to host \"%s\" using file descriptor %d.", request->host, connptr->server_fd);
|
log_message(LOG_CONN,
|
||||||
|
"Established connection to host \"%s\" using file descriptor %d.",
|
||||||
|
request->host, connptr->server_fd);
|
||||||
|
|
||||||
if (!connptr->ssl)
|
if (!connptr->ssl)
|
||||||
establish_http_connection(connptr, request);
|
establish_http_connection(connptr, request);
|
||||||
@ -903,7 +974,7 @@ internal_proxy:
|
|||||||
}
|
}
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
send_error:
|
send_error:
|
||||||
free_request_struct(request);
|
free_request_struct(request);
|
||||||
|
|
||||||
if (!connptr->simple_req) {
|
if (!connptr->simple_req) {
|
||||||
@ -929,14 +1000,15 @@ send_error:
|
|||||||
}
|
}
|
||||||
} else {
|
} else {
|
||||||
if (send_ssl_response(connptr) < 0) {
|
if (send_ssl_response(connptr) < 0) {
|
||||||
log_message(LOG_ERR, "handle_connection: Could not send SSL greeting to client.");
|
log_message(LOG_ERR,
|
||||||
|
"handle_connection: Could not send SSL greeting to client.");
|
||||||
update_stats(STAT_BADCONN);
|
update_stats(STAT_BADCONN);
|
||||||
destroy_conn(connptr);
|
destroy_conn(connptr);
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
relay_proxy:
|
relay_proxy:
|
||||||
relay_connection(connptr);
|
relay_connection(connptr);
|
||||||
|
|
||||||
/*
|
/*
|
||||||
|
43
src/stats.c
43
src/stats.c
@ -1,4 +1,4 @@
|
|||||||
/* $Id: stats.c,v 1.6 2001-09-15 21:27:58 rjkaes Exp $
|
/* $Id: stats.c,v 1.7 2001-11-22 00:31:10 rjkaes Exp $
|
||||||
*
|
*
|
||||||
* This module handles the statistics for tinyproxy. There are only two
|
* This module handles the statistics for tinyproxy. There are only two
|
||||||
* public API functions. The reason for the functions, rather than just a
|
* public API functions. The reason for the functions, rather than just a
|
||||||
@ -48,7 +48,8 @@ pthread_mutex_t stats_mutex = PTHREAD_MUTEX_INITIALIZER;
|
|||||||
/*
|
/*
|
||||||
* Initialise the statistics information to zero.
|
* Initialise the statistics information to zero.
|
||||||
*/
|
*/
|
||||||
void init_stats(void)
|
void
|
||||||
|
init_stats(void)
|
||||||
{
|
{
|
||||||
LOCK();
|
LOCK();
|
||||||
memset(&stats, 0, sizeof(stats));
|
memset(&stats, 0, sizeof(stats));
|
||||||
@ -58,18 +59,19 @@ void init_stats(void)
|
|||||||
/*
|
/*
|
||||||
* Display the statics of the tinyproxy server.
|
* Display the statics of the tinyproxy server.
|
||||||
*/
|
*/
|
||||||
int showstats(struct conn_s *connptr)
|
int
|
||||||
|
showstats(struct conn_s *connptr)
|
||||||
{
|
{
|
||||||
static char *msg = \
|
static char *msg =
|
||||||
"<html><head><title>%s (%s) stats</title></head>\r\n" \
|
"<html><head><title>%s (%s) stats</title></head>\r\n"
|
||||||
"<body>\r\n" \
|
"<body>\r\n"
|
||||||
"<center><h2>%s (%s) run-time statistics</h2></center><hr>\r\n" \
|
"<center><h2>%s (%s) run-time statistics</h2></center><hr>\r\n"
|
||||||
"<blockquote>\r\n" \
|
"<blockquote>\r\n"
|
||||||
"Number of open connections: %lu<br>\r\n" \
|
"Number of open connections: %lu<br>\r\n"
|
||||||
"Number of requests: %lu<br>\r\n" \
|
"Number of requests: %lu<br>\r\n"
|
||||||
"Number of bad connections: %lu<br>\r\n" \
|
"Number of bad connections: %lu<br>\r\n"
|
||||||
"Number of denied connections: %lu<br>\r\n" \
|
"Number of denied connections: %lu<br>\r\n"
|
||||||
"Number of refused connections due to high load: %lu\r\n" \
|
"Number of refused connections due to high load: %lu\r\n"
|
||||||
"</blockquote>\r\n</body></html>\r\n";
|
"</blockquote>\r\n</body></html>\r\n";
|
||||||
|
|
||||||
char *message_buffer;
|
char *message_buffer;
|
||||||
@ -80,12 +82,10 @@ int showstats(struct conn_s *connptr)
|
|||||||
|
|
||||||
LOCK();
|
LOCK();
|
||||||
snprintf(message_buffer, MAXBUFFSIZE, msg,
|
snprintf(message_buffer, MAXBUFFSIZE, msg,
|
||||||
PACKAGE, VERSION, PACKAGE, VERSION,
|
PACKAGE, VERSION, PACKAGE, VERSION,
|
||||||
stats.num_open,
|
stats.num_open,
|
||||||
stats.num_reqs,
|
stats.num_reqs,
|
||||||
stats.num_badcons,
|
stats.num_badcons, stats.num_denied, stats.num_refused);
|
||||||
stats.num_denied,
|
|
||||||
stats.num_refused);
|
|
||||||
UNLOCK();
|
UNLOCK();
|
||||||
|
|
||||||
if (send_http_message(connptr, 200, "OK", message_buffer) < 0) {
|
if (send_http_message(connptr, 200, "OK", message_buffer) < 0) {
|
||||||
@ -101,10 +101,11 @@ int showstats(struct conn_s *connptr)
|
|||||||
* Update the value of the statistics. The update_level is defined in
|
* Update the value of the statistics. The update_level is defined in
|
||||||
* stats.h
|
* stats.h
|
||||||
*/
|
*/
|
||||||
int update_stats(status_t update_level)
|
int
|
||||||
|
update_stats(status_t update_level)
|
||||||
{
|
{
|
||||||
LOCK();
|
LOCK();
|
||||||
switch(update_level) {
|
switch (update_level) {
|
||||||
case STAT_BADCONN:
|
case STAT_BADCONN:
|
||||||
stats.num_badcons++;
|
stats.num_badcons++;
|
||||||
break;
|
break;
|
||||||
|
12
src/stats.h
12
src/stats.h
@ -1,4 +1,4 @@
|
|||||||
/* $Id: stats.h,v 1.3 2001-10-25 16:58:50 rjkaes Exp $
|
/* $Id: stats.h,v 1.4 2001-11-22 00:31:10 rjkaes Exp $
|
||||||
*
|
*
|
||||||
* See 'stats.h' for a detailed description.
|
* See 'stats.h' for a detailed description.
|
||||||
*
|
*
|
||||||
@ -24,11 +24,11 @@
|
|||||||
* Various logable statistics
|
* Various logable statistics
|
||||||
*/
|
*/
|
||||||
typedef enum {
|
typedef enum {
|
||||||
STAT_BADCONN, /* bad connection, for unknown reason */
|
STAT_BADCONN, /* bad connection, for unknown reason */
|
||||||
STAT_OPEN, /* connection opened */
|
STAT_OPEN, /* connection opened */
|
||||||
STAT_CLOSE, /* connection closed */
|
STAT_CLOSE, /* connection closed */
|
||||||
STAT_REFUSE, /* connection refused (to outside world) */
|
STAT_REFUSE, /* connection refused (to outside world) */
|
||||||
STAT_DENIED /* connection denied to tinyproxy itself */
|
STAT_DENIED /* connection denied to tinyproxy itself */
|
||||||
} status_t;
|
} status_t;
|
||||||
|
|
||||||
/*
|
/*
|
||||||
|
@ -1,4 +1,4 @@
|
|||||||
/* $Id: ternary.c,v 1.11 2001-10-25 17:27:39 rjkaes Exp $
|
/* $Id: ternary.c,v 1.12 2001-11-22 00:31:10 rjkaes Exp $
|
||||||
*
|
*
|
||||||
* This module creates a Ternary Search Tree which can store both string
|
* This module creates a Ternary Search Tree which can store both string
|
||||||
* keys, and arbitrary data for each key. It works similar to a hash, and
|
* keys, and arbitrary data for each key. It works similar to a hash, and
|
||||||
@ -61,8 +61,8 @@ static Ttree *trees[MAXTREES]; /* the array of trees */
|
|||||||
/*
|
/*
|
||||||
* nonce generator -- this MUST be non-zero _always_
|
* nonce generator -- this MUST be non-zero _always_
|
||||||
*/
|
*/
|
||||||
#define IOFFSET 0x1221 /* used to hide index number in token */
|
#define IOFFSET 0x1221 /* used to hide index number in token */
|
||||||
#define NOFFSET 0x0502 /* initial nonce */
|
#define NOFFSET 0x0502 /* initial nonce */
|
||||||
static unsigned int noncectr = NOFFSET;
|
static unsigned int noncectr = NOFFSET;
|
||||||
|
|
||||||
/*
|
/*
|
||||||
@ -82,10 +82,11 @@ char te_errbuf[256];
|
|||||||
* (te_errbuf has disambiguating string)
|
* (te_errbuf has disambiguating string)
|
||||||
* Exceptions: none
|
* Exceptions: none
|
||||||
*/
|
*/
|
||||||
static TERNARY create_token_ref(unsigned int ind)
|
static TERNARY
|
||||||
|
create_token_ref(unsigned int ind)
|
||||||
{
|
{
|
||||||
unsigned int high; /* high 16 bits of token (index) */
|
unsigned int high; /* high 16 bits of token (index) */
|
||||||
unsigned int low; /* low 16 bits of token (nonce) */
|
unsigned int low; /* low 16 bits of token (nonce) */
|
||||||
|
|
||||||
/*
|
/*
|
||||||
* Sanity check argument; called internally...
|
* Sanity check argument; called internally...
|
||||||
@ -118,7 +119,7 @@ static TERNARY create_token_ref(unsigned int ind)
|
|||||||
return TE_INTINCON;
|
return TE_INTINCON;
|
||||||
}
|
}
|
||||||
|
|
||||||
return (TERNARY)((high << 16) | low);
|
return (TERNARY) ((high << 16) | low);
|
||||||
}
|
}
|
||||||
|
|
||||||
/*
|
/*
|
||||||
@ -136,9 +137,10 @@ static TERNARY create_token_ref(unsigned int ind)
|
|||||||
* (te_errbuf has disambiguating string)
|
* (te_errbuf has disambiguating string)
|
||||||
* EXCEPTIONS: none
|
* EXCEPTIONS: none
|
||||||
*/
|
*/
|
||||||
static int read_token_ref(TERNARY tno)
|
static int
|
||||||
|
read_token_ref(TERNARY tno)
|
||||||
{
|
{
|
||||||
unsigned int ind; /* index of current tree */
|
unsigned int ind; /* index of current tree */
|
||||||
|
|
||||||
/*
|
/*
|
||||||
* Get the index number and check it for validity
|
* Get the index number and check it for validity
|
||||||
@ -159,8 +161,8 @@ static int read_token_ref(TERNARY tno)
|
|||||||
*/
|
*/
|
||||||
if (trees[ind]->token != tno) {
|
if (trees[ind]->token != tno) {
|
||||||
ERRBUF3("readbuf: token refers to old tree (new=%u, old=%u)",
|
ERRBUF3("readbuf: token refers to old tree (new=%u, old=%u)",
|
||||||
(unsigned int)((trees[ind]->token) & 0xffff) - IOFFSET,
|
(unsigned int) ((trees[ind]->token) & 0xffff) - IOFFSET,
|
||||||
(unsigned int)(tno & 0xffff) - NOFFSET);
|
(unsigned int) (tno & 0xffff) - NOFFSET);
|
||||||
return TE_BADTOKEN;
|
return TE_BADTOKEN;
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -186,7 +188,8 @@ static int read_token_ref(TERNARY tno)
|
|||||||
* (te_errbuf has descriptive string)
|
* (te_errbuf has descriptive string)
|
||||||
* Exceptions: none
|
* Exceptions: none
|
||||||
*/
|
*/
|
||||||
TERNARY ternary_new(void)
|
TERNARY
|
||||||
|
ternary_new(void)
|
||||||
{
|
{
|
||||||
int cur; /* index of current tree */
|
int cur; /* index of current tree */
|
||||||
TERNARY token; /* new token for current tree */
|
TERNARY token; /* new token for current tree */
|
||||||
@ -242,7 +245,8 @@ TERNARY ternary_new(void)
|
|||||||
* read_token_ref()).
|
* read_token_ref()).
|
||||||
* Exceptions: none
|
* Exceptions: none
|
||||||
*/
|
*/
|
||||||
int ternary_destroy(TERNARY tno, void (*freeptr)(void *))
|
int
|
||||||
|
ternary_destroy(TERNARY tno, void (*freeptr) (void *))
|
||||||
{
|
{
|
||||||
int cur; /* index of current tree */
|
int cur; /* index of current tree */
|
||||||
unsigned int i, j;
|
unsigned int i, j;
|
||||||
@ -262,7 +266,7 @@ int ternary_destroy(TERNARY tno, void (*freeptr)(void *))
|
|||||||
ptr = (trees[cur]->freearr[i] + j);
|
ptr = (trees[cur]->freearr[i] + j);
|
||||||
if (ptr->splitchar == 0)
|
if (ptr->splitchar == 0)
|
||||||
if (freeptr)
|
if (freeptr)
|
||||||
(*freeptr)(ptr->eqkid);
|
(*freeptr) (ptr->eqkid);
|
||||||
}
|
}
|
||||||
safefree(trees[cur]->freearr[i]);
|
safefree(trees[cur]->freearr[i]);
|
||||||
}
|
}
|
||||||
@ -287,8 +291,9 @@ int ternary_destroy(TERNARY tno, void (*freeptr)(void *))
|
|||||||
* TE_TOOFULL tree is full, so no new elements can be added.
|
* TE_TOOFULL tree is full, so no new elements can be added.
|
||||||
* Exceptions: none
|
* Exceptions: none
|
||||||
*/
|
*/
|
||||||
int ternary_insert_replace(TERNARY tno, const char *s, void *data,
|
int
|
||||||
short int replace)
|
ternary_insert_replace(TERNARY tno, const char *s, void *data,
|
||||||
|
short int replace)
|
||||||
{
|
{
|
||||||
int cur; /* index of current tree */
|
int cur; /* index of current tree */
|
||||||
Ttree *tree; /* pointer to tree structure */
|
Ttree *tree; /* pointer to tree structure */
|
||||||
@ -301,7 +306,7 @@ int ternary_insert_replace(TERNARY tno, const char *s, void *data,
|
|||||||
*/
|
*/
|
||||||
if (TE_ISERROR(cur = read_token_ref(tno)))
|
if (TE_ISERROR(cur = read_token_ref(tno)))
|
||||||
return cur;
|
return cur;
|
||||||
|
|
||||||
tree = trees[cur];
|
tree = trees[cur];
|
||||||
p = &(tree->tree_root);
|
p = &(tree->tree_root);
|
||||||
|
|
||||||
@ -312,7 +317,7 @@ int ternary_insert_replace(TERNARY tno, const char *s, void *data,
|
|||||||
return TE_EXISTS;
|
return TE_EXISTS;
|
||||||
else {
|
else {
|
||||||
free(pp->eqkid);
|
free(pp->eqkid);
|
||||||
pp->eqkid = (Tnode *)data;
|
pp->eqkid = (Tnode *) data;
|
||||||
return TE_NONE;
|
return TE_NONE;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@ -327,14 +332,14 @@ int ternary_insert_replace(TERNARY tno, const char *s, void *data,
|
|||||||
if (tree->bufn-- == 0) {
|
if (tree->bufn-- == 0) {
|
||||||
tree->buf = safecalloc(BUFSIZE, sizeof(Tnode));
|
tree->buf = safecalloc(BUFSIZE, sizeof(Tnode));
|
||||||
if (!tree->buf) {
|
if (!tree->buf) {
|
||||||
ERRBUF("ternary_insert: malloc: no more memory");
|
ERRBUF
|
||||||
|
("ternary_insert: malloc: no more memory");
|
||||||
return TE_NOROOM;
|
return TE_NOROOM;
|
||||||
}
|
}
|
||||||
|
|
||||||
if (tree->freen == BUFARRAY - 1) {
|
if (tree->freen == BUFARRAY - 1) {
|
||||||
ERRBUF3("ternary_insert: freen %u equals %u",
|
ERRBUF3("ternary_insert: freen %u equals %u",
|
||||||
tree->freen,
|
tree->freen, BUFARRAY - 1);
|
||||||
BUFARRAY - 1);
|
|
||||||
return TE_TOOFULL;
|
return TE_TOOFULL;
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -364,7 +369,8 @@ int ternary_insert_replace(TERNARY tno, const char *s, void *data,
|
|||||||
* Errors:
|
* Errors:
|
||||||
* Exceptions:
|
* Exceptions:
|
||||||
*/
|
*/
|
||||||
int ternary_search(TERNARY tno, const char *s, void **data)
|
int
|
||||||
|
ternary_search(TERNARY tno, const char *s, void **data)
|
||||||
{
|
{
|
||||||
int cur;
|
int cur;
|
||||||
Tnode *p;
|
Tnode *p;
|
||||||
@ -384,7 +390,7 @@ int ternary_search(TERNARY tno, const char *s, void **data)
|
|||||||
else if (toupper(*s) == toupper(p->splitchar)) {
|
else if (toupper(*s) == toupper(p->splitchar)) {
|
||||||
if (*s++ == 0) {
|
if (*s++ == 0) {
|
||||||
if (data)
|
if (data)
|
||||||
*data = (void *)p->eqkid;
|
*data = (void *) p->eqkid;
|
||||||
return TE_NONE;
|
return TE_NONE;
|
||||||
}
|
}
|
||||||
p = p->eqkid;
|
p = p->eqkid;
|
||||||
@ -393,6 +399,6 @@ int ternary_search(TERNARY tno, const char *s, void **data)
|
|||||||
}
|
}
|
||||||
|
|
||||||
if (data)
|
if (data)
|
||||||
*data = (void *)NULL;
|
*data = (void *) NULL;
|
||||||
return TE_EMPTY;
|
return TE_EMPTY;
|
||||||
}
|
}
|
||||||
|
@ -1,4 +1,4 @@
|
|||||||
/* $Id: ternary.h,v 1.3 2001-08-30 16:52:09 rjkaes Exp $
|
/* $Id: ternary.h,v 1.4 2001-11-22 00:31:10 rjkaes Exp $
|
||||||
*
|
*
|
||||||
* See 'ternary.c' for a detailed description.
|
* See 'ternary.c' for a detailed description.
|
||||||
*
|
*
|
||||||
@ -27,7 +27,7 @@ typedef long int TERNARY;
|
|||||||
* Macros for testing for errors from the various functions.
|
* Macros for testing for errors from the various functions.
|
||||||
*/
|
*/
|
||||||
#define TE_ISERROR(x) ((x) < 0) /* true if x is tlib error code */
|
#define TE_ISERROR(x) ((x) < 0) /* true if x is tlib error code */
|
||||||
#define TE_NONE 0 /* no errors */
|
#define TE_NONE 0 /* no errors */
|
||||||
|
|
||||||
/*
|
/*
|
||||||
* Contains any error messages from the functions.
|
* Contains any error messages from the functions.
|
||||||
@ -56,7 +56,7 @@ extern char te_errbuf[256];
|
|||||||
* Library functions.
|
* Library functions.
|
||||||
*/
|
*/
|
||||||
extern TERNARY ternary_new(void);
|
extern TERNARY ternary_new(void);
|
||||||
extern int ternary_destroy(TERNARY tno, void (*freeptr)(void *));
|
extern int ternary_destroy(TERNARY tno, void (*freeptr) (void *));
|
||||||
|
|
||||||
#define ternary_insert(x, y, z) ternary_insert_replace(x, y, z, 0)
|
#define ternary_insert(x, y, z) ternary_insert_replace(x, y, z, 0)
|
||||||
#define ternary_replace(x, y, z) ternary_insert_replace(x, y, z, 1)
|
#define ternary_replace(x, y, z) ternary_insert_replace(x, y, z, 1)
|
||||||
|
59
src/thread.c
59
src/thread.c
@ -1,4 +1,4 @@
|
|||||||
/* $Id: thread.c,v 1.17 2001-10-24 00:37:23 rjkaes Exp $
|
/* $Id: thread.c,v 1.18 2001-11-22 00:31:10 rjkaes Exp $
|
||||||
*
|
*
|
||||||
* Handles the creation/destruction of the various threads required for
|
* Handles the creation/destruction of the various threads required for
|
||||||
* processing incoming connections.
|
* processing incoming connections.
|
||||||
@ -80,7 +80,8 @@ static pthread_mutex_t servers_mutex = PTHREAD_MUTEX_INITIALIZER;
|
|||||||
/*
|
/*
|
||||||
* Set the configuration values for the various thread related settings.
|
* Set the configuration values for the various thread related settings.
|
||||||
*/
|
*/
|
||||||
short int thread_configure(thread_config_t type, unsigned int val)
|
short int
|
||||||
|
thread_configure(thread_config_t type, unsigned int val)
|
||||||
{
|
{
|
||||||
switch (type) {
|
switch (type) {
|
||||||
case THREAD_MAXCLIENTS:
|
case THREAD_MAXCLIENTS:
|
||||||
@ -109,19 +110,20 @@ short int thread_configure(thread_config_t type, unsigned int val)
|
|||||||
/*
|
/*
|
||||||
* This is the main (per thread) loop.
|
* This is the main (per thread) loop.
|
||||||
*/
|
*/
|
||||||
static void *thread_main(void *arg)
|
static void *
|
||||||
|
thread_main(void *arg)
|
||||||
{
|
{
|
||||||
int connfd;
|
int connfd;
|
||||||
struct sockaddr *cliaddr;
|
struct sockaddr *cliaddr;
|
||||||
socklen_t clilen;
|
socklen_t clilen;
|
||||||
struct thread_s *ptr;
|
struct thread_s *ptr;
|
||||||
|
|
||||||
ptr = (struct thread_s *)arg;
|
ptr = (struct thread_s *) arg;
|
||||||
|
|
||||||
cliaddr = safemalloc(addrlen);
|
cliaddr = safemalloc(addrlen);
|
||||||
if (!cliaddr)
|
if (!cliaddr)
|
||||||
return NULL;
|
return NULL;
|
||||||
|
|
||||||
while (!config.quit) {
|
while (!config.quit) {
|
||||||
clilen = addrlen;
|
clilen = addrlen;
|
||||||
|
|
||||||
@ -142,10 +144,13 @@ static void *thread_main(void *arg)
|
|||||||
DEBUG2("%u connections so far...", ptr->connects);
|
DEBUG2("%u connections so far...", ptr->connects);
|
||||||
|
|
||||||
if (ptr->connects >= thread_config.maxrequestsperchild) {
|
if (ptr->connects >= thread_config.maxrequestsperchild) {
|
||||||
log_message(LOG_NOTICE, "Thread has reached MaxRequestsPerChild (%u > %u). Killing thread.", ptr->connects, thread_config.maxrequestsperchild);
|
log_message(LOG_NOTICE,
|
||||||
|
"Thread has reached MaxRequestsPerChild (%u > %u). Killing thread.",
|
||||||
|
ptr->connects,
|
||||||
|
thread_config.maxrequestsperchild);
|
||||||
|
|
||||||
ptr->status = T_EMPTY;
|
ptr->status = T_EMPTY;
|
||||||
|
|
||||||
safefree(cliaddr);
|
safefree(cliaddr);
|
||||||
|
|
||||||
return NULL;
|
return NULL;
|
||||||
@ -160,7 +165,8 @@ static void *thread_main(void *arg)
|
|||||||
*/
|
*/
|
||||||
SERVER_UNLOCK();
|
SERVER_UNLOCK();
|
||||||
|
|
||||||
log_message(LOG_NOTICE, "Waiting servers exceeds MaxSpareServers. Killing thread.");
|
log_message(LOG_NOTICE,
|
||||||
|
"Waiting servers exceeds MaxSpareServers. Killing thread.");
|
||||||
|
|
||||||
ptr->status = T_EMPTY;
|
ptr->status = T_EMPTY;
|
||||||
|
|
||||||
@ -170,7 +176,7 @@ static void *thread_main(void *arg)
|
|||||||
SERVER_UNLOCK();
|
SERVER_UNLOCK();
|
||||||
|
|
||||||
ptr->status = T_WAITING;
|
ptr->status = T_WAITING;
|
||||||
|
|
||||||
SERVER_INC();
|
SERVER_INC();
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -181,7 +187,8 @@ static void *thread_main(void *arg)
|
|||||||
/*
|
/*
|
||||||
* Create the initial pool of threads.
|
* Create the initial pool of threads.
|
||||||
*/
|
*/
|
||||||
short int thread_pool_create(void)
|
short int
|
||||||
|
thread_pool_create(void)
|
||||||
{
|
{
|
||||||
unsigned int i;
|
unsigned int i;
|
||||||
|
|
||||||
@ -196,26 +203,33 @@ short int thread_pool_create(void)
|
|||||||
pthread_attr_setstacksize(&thread_attr, THREAD_STACK_SIZE);
|
pthread_attr_setstacksize(&thread_attr, THREAD_STACK_SIZE);
|
||||||
|
|
||||||
if (thread_config.maxclients == 0) {
|
if (thread_config.maxclients == 0) {
|
||||||
log_message(LOG_ERR, "thread_pool_create: \"MaxClients\" must be greater than zero.");
|
log_message(LOG_ERR,
|
||||||
|
"thread_pool_create: \"MaxClients\" must be greater than zero.");
|
||||||
return -1;
|
return -1;
|
||||||
}
|
}
|
||||||
if (thread_config.startservers == 0) {
|
if (thread_config.startservers == 0) {
|
||||||
log_message(LOG_ERR, "thread_pool_create: \"StartServers\" must be greater than zero.");
|
log_message(LOG_ERR,
|
||||||
|
"thread_pool_create: \"StartServers\" must be greater than zero.");
|
||||||
return -1;
|
return -1;
|
||||||
}
|
}
|
||||||
|
|
||||||
thread_ptr = safecalloc((size_t)thread_config.maxclients, sizeof(struct thread_s));
|
thread_ptr =
|
||||||
|
safecalloc((size_t) thread_config.maxclients,
|
||||||
|
sizeof(struct thread_s));
|
||||||
if (!thread_ptr)
|
if (!thread_ptr)
|
||||||
return -1;
|
return -1;
|
||||||
|
|
||||||
if (thread_config.startservers > thread_config.maxclients) {
|
if (thread_config.startservers > thread_config.maxclients) {
|
||||||
log_message(LOG_WARNING, "Can not start more than \"MaxClients\" servers. Starting %u servers instead.", thread_config.maxclients);
|
log_message(LOG_WARNING,
|
||||||
|
"Can not start more than \"MaxClients\" servers. Starting %u servers instead.",
|
||||||
|
thread_config.maxclients);
|
||||||
thread_config.startservers = thread_config.maxclients;
|
thread_config.startservers = thread_config.maxclients;
|
||||||
}
|
}
|
||||||
|
|
||||||
for (i = 0; i < thread_config.startservers; i++) {
|
for (i = 0; i < thread_config.startservers; i++) {
|
||||||
thread_ptr[i].status = T_WAITING;
|
thread_ptr[i].status = T_WAITING;
|
||||||
pthread_create(&thread_ptr[i].tid, &thread_attr, &thread_main, &thread_ptr[i]);
|
pthread_create(&thread_ptr[i].tid, &thread_attr, &thread_main,
|
||||||
|
&thread_ptr[i]);
|
||||||
}
|
}
|
||||||
servers_waiting = thread_config.startservers;
|
servers_waiting = thread_config.startservers;
|
||||||
|
|
||||||
@ -231,7 +245,8 @@ short int thread_pool_create(void)
|
|||||||
* Keep the proper number of servers running. This is the birth of the
|
* Keep the proper number of servers running. This is the birth of the
|
||||||
* servers. It monitors this at least once a second.
|
* servers. It monitors this at least once a second.
|
||||||
*/
|
*/
|
||||||
void thread_main_loop(void)
|
void
|
||||||
|
thread_main_loop(void)
|
||||||
{
|
{
|
||||||
int i;
|
int i;
|
||||||
|
|
||||||
@ -242,13 +257,15 @@ void thread_main_loop(void)
|
|||||||
|
|
||||||
for (i = 0; i < thread_config.maxclients; i++) {
|
for (i = 0; i < thread_config.maxclients; i++) {
|
||||||
if (thread_ptr[i].status == T_EMPTY) {
|
if (thread_ptr[i].status == T_EMPTY) {
|
||||||
pthread_create(&thread_ptr[i].tid, &thread_attr, &thread_main, &thread_ptr[i]);
|
pthread_create(&thread_ptr[i].tid, &thread_attr,
|
||||||
|
&thread_main, &thread_ptr[i]);
|
||||||
thread_ptr[i].status = T_WAITING;
|
thread_ptr[i].status = T_WAITING;
|
||||||
thread_ptr[i].connects = 0;
|
thread_ptr[i].connects = 0;
|
||||||
|
|
||||||
SERVER_INC();
|
SERVER_INC();
|
||||||
|
|
||||||
log_message(LOG_NOTICE, "Waiting servers is less than MinSpareServers. Creating new thread.");
|
log_message(LOG_NOTICE,
|
||||||
|
"Waiting servers is less than MinSpareServers. Creating new thread.");
|
||||||
|
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
@ -257,13 +274,15 @@ void thread_main_loop(void)
|
|||||||
SERVER_UNLOCK();
|
SERVER_UNLOCK();
|
||||||
}
|
}
|
||||||
|
|
||||||
int thread_listening_sock(uint16_t port)
|
int
|
||||||
|
thread_listening_sock(uint16_t port)
|
||||||
{
|
{
|
||||||
listenfd = listen_sock(port, &addrlen);
|
listenfd = listen_sock(port, &addrlen);
|
||||||
return listenfd;
|
return listenfd;
|
||||||
}
|
}
|
||||||
|
|
||||||
void thread_close_sock(void)
|
void
|
||||||
|
thread_close_sock(void)
|
||||||
{
|
{
|
||||||
close(listenfd);
|
close(listenfd);
|
||||||
}
|
}
|
||||||
|
126
src/tinyproxy.c
126
src/tinyproxy.c
@ -1,4 +1,4 @@
|
|||||||
/* $Id: tinyproxy.c,v 1.18 2001-10-25 17:27:39 rjkaes Exp $
|
/* $Id: tinyproxy.c,v 1.19 2001-11-22 00:31:10 rjkaes Exp $
|
||||||
*
|
*
|
||||||
* The initialise routine. Basically sets up all the initial stuff (logfile,
|
* The initialise routine. Basically sets up all the initial stuff (logfile,
|
||||||
* listening socket, config options, etc.) and then sits there and loops
|
* listening socket, config options, etc.) and then sits there and loops
|
||||||
@ -49,7 +49,8 @@ float load = 0.00;
|
|||||||
/*
|
/*
|
||||||
* Handle a signal
|
* Handle a signal
|
||||||
*/
|
*/
|
||||||
void takesig(int sig)
|
void
|
||||||
|
takesig(int sig)
|
||||||
{
|
{
|
||||||
switch (sig) {
|
switch (sig) {
|
||||||
case SIGHUP:
|
case SIGHUP:
|
||||||
@ -62,7 +63,8 @@ void takesig(int sig)
|
|||||||
|
|
||||||
rename_file = safemalloc(strlen(config.logf_name) + 5);
|
rename_file = safemalloc(strlen(config.logf_name) + 5);
|
||||||
if (!rename_file) {
|
if (!rename_file) {
|
||||||
fprintf(stderr, "Could not allocate memory in signal handler!\n");
|
fprintf(stderr,
|
||||||
|
"Could not allocate memory in signal handler!\n");
|
||||||
exit(EX_OSERR);
|
exit(EX_OSERR);
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -73,14 +75,16 @@ void takesig(int sig)
|
|||||||
|
|
||||||
log_file_des = create_file_safely(config.logf_name);
|
log_file_des = create_file_safely(config.logf_name);
|
||||||
if (log_file_des < 0) {
|
if (log_file_des < 0) {
|
||||||
fprintf(stderr, "Could not safely create new log file.\n");
|
fprintf(stderr,
|
||||||
|
"Could not safely create new log file.\n");
|
||||||
exit(EX_OSERR);
|
exit(EX_OSERR);
|
||||||
}
|
}
|
||||||
|
|
||||||
old_fd = config.logf;
|
old_fd = config.logf;
|
||||||
|
|
||||||
if (!(config.logf = fdopen(log_file_des, "w"))) {
|
if (!(config.logf = fdopen(log_file_des, "w"))) {
|
||||||
fprintf(stderr, "Could not create new log file.\n");
|
fprintf(stderr,
|
||||||
|
"Could not create new log file.\n");
|
||||||
exit(EX_CANTCREAT);
|
exit(EX_CANTCREAT);
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -90,7 +94,6 @@ void takesig(int sig)
|
|||||||
|
|
||||||
safefree(rename_file);
|
safefree(rename_file);
|
||||||
}
|
}
|
||||||
|
|
||||||
#ifdef FILTER_ENABLE
|
#ifdef FILTER_ENABLE
|
||||||
if (config.filter) {
|
if (config.filter) {
|
||||||
filter_destroy();
|
filter_destroy();
|
||||||
@ -98,7 +101,8 @@ void takesig(int sig)
|
|||||||
}
|
}
|
||||||
log_message(LOG_NOTICE, "Re-reading filter file.");
|
log_message(LOG_NOTICE, "Re-reading filter file.");
|
||||||
#endif /* FILTER_ENABLE */
|
#endif /* FILTER_ENABLE */
|
||||||
log_message(LOG_NOTICE, "Finished cleaning memory/connections.");
|
log_message(LOG_NOTICE,
|
||||||
|
"Finished cleaning memory/connections.");
|
||||||
break;
|
break;
|
||||||
case SIGTERM:
|
case SIGTERM:
|
||||||
#ifdef FILTER_ENABLE
|
#ifdef FILTER_ENABLE
|
||||||
@ -118,7 +122,8 @@ void takesig(int sig)
|
|||||||
/*
|
/*
|
||||||
* Display the version information for the user.
|
* Display the version information for the user.
|
||||||
*/
|
*/
|
||||||
static void display_version(void)
|
static void
|
||||||
|
display_version(void)
|
||||||
{
|
{
|
||||||
printf("%s %s (%s)\n", PACKAGE, VERSION, TARGET_SYSTEM);
|
printf("%s %s (%s)\n", PACKAGE, VERSION, TARGET_SYSTEM);
|
||||||
}
|
}
|
||||||
@ -126,7 +131,8 @@ static void display_version(void)
|
|||||||
/*
|
/*
|
||||||
* Display the copyright and license for this program.
|
* Display the copyright and license for this program.
|
||||||
*/
|
*/
|
||||||
static void display_license(void)
|
static void
|
||||||
|
display_license(void)
|
||||||
{
|
{
|
||||||
display_version();
|
display_version();
|
||||||
|
|
||||||
@ -154,7 +160,8 @@ static void display_license(void)
|
|||||||
/*
|
/*
|
||||||
* Display usage to the user.
|
* Display usage to the user.
|
||||||
*/
|
*/
|
||||||
static void display_usage(void)
|
static void
|
||||||
|
display_usage(void)
|
||||||
{
|
{
|
||||||
printf("Usage: %s [options]\n", PACKAGE);
|
printf("Usage: %s [options]\n", PACKAGE);
|
||||||
printf("\
|
printf("\
|
||||||
@ -165,7 +172,6 @@ Options:\n\
|
|||||||
-l Display the license.\n\
|
-l Display the license.\n\
|
||||||
-v Display the version number.\n");
|
-v Display the version number.\n");
|
||||||
|
|
||||||
|
|
||||||
/* Display the modes compiled into tinyproxy */
|
/* Display the modes compiled into tinyproxy */
|
||||||
printf("\nFeatures Compiled In:\n");
|
printf("\nFeatures Compiled In:\n");
|
||||||
#ifdef XTINYPROXY_ENABLE
|
#ifdef XTINYPROXY_ENABLE
|
||||||
@ -183,7 +189,8 @@ Options:\n\
|
|||||||
#endif /* TUNNEL_SUPPORT */
|
#endif /* TUNNEL_SUPPORT */
|
||||||
}
|
}
|
||||||
|
|
||||||
int main(int argc, char **argv)
|
int
|
||||||
|
main(int argc, char **argv)
|
||||||
{
|
{
|
||||||
int optch;
|
int optch;
|
||||||
bool_t godaemon = TRUE;
|
bool_t godaemon = TRUE;
|
||||||
@ -195,18 +202,18 @@ int main(int argc, char **argv)
|
|||||||
* Disable the creation of CORE files right up front.
|
* Disable the creation of CORE files right up front.
|
||||||
*/
|
*/
|
||||||
#ifdef HAVE_SETRLIMIT
|
#ifdef HAVE_SETRLIMIT
|
||||||
struct rlimit core_limit = {0, 0};
|
struct rlimit core_limit = { 0, 0 };
|
||||||
if (setrlimit(RLIMIT_CORE, &core_limit) < 0) {
|
if (setrlimit(RLIMIT_CORE, &core_limit) < 0) {
|
||||||
fprintf(stderr, "%s: Could not set the core limit to zero.\n", argv[0]);
|
fprintf(stderr, "%s: Could not set the core limit to zero.\n",
|
||||||
|
argv[0]);
|
||||||
exit(EX_SOFTWARE);
|
exit(EX_SOFTWARE);
|
||||||
}
|
}
|
||||||
#endif /* HAVE_SETRLIMIT */
|
#endif /* HAVE_SETRLIMIT */
|
||||||
|
|
||||||
/*
|
/*
|
||||||
* Process the various options
|
* Process the various options
|
||||||
*/
|
*/
|
||||||
while ((optch = getopt(argc, argv, "c:vldh")) !=
|
while ((optch = getopt(argc, argv, "c:vldh")) != EOF) {
|
||||||
EOF) {
|
|
||||||
switch (optch) {
|
switch (optch) {
|
||||||
case 'v':
|
case 'v':
|
||||||
display_version();
|
display_version();
|
||||||
@ -220,13 +227,15 @@ int main(int argc, char **argv)
|
|||||||
case 'c':
|
case 'c':
|
||||||
conf_file = strdup(optarg);
|
conf_file = strdup(optarg);
|
||||||
if (!conf_file) {
|
if (!conf_file) {
|
||||||
fprintf(stderr, "%s: Could not allocate memory.\n", argv[0]);
|
fprintf(stderr,
|
||||||
|
"%s: Could not allocate memory.\n",
|
||||||
|
argv[0]);
|
||||||
exit(EX_SOFTWARE);
|
exit(EX_SOFTWARE);
|
||||||
}
|
}
|
||||||
break;
|
break;
|
||||||
case 'h':
|
case 'h':
|
||||||
default:
|
default:
|
||||||
display_usage();
|
display_usage();
|
||||||
exit(EX_OK);
|
exit(EX_OK);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@ -236,14 +245,18 @@ int main(int argc, char **argv)
|
|||||||
*/
|
*/
|
||||||
yyin = fopen(conf_file, "r");
|
yyin = fopen(conf_file, "r");
|
||||||
if (!yyin) {
|
if (!yyin) {
|
||||||
fprintf(stderr, "%s: Could not open configuration file \"%s\".\n", argv[0], conf_file);
|
fprintf(stderr,
|
||||||
|
"%s: Could not open configuration file \"%s\".\n",
|
||||||
|
argv[0], conf_file);
|
||||||
exit(EX_SOFTWARE);
|
exit(EX_SOFTWARE);
|
||||||
}
|
}
|
||||||
yyparse();
|
yyparse();
|
||||||
|
|
||||||
#if defined(TUNNEL_SUPPORT) && defined(UPSTREAM_SUPPORT)
|
#if defined(TUNNEL_SUPPORT) && defined(UPSTREAM_SUPPORT)
|
||||||
if (config.tunnel_name && config.upstream_name) {
|
if (config.tunnel_name && config.upstream_name) {
|
||||||
fprintf(stderr, "%s: \"Tunnel\" and \"Upstream\" directives can not be both set.\n", argv[0]);
|
fprintf(stderr,
|
||||||
|
"%s: \"Tunnel\" and \"Upstream\" directives can not be both set.\n",
|
||||||
|
argv[0]);
|
||||||
exit(EX_SOFTWARE);
|
exit(EX_SOFTWARE);
|
||||||
}
|
}
|
||||||
#endif
|
#endif
|
||||||
@ -253,19 +266,24 @@ int main(int argc, char **argv)
|
|||||||
int log_file_fd;
|
int log_file_fd;
|
||||||
|
|
||||||
if (!config.logf_name) {
|
if (!config.logf_name) {
|
||||||
fprintf(stderr, "%s: You MUST set a LogFile in the configuration file.\n", argv[0]);
|
fprintf(stderr,
|
||||||
|
"%s: You MUST set a LogFile in the configuration file.\n",
|
||||||
|
argv[0]);
|
||||||
exit(EX_SOFTWARE);
|
exit(EX_SOFTWARE);
|
||||||
}
|
}
|
||||||
|
|
||||||
log_file_fd = create_file_safely(config.logf_name);
|
log_file_fd = create_file_safely(config.logf_name);
|
||||||
if (log_file_fd < 0) {
|
if (log_file_fd < 0) {
|
||||||
fprintf(stderr, "Could not safely create logfile \"%s\".\n", config.logf_name);
|
fprintf(stderr,
|
||||||
|
"Could not safely create logfile \"%s\".\n",
|
||||||
|
config.logf_name);
|
||||||
exit(EX_CANTCREAT);
|
exit(EX_CANTCREAT);
|
||||||
}
|
}
|
||||||
|
|
||||||
config.logf = fdopen(log_file_fd, "w");
|
config.logf = fdopen(log_file_fd, "w");
|
||||||
if (!config.logf) {
|
if (!config.logf) {
|
||||||
fprintf(stderr, "Could not write to log file \"%s\".\n", config.logf_name);
|
fprintf(stderr, "Could not write to log file \"%s\".\n",
|
||||||
|
config.logf_name);
|
||||||
exit(EX_CANTCREAT);
|
exit(EX_CANTCREAT);
|
||||||
}
|
}
|
||||||
} else {
|
} else {
|
||||||
@ -281,18 +299,23 @@ int main(int argc, char **argv)
|
|||||||
* Set the default values if they were not set in the config file.
|
* Set the default values if they were not set in the config file.
|
||||||
*/
|
*/
|
||||||
if (config.port == 0) {
|
if (config.port == 0) {
|
||||||
fprintf(stderr, "%s: You MUST set a Port in the configuration file.\n", argv[0]);
|
fprintf(stderr,
|
||||||
|
"%s: You MUST set a Port in the configuration file.\n",
|
||||||
|
argv[0]);
|
||||||
exit(EX_SOFTWARE);
|
exit(EX_SOFTWARE);
|
||||||
}
|
}
|
||||||
if (!config.stathost) {
|
if (!config.stathost) {
|
||||||
log_message(LOG_INFO, "Setting stathost to \"%s\".", DEFAULT_STATHOST);
|
log_message(LOG_INFO, "Setting stathost to \"%s\".",
|
||||||
|
DEFAULT_STATHOST);
|
||||||
config.stathost = DEFAULT_STATHOST;
|
config.stathost = DEFAULT_STATHOST;
|
||||||
}
|
}
|
||||||
if (!config.username) {
|
if (!config.username) {
|
||||||
log_message(LOG_WARNING, "You SHOULD set a UserName in the configuration file. Using current user instead.");
|
log_message(LOG_WARNING,
|
||||||
|
"You SHOULD set a UserName in the configuration file. Using current user instead.");
|
||||||
}
|
}
|
||||||
if (config.idletimeout == 0) {
|
if (config.idletimeout == 0) {
|
||||||
log_message(LOG_INFO, "Setting idle timeout to %u seconds.", MAX_IDLE_TIME);
|
log_message(LOG_INFO, "Setting idle timeout to %u seconds.",
|
||||||
|
MAX_IDLE_TIME);
|
||||||
config.idletimeout = MAX_IDLE_TIME;
|
config.idletimeout = MAX_IDLE_TIME;
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -318,10 +341,10 @@ int main(int argc, char **argv)
|
|||||||
}
|
}
|
||||||
|
|
||||||
if (signal(SIGPIPE, SIG_IGN) == SIG_ERR) {
|
if (signal(SIGPIPE, SIG_IGN) == SIG_ERR) {
|
||||||
fprintf(stderr, "%s: Could not set the \"SIGPIPE\" signal.\n", argv[0]);
|
fprintf(stderr, "%s: Could not set the \"SIGPIPE\" signal.\n",
|
||||||
|
argv[0]);
|
||||||
exit(EX_OSERR);
|
exit(EX_OSERR);
|
||||||
}
|
}
|
||||||
|
|
||||||
#ifdef FILTER_ENABLE
|
#ifdef FILTER_ENABLE
|
||||||
if (config.filter)
|
if (config.filter)
|
||||||
filter_init();
|
filter_init();
|
||||||
@ -331,7 +354,8 @@ int main(int argc, char **argv)
|
|||||||
* Start listening on the selected port.
|
* Start listening on the selected port.
|
||||||
*/
|
*/
|
||||||
if (thread_listening_sock(config.port) < 0) {
|
if (thread_listening_sock(config.port) < 0) {
|
||||||
fprintf(stderr, "%s: Could not create listening socket.\n", argv[0]);
|
fprintf(stderr, "%s: Could not create listening socket.\n",
|
||||||
|
argv[0]);
|
||||||
exit(EX_OSERR);
|
exit(EX_OSERR);
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -342,33 +366,45 @@ int main(int argc, char **argv)
|
|||||||
if (config.group && strlen(config.group) > 0) {
|
if (config.group && strlen(config.group) > 0) {
|
||||||
thisgroup = getgrnam(config.group);
|
thisgroup = getgrnam(config.group);
|
||||||
if (!thisgroup) {
|
if (!thisgroup) {
|
||||||
fprintf(stderr, "%s: Unable to find group \"%s\".\n", argv[0], config.group);
|
fprintf(stderr,
|
||||||
|
"%s: Unable to find group \"%s\".\n",
|
||||||
|
argv[0], config.group);
|
||||||
exit(EX_NOUSER);
|
exit(EX_NOUSER);
|
||||||
}
|
}
|
||||||
if (setgid(thisgroup->gr_gid) < 0) {
|
if (setgid(thisgroup->gr_gid) < 0) {
|
||||||
fprintf(stderr, "%s: Unable to change to group \"%s\".\n", argv[0], config.group);
|
fprintf(stderr,
|
||||||
|
"%s: Unable to change to group \"%s\".\n",
|
||||||
|
argv[0], config.group);
|
||||||
exit(EX_CANTCREAT);
|
exit(EX_CANTCREAT);
|
||||||
}
|
}
|
||||||
log_message(LOG_INFO, "Now running as group \"%s\".", config.group);
|
log_message(LOG_INFO, "Now running as group \"%s\".",
|
||||||
|
config.group);
|
||||||
}
|
}
|
||||||
if (config.username && strlen(config.username) > 0) {
|
if (config.username && strlen(config.username) > 0) {
|
||||||
thisuser = getpwnam(config.username);
|
thisuser = getpwnam(config.username);
|
||||||
if (!thisuser) {
|
if (!thisuser) {
|
||||||
fprintf(stderr, "%s: Unable to find user \"%s\".", argv[0], config.username);
|
fprintf(stderr,
|
||||||
|
"%s: Unable to find user \"%s\".",
|
||||||
|
argv[0], config.username);
|
||||||
exit(EX_NOUSER);
|
exit(EX_NOUSER);
|
||||||
}
|
}
|
||||||
if (setuid(thisuser->pw_uid) < 0) {
|
if (setuid(thisuser->pw_uid) < 0) {
|
||||||
fprintf(stderr, "%s: Unable to change to user \"%s\".", argv[0], config.username);
|
fprintf(stderr,
|
||||||
|
"%s: Unable to change to user \"%s\".",
|
||||||
|
argv[0], config.username);
|
||||||
exit(EX_CANTCREAT);
|
exit(EX_CANTCREAT);
|
||||||
}
|
}
|
||||||
log_message(LOG_INFO, "Now running as user \"%s\".", config.username);
|
log_message(LOG_INFO, "Now running as user \"%s\".",
|
||||||
|
config.username);
|
||||||
}
|
}
|
||||||
} else {
|
} else {
|
||||||
log_message(LOG_WARNING, "Not running as root, so not changing UID/GID.");
|
log_message(LOG_WARNING,
|
||||||
|
"Not running as root, so not changing UID/GID.");
|
||||||
}
|
}
|
||||||
|
|
||||||
if (thread_pool_create() < 0) {
|
if (thread_pool_create() < 0) {
|
||||||
fprintf(stderr, "%s: Could not create the pool of threads.", argv[0]);
|
fprintf(stderr, "%s: Could not create the pool of threads.",
|
||||||
|
argv[0]);
|
||||||
exit(EX_SOFTWARE);
|
exit(EX_SOFTWARE);
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -377,11 +413,13 @@ int main(int argc, char **argv)
|
|||||||
*/
|
*/
|
||||||
log_message(LOG_INFO, "Setting the various signals.");
|
log_message(LOG_INFO, "Setting the various signals.");
|
||||||
if (signal(SIGTERM, takesig) == SIG_ERR) {
|
if (signal(SIGTERM, takesig) == SIG_ERR) {
|
||||||
fprintf(stderr, "%s: Could not set the \"SIGTERM\" signal.\n", argv[0]);
|
fprintf(stderr, "%s: Could not set the \"SIGTERM\" signal.\n",
|
||||||
|
argv[0]);
|
||||||
exit(EX_OSERR);
|
exit(EX_OSERR);
|
||||||
}
|
}
|
||||||
if (signal(SIGHUP, takesig) == SIG_ERR) {
|
if (signal(SIGHUP, takesig) == SIG_ERR) {
|
||||||
fprintf(stderr, "%s: Could not set the \"SIGHUP\" signal.\n", argv[0]);
|
fprintf(stderr, "%s: Could not set the \"SIGHUP\" signal.\n",
|
||||||
|
argv[0]);
|
||||||
exit(EX_OSERR);
|
exit(EX_OSERR);
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -401,10 +439,10 @@ int main(int argc, char **argv)
|
|||||||
* Remove the PID file.
|
* Remove the PID file.
|
||||||
*/
|
*/
|
||||||
if (unlink(config.pidpath) < 0) {
|
if (unlink(config.pidpath) < 0) {
|
||||||
log_message(LOG_WARNING, "Could not remove PID file \"%s\": %s.",
|
log_message(LOG_WARNING,
|
||||||
|
"Could not remove PID file \"%s\": %s.",
|
||||||
config.pidpath, strerror(errno));
|
config.pidpath, strerror(errno));
|
||||||
}
|
}
|
||||||
|
|
||||||
#ifdef FILTER_ENABLE
|
#ifdef FILTER_ENABLE
|
||||||
if (config.filter)
|
if (config.filter)
|
||||||
filter_destroy();
|
filter_destroy();
|
||||||
|
@ -1,4 +1,4 @@
|
|||||||
/* $Id: tinyproxy.h,v 1.19 2001-10-25 17:27:39 rjkaes Exp $
|
/* $Id: tinyproxy.h,v 1.20 2001-11-22 00:31:10 rjkaes Exp $
|
||||||
*
|
*
|
||||||
* See 'tinyproxy.c' for a detailed description.
|
* See 'tinyproxy.c' for a detailed description.
|
||||||
*
|
*
|
||||||
@ -81,7 +81,7 @@
|
|||||||
|
|
||||||
/* Global variables for the main controls of the program */
|
/* Global variables for the main controls of the program */
|
||||||
#define MAXBUFFSIZE ((size_t)(1024 * 48)) /* Max size of buffer */
|
#define MAXBUFFSIZE ((size_t)(1024 * 48)) /* Max size of buffer */
|
||||||
#define MAXLISTEN 1024 /* Max number of connections */
|
#define MAXLISTEN 1024 /* Max number of connections */
|
||||||
#define MAX_IDLE_TIME (60 * 10) /* 10 minutes of no activity */
|
#define MAX_IDLE_TIME (60 * 10) /* 10 minutes of no activity */
|
||||||
|
|
||||||
/* Useful function macros */
|
/* Useful function macros */
|
||||||
|
114
src/utils.c
114
src/utils.c
@ -1,4 +1,4 @@
|
|||||||
/* $Id: utils.c,v 1.16 2001-10-25 17:27:39 rjkaes Exp $
|
/* $Id: utils.c,v 1.17 2001-11-22 00:31:10 rjkaes Exp $
|
||||||
*
|
*
|
||||||
* Misc. routines which are used by the various functions to handle strings
|
* Misc. routines which are used by the various functions to handle strings
|
||||||
* and memory allocation and pretty much anything else we can think of. Also,
|
* and memory allocation and pretty much anything else we can think of. Also,
|
||||||
@ -32,28 +32,35 @@
|
|||||||
*/
|
*/
|
||||||
#ifndef NDEBUG
|
#ifndef NDEBUG
|
||||||
|
|
||||||
void *debugging_calloc(size_t nmemb, size_t size, const char *file, unsigned long line)
|
void *
|
||||||
|
debugging_calloc(size_t nmemb, size_t size, const char *file,
|
||||||
|
unsigned long line)
|
||||||
{
|
{
|
||||||
void *ptr = calloc(nmemb, size);
|
void *ptr = calloc(nmemb, size);
|
||||||
fprintf(stderr, "{calloc: %p:%u x %u} %s:%lu\n", ptr, nmemb, size, file, line);
|
fprintf(stderr, "{calloc: %p:%u x %u} %s:%lu\n", ptr, nmemb, size, file,
|
||||||
|
line);
|
||||||
return ptr;
|
return ptr;
|
||||||
}
|
}
|
||||||
|
|
||||||
void *debugging_malloc(size_t size, const char *file, unsigned long line)
|
void *
|
||||||
|
debugging_malloc(size_t size, const char *file, unsigned long line)
|
||||||
{
|
{
|
||||||
void *ptr = malloc(size);
|
void *ptr = malloc(size);
|
||||||
fprintf(stderr, "{malloc: %p:%u} %s:%lu\n", ptr, size, file, line);
|
fprintf(stderr, "{malloc: %p:%u} %s:%lu\n", ptr, size, file, line);
|
||||||
return ptr;
|
return ptr;
|
||||||
}
|
}
|
||||||
|
|
||||||
void *debugging_realloc(void *ptr, size_t size, const char *file, unsigned long line)
|
void *
|
||||||
|
debugging_realloc(void *ptr, size_t size, const char *file, unsigned long line)
|
||||||
{
|
{
|
||||||
void *newptr = realloc(ptr, size);
|
void *newptr = realloc(ptr, size);
|
||||||
fprintf(stderr, "{realloc: %p -> %p:%u} %s:%lu\n", ptr, newptr, size, file, line);
|
fprintf(stderr, "{realloc: %p -> %p:%u} %s:%lu\n", ptr, newptr, size,
|
||||||
|
file, line);
|
||||||
return newptr;
|
return newptr;
|
||||||
}
|
}
|
||||||
|
|
||||||
void debugging_free(void *ptr, const char *file, unsigned long line)
|
void
|
||||||
|
debugging_free(void *ptr, const char *file, unsigned long line)
|
||||||
{
|
{
|
||||||
fprintf(stderr, "{free: %p} %s:%lu\n", ptr, file, line);
|
fprintf(stderr, "{free: %p} %s:%lu\n", ptr, file, line);
|
||||||
free(ptr);
|
free(ptr);
|
||||||
@ -66,17 +73,16 @@ void debugging_free(void *ptr, const char *file, unsigned long line)
|
|||||||
/*
|
/*
|
||||||
* Build the data for a complete HTTP & HTML message for the client.
|
* Build the data for a complete HTTP & HTML message for the client.
|
||||||
*/
|
*/
|
||||||
int send_http_message(struct conn_s* connptr, int http_code,
|
int
|
||||||
const char *error_title, const char *message)
|
send_http_message(struct conn_s *connptr, int http_code,
|
||||||
|
const char *error_title, const char *message)
|
||||||
{
|
{
|
||||||
static char *headers = \
|
static char *headers =
|
||||||
"HTTP/1.0 %d %s\r\n" \
|
"HTTP/1.0 %d %s\r\n"
|
||||||
"Server: %s/%s\r\n" \
|
"Server: %s/%s\r\n"
|
||||||
"Date: %s\r\n" \
|
"Date: %s\r\n"
|
||||||
"Content-Type: text/html\r\n" \
|
"Content-Type: text/html\r\n"
|
||||||
"Content-Length: %d\r\n" \
|
"Content-Length: %d\r\n" "Connection: close\r\n" "\r\n";
|
||||||
"Connection: close\r\n" \
|
|
||||||
"\r\n";
|
|
||||||
|
|
||||||
char *header_buffer;
|
char *header_buffer;
|
||||||
char timebuf[30];
|
char timebuf[30];
|
||||||
@ -87,9 +93,11 @@ int send_http_message(struct conn_s* connptr, int http_code,
|
|||||||
return -1;
|
return -1;
|
||||||
|
|
||||||
global_time = time(NULL);
|
global_time = time(NULL);
|
||||||
strftime(timebuf, sizeof(timebuf), "%a, %d %b %Y %H:%M:%S GMT", gmtime(&global_time));
|
strftime(timebuf, sizeof(timebuf), "%a, %d %b %Y %H:%M:%S GMT",
|
||||||
|
gmtime(&global_time));
|
||||||
|
|
||||||
snprintf(header_buffer, HEADER_SIZE - 1, headers, http_code, error_title, PACKAGE, VERSION, timebuf, strlen(message));
|
snprintf(header_buffer, HEADER_SIZE - 1, headers, http_code,
|
||||||
|
error_title, PACKAGE, VERSION, timebuf, strlen(message));
|
||||||
|
|
||||||
safe_write(connptr->client_fd, header_buffer, strlen(header_buffer));
|
safe_write(connptr->client_fd, header_buffer, strlen(header_buffer));
|
||||||
safe_write(connptr->client_fd, message, strlen(message));
|
safe_write(connptr->client_fd, message, strlen(message));
|
||||||
@ -104,15 +112,16 @@ int send_http_message(struct conn_s* connptr, int http_code,
|
|||||||
/*
|
/*
|
||||||
* Display an error to the client.
|
* Display an error to the client.
|
||||||
*/
|
*/
|
||||||
int httperr(struct conn_s *connptr, int err, const char *msg)
|
int
|
||||||
|
httperr(struct conn_s *connptr, int err, const char *msg)
|
||||||
{
|
{
|
||||||
static char *message = \
|
static char *message =
|
||||||
"<html><head><title>%s</title></head>\r\n" \
|
"<html><head><title>%s</title></head>\r\n"
|
||||||
"<body>\r\n" \
|
"<body>\r\n"
|
||||||
"<font size=\"+2\">Cache Error!</font><br>\r\n" \
|
"<font size=\"+2\">Cache Error!</font><br>\r\n"
|
||||||
"An error of type %d occurred: %s\r\n" \
|
"An error of type %d occurred: %s\r\n"
|
||||||
"<hr>\r\n" \
|
"<hr>\r\n"
|
||||||
"<font size=\"-1\"><em>Generated by %s (%s)</em></font>\r\n" \
|
"<font size=\"-1\"><em>Generated by %s (%s)</em></font>\r\n"
|
||||||
"</body></html>\r\n\r\n";
|
"</body></html>\r\n\r\n";
|
||||||
|
|
||||||
char *message_buffer;
|
char *message_buffer;
|
||||||
@ -121,7 +130,8 @@ int httperr(struct conn_s *connptr, int err, const char *msg)
|
|||||||
if (!message_buffer)
|
if (!message_buffer)
|
||||||
return -1;
|
return -1;
|
||||||
|
|
||||||
snprintf(message_buffer, MAXBUFFSIZE - 1, message, msg, err, msg, PACKAGE, VERSION);
|
snprintf(message_buffer, MAXBUFFSIZE - 1, message, msg, err, msg,
|
||||||
|
PACKAGE, VERSION);
|
||||||
|
|
||||||
if (send_http_message(connptr, err, msg, message_buffer) < 0) {
|
if (send_http_message(connptr, err, msg, message_buffer) < 0) {
|
||||||
safefree(message_buffer);
|
safefree(message_buffer);
|
||||||
@ -132,7 +142,8 @@ int httperr(struct conn_s *connptr, int err, const char *msg)
|
|||||||
return 0;
|
return 0;
|
||||||
}
|
}
|
||||||
|
|
||||||
void makedaemon(void)
|
void
|
||||||
|
makedaemon(void)
|
||||||
{
|
{
|
||||||
if (fork() != 0)
|
if (fork() != 0)
|
||||||
exit(0);
|
exit(0);
|
||||||
@ -154,7 +165,8 @@ void makedaemon(void)
|
|||||||
/*
|
/*
|
||||||
* Safely creates filename and returns the low-level file descriptor.
|
* Safely creates filename and returns the low-level file descriptor.
|
||||||
*/
|
*/
|
||||||
int create_file_safely(const char *filename)
|
int
|
||||||
|
create_file_safely(const char *filename)
|
||||||
{
|
{
|
||||||
struct stat lstatinfo;
|
struct stat lstatinfo;
|
||||||
int fildes;
|
int fildes;
|
||||||
@ -170,7 +182,8 @@ int create_file_safely(const char *filename)
|
|||||||
* existing", exit.
|
* existing", exit.
|
||||||
*/
|
*/
|
||||||
if (errno != ENOENT) {
|
if (errno != ENOENT) {
|
||||||
log_message(LOG_ERR, "create_file_safely: Error checking PID file %s: %s.",
|
log_message(LOG_ERR,
|
||||||
|
"create_file_safely: Error checking PID file %s: %s.",
|
||||||
filename, strerror(errno));
|
filename, strerror(errno));
|
||||||
return -1;
|
return -1;
|
||||||
}
|
}
|
||||||
@ -180,19 +193,22 @@ int create_file_safely(const char *filename)
|
|||||||
* sure an attacker can't slip in a file between the lstat()
|
* sure an attacker can't slip in a file between the lstat()
|
||||||
* and open()
|
* and open()
|
||||||
*/
|
*/
|
||||||
if ((fildes = open(filename, O_RDWR | O_CREAT | O_EXCL, 0600)) < 0) {
|
if ((fildes =
|
||||||
log_message(LOG_ERR, "create_file_safely: Could not create PID file %s: %s.",
|
open(filename, O_RDWR | O_CREAT | O_EXCL, 0600)) < 0) {
|
||||||
|
log_message(LOG_ERR,
|
||||||
|
"create_file_safely: Could not create PID file %s: %s.",
|
||||||
filename, strerror(errno));
|
filename, strerror(errno));
|
||||||
return -1;
|
return -1;
|
||||||
}
|
}
|
||||||
} else {
|
} else {
|
||||||
struct stat fstatinfo;
|
struct stat fstatinfo;
|
||||||
|
|
||||||
/*
|
/*
|
||||||
* Open an existing file.
|
* Open an existing file.
|
||||||
*/
|
*/
|
||||||
if ((fildes = open(filename, O_RDWR)) < 0) {
|
if ((fildes = open(filename, O_RDWR)) < 0) {
|
||||||
log_message(LOG_ERR, "create_file_safely: Could not open PID file %s: %s.",
|
log_message(LOG_ERR,
|
||||||
|
"create_file_safely: Could not open PID file %s: %s.",
|
||||||
filename, strerror(errno));
|
filename, strerror(errno));
|
||||||
return -1;
|
return -1;
|
||||||
}
|
}
|
||||||
@ -205,7 +221,8 @@ int create_file_safely(const char *filename)
|
|||||||
|| lstatinfo.st_mode != fstatinfo.st_mode
|
|| lstatinfo.st_mode != fstatinfo.st_mode
|
||||||
|| lstatinfo.st_ino != fstatinfo.st_ino
|
|| lstatinfo.st_ino != fstatinfo.st_ino
|
||||||
|| lstatinfo.st_dev != fstatinfo.st_dev) {
|
|| lstatinfo.st_dev != fstatinfo.st_dev) {
|
||||||
log_message(LOG_ERR, "create_file_safely: The PID file %s has been changed before it could be opened.",
|
log_message(LOG_ERR,
|
||||||
|
"create_file_safely: The PID file %s has been changed before it could be opened.",
|
||||||
filename);
|
filename);
|
||||||
close(fildes);
|
close(fildes);
|
||||||
return -1;
|
return -1;
|
||||||
@ -219,7 +236,8 @@ int create_file_safely(const char *filename)
|
|||||||
* st_mode check would also find this)
|
* st_mode check would also find this)
|
||||||
*/
|
*/
|
||||||
if (fstatinfo.st_nlink > 1 || !S_ISREG(lstatinfo.st_mode)) {
|
if (fstatinfo.st_nlink > 1 || !S_ISREG(lstatinfo.st_mode)) {
|
||||||
log_message(LOG_ERR, "create_file_safely: The PID file %s has too many links, or is not a regular file: %s.",
|
log_message(LOG_ERR,
|
||||||
|
"create_file_safely: The PID file %s has too many links, or is not a regular file: %s.",
|
||||||
filename, strerror(errno));
|
filename, strerror(errno));
|
||||||
close(fildes);
|
close(fildes);
|
||||||
return -1;
|
return -1;
|
||||||
@ -237,12 +255,14 @@ int create_file_safely(const char *filename)
|
|||||||
ftruncate(fildes, 0);
|
ftruncate(fildes, 0);
|
||||||
#else
|
#else
|
||||||
close(fildes);
|
close(fildes);
|
||||||
if ((fildes = open(filename, O_RDWR | O_CREAT | O_TRUNC, 0600)) < 0) {
|
if ((fildes =
|
||||||
log_message(LOG_ERR, "create_file_safely: Could not open PID file %s: %s.",
|
open(filename, O_RDWR | O_CREAT | O_TRUNC, 0600)) < 0) {
|
||||||
|
log_message(LOG_ERR,
|
||||||
|
"create_file_safely: Could not open PID file %s: %s.",
|
||||||
filename, strerror(errno));
|
filename, strerror(errno));
|
||||||
return -1;
|
return -1;
|
||||||
}
|
}
|
||||||
#endif /* HAVE_FTRUNCATE */
|
#endif /* HAVE_FTRUNCATE */
|
||||||
}
|
}
|
||||||
|
|
||||||
return fildes;
|
return fildes;
|
||||||
@ -251,7 +271,8 @@ int create_file_safely(const char *filename)
|
|||||||
/*
|
/*
|
||||||
* Write the PID of the program to the specified file.
|
* Write the PID of the program to the specified file.
|
||||||
*/
|
*/
|
||||||
void pidfile_create(const char *filename)
|
void
|
||||||
|
pidfile_create(const char *filename)
|
||||||
{
|
{
|
||||||
int fildes;
|
int fildes;
|
||||||
FILE *fd;
|
FILE *fd;
|
||||||
@ -266,14 +287,15 @@ void pidfile_create(const char *filename)
|
|||||||
* Open a stdio file over the low-level one.
|
* Open a stdio file over the low-level one.
|
||||||
*/
|
*/
|
||||||
if ((fd = fdopen(fildes, "w")) == NULL) {
|
if ((fd = fdopen(fildes, "w")) == NULL) {
|
||||||
log_message(LOG_ERR, "pidfile_create: fdopen() error on PID file %s: %s.",
|
log_message(LOG_ERR,
|
||||||
|
"pidfile_create: fdopen() error on PID file %s: %s.",
|
||||||
filename, strerror(errno));
|
filename, strerror(errno));
|
||||||
close(fildes);
|
close(fildes);
|
||||||
unlink(filename);
|
unlink(filename);
|
||||||
exit(1);
|
exit(1);
|
||||||
}
|
}
|
||||||
|
|
||||||
fprintf(fd, "%ld\n", (long)getpid());
|
fprintf(fd, "%ld\n", (long) getpid());
|
||||||
fclose(fd);
|
fclose(fd);
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -283,7 +305,8 @@ void pidfile_create(const char *filename)
|
|||||||
* buffer, and always NULL terminates the buffer. size is the size of the
|
* buffer, and always NULL terminates the buffer. size is the size of the
|
||||||
* destination buffer.
|
* destination buffer.
|
||||||
*/
|
*/
|
||||||
size_t strlcpy(char *dst, const char *src, size_t size)
|
size_t
|
||||||
|
strlcpy(char *dst, const char *src, size_t size)
|
||||||
{
|
{
|
||||||
size_t len = strlen(src);
|
size_t len = strlen(src);
|
||||||
size_t ret = len;
|
size_t ret = len;
|
||||||
@ -305,7 +328,8 @@ size_t strlcpy(char *dst, const char *src, size_t size)
|
|||||||
* buffer, which should be one more than the maximum resulting string
|
* buffer, which should be one more than the maximum resulting string
|
||||||
* length.
|
* length.
|
||||||
*/
|
*/
|
||||||
size_t strlcat(char *dst, const char *src, size_t size)
|
size_t
|
||||||
|
strlcat(char *dst, const char *src, size_t size)
|
||||||
{
|
{
|
||||||
size_t len1 = strlen(dst);
|
size_t len1 = strlen(dst);
|
||||||
size_t len2 = strlen(src);
|
size_t len2 = strlen(src);
|
||||||
|
17
src/utils.h
17
src/utils.h
@ -1,4 +1,4 @@
|
|||||||
/* $Id: utils.h,v 1.10 2001-10-25 16:58:50 rjkaes Exp $
|
/* $Id: utils.h,v 1.11 2001-11-22 00:31:10 rjkaes Exp $
|
||||||
*
|
*
|
||||||
* See 'utils.h' for a detailed description.
|
* See 'utils.h' for a detailed description.
|
||||||
*
|
*
|
||||||
@ -23,7 +23,7 @@
|
|||||||
|
|
||||||
#include "conns.h"
|
#include "conns.h"
|
||||||
|
|
||||||
extern int send_http_message(struct conn_s* connptr, int http_code,
|
extern int send_http_message(struct conn_s *connptr, int http_code,
|
||||||
const char *error_title, const char *message);
|
const char *error_title, const char *message);
|
||||||
extern int httperr(struct conn_s *connptr, int err, const char *msg);
|
extern int httperr(struct conn_s *connptr, int err, const char *msg);
|
||||||
|
|
||||||
@ -34,21 +34,24 @@ extern int create_file_safely(const char *filename);
|
|||||||
|
|
||||||
#ifndef HAVE_STRLCAT
|
#ifndef HAVE_STRLCAT
|
||||||
extern size_t strlcat(char *dst, const char *src, size_t size);
|
extern size_t strlcat(char *dst, const char *src, size_t size);
|
||||||
#endif /* HAVE_STRLCAT */
|
#endif /* HAVE_STRLCAT */
|
||||||
|
|
||||||
#ifndef HAVE_STRLCPY
|
#ifndef HAVE_STRLCPY
|
||||||
extern size_t strlcpy(char *dst, const char *src, size_t size);
|
extern size_t strlcpy(char *dst, const char *src, size_t size);
|
||||||
#endif /* HAVE_STRLCPY */
|
#endif /* HAVE_STRLCPY */
|
||||||
|
|
||||||
/*
|
/*
|
||||||
* The following is to allow for better memory checking.
|
* The following is to allow for better memory checking.
|
||||||
*/
|
*/
|
||||||
#ifndef NDEBUG
|
#ifndef NDEBUG
|
||||||
|
|
||||||
extern void *debugging_calloc(size_t nmemb, size_t size, const char *file, unsigned long line);
|
extern void *debugging_calloc(size_t nmemb, size_t size, const char *file,
|
||||||
extern void *debugging_malloc(size_t size, const char *file, unsigned long line);
|
unsigned long line);
|
||||||
|
extern void *debugging_malloc(size_t size, const char *file,
|
||||||
|
unsigned long line);
|
||||||
extern void debugging_free(void *ptr, const char *file, unsigned long line);
|
extern void debugging_free(void *ptr, const char *file, unsigned long line);
|
||||||
extern void *debugging_realloc(void *ptr, size_t size, const char *file, unsigned long line);
|
extern void *debugging_realloc(void *ptr, size_t size, const char *file,
|
||||||
|
unsigned long line);
|
||||||
|
|
||||||
# define safecalloc(x, y) debugging_calloc(x, y, __FILE__, __LINE__)
|
# define safecalloc(x, y) debugging_calloc(x, y, __FILE__, __LINE__)
|
||||||
# define safemalloc(x) debugging_malloc(x, __FILE__, __LINE__)
|
# define safemalloc(x) debugging_malloc(x, __FILE__, __LINE__)
|
||||||
|
Loading…
Reference in New Issue
Block a user