proxy_server_obj.c File Reference

#include <unistd.h>
#include <stdio.h>
#include <stdlib.h>
#include <string.h>
#include <strings.h>
#include <sys/socket.h>
#include <sys/types.h>
#include <netinet/in.h>
#include <time.h>
#include <signal.h>
#include <sys/stat.h>
#include <fcntl.h>
#include <netdb.h>
#include <arpa/inet.h>
#include <gtk/gtk.h>
#include <sqlite3.h>

Go to the source code of this file.

Data Structures

struct  queue

Defines

#define BUFFER   4096
#define MAX_QUEUE_SIZE   32
#define SERVER_PORT   8080
#define MAX_URL_SIZE   256

Typedefs

typedef struct queue Queue

Functions

static int callback1 (void *NotUsed, int argc, char **argv, char **azColName)
 This is a callback function for sqlite.
int is_blocked (char *host_ip)
 To check whether ip is blocked or not.
int update_usage (char *client_ip, unsigned long long int bytes_downloaded, unsigned long long int bytes_uploaded)
 It will update database table usage_details, where network usage per IP statistics is updated.
int enqueue (Queue *q, int elt)
int dequeue (Queue *q)
char * get_ip_from_sockfd (int sockfd)
void Close (int fd)
void close_properly (int signal)
ssize_t Write (int fd, const void *buf, size_t count)
int Socket (int domain, int type, int protocol)
void check_argument (int argc, char *argv[])
void Bind (int sockfd, const struct sockaddr *my_addr, socklen_t addrlen)
void Listen (int sockfd, int backlog)
int Open (const char *pathname, int flags)
void Fstat (int filedes, struct stat *buf)
int Accept (int sockfd, struct sockaddr *addr, socklen_t *addrlen)
ssize_t Read (int fd, void *buf, size_t count)
int get_host_file_descriptor (int connection_file_descriptor, char *host_url)
 This function is called from proxy_server_main() to get file_descriptor of host It reads the client's url request header and connects to destination using proxy.iiit.ac.in, If website is in intranet then it directly connects to web server.
int proxy_server_main (int server_port)
 This is where proxy server execution starts.

Variables

sqlite3 * db2
char * zErrMsg1 = 0
int rc1
char sql_query1 [BUFFER]
int flag
int listen_file_descriptor
char filename [100]
char path [BUFFER]
 ="index.html";

Define Documentation

#define BUFFER   4096

Definition at line 18 of file proxy_server_obj.c.

#define MAX_QUEUE_SIZE   32

Definition at line 19 of file proxy_server_obj.c.

Referenced by dequeue(), enqueue(), and proxy_server_main().

#define MAX_URL_SIZE   256

Definition at line 21 of file proxy_server_obj.c.

Referenced by proxy_server_main().

#define SERVER_PORT   8080

Definition at line 20 of file proxy_server_obj.c.

Referenced by proxy_server_main().


Typedef Documentation

typedef struct queue Queue

Definition at line 23 of file proxy_server_obj.c.


Function Documentation

int Accept ( int  sockfd,
struct sockaddr *  addr,
socklen_t *  addrlen 
)

Definition at line 281 of file proxy_server_obj.c.

00282 {
00283     int file_descriptor;
00284     file_descriptor = accept(sockfd, addr, addrlen);
00285     if(file_descriptor < 0)
00286     {
00287     perror("accept() failed.");
00288     return -1;
00289     }
00290     return file_descriptor;
00291 }

void Bind ( int  sockfd,
const struct sockaddr *  my_addr,
socklen_t  addrlen 
)

Definition at line 230 of file proxy_server_obj.c.

Referenced by proxy_server_main().

00231 {
00232     int return_value;
00233     return_value= bind(sockfd,my_addr,addrlen);
00234     if(return_value < 0)
00235     {
00236     perror("Cannot bind");
00237     exit(1);
00238     }
00239 }

static int callback1 ( void *  NotUsed,
int  argc,
char **  argv,
char **  azColName 
) [static]

This is a callback function for sqlite.

It is called when any SELECT query is executed in sql database. Here it is used to detect if any record satisfying the query exists in database or not.

