· 9 years ago · Dec 08, 2016, 12:08 AM
1/*turboserver.c*/
2//gcc turboserver.c -o uts
3//uts 23456 abcdeabcdeab configfile.dat 1
4//gcc -c dropsendto.c -o drps && gcc -c turboserver.c -o c_uts && gcc -o uts c_uts drps && uts 23456 abcdeabcdeab configfile.dat 1 1000
5// gcc -c dropsendto.c -o drps && gcc -c turboserver.c -o c_uts && gcc -o uts c_uts drps
6//
7#include <signal.h>
8#include <sys/wait.h>
9#include <stdio.h>
10#include <fcntl.h>
11#include <sys/stat.h>
12#include <sys/types.h>
13#include <unistd.h>
14#include <string.h>
15#include <stdlib.h>
16#include <netdb.h>
17#include <errno.h>
18#include <sys/socket.h>
19#include <netinet/in.h>
20#include <arpa/inet.h>
21#include <sys/time.h>
22#include "dropsendto.h"
23#include "p_params.h"
24
25#define MAX_BUF 1600
26#define MYHOSTLEN 100
27
28typedef struct
29{
30 int *seq_id;
31 int *paylen;
32 char *payload;
33}PKINFO;
34
35PKINFO *pckt_book = NULL;
36int global_count = 1, loss_mod, lossnum_count, pack_rcv = 1, sockfd_rcv, ack_work_to_do = 0, all_work_done = 0;
37struct sockaddr_storage client_addr;
38socklen_t client_addr_len = sizeof(client_addr);
39
40void signal_sigio_hndlr(int sig);
41void signal_sigio_hndlr_worker();
42
43void signal_sigio_hndlr(int sig){
44 ack_work_to_do = 1;
45 //printf("HHHHHHHHHHHHHHHHHHHHHHHHHHHHAAAAAAAAAAAAAAAAANNNNNNNNNNNNNDDDDDDDDDDDLLLLLLLLLLLLEEEEEEEEEERRRRRRRRRRRR\n");
46}
47
48void signal_sigio_hndlr_worker() {
49 //receive message on sockfd_rcv
50 char *f_ack, *temp_ext;
51 char rc_buf[MAX_BUF], t_rbuf[MAX_BUF];
52 int val, retran, ac_ind;
53 struct sockaddr_storage from;
54 socklen_t from_len = sizeof(from);
55
56 memset(rc_buf, 0, MAX_BUF);
57
58 while ((val = recvfrom(sockfd_rcv, rc_buf, MAX_BUF, 0, (struct sockaddr *) &from, &from_len)) > 0) {
59
60 //printf("Feedback %s\n", rc_buf);
61
62 f_ack = strtok_r(rc_buf, "$", &temp_ext);
63
64 if(!strcmp(f_ack, "P")){
65 pack_rcv = 1;
66 ack_work_to_do = 0;
67 return;
68 }
69 else if(!strcmp(f_ack, "N")){
70 retran = atoi(temp_ext);
71 ac_ind = retran%CACHE_SZ;
72 //printf("retran %d\n", retran);
73 memset(t_rbuf, 0, MAX_BUF);
74 int ss_id = *(pckt_book[ac_ind].seq_id), ss_sz = *(pckt_book[ac_ind].paylen);
75 printf("Should match %d %d\n", retran, ss_id);
76 sprintf(t_rbuf, "$%d$", ss_id);
77 memcpy(t_rbuf + strlen(t_rbuf), pckt_book[ac_ind].payload, ss_sz);
78 if ((val = sendto(sockfd_rcv, t_rbuf, strlen(t_rbuf) + ss_sz, 0, (struct sockaddr *) &client_addr, client_addr_len)) == -1) {
79 perror("Error in sendto");
80 exit(1);
81 }
82
83 }
84 else if(!strcmp(f_ack, "A")){
85 //normal client request
86 all_work_done = 1;
87 return;
88 }
89 else{
90 ack_work_to_do = 0;
91 return;
92 }
93 memset(rc_buf, 0, MAX_BUF);
94 }
95 ack_work_to_do = 0;
96}
97
98int main(int argc, char * argv[]) {
99
100 struct sockaddr_in sin;
101 socklen_t len;
102 FILE *fp;
103 int fd, val, block_size, n, j, k, seq_no = 0, lossnum, snd_int, done_reading = 0;
104 long bytes_sent = 0;
105
106 char *srv_port, *skey_argv, *config_fname, myhost[MYHOSTLEN], rbuf[MAX_BUF], filename[MAX_BUF], *skey_decoded, *temp, *filename_t;
107
108 struct addrinfo hints, *own_info, *p_temp;
109
110 struct sockaddr_in udp_server;
111 struct hostent *hp;
112
113 if (argc == 6) {
114 srv_port = argv[1];
115 skey_argv = argv[2];
116 config_fname = argv[3];
117 lossnum = atoi(argv[4]);
118 loss_mod = atoi(argv[5]);
119 } else {
120 printf("usage: $turboserver portnumber secretkey configfile.dat lossnum\n");
121 exit(1);
122 }
123 lossnum_count = lossnum;
124 pckt_book = (PKINFO*)malloc(CACHE_SZ * sizeof(PKINFO));
125
126 for(j = 0; j< CACHE_SZ; j++) {
127 PKINFO tmp;
128 tmp.seq_id = (int *)malloc(sizeof(int));
129 tmp.paylen = (int *)malloc(sizeof(int));
130 tmp.payload = (char *)malloc(MAX_BUF);
131 memcpy((pckt_book + j), &tmp, sizeof(PKINFO));
132 }
133
134 //reading block_size
135 fp = fopen(config_fname, "r");
136 fscanf(fp, "%d", &block_size);
137 printf("block size: %d\n", block_size);
138 fclose(fp);
139
140 char read_buf[MAX_BUF], t_rbuf[MAX_BUF];
141
142 //Setting up io signal
143 struct sigaction sgio;
144 sgio.sa_handler = signal_sigio_hndlr;
145 sgio.sa_flags = 0;
146 //sgio.sa_flags = SA_RESTART;
147 sigemptyset(&sgio.sa_mask);
148
149 if (sigaction(SIGPOLL, &sgio, NULL) == -1) {
150 perror("sigaction sigio");
151 exit(1);
152 }
153
154 //prepare own name
155// gethostname(myhost, MYHOSTLEN);
156// hp = gethostbyname(myhost);
157// bcopy(hp->h_addr, &(udp_server.sin_addr), hp->h_length);
158 udp_server.sin_family = AF_INET;
159 udp_server.sin_addr.s_addr = htonl(INADDR_ANY);
160 udp_server.sin_port = htons(atoi(srv_port));
161
162 //Create socket for server to receive requests
163 sockfd_rcv = socket(AF_INET, SOCK_DGRAM, 0);
164 bind(sockfd_rcv, (struct sockaddr *) &udp_server, sizeof(udp_server));
165 printf("Server running \n");
166
167 while(1){
168 //receive file request from client
169 memset(rbuf, 0, MAX_BUF);
170 if ((val = recvfrom(sockfd_rcv, rbuf, MAX_BUF, 0, (struct sockaddr *) &client_addr, &client_addr_len)) == -1) {
171 perror("Error in recvfrom call");
172 exit(1);
173 }
174
175 skey_decoded = strtok_r(rbuf, "$", &temp);
176 filename_t = strtok_r(NULL, "$", &temp);
177 strcpy(filename, "/tmp/");
178 strcat(filename, filename_t);
179
180 fcntl(sockfd_rcv, F_SETFL, O_NONBLOCK|O_ASYNC);
181 fcntl(sockfd_rcv, F_SETOWN, getpid());
182
183 if (strcmp(skey_decoded, skey_argv) == 0) {
184
185 if (access(filename, F_OK) != -1) {
186 // file exists
187 fd = open(filename, O_RDWR, S_IRUSR | S_IWUSR |S_IXUSR);
188 memset(read_buf, 0, MAX_BUF); memset(t_rbuf, 0, MAX_BUF);
189 int seq = 0;
190
191 while(1){
192 //printf("INfinity loop\n");
193 if(pack_rcv == 1){
194 for(snd_int = 0; snd_int < CACHE_SZ; snd_int++){
195 if((n = read(fd, read_buf, block_size))>0){
196 //cac_ind = (cac_ind + 1)%CACHE_SZ;
197 sprintf(t_rbuf, "$%d$", seq);
198 int t_len = strlen(t_rbuf);
199
200 memcpy(t_rbuf + t_len, read_buf, n);
201 memcpy(pckt_book[snd_int].seq_id, &seq, sizeof(seq));
202 memcpy(pckt_book[snd_int].paylen, &n, sizeof(n));
203 memcpy(pckt_book[snd_int].payload, read_buf, n);
204
205
206 //writing to the client
207 //printf("Sending %d\n", seq);
208 // if(ack_work_to_do == 1){
209 // printf("pack = %d\n", pack_rcv);
210 // signal_sigio_hndlr_worker();
211 // }
212 //usleep(100000);
213
214 if ((val = dropsendto(sockfd_rcv, t_rbuf, t_len + n, 0, (struct sockaddr *) &client_addr, client_addr_len, &global_count, &lossnum_count, lossnum, loss_mod)) > 0) {
215 if(val == 1){
216 printf("Skipping\n");
217 }
218 memset(read_buf, 0, MAX_BUF); memset(t_rbuf, 0, MAX_BUF);
219 }
220 printf("(seq, snd_int) = (%d %d)\n", seq, snd_int);
221 seq++;
222
223 //handle all acks here ?
224 if(ack_work_to_do == 1){
225 printf("pack = %d\n", pack_rcv);
226 signal_sigio_hndlr_worker();
227 }
228
229 bytes_sent += val;
230 memset(read_buf, 0, MAX_BUF); memset(t_rbuf, 0, MAX_BUF);
231 //printf("Read in %dth loop... %d\t", snd_int, n);
232 }
233 else{
234 done_reading = 1;
235 printf("Done reading\n");
236 break;
237 }
238
239 }
240 pack_rcv = 0;
241 if(done_reading == 1 || all_work_done){
242 break;
243 }
244 }
245 if(ack_work_to_do == 1){
246 printf("Here 2\n");
247 signal_sigio_hndlr_worker();
248 }
249 if(all_work_done){
250 break;
251 }
252 }
253
254 printf("Bytes sent by server on socket: %ld\n", bytes_sent);
255 bytes_sent = 0;
256
257 close(fd);
258
259 char *eot = "\0";
260 if ((val = sendto(sockfd_rcv, eot, 1, 0, (struct sockaddr *) &client_addr, client_addr_len)) > 0) {
261 }
262 printf("End of transmission packet sent\n");
263
264 while(!all_work_done){
265 if(ack_work_to_do == 1){
266 printf("Here 3\n");
267 signal_sigio_hndlr_worker();
268 }
269 }
270
271 } else {
272 // file doesn't exist
273 printf("File does not exist\n");
274 exit(1);
275 }
276 } else{
277 printf("Key mismatch\n");
278 exit(1);
279 }
280
281
282 }
283
284 return 0;
285}