/* this server is used to run on Dublin.cs.unh.edu port 5678 ONLY * It's used to accept request from madrid.cs.unh.edu and change * kernel packet dropping rate and reset the number of TCP packet loss * to 0 * It needs to be run by root because it will change proc files * It needs to be run after insert module "packet_dropper" and "change" * */ #include #include #include #include #include #include #include #include #include #include #include #include "server.h" #include "tcpblockio.h" #define BUFSIZE 10000000 #define listening_depth 2 #define SET_RATE 1 #define RECORD_LOSS 2 char buffer[BUFSIZE]; int main( int argc, char *argv[] ) { int n, len, fd, client_fd, amount, nettemp; struct sockaddr_in address, client; pid_t pid; int status, command,iteration=0; FILE * procEntry; char * pathName; float rate; pathName = malloc( 256 ); /* default to any interface. port 5678*/ fd = openserver(5678, NULL, &address); /* we are now successfully established as a server */ /* now accept a client connection (we'll block until one arrives) */ len = sizeof(client); if( (client_fd = accept(fd, (struct sockaddr *)&client, &len)) < 0 ) { perror("server accept"); exit(EXIT_FAILURE); } /* we are now successfully connected to a remote client */ fprintf(stderr, "server: connected to client at internet address %s, port %d\n", inet_ntoa(client.sin_addr), ntohs(client.sin_port)); /* now read data messages from client then write them back */ while( 1 ) { /* first read the size of the message blocks */ readblock(client_fd, (char *)&nettemp, sizeof(nettemp)); amount = ntohl(nettemp); /* secondly, read that amount of data */ if( (n=readblock(client_fd, buffer, amount)) > 0 ) { /* first all. Check what client needs me to do */ sscanf( buffer, "%d", &command ); if ( command == SET_RATE ) { sscanf( buffer, "%d %f", &command, &rate ); /* setup a directory with the rate as name */ sprintf(pathName, "%f", rate ); if ( mkdir( pathName, 777 ) ) { fprintf(stderr, "Error making direcotry\n" ); exit(EXIT_FAILURE ); } /* change kernel drop rate via /proc file system */ procEntry = fopen( "/proc/dropperInfo/dropper", "w" ); if ( procEntry == NULL ) { printf("Error opening: /proc/dropperInfo/dropper for writing\n" ); exit( EXIT_FAILURE ); } /* IP 192.168.2.2 */ fprintf( procEntry, "%f %u", rate, 0x0202A8C0 ); fclose( procEntry ); /* reset the packet loss to 0 */ procEntry = fopen( "/proc/dropperInfo/numDropped", "w" ); if ( procEntry == NULL ) { printf("Error opening: /proc/dropperInfo/numDropped for \n" ); exit( EXIT_FAILURE ); } fprintf( procEntry, "0" ); fclose( procEntry ); /* update iteration time */ iteration = 0; }/* end of set rate */ else if ( command == RECORD_LOSS ) { /* cat /proc/dropperInfo/numDropped > $rate/$i */ sprintf( pathName, "%f/%d", rate, iteration ); if ( (pid = vfork()) < 0 ) { fprintf(stderr,"error vfork()\n"); exit(EXIT_FAILURE); }else if ( pid ) { /*parent process waits*/ wait(&status); iteration ++; }else { /* child process do cat */ execlp("cat", "cat", "/proc/dropperInfo/numDropped", ">", pathName, NULL); exit(0); } } else { fprintf( stderr, "Read bad data from client\n" ); exit( EXIT_FAILURE ); } /* server writes back the data he received as ACKnowledgement*/ writeblock(client_fd, buffer, n); }/* end of if readblock OK */ else { fprintf(stderr, "error reading from client\n"); exit( EXIT_FAILURE ); } }/* end of while */ return 0; /* never reached */ }/* end of main */