Parameters:
argc no. of tuples in a record which is passed automatically by sqlite
argv values in a record which is also passed automatically by sqlite

Definition at line 38 of file proxy_server_obj.c.

References flag.

Referenced by is_blocked(), proxy_server_main(), and update_usage().

00039 {
00040     NotUsed = 0;
00041     int i;
00042     flag = 1;
00043     if(argc)
00044     {
00045     flag=0;
00046     }
00047     for (i = 0; i < argc; i++)
00048     {
00049     printf ("%s = %s\n", azColName[i], argv[i] ? argv[i] : "NULL");
00050     }
00051     printf ("\n");
00052     return 0;
00053 }

void check_argument ( int  argc,
char *  argv[] 
)

Definition at line 220 of file proxy_server_obj.c.

00221 {
00222     if(argc < 2)
00223     {
00224     fprintf(stderr, "usage: %s <port_number> \n", argv[0]);
00225     exit(1);
00226     }
00227 }

void Close ( int  fd  ) 

Definition at line 171 of file proxy_server_obj.c.

Referenced by close_properly(), and proxy_server_main().

00172 {
00173     int return_value;
00174     return_value=close(fd);
00175     if(return_value<0)
00176     {
00177     fprintf(stderr, "Cannot close\n");
00178     perror("REASON");
00179     //return return_value;
00180     }
00181 }

void close_properly ( int  signal  ) 

Definition at line 184 of file proxy_server_obj.c.

References Close(), and listen_file_descriptor.

Referenced by proxy_server_main().

00185 {
00186     printf("Shutting down...\n");
00187     Close(listen_file_descriptor);
00188     printf("Shutdown complete.\n");
00189     exit(0);
00190 }

int dequeue ( Queue q  ) 

Definition at line 150 of file proxy_server_obj.c.

References queue::back, queue::data, queue::front, and MAX_QUEUE_SIZE.

Referenced by proxy_server_main().

00151 {
00152     if(q->back == q->front) return -1;
00153     
00154     int ret = q->data[q->front];
00155     q->front = (q->front+1) % MAX_QUEUE_SIZE;
00156     return ret; 
00157 }

int enqueue ( Queue q,
int  elt 
)

Definition at line 141 of file proxy_server_obj.c.

References queue::back, queue::data, queue::front, and MAX_QUEUE_SIZE.

Referenced by proxy_server_main().

00142 {
00143     if((q->back+1)%MAX_QUEUE_SIZE == q->front) return 0;
00144     
00145     q->data[q->back] = elt;
00146     q->back = (q->back+1) % MAX_QUEUE_SIZE;
00147     return 1;
00148 }

void Fstat ( int  filedes,
struct stat *  buf 
)

Definition at line 268 of file proxy_server_obj.c.

00269 {
00270     int return_value;
00271     return_value = fstat(filedes,buf);
00272     if(return_value == -1)
00273     {
00274     fprintf(stderr, "Cannot read file status\n");
00275     perror("REASON");
00276     exit(1);
00277     }
00278 }

int get_host_file_descriptor ( int  connection_file_descriptor,
char *  host_url 
)

This function is called from proxy_server_main() to get file_descriptor of host It reads the client's url request header and connects to destination using proxy.iiit.ac.in, If website is in intranet then it directly connects to web server.

printf("%s",request_buffer[linecnt]);

Definition at line 311 of file proxy_server_obj.c.

References BUFFER, is_blocked(), and Read().

Referenced by proxy_server_main().

