/*
File: proxy_init.c
Description: Initialization functions for proxy data structure.
*/
#include <stdio.h>
#include <stdlib.h>
#include <fcntl.h>
#include <sys/types.h>
#include <sys/socket.h>
#include <netdb.h>
#include <unistd.h>
#include <time.h>
#include "config.h"
#include "proxy_protos.h"
/* allocate memory for the main data structure */
struct mdata *
init_mdata ( char *l_name, unsigned short l_port, char *s_name,
unsigned short s_port, char *log_file, int verbose )
{
struct hostent *he;
struct mdata *md = NULL;
int ok = 0;
/* first try to resolve the server's IP address */
if ( (he = gethostbyname(s_name)) ) {
/* now allocate memory for the main data structure */
if ( (md = calloc(1,sizeof(struct mdata))) ) {
/* get max number of open files */
md->nofile = getdtablesize();
/* verbosity */
md->verbose = verbose;
/* set the server address in the main data structure */
md->server_port = s_port;
md->local_port = l_port;
md->sa.sin_family = AF_INET;
md->sa.sin_port = htons(s_port);
memcpy(&(md->sa.sin_addr), he->h_addr_list[0], sizeof(unsigned long));
memcpy(md->server_name, s_name, sizeof(md->server_name)-1);
he = gethostbyname(l_name);
md->la.sin_family = AF_INET;
md->la.sin_port = htons(l_port);
memcpy(&(md->la.sin_addr), he->h_addr_list[0], sizeof(unsigned long));
memcpy(md->local_name, l_name, sizeof(md->local_name)-1);
/* try to open the log file if one was specified. */
memcpy(md->log_file, log_file, sizeof(md->log_file)-1);
if ( md->log_file[0] ) {
md->log_fp = fopen(md->log_file,"a");
setlinebuf(md->log_fp);
log_msg(md,"===> %s version %s started",PACKAGE,VERSION);
log_msg(md,"Local host: %s",md->local_name);
log_msg(md,"Local port: %u",md->local_port);
log_msg(md,"Server host: %s",md->server_name);
log_msg(md,"Server port: %u",md->server_port);
}
/* otherwise, just use stderr. */
if ( md->log_fp == NULL )
md->log_fp = stderr;
/* allocate state structures for the file descriptors */
md->r = calloc(md->nofile,sizeof(struct rdata));
/* allocate a memory pool for the queue buffers */
md->m = g_mem_chunk_create(qdata,65536,G_ALLOC_AND_FREE);
ok = (md->r && md->m);
}
}
if ( !ok ) {
deinit_mdata(md);
md = NULL;
}
return md;
}
/* set up event queue, bind to local port, listen for connections */
int
pay_attention ( struct mdata *md )
{
struct kevent ke;
int err = 1;
/* create the kernel event queue */
if ( (md->kq = kqueue()) != -1 ) {
/* create a socket for binding to port PROXY_PORT */
if ((md->server_sock = socket(PF_INET, SOCK_STREAM, 0)) != -1) {
/* make reusable */
setsockopt(md->server_sock,
SOL_SOCKET,
SO_REUSEADDR,
(void *)&err,
sizeof(int));
if ( bind(md->server_sock,(struct sockaddr *)&(md->la),sizeof(md->la)) != -1 ) {
/* listen for incoming connections */
if ( listen(md->server_sock,SOMAXCONN) != -1 ) {
md->r[md->server_sock].status = FD_OPEN;
/* register the file descriptor with the event queue */
ke.ident = md->server_sock;
ke.filter = EVFILT_READ;
ke.flags = EV_ADD;
ke.udata = accept_client;
if ( kevent(md->kq,&ke,1,NULL,0,NULL) != -1 ) {
err = 0;
} else {
md->kevent_errors++;
}
}
}
}
}
return !err;
}
syntax highlighted by Code2HTML, v. 0.9.1