diff --git a/438CommunicationNetworks/ComputerNetworksASystemsApproach.pdf b/438CommunicationNetworks/ComputerNetworksASystemsApproach.pdf new file mode 100644 index 0000000..a8c6745 Binary files /dev/null and b/438CommunicationNetworks/ComputerNetworksASystemsApproach.pdf differ diff --git a/438CommunicationNetworks/Exams/Final Short Answer.docx b/438CommunicationNetworks/Exams/Final Short Answer.docx new file mode 100644 index 0000000..09561bd Binary files /dev/null and b/438CommunicationNetworks/Exams/Final Short Answer.docx differ diff --git a/438CommunicationNetworks/Exams/Final Study Guide.docx b/438CommunicationNetworks/Exams/Final Study Guide.docx new file mode 100644 index 0000000..c22ab56 Binary files /dev/null and b/438CommunicationNetworks/Exams/Final Study Guide.docx differ diff --git a/438CommunicationNetworks/Exams/final-study-s17.pdf b/438CommunicationNetworks/Exams/final-study-s17.pdf new file mode 100644 index 0000000..c7acab2 Binary files /dev/null and b/438CommunicationNetworks/Exams/final-study-s17.pdf differ diff --git a/438CommunicationNetworks/Exams/mtstudyguide.pdf b/438CommunicationNetworks/Exams/mtstudyguide.pdf new file mode 100644 index 0000000..023396b Binary files /dev/null and b/438CommunicationNetworks/Exams/mtstudyguide.pdf differ diff --git a/438CommunicationNetworks/PSsolutions/ps1-sol.pdf b/438CommunicationNetworks/PSsolutions/ps1-sol.pdf new file mode 100644 index 0000000..e7dba6d Binary files /dev/null and b/438CommunicationNetworks/PSsolutions/ps1-sol.pdf differ diff --git a/438CommunicationNetworks/PSsolutions/ps2-sol.pdf b/438CommunicationNetworks/PSsolutions/ps2-sol.pdf new file mode 100644 index 0000000..9af0f91 Binary files /dev/null and b/438CommunicationNetworks/PSsolutions/ps2-sol.pdf differ diff --git a/438CommunicationNetworks/PSsolutions/ps3-sol.pdf b/438CommunicationNetworks/PSsolutions/ps3-sol.pdf new file mode 100644 index 0000000..41dd2a9 Binary files /dev/null and b/438CommunicationNetworks/PSsolutions/ps3-sol.pdf differ diff --git a/438CommunicationNetworks/PSsolutions/ps5-sol.pdf b/438CommunicationNetworks/PSsolutions/ps5-sol.pdf new file mode 100644 index 0000000..cc8dcff Binary files /dev/null and b/438CommunicationNetworks/PSsolutions/ps5-sol.pdf differ diff --git a/438CommunicationNetworks/PSsolutions/ps6-sol.pdf b/438CommunicationNetworks/PSsolutions/ps6-sol.pdf new file mode 100644 index 0000000..60c0013 Binary files /dev/null and b/438CommunicationNetworks/PSsolutions/ps6-sol.pdf differ diff --git a/438CommunicationNetworks/PSsolutions/ps7-sol.pdf b/438CommunicationNetworks/PSsolutions/ps7-sol.pdf new file mode 100644 index 0000000..2674121 Binary files /dev/null and b/438CommunicationNetworks/PSsolutions/ps7-sol.pdf differ diff --git a/438CommunicationNetworks/SVN repo/MP0/Makefile b/438CommunicationNetworks/SVN repo/MP0/Makefile new file mode 100755 index 0000000..1a3b759 --- /dev/null +++ b/438CommunicationNetworks/SVN repo/MP0/Makefile @@ -0,0 +1,39 @@ +# CS438 - spring 2013 MP0 +# +# This is a simple example of a makefile, use this for reference when you create your own +# +# NOTE: if you decide to write your solution in C++, you will have to change the compiler +# in this file. + +CC=/usr/bin/gcc +CC_OPTS=-g3 +CC_LIBS= +CC_DEFINES= +CC_INCLUDES= +CC_ARGS=${CC_OPTS} ${CC_LIBS} ${CC_DEFINES} ${CC_INCLUDES} + +# clean is not a file +.PHONY=clean + +#target "all" depends on all others +all: client server listener talker mp0client + +# client C depends on source file client.c, if that changes, make client will +# rebuild the binary +mp0client: mp0client.c + @${CC} ${CC_ARGS} -o mp0client mp0client.c + +client: client.c + @${CC} ${CC_ARGS} -o client client.c + +listener: listener.c + @${CC} ${CC_ARGS} -o listener listener.c + +talker: talker.c + @${CC} ${CC_ARGS} -o talker talker.c + +server: server.c + @${CC} ${CC_ARGS} -o server server.c + +clean: + @rm -f talker server client listener mp0client *.o \ No newline at end of file diff --git a/438CommunicationNetworks/SVN repo/MP0/client.c b/438CommunicationNetworks/SVN repo/MP0/client.c new file mode 100755 index 0000000..b494807 --- /dev/null +++ b/438CommunicationNetworks/SVN repo/MP0/client.c @@ -0,0 +1,94 @@ +/* +** client.c -- a stream socket client demo +*/ + +#include +#include +#include +#include +#include +#include +#include +#include +#include + +#include + +#define PORT "3490" // the port client will be connecting to + +#define MAXDATASIZE 100 // max number of bytes we can get at once + +// get sockaddr, IPv4 or IPv6: +void *get_in_addr(struct sockaddr *sa) +{ + if (sa->sa_family == AF_INET) { + return &(((struct sockaddr_in*)sa)->sin_addr); + } + + return &(((struct sockaddr_in6*)sa)->sin6_addr); +} + +int main(int argc, char *argv[]) +{ + int sockfd, numbytes; + char buf[MAXDATASIZE]; + struct addrinfo hints, *servinfo, *p; + int rv; + char s[INET6_ADDRSTRLEN]; + + if (argc != 2) { + fprintf(stderr,"usage: client hostname\n"); + exit(1); + } + + memset(&hints, 0, sizeof hints); + hints.ai_family = AF_UNSPEC; + hints.ai_socktype = SOCK_STREAM; + + if ((rv = getaddrinfo(argv[1], PORT, &hints, &servinfo)) != 0) { + fprintf(stderr, "getaddrinfo: %s\n", gai_strerror(rv)); + return 1; + } + + // loop through all the results and connect to the first we can + for(p = servinfo; p != NULL; p = p->ai_next) { + if ((sockfd = socket(p->ai_family, p->ai_socktype, + p->ai_protocol)) == -1) { + perror("client: socket"); + continue; + } + + if (connect(sockfd, p->ai_addr, p->ai_addrlen) == -1) { + close(sockfd); + perror("client: connect"); + continue; + } + + break; + } + + if (p == NULL) { + fprintf(stderr, "client: failed to connect\n"); + return 2; + } + + inet_ntop(p->ai_family, get_in_addr((struct sockaddr *)p->ai_addr), + s, sizeof s); + printf("client: connecting to %s\n", s); + + freeaddrinfo(servinfo); // all done with this structure + + if ((numbytes = recv(sockfd, buf, MAXDATASIZE-1, 0)) == -1) { + perror("recv"); + exit(1); + } + + buf[numbytes] = '\0'; + + printf("client: received '%s'\n",buf); + + close(sockfd); + + return 0; +} + diff --git a/438CommunicationNetworks/SVN repo/MP0/listener.c b/438CommunicationNetworks/SVN repo/MP0/listener.c new file mode 100755 index 0000000..e76aec9 --- /dev/null +++ b/438CommunicationNetworks/SVN repo/MP0/listener.c @@ -0,0 +1,95 @@ +/* +** listener.c -- a datagram sockets "server" demo +*/ + +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include + +#define MYPORT "4950" // the port users will be connecting to + +#define MAXBUFLEN 100 + +// get sockaddr, IPv4 or IPv6: +void *get_in_addr(struct sockaddr *sa) +{ + if (sa->sa_family == AF_INET) { + return &(((struct sockaddr_in*)sa)->sin_addr); + } + + return &(((struct sockaddr_in6*)sa)->sin6_addr); +} + +int main(void) +{ + int sockfd; + struct addrinfo hints, *servinfo, *p; + int rv; + int numbytes; + struct sockaddr_storage their_addr; + char buf[MAXBUFLEN]; + socklen_t addr_len; + char s[INET6_ADDRSTRLEN]; + + memset(&hints, 0, sizeof hints); + hints.ai_family = AF_UNSPEC; // set to AF_INET to force IPv4 + hints.ai_socktype = SOCK_DGRAM; + hints.ai_flags = AI_PASSIVE; // use my IP + + if ((rv = getaddrinfo(NULL, MYPORT, &hints, &servinfo)) != 0) { + fprintf(stderr, "getaddrinfo: %s\n", gai_strerror(rv)); + return 1; + } + + // loop through all the results and bind to the first we can + for(p = servinfo; p != NULL; p = p->ai_next) { + if ((sockfd = socket(p->ai_family, p->ai_socktype, + p->ai_protocol)) == -1) { + perror("listener: socket"); + continue; + } + + if (bind(sockfd, p->ai_addr, p->ai_addrlen) == -1) { + close(sockfd); + perror("listener: bind"); + continue; + } + + break; + } + + if (p == NULL) { + fprintf(stderr, "listener: failed to bind socket\n"); + return 2; + } + + freeaddrinfo(servinfo); + + printf("listener: waiting to recvfrom...\n"); + + addr_len = sizeof their_addr; + if ((numbytes = recvfrom(sockfd, buf, MAXBUFLEN-1 , 0, + (struct sockaddr *)&their_addr, &addr_len)) == -1) { + perror("recvfrom"); + exit(1); + } + + printf("listener: got packet from %s\n", + inet_ntop(their_addr.ss_family, + get_in_addr((struct sockaddr *)&their_addr), + s, sizeof s)); + printf("listener: packet is %d bytes long\n", numbytes); + buf[numbytes] = '\0'; + printf("listener: packet contains \"%s\"\n", buf); + + close(sockfd); + + return 0; +} diff --git a/438CommunicationNetworks/SVN repo/MP0/mp0client.c b/438CommunicationNetworks/SVN repo/MP0/mp0client.c new file mode 100644 index 0000000..537f4c0 --- /dev/null +++ b/438CommunicationNetworks/SVN repo/MP0/mp0client.c @@ -0,0 +1,149 @@ +/* +** client.c -- a stream socket client demo +*/ + +#include +#include +#include +#include +#include +#include +#include +#include +#include + +#include + +#define MAXDATASIZE 100 // max number of bytes we can get at once + +// get sockaddr, IPv4 or IPv6: +void *get_in_addr(struct sockaddr *sa) +{ + if (sa->sa_family == AF_INET) { + return &(((struct sockaddr_in*)sa)->sin_addr); + } + + return &(((struct sockaddr_in6*)sa)->sin6_addr); +} + +int main(int argc, char *argv[]) +{ + int sockfd, numbytes; + char buf[MAXDATASIZE]; + struct addrinfo hints, *servinfo, *p; + int rv; + char s[INET6_ADDRSTRLEN]; + + char *msg = "HELO\n"; + char *repeat = "RECV\n"; + char *bye = "BYE\n"; + char *netid_part1 = "USERNAME "; + char *netid_part2 = argv[3]; + char *netid_part3 = "\n"; + char netid[20],temp1[20],temp2[5]; + strcpy(netid,netid_part1); + strcpy(temp1,netid_part2); + strcpy(temp2,netid_part3); + strcat(netid, temp1); + strcat(netid, temp2); + + int len, bytes_sent; + + if (argc != 4) { + fprintf(stderr,"usage: client hostname\n"); + exit(1); + } + + memset(&hints, 0, sizeof hints); + hints.ai_family = AF_UNSPEC; + hints.ai_socktype = SOCK_STREAM; + + if ((rv = getaddrinfo(argv[1], argv[2], &hints, &servinfo)) != 0) { + fprintf(stderr, "getaddrinfo: %s\n", gai_strerror(rv)); + return 1; + } + + // loop through all the results and connect to the first we can + for(p = servinfo; p != NULL; p = p->ai_next) { + if ((sockfd = socket(p->ai_family, p->ai_socktype, + p->ai_protocol)) == -1) { + perror("client: socket"); + continue; + } + + if (connect(sockfd, p->ai_addr, p->ai_addrlen) == -1) { + close(sockfd); + perror("client: connect"); + continue; + } + + break; + } + + if (p == NULL) { + fprintf(stderr, "client: failed to connect\n"); + return 2; + } + + // inet_ntop(p->ai_family, get_in_addr((struct sockaddr *)p->ai_addr), + // s, sizeof s); + + freeaddrinfo(servinfo); // all done with this structure + + // HELO -> 100 - OK + len = strlen(msg); + bytes_sent = send(sockfd, msg, len, 0); + if(len != bytes_sent){ // check number of bytes sent + perror("send"); + exit(1); + } + if ((numbytes = recv(sockfd, buf, MAXDATASIZE-1, 0)) == -1) { + perror("recv"); + exit(1); + } + + // USERNAME haow4 -> 200 - Username: haow4 + len = strlen(netid); + bytes_sent = send(sockfd, netid, len, 0); + if(len != bytes_sent){ // check number of bytes sent + perror("send"); + exit(1); + } + if ((numbytes = recv(sockfd, buf, MAXDATASIZE-1, 0)) == -1) { + perror("recv"); + exit(1); + } + + // Repeat RECV + len = strlen(repeat); + for(int i = 0; i < 10; i++){ + bytes_sent = send(sockfd, repeat, len, 0); + if(len != bytes_sent){ // check number of bytes sent + perror("send"); + exit(1); + } + if ((numbytes = recv(sockfd, buf, MAXDATASIZE-1, 0)) == -1) { + perror("recv"); + exit(1); + } + buf[numbytes] = '\0'; + printf("Received: %s", buf+12); + } + + // Send bye + len = strlen(bye); + bytes_sent = send(sockfd, bye, len, 0); + if(len != bytes_sent){ // check number of bytes sent + perror("send"); + exit(1); + } + if ((numbytes = recv(sockfd, buf, MAXDATASIZE-1, 0)) == -1) { + perror("recv"); + exit(1); + } + buf[numbytes] = '\0'; + + close(sockfd); + + return 0; +} \ No newline at end of file diff --git a/438CommunicationNetworks/SVN repo/MP0/server.c b/438CommunicationNetworks/SVN repo/MP0/server.c new file mode 100755 index 0000000..74cf914 --- /dev/null +++ b/438CommunicationNetworks/SVN repo/MP0/server.c @@ -0,0 +1,128 @@ +/* +** server.c -- a stream socket server demo +*/ + +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include + +#define PORT "3490" // the port users will be connecting to + +#define BACKLOG 10 // how many pending connections queue will hold + +void sigchld_handler(int s) +{ + while(waitpid(-1, NULL, WNOHANG) > 0); +} + +// get sockaddr, IPv4 or IPv6: +void *get_in_addr(struct sockaddr *sa) +{ + if (sa->sa_family == AF_INET) { + return &(((struct sockaddr_in*)sa)->sin_addr); + } + + return &(((struct sockaddr_in6*)sa)->sin6_addr); +} + +int main(void) +{ + int sockfd, new_fd; // listen on sock_fd, new connection on new_fd + struct addrinfo hints, *servinfo, *p; + struct sockaddr_storage their_addr; // connector's address information + socklen_t sin_size; + struct sigaction sa; + int yes=1; + char s[INET6_ADDRSTRLEN]; + int rv; + + memset(&hints, 0, sizeof hints); + hints.ai_family = AF_UNSPEC; + hints.ai_socktype = SOCK_STREAM; + hints.ai_flags = AI_PASSIVE; // use my IP + + if ((rv = getaddrinfo(NULL, PORT, &hints, &servinfo)) != 0) { + fprintf(stderr, "getaddrinfo: %s\n", gai_strerror(rv)); + return 1; + } + + // loop through all the results and bind to the first we can + for(p = servinfo; p != NULL; p = p->ai_next) { + if ((sockfd = socket(p->ai_family, p->ai_socktype, + p->ai_protocol)) == -1) { + perror("server: socket"); + continue; + } + + if (setsockopt(sockfd, SOL_SOCKET, SO_REUSEADDR, &yes, + sizeof(int)) == -1) { + perror("setsockopt"); + exit(1); + } + + if (bind(sockfd, p->ai_addr, p->ai_addrlen) == -1) { + close(sockfd); + perror("server: bind"); + continue; + } + + break; + } + + if (p == NULL) { + fprintf(stderr, "server: failed to bind\n"); + return 2; + } + + freeaddrinfo(servinfo); // all done with this structure + + if (listen(sockfd, BACKLOG) == -1) { + perror("listen"); + exit(1); + } + + sa.sa_handler = sigchld_handler; // reap all dead processes + sigemptyset(&sa.sa_mask); + sa.sa_flags = SA_RESTART; + if (sigaction(SIGCHLD, &sa, NULL) == -1) { + perror("sigaction"); + exit(1); + } + + printf("server: waiting for connections...\n"); + + while(1) { // main accept() loop + sin_size = sizeof their_addr; + new_fd = accept(sockfd, (struct sockaddr *)&their_addr, &sin_size); + if (new_fd == -1) { + perror("accept"); + continue; + } + + inet_ntop(their_addr.ss_family, + get_in_addr((struct sockaddr *)&their_addr), + s, sizeof s); + printf("server: got connection from %s\n", s); + + if (!fork()) { // this is the child process + close(sockfd); // child doesn't need the listener + if (send(new_fd, "Hello, world!", 13, 0) == -1) + perror("send"); + close(new_fd); + exit(0); + } + close(new_fd); // parent doesn't need this + } + + return 0; +} + diff --git a/438CommunicationNetworks/SVN repo/MP0/talker.c b/438CommunicationNetworks/SVN repo/MP0/talker.c new file mode 100755 index 0000000..c5f5cd6 --- /dev/null +++ b/438CommunicationNetworks/SVN repo/MP0/talker.c @@ -0,0 +1,67 @@ +/* +** talker.c -- a datagram "client" demo +*/ + +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include + +#define SERVERPORT "4950" // the port users will be connecting to + +int main(int argc, char *argv[]) +{ + int sockfd; + struct addrinfo hints, *servinfo, *p; + int rv; + int numbytes; + + if (argc != 3) { + fprintf(stderr,"usage: talker hostname message\n"); + exit(1); + } + + memset(&hints, 0, sizeof hints); + hints.ai_family = AF_UNSPEC; + hints.ai_socktype = SOCK_DGRAM; + + if ((rv = getaddrinfo(argv[1], SERVERPORT, &hints, &servinfo)) != 0) { + fprintf(stderr, "getaddrinfo: %s\n", gai_strerror(rv)); + return 1; + } + + // loop through all the results and make a socket + for(p = servinfo; p != NULL; p = p->ai_next) { + if ((sockfd = socket(p->ai_family, p->ai_socktype, + p->ai_protocol)) == -1) { + perror("talker: socket"); + continue; + } + + break; + } + + if (p == NULL) { + fprintf(stderr, "talker: failed to bind socket\n"); + return 2; + } + + if ((numbytes = sendto(sockfd, argv[2], strlen(argv[2]), 0, + p->ai_addr, p->ai_addrlen)) == -1) { + perror("talker: sendto"); + exit(1); + } + + freeaddrinfo(servinfo); + + printf("talker: sent %d bytes to %s\n", numbytes, argv[1]); + close(sockfd); + + return 0; +} diff --git a/438CommunicationNetworks/SVN repo/MP1/Makefile b/438CommunicationNetworks/SVN repo/MP1/Makefile new file mode 100644 index 0000000..decd376 --- /dev/null +++ b/438CommunicationNetworks/SVN repo/MP1/Makefile @@ -0,0 +1,30 @@ +# CS438 - spring 2013 MP0 +# +# This is a simple example of a makefile, use this for reference when you create your own +# +# NOTE: if you decide to write your solution in C++, you will have to change the compiler +# in this file. + +CC=/usr/bin/g++ +CC_OPTS=-g3 +CC_LIBS= +CC_DEFINES= +CC_INCLUDES= +CC_ARGS=${CC_OPTS} ${CC_LIBS} ${CC_DEFINES} ${CC_INCLUDES} + +# clean is not a file +.PHONY=clean + +#target "all" depends on all others +all: http_client http_server + +# client C depends on source file client.c, if that changes, make client will +# rebuild the binary +http_client: http_client.cpp + @${CC} ${CC_ARGS} -o http_client http_client.cpp + +http_server: http_server.cpp + @${CC} ${CC_ARGS} -o http_server http_server.cpp + +clean: + @rm -f http_server http_client *.o \ No newline at end of file diff --git a/438CommunicationNetworks/SVN repo/MP1/http_client.cpp b/438CommunicationNetworks/SVN repo/MP1/http_client.cpp new file mode 100644 index 0000000..b40c15f --- /dev/null +++ b/438CommunicationNetworks/SVN repo/MP1/http_client.cpp @@ -0,0 +1,173 @@ +/* +** client.c -- a stream socket client demo +*/ + +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include + +using namespace std; + +#define MAXDATASIZE 1024 // max number of bytes we can get at once + +// get sockaddr, IPv4 or IPv6: +void *get_in_addr(struct sockaddr *sa) +{ + if (sa->sa_family == AF_INET) { + return &(((struct sockaddr_in*)sa)->sin_addr); + } + + return &(((struct sockaddr_in6*)sa)->sin6_addr); +} + +int client(string arg){ + int sockfd, numbytes; + char buf[MAXDATASIZE]; + struct addrinfo hints, *servinfo, *p; + int rv; + char s[INET6_ADDRSTRLEN]; + int bytes_sent; + int len; + int count = 0; + string url; + string host; + string port = "80"; + string path; + string msg; + int loc_port; + int loc_path; + for (int i = 0; i < arg.length(); ++i) + { + if(arg[i]==':'){ + count++; + } + } + // drop protocal + url = arg.substr(7); + if(count==2){ + loc_port = url.find(':'); + loc_path = url.find('/'); + host = url.substr(0,loc_port); + port = url.substr(loc_port+1,loc_path-loc_port-1); + if(loc_path!=-1){ + path = url.substr(loc_path); + } + }else{ + loc_path = url.find('/'); + host = url.substr(0,loc_path); + if(loc_path!=-1){ + path = url.substr(loc_path); + } + } + + memset(&hints, 0, sizeof hints); + hints.ai_family = AF_UNSPEC; + hints.ai_socktype = SOCK_STREAM; + + if ((rv = getaddrinfo(host.c_str(), port.c_str(), &hints, &servinfo)) != 0) { + fprintf(stderr, "getaddrinfo: %s\n", gai_strerror(rv)); + return 1; + } + + // loop through all the results and connect to the first we can + for(p = servinfo; p != NULL; p = p->ai_next) { + if ((sockfd = socket(p->ai_family, p->ai_socktype, + p->ai_protocol)) == -1) { + perror("client: socket"); + continue; + } + + if (connect(sockfd, p->ai_addr, p->ai_addrlen) == -1) { + close(sockfd); + perror("client: connect"); + continue; + } + + break; + } + + if (p == NULL) { + fprintf(stderr, "client: failed to connect\n"); + return 2; + } + + inet_ntop(p->ai_family, get_in_addr((struct sockaddr *)p->ai_addr), + s, sizeof s); + printf("client: connecting to %s\n", s); + + freeaddrinfo(servinfo); // all done with this structure + + //send request + if (path.length() == 0) + { + path = "/"; + } + cout<<"path: "< +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +using namespace std; + + +#define BACKLOG 10 // how many pending connections queue will hold + +void sigchld_handler(int s) +{ + while(waitpid(-1, NULL, WNOHANG) > 0); +} + +// get sockaddr, IPv4 or IPv6: +void *get_in_addr(struct sockaddr *sa) +{ + if (sa->sa_family == AF_INET) { + return &(((struct sockaddr_in*)sa)->sin_addr); + } + + return &(((struct sockaddr_in6*)sa)->sin6_addr); +} + +int main(int argc, char *argv[]) +{ + if (argc != 2) { + fprintf(stderr,"usage: server port\n"); + exit(1); + } + int sockfd, new_fd; // listen on sock_fd, new connection on new_fd + struct addrinfo hints, *servinfo, *p; + struct sockaddr_storage their_addr; // connector's address information + socklen_t sin_size; + struct sigaction sa; + int yes=1; + char s[INET6_ADDRSTRLEN]; + int rv; + + + memset(&hints, 0, sizeof hints); + hints.ai_family = AF_UNSPEC; + hints.ai_socktype = SOCK_STREAM; + hints.ai_flags = AI_PASSIVE; // use my IP + + if ((rv = getaddrinfo(NULL, argv[1], &hints, &servinfo)) != 0) { + fprintf(stderr, "getaddrinfo: %s\n", gai_strerror(rv)); + return 1; + } + + // loop through all the results and bind to the first we can + for(p = servinfo; p != NULL; p = p->ai_next) { + if ((sockfd = socket(p->ai_family, p->ai_socktype, + p->ai_protocol)) == -1) { + perror("server: socket"); + continue; + } + + if (setsockopt(sockfd, SOL_SOCKET, SO_REUSEADDR, &yes, + sizeof(int)) == -1) { + perror("setsockopt"); + exit(1); + } + + if (bind(sockfd, p->ai_addr, p->ai_addrlen) == -1) { + close(sockfd); + perror("server: bind"); + continue; + } + + break; + } + + if (p == NULL) { + fprintf(stderr, "server: failed to bind\n"); + return 2; + } + + freeaddrinfo(servinfo); // all done with this structure + + if (listen(sockfd, BACKLOG) == -1) { + perror("listen"); + exit(1); + } + + sa.sa_handler = sigchld_handler; // reap all dead processes + sigemptyset(&sa.sa_mask); + sa.sa_flags = SA_RESTART; + if (sigaction(SIGCHLD, &sa, NULL) == -1) { + perror("sigaction"); + exit(1); + } + + printf("server: waiting for connections...\n"); + + while(1) { // main accept() loop + sin_size = sizeof their_addr; + new_fd = accept(sockfd, (struct sockaddr *)&their_addr, &sin_size); + if (new_fd == -1) { + perror("accept"); + continue; + } + + inet_ntop(their_addr.ss_family, + get_in_addr((struct sockaddr *)&their_addr), + s, sizeof s); + printf("server: got connection from %s\n", s); + + if (!fork()) { // this is the child process + close(sockfd); // child doesn't need the listener + // start-------------------------------------------------- + int byte_count; + int index_path = 5; + int end_path; + int newline; + char buf[1000]; + string path; + string response; + string firstline; + string context; + bool protocal; + //recieve data -------------------------------------------- + byte_count = recv(new_fd, buf, sizeof buf, 0); + buf[byte_count] = '\0'; + cout<<"request: "<1)&&(path.at(0)=='/')){ + FILE *file; + char c; + char buf_send[1000]; + int numbytes = 0; + path = str.substr(index_path,end_path-index_path-1); + file = fopen(path.c_str(),"rb"); + if(file){ // file exists + sprintf(buf_send,"HTTP/1.0 200 OK\r\n\r\n"); + if (send(new_fd, buf_send, strlen(buf_send), 0) == -1){ + perror("send"); + } + while(1){ //send file + numbytes = fread(buf_send,1,1000,file); + if (numbytes <= 0) + { + break; + }else{ + if (send(new_fd, buf_send, numbytes, 0) == -1){ + perror("send"); + } + } + } + + }else{ //file not exists + context = "whoops,file not found!"; + response = "HTTP/1.0 404 Not Found\r\n\r\n"+context; + if (send(new_fd, response.c_str(), response.length(), 0) == -1){ + perror("send"); + } + } + fclose(file); + }else{ + response = "HTTP/1.0 400 Bad Request\r\n\r\n"; + if (send(new_fd, response.c_str(), response.length(), 0) == -1){ + perror("send"); + } + } + cout<<"response: "< +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include "monitor_neighbors.h" + +int globalMyID = 0; +//last time you heard from each node. TODO: you will want to monitor this +//in order to realize when a neighbor has gotten cut off from you. +struct timeval globalLastHeartbeat[NUM_HOP]; + +//our all-purpose UDP socket, to be bound to 10.1.1.globalMyID, port 7777 +int globalSocketUDP; +//pre-filled for sending to 10.1.1.0 - 255, port 7777 +struct sockaddr_in globalNodeAddrs[NUM_HOP]; + +struct Neighbors neighbors[NUM_HOP]; +pthread_mutex_t neighbors_lock = PTHREAD_MUTEX_INITIALIZER; +pthread_mutex_t topo_lock = PTHREAD_MUTEX_INITIALIZER; +pthread_mutex_t lsp_lock = PTHREAD_MUTEX_INITIALIZER; + +struct Neighbors neighbors_last[NUM_HOP]; +struct topo topo_distances[NUM_HOP]; +int topo_forward[NUM_HOP]; +int nextHop[NUM_HOP]; + +int distances[NUM_HOP][NUM_HOP]; //all members LSP +int sequences[NUM_HOP]; +int topochanged = 0; +int temp_cost[NUM_HOP]; + +FILE *logfile = NULL; +void append_log(char* line){ + fwrite(line, 1, strlen(line), logfile); + fflush(logfile); +} + +int main(int argc, char** argv) +{ + if(argc != 4) + { + fprintf(stderr, "Usage: %s mynodeid initialcostsfile logfile\n\n", argv[0]); + exit(1); + } + + //initialization: get this process's node ID, record what time it is, + //and set up our sockaddr_in's for sending to the other nodes. + globalMyID = atoi(argv[1]); + int i; + for(i=0;i/dev/null`; +`sudo ifconfig eth0:manager up 10.0.0.10 2>/dev/null`; + +open(TOPOFILE, "<$topoFileName") or die("$topoFileName does not exist.\n"); +while(my $curLine = ) +{ + $curLine =~ s/\n//; + next unless($curLine =~ m/[0-9]/); + + my @nodes = split(/ /, $curLine); + my $addr0 = "10.1.1.$nodes[0]"; + my $addr1 = "10.1.1.$nodes[1]"; + + `sudo ifconfig eth0:$nodes[0] up $addr0 2>/dev/null`; + `sudo ifconfig eth0:$nodes[0] up $addr0 2>/dev/null`; + `sudo ifconfig eth0:$nodes[1] up $addr1 2>/dev/null`; + `sudo ifconfig eth0:$nodes[1] up $addr1 2>/dev/null`; + + `sudo iptables -A OUTPUT -s $addr0 -d $addr1 -j ACCEPT`; + `sudo iptables -A OUTPUT -s $addr1 -d $addr0 -j ACCEPT`; +} + +`sudo iptables -A OUTPUT -s 10.0.0.10 -p udp --dport 7777 -j ACCEPT`; +#NOTE: if you have your VM configured with the NAT interface that lets +# it access the internet, this next line will cut it off. +# Can you figure out how to tell iptables to keep that address online? +`sudo iptables -A OUTPUT -s 10.0.0.0/8 -j DROP`; diff --git a/438CommunicationNetworks/SVN repo/MP2/manager_send.c b/438CommunicationNetworks/SVN repo/MP2/manager_send.c new file mode 100755 index 0000000..9a223fa --- /dev/null +++ b/438CommunicationNetworks/SVN repo/MP2/manager_send.c @@ -0,0 +1,80 @@ +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include + +int main(int argc, char** argv) +{ + if(argc != 5 || (strcmp(argv[2], "cost") && strcmp(argv[2], "send"))) + { + fprintf(stderr, "Usage: %s srcNode command [args]\n'command' must be 'send' or 'cost'.\n\n", argv[0]); + if(argc>2 && !strcmp(argv[2], "cost") && argc != 5) + fprintf(stderr, "Usage: %s srcNode cost destNode newCost\n\n", argv[0]); + if(argc>2 && !strcmp(argv[2], "send") && argc != 5) + fprintf(stderr, "Usage: %s srcNode send destNode \"the message\"\n\n", argv[0]); + exit(1); + } + + short int destID = atoi(argv[3]); + short int no_destID = htons(destID); + + int senderSocket = socket(AF_INET, SOCK_DGRAM, 0); + if(senderSocket < 0) + perror("socket()"); + + //NOTE: it is normally not necessary to bind() a socket you only plan to sendto() from, + // but the virtual network interfaces we're using make things a little weird. + // (specifically, there is a specific IP address that we want our packets to use + // as the source, and you have to bind() if you want to control that. + // (We're also explicitly choosing source port 8999, but that's not actually important here.) + struct sockaddr_in srcAddr; + memset(&srcAddr, 0, sizeof(srcAddr)); + srcAddr.sin_family = AF_INET; + srcAddr.sin_port = htons(8999); + inet_pton(AF_INET, "10.0.0.10", &srcAddr.sin_addr); + if(bind(senderSocket, (struct sockaddr*)&srcAddr, sizeof(srcAddr)) < 0) + perror("bind()"); + + struct sockaddr_in destAddr; + char tempaddr[100]; + sprintf(tempaddr, "10.1.1.%s", argv[1]); + memset(&destAddr, 0, sizeof(destAddr)); + destAddr.sin_family = AF_INET; + destAddr.sin_port = htons(7777); + inet_pton(AF_INET, tempaddr, &destAddr.sin_addr); + + if(!strcmp(argv[2], "cost")) + { + int no_newCost = htonl(atoi(argv[4])); + + char sendBuf[4+sizeof(short int)+sizeof(int)]; + + strcpy(sendBuf, "cost"); + memcpy(sendBuf+4, &no_destID, sizeof(short int)); + memcpy(sendBuf+4+sizeof(short int), &no_newCost, sizeof(int)); + + if(sendto(senderSocket, sendBuf, 4+sizeof(short int)+sizeof(int), 0, + (struct sockaddr*)&destAddr, sizeof(destAddr)) < 0) + perror("sendto()"); + } + else + { + int msgLen = 4+sizeof(short int)+strlen(argv[4]); + char* sendBuf = malloc(msgLen); + + strcpy(sendBuf, "send"); + memcpy(sendBuf+4, &no_destID, sizeof(short int)); + memcpy(sendBuf+4+sizeof(short int), argv[4], strlen(argv[4])); + + if(sendto(senderSocket, sendBuf, msgLen, 0, (struct sockaddr*)&destAddr, sizeof(destAddr)) < 0) + perror("sendto()"); + free(sendBuf); + } + close(senderSocket); +} diff --git a/438CommunicationNetworks/SVN repo/MP2/monitor_neighbors.c b/438CommunicationNetworks/SVN repo/MP2/monitor_neighbors.c new file mode 100755 index 0000000..3483977 --- /dev/null +++ b/438CommunicationNetworks/SVN repo/MP2/monitor_neighbors.c @@ -0,0 +1,477 @@ +#include "monitor_neighbors.h" + +extern int globalMyID; +//last time you heard from each node. TODO: you will want to monitor this +//in order to realize when a neighbor has gotten cut off from you. +extern struct timeval globalLastHeartbeat[NUM_HOP]; + +//our all-purpose UDP socket, to be bound to 10.1.1.globalMyID, port 7777 +extern int globalSocketUDP; +//pre-filled for sending to 10.1.1.0 - 255, port 7777 +extern struct sockaddr_in globalNodeAddrs[NUM_HOP]; + +extern struct Neighbors neighbors[NUM_HOP]; +extern pthread_mutex_t neighbors_lock; +extern pthread_mutex_t topo_lock; +extern pthread_mutex_t lsp_lock; + +extern struct Neighbors neighbors_last[NUM_HOP]; + +extern int distances[NUM_HOP][NUM_HOP]; +extern int sequences[NUM_HOP]; +extern int topochanged; + +extern struct topo topo_distances[NUM_HOP]; +extern int topo_forward[NUM_HOP]; +extern int nextHop[NUM_HOP]; +extern int temp_cost[NUM_HOP]; + +int myseq = 0; +int reTopo = 0; + +//Yes, this is terrible. It's also terrible that, in Linux, a socket +//can't receive broadcast packets unless it's bound to INADDR_ANY, +//which we can't do in this assignment. +void hackyBroadcast(const char* buf, int length) +{ + int i; + for(i=0;i TIME_OUT){ + neighbors[i].up = 0; + } + else{ + neighbors[i].up = 1; + if(temp_cost[i] != -1){ //get cost by global msg, now this node is up + neighbors[i].cost = temp_cost[i]; + temp_cost[i] = -1; + } + } + } + neighbors[globalMyID].up = 1; + pthread_mutex_unlock(&neighbors_lock); +} + +void generateNexthop(){ + int i; + int j; + for (i = 0; i < NUM_HOP; ++i) + { + j = i; + if(topo_forward[i] != -1){ + while(topo_forward[j] != j){ + j = topo_forward[j]; + } + nextHop[i] = j; + }else{ + nextHop[i] = -1; + } + } +} + +int moveToConfirmed(){ + int i; + int smallest = INT_MAX; + int node = -1; + for (i = 0; i < NUM_HOP; i++){ + if ((topo_distances[i].cost != -1) && (topo_distances[i].cost < smallest) && (topo_distances[i].confirmed != 1)) + { + smallest = topo_distances[i].cost; + node = i; + } + } + if(node == -1){ + return -1; + } + topo_distances[node].confirmed = 1; + return node; +} + +void updateTopo(){ + // pthread_mutex_lock(&topo_lock); + int smallest = INT_MAX; + int node; + int i, j; + + for (i = 0; i < NUM_HOP; i++) + { + topo_distances[i].cost = distances[globalMyID][i]; + topo_distances[i].confirmed = 0; + } + topo_distances[globalMyID].confirmed = 1; + for (i = 0; i < NUM_HOP; i++) + { + if (topo_distances[i].cost != -1) + { + topo_forward[i] = i; + }else{ + topo_forward[i] = -1; + } + } + topo_forward[globalMyID] = globalMyID; + + while(1){ + int finish = 1; + int node = moveToConfirmed(); + if(node == -1){ + break; + } + for (i = 0; i < NUM_HOP; i++) + { + if(distances[node][i] > 0){ + if(topo_distances[i].cost == -1){ //current node can reach a new hop + topo_distances[i].cost = topo_distances[node].cost + distances[node][i]; + topo_forward[i] = node; + }else{ //they can both reach hop i + int newcost = topo_distances[node].cost + distances[node][i]; + if((newcost == topo_distances[i].cost) && (node < topo_forward[i])){ + topo_forward[i] = node; + } + if(newcost < topo_distances[i].cost){ + topo_distances[i].cost = newcost; + topo_forward[i] = node; + } + } + } + } + + for (i = 0; i < NUM_HOP; i++){ + if((topo_forward[i] != -1) && (topo_distances[i].confirmed == 0)){ + finish = 0; + } + } + if(finish){ + break; + } + } + // pthread_mutex_unlock(&topo_lock); +} + +int prepareLSP(char * lspbuf){ + char* it = lspbuf; + + memcpy(it, "LSP", 3); + it += 3; + + short int globalMyID_net = htons( (short int)(globalMyID) ); + memcpy(it, &globalMyID_net, sizeof(short int)); + it += sizeof(short int); + + int seqnum_net = htonl(myseq); + myseq++; + memcpy(it, &seqnum_net, sizeof(int)); + it += sizeof(int); + + int i; + for(i=0; i < NUM_HOP; i++){ + if(neighbors_last[i].up == 1){ + short int nodeid_net = (short int)(neighbors_last[i].neighborID); + nodeid_net = htons(nodeid_net); + int cost_net = neighbors_last[i].cost; + cost_net = htonl(cost_net); + + memcpy(it, &nodeid_net, sizeof(short int)); + it += sizeof(short int); + memcpy(it, &cost_net, sizeof(int)); + it += sizeof(int); + } + } + return (it - lspbuf); +} + +//store in lsdb +int storeLSP(char* lspbuf, int size){ + char * it = lspbuf + 3; + + short int from; + memcpy(&from, it, sizeof(short int)); + it += sizeof(short int); + from = ntohs(from); + + int sequence; + memcpy(&sequence, it, sizeof(int)); + it += sizeof(int); + sequence = ntohl(sequence); + + //sequence number of this node is too old! + if(sequence <= sequences[from]) + return 0; + + sequences[from] = sequence; + + int distance_last[NUM_HOP]; + memcpy(distance_last, distances[from], NUM_HOP*sizeof(int)); + + int i; + for(i=0; i < NUM_HOP; i++) + distances[from][i] = -1; + + while( it-lspbuf < size ){ + short int to; + memcpy(&to, it, sizeof(short int)); + it += sizeof(short int); + to = ntohs(to); + + int cost; + memcpy(&cost, it, sizeof(int)); + it += sizeof(int); + cost = ntohl(cost); + + distances[from][to] = cost; + } + + topochanged = topochanged || memcmp(distance_last, distances[from], NUM_HOP*sizeof(int)); + + // debug Dijkstra + // if(topochanged){ + // pthread_mutex_lock(&topo_lock); + // int j; + // char line[50]; + // for(i=0; i < NUM_HOP; i++){ + // for (j = 0; j < NUM_HOP; ++j) + // { + // if( distances[i][j] != -1 ){ + // sprintf(line, "%d thinks from %d to %d is %d\n", globalMyID, i, j, distances[i][j]); + // append_log(line); + // } + // } + // } + // append_log("goes into updateTopo\n"); + // updateTopo(); + // for(i=0; i < NUM_HOP; i++){ + // if( neighbors[i].up != 0 ){ + // sprintf(line, "%d alive\n", i); + // append_log(line); + // } + // } + // append_log("updateTopo finish, goes into generateNexthop\n"); + // generateNexthop(); + // append_log("generateNexthop finish\n"); + // topochanged = 0; + // append_log("--------------------------------------------\n"); + // append_log("topo_distances: \n"); + // for(i=0; i < NUM_HOP; i++){ + // if( topo_distances[i].cost != -1 ){ + // sprintf(line, "distance from %d to %d is %d\n", globalMyID, i, topo_distances[i].cost); + // append_log(line); + // } + // } + // for(i=0; i < NUM_HOP; i++){ + // if( topo_forward[i] != -1 ){ + // sprintf(line, "%d to %d via %d\n", globalMyID, i, topo_forward[i]); + // append_log(line); + // } + // } + // for(i=0; i < NUM_HOP; i++){ + // if( nextHop[i] != -1 ){ + // sprintf(line, "%d to %d nexthop %d\n", globalMyID, i, nextHop[i]); + // append_log(line); + // } + // } + // append_log("\n\n\n\n"); + // pthread_mutex_unlock(&topo_lock); + // } + + return 1; +} + +void floodLSP(char* lspbuf, int size, int heardFrom){ + int i; + for(i=0; i < NUM_HOP; i++){ + if(neighbors_last[i].up == 0) + continue; + if(i == globalMyID || i == heardFrom) //smed tp all neighbors, excluding myself + continue; + sendto(globalSocketUDP, lspbuf, size, 0, + (struct sockaddr*)&globalNodeAddrs[i], sizeof(globalNodeAddrs[i])); + } +} + +void checkSendLSPs(){ + pthread_mutex_lock(&neighbors_lock); + int changed = memcmp(neighbors_last, neighbors, sizeof(neighbors)); + if (changed){ + memcpy(neighbors_last, neighbors, sizeof(neighbors)); + } + pthread_mutex_unlock(&neighbors_lock); + + if(changed || topochanged){ + reTopo = 1; + char lspbuf[SIZE_REC]; + int size = prepareLSP(lspbuf); + storeLSP(lspbuf, size); + floodLSP(lspbuf, size, globalMyID); + topochanged = 0; + } +} + + +void* announceToNeighbors(void* unusedParam) +{ + struct timespec initialSleep; + initialSleep.tv_sec = 0; + initialSleep.tv_nsec = 800 * 1000 * 1000; //800 ms + nanosleep(&initialSleep, 0); + + struct timespec sleepFor; + sleepFor.tv_sec = 0; + sleepFor.tv_nsec = 300 * 1000 * 1000; //300 ms + + while(1) + { + + hackyBroadcast("HEREIAM", 7); + + //check neighbor link alive + checkNeighbors(); + + //maybe send LSPs + checkSendLSPs(); + + nanosleep(&sleepFor, 0); + } +} + +void sendMSG(int nexthop, char* msgbuf, int buflen ){ + sendto(globalSocketUDP, msgbuf, buflen, 0, (struct sockaddr*)&globalNodeAddrs[nexthop], sizeof(globalNodeAddrs[nexthop])); +} + +void sendMessage(int heardFrom, int destId, char* msgbuf, int buflen){ + if(reTopo){ + pthread_mutex_lock(&topo_lock); + // printf("%d goes into updateTopo\n", globalMyID); + updateTopo(); + // printf("%d goes into generateNexthop\n", globalMyID); + generateNexthop(); + reTopo = 0; + pthread_mutex_unlock(&topo_lock); + } + int nexthop = nextHop[destId]; + char logLine[256]; + if(nexthop == -1){ + sprintf(logLine, "unreachable dest %d\n", destId); + }else{ + sendMSG(nexthop,msgbuf,buflen ); + msgbuf[buflen] = '\0'; + if(heardFrom == globalMyID){ + sprintf(logLine, "sending packet dest %d nexthop %d message %s\n", destId, nexthop, msgbuf+5); + }else{ + sprintf(logLine, "forward packet dest %d nexthop %d message %s\n", destId, nexthop, msgbuf+5); + } + } + append_log(logLine); +} + +void recGlobalMsg(int destId, char* message, int msg_size){ + char msgbuf[256]; + + memcpy(msgbuf, "MSG", 3); + short int dest = htons((short int)(destId)); + memcpy(msgbuf+3, &dest, 2); + memcpy(msgbuf+5, message, msg_size); + + sendMessage(globalMyID, destId, msgbuf, msg_size+5); +} + +void listenForNeighbors() +{ + char fromAddr[100]; + struct sockaddr_in theirAddr; + socklen_t theirAddrLen; + unsigned char recvBuf[SIZE_REC]; + + int bytesRecvd; + while(1) + { + theirAddrLen = sizeof(theirAddr); + if ((bytesRecvd = recvfrom(globalSocketUDP, recvBuf, SIZE_REC , 0, + (struct sockaddr*)&theirAddr, &theirAddrLen)) == -1) + { + perror("connectivity listener: recvfrom failed"); + exit(1); + } + + inet_ntop(AF_INET, &theirAddr.sin_addr, fromAddr, 100); + + short int heardFrom = -1; + if(strstr(fromAddr, "10.1.1.")) + { + heardFrom = atoi( + strchr(strchr(strchr(fromAddr,'.')+1,'.')+1,'.')+1); + + //record that we heard from heardFrom just now. + gettimeofday(&globalLastHeartbeat[heardFrom], 0); + + //TODO: this node can consider heardFrom to be directly connected to it; do any such logic now. + + if (!strncmp(recvBuf, "HEREIAM", 7)){ + gettimeofday(&globalLastHeartbeat[heardFrom], 0); + }else if (!strncmp(recvBuf, "LSP", 3)){ + // use LSP + if(storeLSP(recvBuf, bytesRecvd)==1) + floodLSP(recvBuf, bytesRecvd, heardFrom); + }else if (!strncmp(recvBuf, "MSG", 3)){ + // receive message or forward message + int destId = ntohs(*((short int *)(recvBuf+3))); + if(destId == globalMyID){ + char logLine[200]; + recvBuf[bytesRecvd] = '\0'; + sprintf(logLine, "receive packet message %s\n", recvBuf+5); + append_log(logLine); + }else{ + sendMessage(heardFrom, destId, recvBuf, bytesRecvd); + } + }else{ + printf("unknown type message\n"); + } + + //record that we heard from heardFrom just now. + gettimeofday(&globalLastHeartbeat[heardFrom], 0); + } + + //Is it a packet from the manager? (see mp2 specification for more details) + //send format: 'send'<4 ASCII bytes>, destID, + if(!strncmp(recvBuf, "send", 4)) + { + //TODO send the requested message to the requested destination node + // ... + short int destId = ntohs(*((short int *)(recvBuf+4))); + recGlobalMsg((int)destId, recvBuf+6, bytesRecvd-6); + } + //'cost'<4 ASCII bytes>, destID newCost + else if(!strncmp(recvBuf, "cost", 4)) + { + //TODO record the cost change (remember, the link might currently be down! in that case, + //this is the new cost you should treat it as having once it comes back up.) + // ... + short int neighborID = ntohs(*((short int *)(recvBuf+4))); + int cost = ntohl(*((int *)(recvBuf+6))); + if(neighbors[neighborID].up == 1){ + neighbors[neighborID].cost = cost; + }else{ + temp_cost[neighborID] = cost; + } + } + + //TODO now check for the various types of packets you use in your own protocol + //else if(!strncmp(recvBuf, "your other message types", )) + // ... + } + //(should never reach here) + close(globalSocketUDP); +} + diff --git a/438CommunicationNetworks/SVN repo/MP2/monitor_neighbors.h b/438CommunicationNetworks/SVN repo/MP2/monitor_neighbors.h new file mode 100644 index 0000000..1a64bb0 --- /dev/null +++ b/438CommunicationNetworks/SVN repo/MP2/monitor_neighbors.h @@ -0,0 +1,39 @@ +#ifndef MONITOR_NEIGHBOR_H +#define MONITOR_NEIGHBOR_H + +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include + +#define NUM_HOP 256 +#define TIME_OUT 800000 +#define SIZE_REC 2000 //256*6+9 = 1545 < 2000 + +struct Neighbors +{ + int neighborID; + int cost; + int up; +}; + +struct topo +{ + int cost; + int confirmed; +}; + +void listenForNeighbors(); +void* announceToNeighbors(void* unusedParam); +void* checkLinkDown(void* unusedParam); + +#endif \ No newline at end of file diff --git a/438CommunicationNetworks/SVN repo/MP2/results.txt b/438CommunicationNetworks/SVN repo/MP2/results.txt new file mode 100644 index 0000000..7d37862 --- /dev/null +++ b/438CommunicationNetworks/SVN repo/MP2/results.txt @@ -0,0 +1,14 @@ +10 LS send message over 3 node topology succeeded! +10 LS shortest path in example topology succeeded! +10 LS shortest path in 8x8 grid topology succeeded! +10 LS switch to better path when available succeeded! +10 LS fall back to worse path succeeded! +10 LS report unreachable after partition succeeded! +10 LS heal after partition succeeded! +10 LS with lots of link up/downs succeeded! +---------------- +Total score: 100 + +svn rev: 6217 + +09:00 PM on April 07, 2017 \ No newline at end of file diff --git a/438CommunicationNetworks/SVN repo/MP2/results.txt.1 b/438CommunicationNetworks/SVN repo/MP2/results.txt.1 new file mode 100644 index 0000000..45934d6 --- /dev/null +++ b/438CommunicationNetworks/SVN repo/MP2/results.txt.1 @@ -0,0 +1,14 @@ +10 LS send message over 3 node topology succeeded! +10 LS shortest path in example topology succeeded! +10 LS shortest path in 8x8 grid topology succeeded! +10 LS switch to better path when available succeeded! +10 LS fall back to worse path succeeded! +10 LS report unreachable after partition succeeded! +10 LS heal after partition succeeded! +10 LS with lots of link up/downs succeeded! +---------------- +Total score: 100 + +svn rev: 6388 + +02:00 PM on April 16, 2017 \ No newline at end of file diff --git a/438CommunicationNetworks/SVN repo/MP2/results.txt.2 b/438CommunicationNetworks/SVN repo/MP2/results.txt.2 new file mode 100644 index 0000000..f9033a8 --- /dev/null +++ b/438CommunicationNetworks/SVN repo/MP2/results.txt.2 @@ -0,0 +1,14 @@ +10 LS send message over 3 node topology succeeded! +10 LS shortest path in example topology succeeded! +10 LS shortest path in 8x8 grid topology succeeded! +10 LS switch to better path when available succeeded! +10 LS fall back to worse path succeeded! +10 LS report unreachable after partition succeeded! +10 LS heal after partition succeeded! +10 LS with lots of link up/downs succeeded! +---------------- +Total score: 100 + +svn rev: 6388 + +03:24 AM on April 17, 2017 \ No newline at end of file diff --git a/438CommunicationNetworks/SVN repo/MP2/results.txt.3 b/438CommunicationNetworks/SVN repo/MP2/results.txt.3 new file mode 100644 index 0000000..ef3e5b0 --- /dev/null +++ b/438CommunicationNetworks/SVN repo/MP2/results.txt.3 @@ -0,0 +1,14 @@ +10 LS send message over 3 node topology succeeded! +10 LS shortest path in example topology succeeded! +10 LS shortest path in 8x8 grid topology succeeded! +10 LS switch to better path when available succeeded! +10 LS fall back to worse path succeeded! +10 LS report unreachable after partition succeeded! +10 LS heal after partition succeeded! +10 LS with lots of link up/downs succeeded! +---------------- +Total score: 100 + +svn rev: 6388 + +11:08 AM on April 17, 2017 \ No newline at end of file diff --git a/438CommunicationNetworks/SVN repo/MP2/version.txt b/438CommunicationNetworks/SVN repo/MP2/version.txt new file mode 100644 index 0000000..b8626c4 --- /dev/null +++ b/438CommunicationNetworks/SVN repo/MP2/version.txt @@ -0,0 +1 @@ +4 diff --git a/438CommunicationNetworks/SVN repo/MP3/Makefile b/438CommunicationNetworks/SVN repo/MP3/Makefile new file mode 100644 index 0000000..e831917 --- /dev/null +++ b/438CommunicationNetworks/SVN repo/MP3/Makefile @@ -0,0 +1,10 @@ +all: reliable_sender reliable_receiver + +reliable_sender: + gcc -o reliable_sender sender_main.c + +reliable_receiver: + gcc -o reliable_receiver receiver_main.c + +clean: + rm reliable_sender reliable_receiver diff --git a/438CommunicationNetworks/SVN repo/MP3/partner.txt b/438CommunicationNetworks/SVN repo/MP3/partner.txt new file mode 100644 index 0000000..e69de29 diff --git a/438CommunicationNetworks/SVN repo/MP3/receiver_main.c b/438CommunicationNetworks/SVN repo/MP3/receiver_main.c new file mode 100644 index 0000000..a6ef28d --- /dev/null +++ b/438CommunicationNetworks/SVN repo/MP3/receiver_main.c @@ -0,0 +1,125 @@ + #include + #include + #include + #include + #include + #include + #include + #include + + int Max_n; + struct sockaddr_in serv; + + int Socket_bind(unsigned short int myUDPport) + { + int s; + struct sockaddr_in serv; + struct timeval timeout={0,10}; + s=socket(AF_INET,SOCK_DGRAM,0); + bzero(&serv,sizeof(serv)); + serv.sin_family=AF_INET; + serv.sin_addr.s_addr = htonl(INADDR_ANY); + serv.sin_port=htons(myUDPport); + int Socket_Buf_Size=64*1024; + setsockopt(s,SOL_SOCKET,SO_RCVBUF,(const char*)&Socket_Buf_Size,sizeof(int)); + setsockopt(s,SOL_SOCKET,SO_SNDBUF,(const char*)&Socket_Buf_Size,sizeof(int)); + setsockopt(s,SOL_SOCKET,SO_RCVTIMEO,(char*)&timeout,sizeof(struct timeval)); + int addr_len=sizeof(serv); + if(bind(s,(struct sockaddr*)&serv,sizeof(serv))==-1) + { + return(-1); + } + else + { + return(s); + } + } + + void Message_Send_ACK(int s,int number) + { + int sed_num=htonl(number); + int ans; + char Write_Buff[100]; + memcpy(Write_Buff,&sed_num,4); + // printf("Send:%d\n",number); + ans=sendto(s,Write_Buff,4,0,(struct sockaddr *)&serv,sizeof(serv)); + // printf(":%d\n",ans); + } + + int Message_Get(int s,int Msg_length,int number,char* Read_Buff,int* len) + { + int ans; + int ret; + int addr_len=sizeof(serv); + ans=recvfrom(s,Read_Buff,4+Msg_length,0,(struct sockaddr *)&serv,&addr_len); + if(ans==-1) + { + return(-1); + } + else + { + if(number!=Max_n-1) + { + if(ans!=Msg_length+4) + { + //lost_byte+=Msg_length-ans; + return(-1); + } + } + memcpy(&ret,Read_Buff,4); + // printf("GET:%d\n",ntohl(ret)); + *len=ans-4; + return(ntohl(ret)); + } + } + +void reliablyReceive(unsigned short int myUDPport, char* destinationFile) +{ + int number=0; + int s=Socket_bind(myUDPport); + int ret; + int Msg_length=1468; // length of each frame + char Read_Buff[65541]; + int len; + FILE* outfile; + // printf("Start\n"); + Max_n=-1; + while(Max_n==-1) + { + //Message_Send_ACK(s,number); + Max_n=Message_Get(s,0,number,Read_Buff,&len); + } + Message_Send_ACK(s,number); + outfile = fopen(destinationFile, "wb" ); + while(number +#include +#include +#include +#include +#include +#include +#include + + struct sockaddr_in serv; + + int Socket_bind(char* hostname, unsigned short int hostUDPport) + { + int s; + struct timeval timeout={0,10}; + s=socket(AF_INET,SOCK_DGRAM,0); + bzero(&serv,sizeof(serv)); + serv.sin_family=AF_INET; + serv.sin_addr.s_addr=inet_addr(hostname); + serv.sin_port=htons(hostUDPport); + + int Socket_Buf_Size=64*1024; + setsockopt(s,SOL_SOCKET,SO_RCVBUF,(const char*)&Socket_Buf_Size,sizeof(int)); + setsockopt(s,SOL_SOCKET,SO_SNDBUF,(const char*)&Socket_Buf_Size,sizeof(int)); + setsockopt(s,SOL_SOCKET,SO_RCVTIMEO,(char*)&timeout,sizeof(struct timeval)); + return(s); + } + + void Socket_Close(int s) + { + close(s); + } + + int Message_Send(int s,int num,char* Msg,int SendLength) + { + int sed_num=htonl(num); + //struct sockaddr_in client; + char Write_Buff[65541]; + memcpy(Write_Buff,&sed_num,4); + memcpy(Write_Buff+4,Msg,SendLength); + int addr_len=sizeof(serv); + //printf("send %d\n",num); + return(sendto(s,Write_Buff,SendLength+4,0,(struct sockaddr *)&serv,addr_len)); + } + + int Message_Get_ACK(int s) + { + int ans; + int ret; + //struct sockaddr_in client; + char Read_Buff[65536]; + int addr_len=sizeof(serv); + ans=recvfrom(s,Read_Buff,4,0,(struct sockaddr *)&serv,&addr_len); + if(ans!=-1) + { + memcpy(&ret,Read_Buff,4); + // printf("get %d\n",ntohl(ret)); + return(ntohl(ret)); + } + else + { + return(-1); + } + } + +void reliablyTransfer(char* hostname, unsigned short int hostUDPport, char* filename, unsigned long long int bytesToTransfer) +{ + int number; + int s; + int i,j; + unsigned char** text; // msg need to be send + int* length; + int Msg_length = 1468; // length of each frame + int set_timeout = 40; // init RTT : ms + int n = 8; // n + int temp = 40; // current RTT + int ACK; + struct timeval t1,t2; + int tmp_tail; + + FILE *infile; + infile=fopen(filename,"rb"); + int Max_n; + int Size_n=1000; +//printf("[%s] %d",hostname,hostUDPport); + s=Socket_bind(hostname,hostUDPport); + Max_n=(bytesToTransfer+Msg_length-1)/Msg_length; + text=malloc(sizeof(char*)*Size_n); + length=malloc(sizeof(int)*Size_n); + + tmp_tail=0; + for(i=0;i=Max_n) + { + break; + } + text[i]=malloc(sizeof(unsigned char)*(Msg_length+1)); + fread(text[i],sizeof(unsigned char),Msg_length,infile); + tmp_tail++; + if(i=Max_n) + { + break; + } + int ret_tmp; + ret_tmp=Message_Send(s,i,text[i%Size_n],length[i%Size_n]); + //printf("%d\n",ret_tmp); + } + gettimeofday(&t1,0); + gettimeofday(&t2,0); + while(numberSize_n) + { + n=Size_n; + } + } + for(j=number;j=Max_n) + { + break; + } + if(j>=tmp_tail) + { + if(text[j%Size_n]!=NULL) + { + free(text[j%Size_n]); + } + tmp_tail++; + text[j%Size_n]=malloc(sizeof(unsigned char)*(Msg_length+1)); + fread(text[j%Size_n],sizeof(unsigned char),Msg_length,infile); + length[j%Size_n]=strlen(text[j%Size_n]); + if(j