00312 {
00313     int host_file_descriptor;
00314     int linecnt=0;
00315     char *token;
00316     char host[BUFFER] = "Host:";    //for strtok to break Host
00317     char *delim = host;
00318     char *heystack, *needle = host;
00319     struct hostent *host_struct;
00320     struct in_addr h_addr;    /* internet address */
00321     struct in_addr ip_10, ip_172, ip_192;
00322     struct in_addr mask_10, mask_172, mask_192;
00323     struct sockaddr_in host_address;
00324     char host_ip[256];
00325     int is_intranet = 0;
00326     int host_port = 80;
00327     char request_buffer[100][BUFFER];
00328     int characters_read;
00329     int i,j;
00330     
00331     //initialization for next connection starts here
00332     linecnt = 0;
00333     strcpy(host,"Host:");
00334     delim = host;
00335     needle = host;
00336     is_intranet = 0;
00337         host_port = 80;
00338     
00339     printf("____________________________\n\n");
00340     
00341     //storing the whole request in an array of strings.
00342     do
00343     {
00344         characters_read = Read(connection_file_descriptor, &request_buffer[linecnt], 4094);
00345         if(characters_read <= 0)
00346             break;
00347         request_buffer[linecnt][characters_read] = '\0';
00349         linecnt++;
00350         //printf("No. of line read = %d No. of characters read = %d\n", linecnt,characters_read);
00351         token = strtok(request_buffer[linecnt], "\r\n\r\n");
00352         if(token == NULL)
00353             break;
00354         
00355     }while(characters_read > 0);
00356 
00357     //Getting Host name and converting to its ip
00358     for(i=0;i<linecnt;i++)
00359     {
00360         heystack = &request_buffer[i][0];
00361         token = strstr(heystack, needle);   //delim already initialised at declaration above delim->"Host:"
00362         if(token!=NULL)
00363         {
00364             //copying exact host url to host
00365             for(j=6; token[j]!='\r' && token[j]!='\r'; j++) //host string starts from 6th char to \n or \r
00366             {
00367                 host[j-6] = token[j];
00368             }
00369             host[j-6] = '\0';
00370             printf("Host=%s\n", host);
00371             //copying host url 
00372             strcpy(host_url, host);
00373 
00374             break;  //break for outer for loop
00375         }
00376     }
00377 
00378     //Converting host address to its IP
00379     if (token == NULL) {
00380           fprintf(stderr, "Can not get host information\n");
00381           return -1;
00382         }
00383         host_struct = (struct hostent *)gethostbyname(host);
00384         if (host_struct == NULL)
00385     {
00386             fprintf(stderr,"ERROR, no such host\n");
00387             return -1;
00388         }
00389         h_addr.s_addr = *((unsigned long *) host_struct->h_addr_list[0]);
00390     strcpy(host_ip, inet_ntoa(h_addr));
00391         fprintf(stdout, "Host IP=%s\n", inet_ntoa(h_addr));
00392     
00393     if(is_blocked(host_ip) == 0 || is_blocked(host_url) == 0)   //if ip is blocked
00394     {
00395         printf("This Website is blocked.. IP:%s\n",host_ip);
00396         return -1;
00397     }
00398         
00399 
00400     //now checking IP if available in intranet 10... 172.. 192..
00401     inet_aton("10.0.0.0", &ip_10);
00402     inet_aton("172.16.0.0", &ip_172);
00403     inet_aton("192.168.0.0", &ip_192);
00404     inet_aton("255.0.0.0", &mask_10);
00405     inet_aton("255.240.0.0", &mask_172);
00406     inet_aton("255.255.0.0", &mask_192);
00407     if( ((h_addr.s_addr & mask_10.s_addr) == ip_10.s_addr)
00408         || ((h_addr.s_addr & mask_172.s_addr) == ip_172.s_addr)
00409         || ((h_addr.s_addr & mask_192.s_addr) == ip_192.s_addr)
00410            )
00411     {
00412         is_intranet = 1;
00413     }
00414     
00415     //If not an intranet website(is_intranet=0), then host will be proxy.iiit.ac.in
00416     if(is_intranet == 0)
00417     {
00418         host_struct = (struct hostent *)gethostbyname("proxy.iiit.ac.in");
00419             if (host_struct == NULL)
00420         {
00421                 fprintf(stderr,"ERROR, no such host proxy.iiit.ac.in\n");
00422                 return -1;
00423             }
00424             h_addr.s_addr = *((unsigned long *) host_struct->h_addr_list[0]);   //host ip = ip of proxy.iiit.ac.in
00425         strcpy(host_ip, inet_ntoa(h_addr));
00426             
00427         host_port = 8080;   //host port = 8080 port of proxy
00428     }
00429 
00430     //procedure of coonecting to host
00431     //try to open socket
00432         host_file_descriptor = socket(AF_INET, SOCK_STREAM, 0);
00433 
00434     //if socket opening failed then print error message and quit
00435         if(host_file_descriptor < 0)
00436         {
00437         fprintf(stderr, ": cannot open socket.\n");
00438         return -1;
00439         }
00440 
00441     //initialize struct server_address to all zeros.
00442         bzero(&host_address, sizeof(host_address));
00443 
00444         //set the protocol used to be ipv4
00445         host_address.sin_family = AF_INET;
00446 
00447         //set the port to be 80 0r 8080 stored in host_port, by default tcp day time servers
00448         host_address.sin_port = htons(host_port);
00449 
00450         //set the ip address of server
00451     //host_address.sin_addr = h_addr;
00452     if(inet_pton(AF_INET, inet_ntoa(h_addr), &host_address.sin_addr) <= 0)  //where inet_ntoa(h_addr) will return IP in string 
00453         {
00454         fprintf(stderr, ": the supplied ipv4 address  is incorrect.\n");
00455         return -1;
00456         }
00457 
00458     //connecting to host
00459     if(connect(host_file_descriptor, (struct sockaddr *) &host_address, sizeof(host_address)) < 0)
00460         {
00461         fprintf(stderr, ": cannot connect to host %s\n", inet_ntoa(h_addr));
00462         return -1;
00463         }
00464    
00465     //write the request packet came from client to host which is already stored in char request_buffer[][]
00466     for(i=0; i<linecnt; i++)
00467     {
00468         write(host_file_descriptor, request_buffer[i], strlen(request_buffer[i]));
00469     }
00470     return host_file_descriptor;
00471 }

