00001 #include <unistd.h>
00002 #include <stdio.h>
00003 #include <stdlib.h>
00004 #include <string.h>
00005 #include <strings.h>
00006 #include <sys/socket.h>
00007 #include <sys/types.h>
00008 #include <netinet/in.h>
00009 #include <time.h>
00010 #include <signal.h>
00011 #include <sys/stat.h>
00012 #include <fcntl.h>
00013 #include <netdb.h>
00014 #include <arpa/inet.h>
00015 #include <gtk/gtk.h>
00016 #include <sqlite3.h>
00017
00018 #define BUFFER 4096
00019 #define MAX_QUEUE_SIZE 32
00020 #define SERVER_PORT 8080
00021 #define MAX_URL_SIZE 256 //maximum url length
00022
00023 typedef struct queue Queue;
00024
00025 sqlite3 *db2;
00026 char *zErrMsg1 = 0;
00027 int rc1;
00028 char sql_query1[BUFFER];
00029 int flag;
00030
00038 static int callback1 (void *NotUsed, int argc, char **argv, char **azColName)
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 }
00054
00058 int is_blocked(char *host_ip)
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
00067 if (zErrMsg1)
00068 sqlite3_free (zErrMsg1);
00069 }
00070
00071 if(flag)
00072 {
00073
00074 return 1;
00075 }
00076 else
00077 {
00078
00079 return 0;
00080 }
00081 }
00082
00086 int update_usage(char *client_ip, unsigned long long int bytes_downloaded, unsigned long long int bytes_uploaded)
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
00095 if (zErrMsg1)
00096 sqlite3_free (zErrMsg1);
00097 }
00098
00099 if(flag)
00100 {
00101
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
00108 if (zErrMsg1)
00109 sqlite3_free (zErrMsg1);
00110 }
00111 return 1;
00112 }
00113 else
00114 {
00115
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
00122 if (zErrMsg1)
00123 sqlite3_free (zErrMsg1);
00124 }
00125 return 0;
00126 }
00127
00128 }
00129
00130 struct queue
00131 {
00132 int data[MAX_QUEUE_SIZE];
00133 int front;
00134 int back;
00135 };
00136
00137 int listen_file_descriptor;
00138 char filename[100];
00139 char path[BUFFER];
00140
00141 int enqueue(Queue *q, int elt)
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 }
00149
00150 int dequeue(Queue *q)
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 }
00158
00159
00160 char *get_ip_from_sockfd(int sockfd)
00161 {
00162 struct sockaddr_in addr;
00163
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 }
00170
00171 void Close(int fd)
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
00180 }
00181 }
00182
00183
00184 void close_properly(int signal)
00185 {
00186 printf("Shutting down...\n");
00187 Close(listen_file_descriptor);
00188 printf("Shutdown complete.\n");
00189 exit(0);
00190 }
00191
00192
00193 ssize_t Write(int fd, const void *buf, size_t count)
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 }
00204
00205
00206 int Socket(int domain, int type, int protocol)
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 }
00218
00219
00220 void check_argument(int argc, char *argv[])
00221 {
00222 if(argc < 2)
00223 {
00224 fprintf(stderr, "usage: %s <port_number> \n", argv[0]);
00225 exit(1);
00226 }
00227 }
00228
00229
00230 void Bind(int sockfd, const struct sockaddr *my_addr, socklen_t addrlen)
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 }
00240
00241
00242 void Listen(int sockfd, int backlog)
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 }
00252
00253
00254 int Open(const char *pathname, int flags)
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
00263 }
00264 return file_descriptor;
00265 }
00266
00267
00268 void Fstat(int filedes, struct stat *buf)
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 }
00279
00280
00281 int Accept(int sockfd, struct sockaddr *addr, socklen_t *addrlen)
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 }
00292
00293
00294 ssize_t Read(int fd, void *buf, size_t count)
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 }
00305
00311 int get_host_file_descriptor(int connection_file_descriptor, char *host_url)
00312 {
00313 int host_file_descriptor;
00314 int linecnt=0;
00315 char *token;
00316 char host[BUFFER] = "Host:";
00317 char *delim = host;
00318 char *heystack, *needle = host;
00319 struct hostent *host_struct;
00320 struct in_addr h_addr;
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
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
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
00351 token = strtok(request_buffer[linecnt], "\r\n\r\n");
00352 if(token == NULL)
00353 break;
00354
00355 }while(characters_read > 0);
00356
00357
00358 for(i=0;i<linecnt;i++)
00359 {
00360 heystack = &request_buffer[i][0];
00361 token = strstr(heystack, needle);
00362 if(token!=NULL)
00363 {
00364
00365 for(j=6; token[j]!='\r' && token[j]!='\r'; j++)
00366 {
00367 host[j-6] = token[j];
00368 }
00369 host[j-6] = '\0';
00370 printf("Host=%s\n", host);
00371
00372 strcpy(host_url, host);
00373
00374 break;
00375 }
00376 }
00377
00378
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)
00394 {
00395 printf("This Website is blocked.. IP:%s\n",host_ip);
00396 return -1;
00397 }
00398
00399
00400
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
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]);
00425 strcpy(host_ip, inet_ntoa(h_addr));
00426
00427 host_port = 8080;
00428 }
00429
00430
00431
00432 host_file_descriptor = socket(AF_INET, SOCK_STREAM, 0);
00433
00434
00435 if(host_file_descriptor < 0)
00436 {
00437 fprintf(stderr, ": cannot open socket.\n");
00438 return -1;
00439 }
00440
00441
00442 bzero(&host_address, sizeof(host_address));
00443
00444
00445 host_address.sin_family = AF_INET;
00446
00447
00448 host_address.sin_port = htons(host_port);
00449
00450
00451
00452 if(inet_pton(AF_INET, inet_ntoa(h_addr), &host_address.sin_addr) <= 0)
00453 {
00454 fprintf(stderr, ": the supplied ipv4 address is incorrect.\n");
00455 return -1;
00456 }
00457
00458
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
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 }
00472
00478 int proxy_server_main(int server_port)
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;
00499
00500 time_t ticks;
00501 char time_string[BUFFER];
00502
00503 int highsock;
00504 Queue q;
00505 q.front = 0;
00506 q.back = 0;
00507 int i,j;
00508
00509
00510
00511 if(server_port <= 0)
00512 {
00513 server_port = SERVER_PORT;
00514 }
00515
00516
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));
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
00543 while(1)
00544 {
00545
00546
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;
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
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
00572 if(FD_ISSET(listen_file_descriptor, &read_file_descriptor_set))
00573 {
00574 addrlen = sizeof(client_addr[q.back]);
00575
00576
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
00583 }
00584 else
00585 {
00586
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)
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
00596 }
00597 else
00598 {
00599 total_bytes_sent[q.back] = 0;
00600 total_bytes_received[q.back] = 0;
00601 connection_count++;
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;
00612 if(connection_file_descriptor[i] == -1)
00613 continue;
00614
00615
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
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
00637 printf("Connection seems to be closed\n");
00638
00639
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
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
00655 if (zErrMsg1)
00656 sqlite3_free (zErrMsg1);
00657 }
00658
00659
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;
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
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
00690 printf("Connection seems to be closed\n");
00691
00692
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
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
00708 if (zErrMsg1)
00709 sqlite3_free (zErrMsg1);
00710 }
00711
00712
00713 update_usage(inet_ntoa(client_addr[i].sin_addr), total_bytes_received[i], total_bytes_sent[i]);
00714
00715 connection_count--;
00716 if(dequeue(&q) == -1)
00717 printf("Error: Queue is empty\n");
00718 connection_file_descriptor[i] = -1;
00719 break;
00720 }
00721 }
00722 }
00723 }
00724
00725 return 0;
00726 }
00727