-
Notifications
You must be signed in to change notification settings - Fork 0
/
Copy pathproxy_server_with_cache.c
136 lines (109 loc) · 3.7 KB
/
proxy_server_with_cache.c
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
#include "proxy_parse.h"
#include <stdio.h>
#include <stdlib.h>
#include <string.h>
#include <sys/types.h>
#include <sys/socket.h>
#include <netinet/in.h>
#include <netdb.h>
#include <arpa/inet.h>
#include <unistd.h>
#include <fcntl.h>
#include <time.h>
#include <sys/wait.h>
#include <errno.h>
#include <pthread.h>
#include <semaphore.h>
#include <time.h>
#define MAX_BYTES 4096 //max allowed size of request/response
#define MAX_CLIENTS 400 //max number of client requests served at a time
#define MAX_SIZE 200*(1<<20) //size of the cache
#define MAX_ELEMENT_SIZE 10*(1<<20) //max size of an element in cache
typedef struct cache_element cache_element;
struct cache_element {
char* data;
int len;
char* url;
time_t lru_time_track;
cache_element* next;
};
cache_element* find(char* url);
int add_cache_element(char* data, int len, char* url);
void remove_cache_element();
int port_number = 8080;
int proxy_socketId;
pthread_t tid[MAX_CLIENTS];
sem_t semaphore;
pthread_mutex_t lock;
int main(int argc, char * argv[]) {
int client_socketId, client_len;
struct sockaddr_in server_addr, client_addr;
sem_init(&semaphore,0,MAX_CLIENTS);
pthread_mutex_init(&lock,NULL); // Initializing lock for cache
if(argc == 2) //checking whether two arguments are received or not
{
port_number = atoi(argv[1]);
}
else
{
printf("Too few arguments\n");
exit(1);
}
printf("Setting Proxy Server Port : %d\n",port_number);
proxy_socketId = socket(AF_INET, SOCK_STREAM, 0);
if( proxy_socketId < 0)
{
perror("Failed to create socket.\n");
exit(1);
}
int reuse =1;
if (setsockopt(proxy_socketId, SOL_SOCKET, SO_REUSEADDR, (const char*)&reuse, sizeof(reuse)) < 0)
perror("setsockopt(SO_REUSEADDR) failed\n");
bzero((char*)&server_addr, sizeof(server_addr));
server_addr.sin_family = AF_INET;
server_addr.sin_port = htons(port_number);
server_addr.sin_addr.s_addr = INADDR_ANY;
// Binding the socket
if( bind(proxy_socketId, (struct sockaddr*)&server_addr, sizeof(server_addr)) < 0 )
{
perror("Port is not free\n");
exit(1);
}
printf("Binding on port: %d\n",port_number);
// Proxy socket listening to the requests
int listen_status = listen(proxy_socketId, MAX_CLIENTS);
if(listen_status < 0 )
{
perror("Error while Listening !\n");
exit(1);
}
int i = 0; // Iterator for thread_id (tid) and Accepted Client_Socket for each thread
int Connected_socketId[MAX_CLIENTS]; // This array stores socket descriptors of connected clients
// Infinite Loop for accepting connections
while(1)
{
bzero((char*)&client_addr, sizeof(client_addr)); // Clears struct client_addr
client_len = sizeof(client_addr);
// Accepting the connections
client_socketId = accept(proxy_socketId, (struct sockaddr*)&client_addr,(socklen_t*)&client_len); // Accepts connection
if(client_socketId < 0)
{
fprintf(stderr, "Error in Accepting connection !\n");
exit(1);
}
else{
Connected_socketId[i] = client_socketId; // Storing accepted client into array
}
// Getting IP address and port number of client
struct sockaddr_in* client_pt = (struct sockaddr_in*)&client_addr;
struct in_addr ip_addr = client_pt->sin_addr;
char str[INET_ADDRSTRLEN]; // INET_ADDRSTRLEN: Default ip address size
inet_ntop( AF_INET, &ip_addr, str, INET_ADDRSTRLEN );
printf("Client is connected with port number: %d and ip address: %s \n",ntohs(client_addr.sin_port), str);
//printf("Socket values of index %d in main function is %d\n",i, client_socketId);
pthread_create(&tid[i],NULL,thread_fn, (void*)&Connected_socketId[i]); // Creating a thread for each client accepted
i++;
}
close(proxy_socketId); // Close socket
return 0;
}