char* get_ip_from_sockfd ( int  sockfd  ) 

Definition at line 160 of file proxy_server_obj.c.

00161 {
00162     struct sockaddr_in addr;
00163     //initialize struct server_address to all zeros.
00164         bzero(&addr, sizeof(addr));
00165     socklen_t addrlen = sizeof(addr);
00166     if(getsockname (sockfd, (struct sockaddr *) &addr, &addrlen)<0) return NULL;
00167     printf("Inside get_ip_from_sockfd : Ip is %s\n", inet_ntoa(addr.sin_addr));
00168     return inet_ntoa(addr.sin_addr);
00169 }

int is_blocked ( char *  host_ip  ) 

To check whether ip is blocked or not.

Definition at line 58 of file proxy_server_obj.c.

References callback1(), db2, flag, rc1, sql_query1, and zErrMsg1.

Referenced by get_host_file_descriptor().

00059 {
00060     flag = 1;
00061     sprintf(sql_query1, "SELECT blocked_ip from blocked_ip where blocked_ip='%s'", host_ip);
00062     rc1 = sqlite3_exec (db2, sql_query1, callback1, 0, &zErrMsg1);
00063     if (rc1 != SQLITE_OK)
00064     {
00065     fprintf (stderr, "SQL error: %s\n", zErrMsg1);
00066     // This will free zErrMsg if assigned 
00067     if (zErrMsg1)
00068         sqlite3_free (zErrMsg1);
00069     }
00070 
00071     if(flag)
00072     {
00073     //no records found... Not blocked
00074     return 1;
00075     }
00076     else
00077     {
00078     //ip blocked
00079     return 0;
00080     }
00081 }

void Listen ( int  sockfd,
int  backlog 
)

Definition at line 242 of file proxy_server_obj.c.

Referenced by proxy_server_main().

00243 {
00244     int return_value;
00245     return_value = listen(sockfd, backlog);
00246     if(return_value < 0)
00247     {
00248     perror("Cannot listen");
00249     exit(1);
00250     }
00251 }

int Open ( const char *  pathname,
int  flags 
)

Definition at line 254 of file proxy_server_obj.c.

00255 {
00256     int file_descriptor;
00257     file_descriptor=open(pathname,flags);
00258     if(file_descriptor < 0)
00259     {
00260     fprintf(stderr, "Cannot open file\n");
00261     perror("REASON");
00262     //exit(1);
00263     }
00264     return file_descriptor;
00265 }

int proxy_server_main ( int  server_port  ) 

This is where proxy server execution starts.

