Advertisement
Guest User

client

a guest
Dec 7th, 2016
70
0
Never
Not a member of Pastebin yet? Sign Up, it unlocks many cool features!
C 10.35 KB | None | 0 0
  1. /*turboclient.c*/
  2. //gcc turboclient.c -o utc && utc 128.10.104.134 23456 abcdeabcdeab kl.au configfile.dat
  3. //utc 128.10.104.134 23456 abcdeabcdeab kl.au configfile.dat
  4. #include <signal.h>
  5. #include <sys/wait.h>
  6. #include <stdio.h>
  7. #include <fcntl.h>
  8. #include <sys/stat.h>
  9. #include <sys/types.h>
  10. #include <unistd.h>
  11. #include <string.h>
  12. #include <stdlib.h>
  13. #include <netdb.h>
  14. #include <errno.h>
  15. #include <sys/socket.h>
  16. #include <netinet/in.h>
  17. #include <arpa/inet.h>
  18. #include <sys/time.h>
  19. #include "dropsendto.h"
  20. #include "p_params.h"
  21.  
  22. #define MAX_BUF 1600
  23. #define MAX_LOAD 1600
  24.  
  25. #ifndef max
  26.     #define max(a,b) ((a) > (b) ? (a) : (b))
  27. #endif
  28. void signal_sigio_hndlr(int sig);
  29.  
  30. int work_to_do = 0;
  31. void signal_sigio_hndlr(int sig){
  32.     work_to_do = 1;
  33.     //printf("HHHHHHHHHHHHHHHHHHHHHHHHHHHHAAAAAAAAAAAAAAAAANNNNNNNNNNNNNDDDDDDDDDDDLLLLLLLLLLLLEEEEEEEEEERRRRRRRRRRRR\n");
  34. }
  35.  
  36. typedef struct
  37. {
  38.     int *seq_id;
  39.     int *paylen;
  40.     int *h_exist;
  41.     char *payload;
  42. }PKINFO;
  43.  
  44. PKINFO *pckt_book = NULL;
  45.  
  46. int check_fname(char *s);
  47.  
  48. int check_fname(char *s){
  49.  
  50.     //0 means good file name
  51.     //1 means bad file name
  52.     char *c = s;
  53.     int len = strlen(s);
  54.     const char *invalid_chars = " /";
  55.     if(len>16)
  56.         return 1;
  57.     while(*c){
  58.         if(strchr(invalid_chars, *c))
  59.             return 1;
  60.         c++;
  61.     }
  62.  
  63.     return 0;
  64. }
  65.  
  66. int main(int argc, char * argv[]) {
  67.  
  68.     char *srv_name, *srv_port, *secretkey, *filename, *config_file;
  69.     struct sockaddr_in srv_addr, udp_cl;
  70.     struct sockaddr_storage from_addr;
  71.     socklen_t from_addr_len = sizeof(from_addr);
  72.     struct hostent *hp;
  73.     int len, block_size, val, fd, send_sock, sock_ack, j;
  74.     FILE *fp;
  75.     char request[MAX_BUF], f_name[MAX_BUF], r_filename[MAX_BUF], nack[25], p_ack[5] = "$P$", all_ack[5] = "$A$";
  76.  
  77.  
  78.     struct timeval tv1, tv2;
  79.     long time_elapsed = 0, bytes_read = 0;
  80.  
  81.     if (argc == 6) {
  82.         srv_name= argv[1];
  83.         srv_port = argv[2];
  84.         secretkey = argv[3];
  85.         filename = argv[4];
  86.         config_file = argv[5];
  87.     } else {
  88.         printf(
  89.             "usage: $turboclient hostname portnumber secretkey filename configfile.dat\n");
  90.         exit(1);
  91.     }
  92.  
  93.     if(check_fname(filename) == 1){
  94.         printf("Bad filename, cannot contain spaces, slashes or exceed a length of 16 ascii characters\n");
  95.         exit(1);
  96.     }
  97.  
  98.     pckt_book = (PKINFO*)malloc(CACHE_SZ * sizeof(PKINFO));
  99.  
  100.     for(j = 0; j< CACHE_SZ; j++) {
  101.         PKINFO tmp;
  102.         tmp.seq_id = (int *)malloc(sizeof(int));
  103.         tmp.paylen = (int *)malloc(sizeof(int));
  104.         tmp.h_exist = (int *)malloc(sizeof(int));
  105.         tmp.payload = (char *)malloc(MAX_LOAD);
  106.         memcpy((pckt_book + j), &tmp, sizeof(PKINFO));
  107.     }
  108.     for(j = 0; j< CACHE_SZ; j++) {
  109.         memset(pckt_book[j].seq_id, 0, sizeof(int));
  110.         memset(pckt_book[j].h_exist, 1, sizeof(int));
  111.         memset(pckt_book[j].paylen, 0, sizeof(int));
  112.         memset(pckt_book[j].payload, 0, MAX_LOAD);
  113.     }
  114.  
  115.  
  116.     //reading blocksize
  117.     fp = fopen(config_file, "r");
  118.     //fscanf stops scanning at whitespace
  119.     fscanf(fp, "%d", &block_size);
  120.     fclose(fp);
  121.  
  122.     //Setting up io signal
  123.     struct sigaction sgio;
  124.     sgio.sa_handler = signal_sigio_hndlr;
  125.     sgio.sa_flags = 0;
  126.     //sgio.sa_flags = SA_RESTART;
  127.     sigemptyset(&sgio.sa_mask);
  128.  
  129.     if (sigaction(SIGPOLL, &sgio, NULL) == -1) {
  130.         perror("sigaction sigio");
  131.         exit(1);
  132.     }
  133.  
  134.     //char recvbuf[block_size];
  135.     char recvbuf[MAX_BUF];
  136.  
  137.     hp = gethostbyname(srv_name);
  138.     if (!hp) {
  139.         printf("Error: unknown host: %s\n", srv_name);
  140.         exit(1);
  141.     }
  142.  
  143.     memset((char *) &srv_addr, 0, sizeof(srv_addr));
  144.     srv_addr.sin_family = AF_INET;
  145.     bcopy(hp->h_addr_list[0], (char *) &srv_addr.sin_addr, hp->h_length);
  146.     srv_addr.sin_port = htons(atoi(srv_port));
  147.  
  148.     send_sock = socket(AF_INET, SOCK_DGRAM, 0);
  149.  
  150.     sprintf(request, "$%s$%s", secretkey, filename);
  151.  
  152.     if ((val = sendto(send_sock, request, strlen(request), 0, (struct sockaddr *)&srv_addr, sizeof(srv_addr))) == -1) {
  153.         perror("Send to error: forwarding");
  154.         exit(1);
  155.     }
  156.  
  157.     strcpy(f_name, "/tmp/");
  158.     strcpy(r_filename, "/tmp/");
  159.     strcat(r_filename, filename);
  160.  
  161.     srand(time(NULL));
  162.     int f_ind = rand();
  163.     char r_append[MAX_BUF];
  164.     sprintf(r_append, "_w%d", f_ind);
  165.     strcat(strcat(f_name, filename), r_append);
  166.     //printf("f_name is %s\n", f_name);
  167.  
  168.     //Read response and save it in ./filename
  169.     if (access(f_name, F_OK) != -1) {
  170.             // file exists
  171.         printf("Error: File already exists\n");
  172.         exit(1);
  173.  
  174.     } else {
  175.             // file doesn't exist, hence create it
  176.         fd = open(f_name, O_RDWR| O_APPEND | O_CREAT, S_IRUSR | S_IWUSR |S_IXUSR);
  177.  
  178.             //noting starting time
  179.         if (gettimeofday(&tv1, NULL) == -1) {
  180.             exit(1);
  181.         }
  182.         memset(recvbuf, 0, MAX_BUF);
  183.         int n_excpt = 0, seq_no = -1, p_len, buf_ind, eot_flag = 0, holes = CACHE_SZ, f_in, true_h = 0, c_rcv = 0;
  184.  
  185.  
  186.         memset((char *) &udp_cl, 0, sizeof(udp_cl));
  187.         udp_cl.sin_family = AF_INET;
  188.         bcopy(hp->h_addr_list[0], (char *) &udp_cl.sin_addr, hp->h_length);
  189.         udp_cl.sin_port = htons(0);
  190.         sock_ack = socket(AF_INET, SOCK_DGRAM, 0);
  191.         bind(sock_ack, (struct sockaddr *) &udp_cl, sizeof(udp_cl));
  192.  
  193.         fcntl(send_sock, F_SETFL, O_NONBLOCK|O_ASYNC);
  194.         fcntl(send_sock, F_SETOWN, getpid());
  195.         int dum = 0, retran;
  196.         while (1) {
  197.             memset(recvbuf, 0, MAX_BUF);
  198.             if(work_to_do == 1){
  199.                 if ((val = recvfrom(send_sock, recvbuf, MAX_BUF, 0, (struct sockaddr *) &from_addr, &from_addr_len)) > 0) {
  200.                     work_to_do = 0;
  201.                     //printf("Here000\n");
  202.                     if (val == 1) {
  203.                         eot_flag = 1;
  204.                         break;
  205.                     }
  206.                 //Update holes upon any packet reception (except EOT)
  207.                     c_rcv++;
  208.                     printf("cum recv %d\t", c_rcv);
  209.                     holes--;
  210.                     char *temp_unravel;
  211.                     char *s_et = strtok_r(recvbuf, "$", &temp_unravel);
  212.                     seq_no = atoi(s_et);
  213.                     printf("(n, s) (%d, %d)\n", n_excpt, seq_no);
  214.  
  215.                     if (n_excpt < seq_no) {
  216.                     //It's a hole, retransmission requests to be sent from n_excpt to & including seq_no
  217.                         retran = n_excpt;
  218.                         true_h += (seq_no - n_excpt);
  219.                         printf("Holes detected %d ##########\n", seq_no - retran);
  220.                         n_excpt = seq_no + 1;
  221.                     //fork child to retransmit -ve acks so that you may not lose packets being sent in that time
  222.                         if(!fork()){
  223.  
  224.                             while (seq_no > retran) {
  225.                                 memset(nack, 0, 25);
  226.                                 printf("Sendin nack %d\n", retran);
  227.                                 sprintf(nack, "$N$%d$", retran++);
  228.  
  229.                             //send from different socket
  230.                                 if ((val = sendto(sock_ack, nack, strlen(nack), 0, (struct sockaddr *) &from_addr, from_addr_len))== -1) {
  231.                                     perror("Send to nack: forwarding");
  232.                                     exit(1);
  233.                                 }
  234.                             }
  235.                             printf("Exiting child ######\n");
  236.                             exit(0);
  237.                         }
  238.                     }
  239.                     else if (n_excpt > seq_no) {
  240.                     //hole being filled
  241.                         memset(pckt_book[(seq_no%CACHE_SZ)].h_exist, 0, sizeof(int));
  242.                         true_h--;
  243.                     }
  244.                     else {
  245.                         n_excpt++;
  246.                     }
  247.                     // printf("Here111\n");
  248.                     buf_ind = seq_no % CACHE_SZ;
  249.                     p_len = val - (strlen(s_et) + 2);
  250.  
  251.                     memcpy(pckt_book[buf_ind].seq_id, &(seq_no), sizeof(seq_no));
  252.                     memcpy(pckt_book[buf_ind].paylen, &(p_len), sizeof(p_len));
  253.                     memcpy(pckt_book[buf_ind].payload, temp_unravel, p_len);
  254.                     memset(pckt_book[buf_ind].h_exist, 0, sizeof(int));
  255.  
  256.                     bytes_read += val;
  257.  
  258.                     if (holes == 0) {
  259.                         printf("true_h must 0, is %d\t \n", true_h);
  260.                         int v_wrt = 0;
  261.                         for (f_in = 0; f_in < CACHE_SZ; f_in++) {
  262.                             if ((val = write(fd, pckt_book[f_in].payload, *(pckt_book[f_in].paylen))) < 0) {
  263.                                 perror("write error\n");
  264.                                 exit(1);
  265.                             }
  266.                             v_wrt += val;
  267.  
  268.                         }
  269.                         printf("$$$$$$$$$$$$$written all %d$$$$$$$$$$$$$$$$\n", v_wrt);
  270.                         if (eot_flag == 1) {
  271.                             //All work done
  272.                             break;
  273.                         }
  274.                         else {
  275.                         //reset buffer
  276.                             for(j = 0; j< CACHE_SZ; j++) {
  277.                                 memset(pckt_book[j].seq_id, 0, sizeof(int));
  278.                                 memset(pckt_book[j].paylen, 0, sizeof(int));
  279.                                 memset(pckt_book[j].h_exist, 1, sizeof(int));
  280.                                 memset(pckt_book[j].payload, 0, MAX_LOAD);
  281.                             }
  282.  
  283.                             holes = CACHE_SZ;
  284.                             if ((val = sendto(send_sock, p_ack, strlen(p_ack), 0, (struct sockaddr *) &from_addr, from_addr_len)) == -1) {
  285.                                 perror("Send to nack: forwarding");
  286.                                 exit(1);
  287.                             }
  288.                             printf("sent p_ack %s\n", p_ack);
  289.                         }
  290.                     }
  291.                     else if (eot_flag == 1 && (true_h == 0)) {
  292.                         for (f_in = 0; f_in < (n_excpt%CACHE_SZ); f_in++) {
  293.                             write(fd, pckt_book[f_in].payload, *(pckt_book[f_in].paylen));
  294.                         }
  295.                     }
  296.                 //printf("in3\n");
  297.                 //printf("Wfn %d; holes %d true_h %d \n", n_excpt, holes, true_h);
  298.                     memset(recvbuf, 0, MAX_BUF);
  299.                     // printf("Her3333\n");
  300.                 }
  301.  
  302.             }
  303.            
  304.             if(true_h > 0){
  305.                     //Send negative acks again for the first hole
  306.                 if(!fork()){   
  307.                     for(j = 0; j< CACHE_SZ; j++) {                 
  308.                         if(*(pckt_book[j].h_exist) == 1){
  309.                             int quo = (int)n_excpt/CACHE_SZ;
  310.                             memset(nack, 0, 25);
  311.                             printf("Extra nack %d\n", quo + j);
  312.                             sprintf(nack, "$N$%d$", (quo + j));
  313.  
  314.                         //send from different socket
  315.                             if ((val = sendto(sock_ack, nack, strlen(nack), 0, (struct sockaddr *) &from_addr, from_addr_len))== -1) {
  316.                                 perror("Send to nack: forwarding");
  317.                                 exit(1);
  318.                             }
  319.                             break;
  320.                         }                  
  321.                     }
  322.                     exit(0);
  323.                 }      
  324.             }
  325.            
  326.  
  327.             // if(eot_flag && !holes){
  328.             //  for (f_in = 0; f_in < CACHE_SZ; f_in++) {
  329.             //          if ((val = write(fd, pckt_book[f_in].payload, *(pckt_book[f_in].paylen))) < 0) {
  330.             //              perror("write error\n");
  331.             //              exit(1);
  332.             //          }                  
  333.             //      }
  334.             //  break;
  335.             // }
  336.  
  337.             if(eot_flag && (true_h == 0)){
  338.                 for (f_in = 0; f_in < (n_excpt%CACHE_SZ); f_in++) {
  339.                     write(fd, pckt_book[f_in].payload, *(pckt_book[f_in].paylen));
  340.                 }
  341.                 break;
  342.             }
  343.         }
  344.  
  345.  
  346.         close(fd);
  347.  
  348.         if ((val = sendto(send_sock, all_ack, strlen(all_ack), 0, (struct sockaddr *) &from_addr, from_addr_len)) == -1) {
  349.             perror("Send to all_ack: forwarding");
  350.             exit(1);
  351.         }
  352.  
  353.             //noting ending time
  354.         if (gettimeofday(&tv2, NULL) == -1) {
  355.             exit(1);
  356.         }
  357.  
  358.         char cmd_to_exec[MAX_BUF];
  359.  
  360.             //Checking content of files
  361.         sprintf(cmd_to_exec, "cmp %s %s && echo 'SUCCESS, FILES MATCH' || echo 'FILES DO NOT MATCH'", r_filename, f_name);
  362.         system(cmd_to_exec);
  363.  
  364.             //seconds to milliseconds
  365.         time_elapsed = (tv2.tv_sec - tv1.tv_sec) * 1000.0;
  366.             //micro to milliseconds
  367.         time_elapsed += (tv2.tv_usec - tv1.tv_usec) / 1000.0;
  368.  
  369.         printf("Last seq: %d\n", seq_no);
  370.         printf("Completion time: %ld msec\n", time_elapsed);
  371.         printf("Bytes downloaded: %ld\n", bytes_read);
  372.         printf("Throughput: %f KBps\n", (float)bytes_read/time_elapsed);
  373.  
  374.     }
  375.  
  376.  
  377.  
  378.  
  379.  
  380.  
  381.     return 0;
  382. }
Advertisement
Add Comment
Please, Sign In to add comment
Advertisement