It is called when clicked on Start Server button from GUI, and stops when Stop Server is clicked.

Parameters:
server_port it will be used to configure the server to listen on this port

Definition at line 478 of file proxy_server_obj.c.

References queue::back, Bind(), BUFFER, callback1(), Close(), close_properly(), db2, dequeue(), enqueue(), queue::front, get_host_file_descriptor(), Listen(), listen_file_descriptor, MAX_QUEUE_SIZE, MAX_URL_SIZE, rc1, SERVER_PORT, Socket(), sql_query1, update_usage(), and zErrMsg1.

00479 {
00480     int connection_file_descriptor[MAX_QUEUE_SIZE]; 
00481     int host_file_descriptor[MAX_QUEUE_SIZE];
00482     unsigned long long int total_bytes_sent[MAX_QUEUE_SIZE];
00483     unsigned long long int total_bytes_received[MAX_QUEUE_SIZE];
00484     int connection_count = 0;
00485     char input_data[BUFFER];
00486    
00487     char host_url[MAX_QUEUE_SIZE][MAX_URL_SIZE];
00488     struct sockaddr_in server_address;
00489     struct sigaction act1;
00490     struct sockaddr_in client_addr[MAX_QUEUE_SIZE];
00491     socklen_t addrlen = sizeof(client_addr[0]);
00492     int characters_read;
00493     
00494     fd_set read_file_descriptor_set;
00495     int read_descriptor;
00496     int write_descriptor;
00497     int return_value;
00498     int optval = 1; //used to handle bind error
00499     
00500     time_t ticks;   //used to store time in ticks temporarily
00501     char time_string[BUFFER];
00502 
00503     int highsock;   //for slecect function's first argumrnt highsock+1
00504     Queue q;    //structure of queue type
00505     q.front = 0;    //initialization
00506     q.back = 0;     //queue is empty
00507     int i,j;
00508     
00509     
00510     //get port name 
00511     if(server_port <= 0)        //checking valid port is given
00512     {
00513         server_port = SERVER_PORT;  
00514     }
00515 
00516     //Opening database connection
00517     rc1 = sqlite3_open ("proxyDB.sqlite", &db2);
00518     if (rc1)
00519     {
00520     fprintf (stderr, "Can't open database: %s\n", sqlite3_errmsg (db2));
00521     sqlite3_close (db2);
00522     }
00523 
00524     act1.sa_handler = close_properly;
00525     sigemptyset(&act1.sa_mask);
00526     act1.sa_flags=0;
00527     sigaction(SIGINT, &act1, 0);
00528 
00529     
00530     listen_file_descriptor = Socket(AF_INET, SOCK_STREAM, 0);
00531     setsockopt(listen_file_descriptor, SOL_SOCKET, SO_REUSEADDR, (void *)&optval, sizeof(optval));  //used to handle bind error TIME-WAIT
00532 
00533     bzero(&server_address, sizeof(server_address));
00534     server_address.sin_family = AF_INET;
00535     server_address.sin_addr.s_addr  = htonl(INADDR_ANY);
00536     server_address.sin_port = htons(server_port);
00537     Bind(listen_file_descriptor, (struct sockaddr *) &server_address, sizeof(server_address));
00538     Listen(listen_file_descriptor, MAX_QUEUE_SIZE);
00539     
00540 
00541 
00542     //Now select function will work inside while loop for read and write
00543     while(1)
00544     {
00545         //should be under while loop 
00546         //as select would modify this set and clear fds where we cant read without getting blocked
00547         FD_ZERO(&read_file_descriptor_set);
00548         FD_SET(listen_file_descriptor, &read_file_descriptor_set);
00549         highsock = listen_file_descriptor;
00550         for(j=0; j<connection_count; j++)
00551         {
00552         i = (j+q.front) % MAX_QUEUE_SIZE;   //i is index in Queue
00553         if(connection_file_descriptor[i] == -1)
00554             continue;
00555             FD_SET(connection_file_descriptor[i], &read_file_descriptor_set);
00556         if(highsock<connection_file_descriptor[i])
00557             highsock = connection_file_descriptor[i];
00558             FD_SET(host_file_descriptor[i], &read_file_descriptor_set);
00559         if(highsock<host_file_descriptor[i])
00560             highsock = host_file_descriptor[i];
00561         }
00562 
00563         //block till can read from one of the two file descriptors
00564         return_value =select(highsock+1, &read_file_descriptor_set, NULL, NULL, NULL);
00565         if(return_value<0)
00566         {
00567         perror("Select failed");
00568         exit(EXIT_FAILURE);
00569         }
00570 
00571         //see if listen_socket can be read that means we have new connection in queue, so accept it
00572         if(FD_ISSET(listen_file_descriptor, &read_file_descriptor_set))
00573         {
00574         addrlen = sizeof(client_addr[q.back]);  //for passing it to accept()
00575 
00576         //[q.back] is the ith connection  and extrcting IP of client using accept()
00577         connection_file_descriptor[q.back] = accept(listen_file_descriptor, (struct sockaddr *) &client_addr[q.back],&addrlen); 
00578 
00579         if(connection_file_descriptor[q.back] < 0)
00580         {
00581             perror("accept() failed.");
00582             //exit(EXIT_FAILURE);
00583         }
00584         else
00585         {
00586             //User defined function for getting actual host file descriptor
00587             host_file_descriptor[q.back] = get_host_file_descriptor(connection_file_descriptor[q.back], host_url[q.back]);  
00588             
00589             if(host_file_descriptor[q.back] < 0)    //if unable to get host_file_descriptor
00590             {
00591             fprintf(stderr, ": can not connect to host.\n");
00592             Close(connection_file_descriptor[q.back]);
00593             printf("Connection to client closed\n");
00594             connection_file_descriptor[q.back] = -1;
00595             //return -1;
00596             }
00597             else
00598             {
00599                 total_bytes_sent[q.back] = 0;   //total bytes uploaded=0
00600                 total_bytes_received[q.back] = 0;   //total bytes downloaded=0
00601                 connection_count++;         //incrementing Counter no. of clients connected
00602                 if(enqueue(&q,1) != 1)
00603                 printf("Error:Queue size exceeds\n");
00604                 printf("Got client%d for connection1. HostFD=%d ConnectionFD=%d\n",connection_count,host_file_descriptor[q.back-1], connection_file_descriptor[q.back-1]);
00605             }
00606         }
00607         }   
00608 
00609         for(j=0; j<connection_count; j++)
00610         {
00611             i = (j+q.front) % MAX_QUEUE_SIZE;   //i is index in Queue
00612             if(connection_file_descriptor[i] == -1) //for safety purpose checking invalid descriptor
00613             continue;
00614             //see from which descriptor we can read and set variables
00615             //read_descriptor and write_descriptor appropriately
00616             if(FD_ISSET(host_file_descriptor[i], &read_file_descriptor_set))
00617             {
00618                 read_descriptor=host_file_descriptor[i];
00619                 write_descriptor=connection_file_descriptor[i];
00620 
00621                 //read from read_descriptor and write to write_descriptor
00622                 characters_read=read(read_descriptor, input_data, BUFFER-1);
00623                 if(characters_read > 0)
00624                 {
00625                 input_data[characters_read]='\0';
00626                 write(write_descriptor, input_data, characters_read);
00627                 total_bytes_received[i] = total_bytes_received[i] + characters_read;
00628                 }
00629                 else if(characters_read<0)
00630                 {
00631                 perror("Read failed");
00632                 break;
00633                 }
00634                 else
00635                 {
00636                 // characters_read=0, and return on blocking IO means connection1 closed.
00637                 printf("Connection seems to be closed\n");
00638                 
00639                 //closing connections
00640                 Close(host_file_descriptor[i]);
00641                 printf("Connection to host closed\n");
00642                 Close(connection_file_descriptor[i]);
00643                 printf("Connection to client closed\n");
00644 
00645                 //making timestamp
00646                 ticks = time(NULL); 
00647                 snprintf(time_string, sizeof(time_string), "%.24s", ctime(&ticks));
00648         
00649                 sprintf(sql_query1, "INSERT into log_details values('%s', '%s', %llu, %llu, '%s')", inet_ntoa(client_addr[i].sin_addr), time_string, total_bytes_received[i], total_bytes_sent[i], host_url[i]);
00650                 rc1 = sqlite3_exec (db2, sql_query1, callback1, 0, &zErrMsg1);
00651                 if (rc1 != SQLITE_OK)
00652                 {
00653                     fprintf (stderr, "SQL error: %s\n", zErrMsg1);
00654                     // This will free zErrMsg if assigned 
00655                     if (zErrMsg1)
00656                         sqlite3_free (zErrMsg1);
00657                 }
00658 
00659                 //updating per user IP statistics
00660                 update_usage(inet_ntoa(client_addr[i].sin_addr), total_bytes_received[i], total_bytes_sent[i]);
00661 
00662                 connection_count--;
00663                 if(dequeue(&q) == -1)
00664                     printf("Error: Queue is empty\n");
00665                 connection_file_descriptor[i] = -1; //to detect in array this is invalid FD
00666                 break;
00667                 }
00668             }
00669             if(FD_ISSET(connection_file_descriptor[i], &read_file_descriptor_set))
00670             {
00671                 read_descriptor=connection_file_descriptor[i];
00672                 write_descriptor=host_file_descriptor[i];
00673                 
00674                 //read from read_descriptor and write to write_descriptor
00675                 characters_read=read(read_descriptor, input_data, BUFFER-1);
00676                 if(characters_read > 0)
00677                 {
00678                 input_data[characters_read]='\0';
00679                 write(write_descriptor, input_data, characters_read);
00680                 total_bytes_sent[i] = total_bytes_sent[i] + characters_read;    
00681                 }
00682                 else if(characters_read<0)
00683                 {
00684                 perror("Read failed");
00685                 break;
00686                 }
00687                 else
00688                 {
00689                 // characters_read=0, and return on blocking IO means connection1 closed.
00690                 printf("Connection seems to be closed\n");
00691                 
00692                 //closing connections
00693                 Close(host_file_descriptor[i]);
00694                 printf("Connection to host closed\n");
00695                 Close(connection_file_descriptor[i]);
00696                 printf("Connection to client closed\n");
00697                 
00698                 //making timestamp
00699                 ticks = time(NULL); 
00700                 snprintf(time_string, sizeof(time_string), "%.24s", ctime(&ticks));
00701             
00702                 sprintf(sql_query1, "INSERT into log_details values('%s', '%s', %llu, %llu, '%s')", inet_ntoa(client_addr[i].sin_addr), time_string, total_bytes_received[i], total_bytes_sent[i], host_url[i]);
00703                 rc1 = sqlite3_exec (db2, sql_query1, callback1, 0, &zErrMsg1);
00704                 if (rc1 != SQLITE_OK)
00705                 {
00706                     fprintf (stderr, "SQL error: %s\n", zErrMsg1);
00707                     // This will free zErrMsg if assigned 
00708                     if (zErrMsg1)
00709                         sqlite3_free (zErrMsg1);
00710                 }
00711 
00712                 //updating per user IP statistics
00713                 update_usage(inet_ntoa(client_addr[i].sin_addr), total_bytes_received[i], total_bytes_sent[i]);
00714 
00715                 connection_count--; //decrementing counter
00716                 if(dequeue(&q) == -1)   //removing FD entry from queue
00717                     printf("Error: Queue is empty\n");
00718                 connection_file_descriptor[i] = -1; //to detect in array this is invalid FD
00719                 break;
00720                 }
00721             }    
00722         }
00723     }
00724 
00725     return 0;
00726 }

ssize_t Read ( int  fd,
void *  buf,
size_t  count 
)

Definition at line 294 of file proxy_server_obj.c.

Referenced by get_host_file_descriptor().

00295 {
00296     ssize_t characters_read;
00297     characters_read = read(fd, buf, count);
00298     if(characters_read < 0)
00299     {
00300     perror("Can't read");
00301     return -1;
00302     }
00303     return characters_read;
00304 }

int Socket ( int  domain,
int  type,
int  protocol 
)

Definition at line 206 of file proxy_server_obj.c.

Referenced by proxy_server_main().

00207 {
00208     int return_value;
00209     return_value = socket(domain, type, protocol);
00210     if(return_value < 0)
00211     {
00212     fprintf(stderr, "Cannot open socket.\n");
00213     perror("REASON");
00214     exit(1);
00215     }
00216     return return_value;
00217 }

int update_usage ( char *  client_ip,
unsigned long long int  bytes_downloaded,
unsigned long long int  bytes_uploaded 
)

It will update database table usage_details, where network usage per IP statistics is updated.

Definition at line 86 of file proxy_server_obj.c.

References callback1(), db2, flag, rc1, sql_query1, and zErrMsg1.

Referenced by proxy_server_main().

00087 {
00088     flag = 1;
00089     sprintf(sql_query1, "SELECT client_ip from usage_details where client_ip='%s'", client_ip);
00090     rc1 = sqlite3_exec (db2, sql_query1, callback1, 0, &zErrMsg1);
00091     if (rc1 != SQLITE_OK)
00092     {
00093     fprintf (stderr, "SQL error: %s\n", zErrMsg1);
00094     // This will free zErrMsg if assigned 
00095     if (zErrMsg1)
00096         sqlite3_free (zErrMsg1);
00097     }
00098 
00099     if(flag)
00100     {
00101     //no records found... Need to insert
00102         sprintf(sql_query1, "INSERT into usage_details values('%s', %llu, %llu)", client_ip, bytes_downloaded, bytes_uploaded);
00103         rc1 = sqlite3_exec (db2, sql_query1, callback1, 0, &zErrMsg1);
00104         if (rc1 != SQLITE_OK)
00105         {
00106         fprintf (stderr, "SQL error: %s\n", zErrMsg1);
00107         // This will free zErrMsg if assigned 
00108         if (zErrMsg1)
00109             sqlite3_free (zErrMsg1);
00110         }   
00111     return 1;
00112     }
00113     else
00114     {
00115     //record present ... Need to update
00116         sprintf(sql_query1, "UPDATE usage_details SET downloads = downloads + %llu, uploads = uploads + %llu where client_ip='%s'", bytes_downloaded, bytes_uploaded, client_ip);
00117         rc1 = sqlite3_exec (db2, sql_query1, callback1, 0, &zErrMsg1);
00118         if (rc1 != SQLITE_OK)
00119         {
00120         fprintf (stderr, "SQL error: %s\n", zErrMsg1);
00121         // This will free zErrMsg if assigned 
00122         if (zErrMsg1)
00123             sqlite3_free (zErrMsg1);
00124         }   
00125     return 0;
00126     }
00127 
00128 }

ssize_t Write ( int  fd,
const void *  buf,
size_t  count 
)

Definition at line 193 of file proxy_server_obj.c.

00194 {
00195     ssize_t return_value;
00196     return_value=write(fd,buf,count);
00197     if(return_value < 0)
00198     {
00199     perror("Write failed\n");
00200     return -1;
00201     }
00202     return return_value;
00203 }


Variable Documentation

sqlite3* db2

Definition at line 25 of file proxy_server_obj.c.

Referenced by is_blocked(), proxy_server_main(), and update_usage().

char filename[100]

Definition at line 138 of file proxy_server_obj.c.

int flag

Definition at line 29 of file proxy_server_obj.c.

Referenced by callback1(), is_blocked(), and update_usage().

Definition at line 137 of file proxy_server_obj.c.

Referenced by close_properly(), and proxy_server_main().

char path[BUFFER]

="index.html";

Definition at line 139 of file proxy_server_obj.c.

int rc1

Definition at line 27 of file proxy_server_obj.c.

Referenced by is_blocked(), proxy_server_main(), and update_usage().

char sql_query1[BUFFER]

Definition at line 28 of file proxy_server_obj.c.

Referenced by is_blocked(), proxy_server_main(), and update_usage().

char* zErrMsg1 = 0

Definition at line 26 of file proxy_server_obj.c.

Referenced by is_blocked(), proxy_server_main(), and update_usage().

 All Data Structures Files Functions Variables Typedefs Defines

Generated on Wed Apr 7 23:49:15 2010 for Doxygentestproject by  doxygen 1.6.1