aboutsummaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorsotech117 <michael_foiani@brown.edu>2023-09-24 00:24:01 -0400
committersotech117 <michael_foiani@brown.edu>2023-09-24 00:24:01 -0400
commitb578b114fd919d72948b051c036b34cb60976389 (patch)
treee100258c4af1068013aab7ef521513278c133bf0
parent9625efcaf8e7d7f57c8d2678b4d68b85dae91980 (diff)
simplify into functions and add log output
-rw-r--r--server.c313
-rwxr-xr-xsnowcast_serverbin54332 -> 54572 bytes
2 files changed, 161 insertions, 152 deletions
diff --git a/server.c b/server.c
index 3d23394..84c332a 100644
--- a/server.c
+++ b/server.c
@@ -91,10 +91,14 @@ void *print_user_data(int sockfd);
void destroy_user(int sockfd);
void send_announce_reply(int fd, int station_num);
-void send_invalid_command_reply(int fd, size_t message_size, char* message);
-void *send_stations_info_reply(void *arg);
+void send_invalid_reply(int fd, size_t message_size, char* message);
+void *send_stationsinfo_reply(void *arg);
+int send_welcome_reply(int fd);
+void handle_setstation_command(int fd);
-// void *load_file(void* arg);
+uint16_t handle_handshake(int newfd);
+
+int l = 1;
main(int argc, char *argv[])
{
@@ -179,6 +183,9 @@ main(int argc, char *argv[])
print_user_data(i);
}
}
+ else if (!strcmp(command, "log")) {
+ l= !l;
+ }
}
return 0;
@@ -462,27 +469,15 @@ void *send_announce_routine(void *arg) {
}
}
-// void *sync_routine(void *arg) {
-// int c = 0;
-// while (1)
-// {
-// start_threads = 1;
-// pthread_cond_broadcast(&cond);
-// usleep(2000);
-
-// start_threads = 0;
-// usleep(1000000-2000);
-// }
-// }
+fd_set master; // master file descriptor list
void *select_routine(void *arg) {
- fd_set master; // master file descriptor list
fd_set read_fds; // temp file descriptor list for select()
- int fdmax; // maximum file descriptor number
int listener; // listening socket descriptor
int newfd; // newly accept()ed socket descriptor
+ int fdmax; // maximum file descriptor number
struct sockaddr_storage remoteaddr; // client address
socklen_t addrlen;
@@ -569,62 +564,28 @@ void *select_routine(void *arg) {
if (newfd == -1) {
perror("accept");
} else {
- struct timeval tv;
- tv.tv_sec = 0;
- tv.tv_usec = TCP_TIMEOUT;
- if (setsockopt(newfd, SOL_SOCKET, SO_RCVTIMEO, &tv, sizeof(tv)) < 0) {
- perror("setsockopt");
- }
-
- uint8_t command_type = -1;
- if ((nbytes = recv(newfd, &command_type, 1, 0)) <= 0)
- {
- // got error or connection closed by client
- if (nbytes == 0) {
- // connection closed
- // printf("selectserver: socket %d hung up\n", i);
- } else {
- perror("recv");
- }
- // remove user from data structures
- close(newfd);
- // destroy_user(i);
- continue;
- }
-
- if (command_type != 0) {
- char * message = "must send a Hello message first";
- send_invalid_command_reply(newfd, strlen(message), message);
- close(newfd);
- continue;
- }
-
- // get the udp port
- uint16_t udp_port = -1;
- int bytes_to_read = sizeof(uint16_t);
- if (recv_all(newfd, &udp_port, &bytes_to_read) == -1) {
- perror("recv_all");
+ // new user, we need to do the handshake
+ uint16_t udp_port = handle_handshake(newfd);
+ if (udp_port == 0) {
+ // drop connection upon error
close(newfd);
- // destroy_user(i);
continue;
}
- udp_port = ntohs(udp_port);
+ // add the user to the set
FD_SET(newfd, &master); // add to master set
if (newfd > fdmax) { // keep track of the max
fdmax = newfd;
- }
+ }
+
+ // TODO: thread or combine into one function
+ // init the user
init_user(newfd);
+ // update the udp port
update_user_udpPort(newfd, udp_port);
- // send the welcome message to client
- struct Welcome welcome;
- welcome.replyType = 2;
- welcome.numStations = htons(num_stations);
- int bytes_to_send = sizeof(struct Welcome);
- if (send_all(newfd, &welcome, &bytes_to_send) == -1)
- perror("send_all");
- }
+ send_welcome_reply(newfd);
+ }
} else {
// handle data from a client
uint8_t command_type = -1;
@@ -633,105 +594,43 @@ void *select_routine(void *arg) {
// got error or connection closed by client
if (nbytes == 0) {
// connection closed
- // printf("selectserver: socket %d hung up\n", i);
+ if (l) printf("socket %d HUNGUP. lost connection.\n", newfd);
} else {
perror("recv");
}
- close(i); // bye!
- FD_CLR(i, &master); // remove from master set
- // remove user from data structures
destroy_user(i);
}
- else
+ else // we got some data from a client
{
- // we got some data from a client
- if (command_type == 0) { // we got a Hello commmand
-
- // get the udp port
- uint16_t udp_port = -1;
- int bytes_to_read = sizeof(uint16_t);
- if (recv_all(i, &udp_port, &bytes_to_read) == -1) {
- perror("recv_all");
- close(i);
- FD_CLR(i, &master);
- destroy_user(i);
- continue;
- }
-
+ if (command_type == 0) { // we got a HELLO commmand
+ // send back in invalid command if user already sent a hello
if (user_data[sockfd_to_user[i]].udpPort != -1) {
- // send back in invalid command
+ if (l) printf("received an extraneous HELLO from socket %d. sending INVALID reply.\n", i);
char * message = "must not sent more than one Hello message";
- send_invalid_command_reply(i, strlen(message), message);
- // drop connection upon invalid command
- close(i);
- FD_CLR(i, &master);
+ send_invalid_reply(i, strlen(message), message);
destroy_user(i);
- continue;
}
}
- else if (command_type == 1) { // we got a SetStation command
- // get the station number
-
- uint16_t station_number = -1;
- int bytes_to_read = sizeof(uint16_t);
- if (recv_all(i, &station_number, &bytes_to_read) == -1) {
- perror("recv_all");
- close(i);
- FD_CLR(i, &master);
- destroy_user(i);
- continue;
- }
- station_number = ntohs(station_number);
-
- // check if user has a udpPort to stream to
- if (user_data[sockfd_to_user[i]].udpPort == -1) {
- // send back in invalid command
- char * message = "must send Hello message first";
- send_invalid_command_reply(i, strlen(message), message);
- // drop connection upon invalid command
- close(i);
- FD_CLR(i, &master);
- destroy_user(i);
- continue;
- }
-
- // check if station num is in range
- if (station_number >= num_stations || station_number < 0) {
- // send back in invalid command
- char * message = "station number out of range";
- send_invalid_command_reply(i, strlen(message), message);
- // drop connection upon invalid command
- close(i);
- FD_CLR(i, &master);
- destroy_user(i);
- continue;
- }
- // printf("setting station to %d\n", ntohs(command.number));
- // update station of user
- update_user_station(i, station_number);
- send_announce_reply(i, station_number);
+ else if (command_type == 1) { // we got a SETSTATION command
+ handle_setstation_command(i);
}
else if (command_type == 5) { // we got a ListStations command
+ if (l) printf("received a LISTSTATIONS from socket %d\n", i);
pthread_t t;
- pthread_create(&t, NULL, send_stations_info_reply, i);
+ pthread_create(&t, NULL, send_stationsinfo_reply, i);
}
else {
- // send back in invalid command
- char * message = "invalid command";
- send_invalid_command_reply(i, strlen(message), message);
-
- // drop connection upon invalid command
- close(i);
- FD_CLR(i, &master);
+ if (l) printf("received unknown command type %d from socket %d. sending INVALID reply.\n", command_type, i);
+ char *message = "invalid command type";
+ send_invalid_reply(i, strlen(message), message);
destroy_user(i);
}
}
- } // END handle data from client
- } // END got new incoming connection
- } // END looping through file descriptors
-
- } // END for(;;)--and you thought it would never end!
+ }
+ }
+ }
+ }
}
void *init_user(int sockfd) {
@@ -766,7 +665,10 @@ void *init_user(int sockfd) {
sockfd_to_user[sockfd] = running_index;
// free(user_stream_threads);
pthread_mutex_unlock(&mutex_user_data);
+
+ return (NULL);
}
+
void *update_user_udpPort(int sockfd, int udpPort) {
pthread_mutex_lock(&mutex_user_data);
// get the user
@@ -776,6 +678,8 @@ void *update_user_udpPort(int sockfd, int udpPort) {
// start the stream thread, now that we have the udpPort
// pthread_create(&user->streamThread, NULL, send_udp_packet_routine, (void *)sockfd_to_user[sockfd]);
pthread_mutex_unlock(&mutex_user_data);
+
+ return (NULL);
}
void *update_user_station(int sockfd, int stationNum) {
pthread_mutex_lock(&mutex_user_data);
@@ -788,13 +692,11 @@ void *print_user_data(int index) {
}
void destroy_user(int sockfd) {
+ close(sockfd); // bye!
+ FD_CLR(sockfd, &master); // remove from master set
+
+ // remove user from data structures
pthread_mutex_lock(&mutex_user_data);
- // stop the thread streaming to the user
- // pthread_t thread = user_data[sockfd_to_user[sockfd]].streamThread;
- // if (thread != -1) {
- // pthread_cancel(thread);
- // }
- // "remove" the user from the list of user data
user_data[sockfd_to_user[sockfd]] = (user_t) {-1, -1, -1};
// map sockfd to -1
sockfd_to_user[sockfd] = -1;
@@ -813,6 +715,9 @@ void *get_in_addr(struct sockaddr *sa)
}
void send_announce_reply(int fd, int station_num) {
+ if (l) printf("sending ANNNOUNCE reply to socket %d\n", fd);
+
+
char* file_path = stations[station_num].filePath;
int len_file_path = strlen(file_path);
@@ -833,7 +738,7 @@ void send_announce_reply(int fd, int station_num) {
free(send_buffer);
}
-void send_invalid_command_reply(int fd, size_t message_size, char* message) {
+void send_invalid_reply(int fd, size_t message_size, char* message) {
char *send_buffer = malloc(message_size+2);
if (!send_buffer) {
perror("malloc in send invalid command");
@@ -853,11 +758,14 @@ void send_invalid_command_reply(int fd, size_t message_size, char* message) {
free(send_buffer);
}
-void *send_stations_info_reply(void * arg) {
+void *send_stationsinfo_reply(void * arg) {
int fd = (int) arg;
+ if (l) printf("sending STATIONSINFO reply to socket %d\n", fd);
+
uint8_t reply_size = 0;
- for (int i = 0; i < num_stations; i++) reply_size += snprintf(NULL, 0, "%d,%s\n", i, stations[i].filePath);
+ for (int i = 0; i < num_stations; i++)
+ reply_size += snprintf(NULL, 0, "%d,%s\n", i, stations[i].filePath);
reply_size--; // don't want final \n
// send type
@@ -892,4 +800,105 @@ int parse(char buffer[LINE_MAX], char *tokens[LINE_MAX / 2]) {
}
return 1;
-} \ No newline at end of file
+}
+
+uint16_t handle_handshake(int newfd)
+{
+ if (l) printf("waiting for HELLO command. new connection on socket %d\n", newfd);
+
+ // apply timeout to socket
+ apply_timeout(newfd);
+
+ uint8_t command_type = -1;
+ size_t nbytes;
+ if (nbytes = recv(newfd, &command_type, 1, 0) <= 0)
+ {
+ // got error or connection closed by client
+ if (nbytes == 0) {
+ // connection closed
+ if (l) printf("socket %d HUNGUP. lost connection.\n", newfd);
+ }
+ else
+ {
+ perror("recv in handle handshake");
+ }
+ // remove user from data structures
+ close(newfd);
+ return 0;
+ }
+
+ if (command_type != 0) {
+ char * message = "must send a Hello message first";
+ send_invalid_reply(newfd, strlen(message), message);
+ close(newfd);
+ return 0;
+ }
+
+ // get the udp port
+ uint16_t udp_port = -1;
+ int bytes_to_read = sizeof(uint16_t);
+ if (recv_all(newfd, &udp_port, &bytes_to_read) == -1) {
+ perror("recv_all");
+ close(newfd);
+ return 0;
+ }
+ // remove timeout, after reading data
+ remove_timeout(newfd);
+
+ if(l) printf("received HELLO from socket %d with udp port %u\n", newfd, ntohs(udp_port));
+
+ return ntohs(udp_port);
+}
+
+
+int send_welcome_reply(int fd) {
+ if(l) printf("sending WELCOME reply to socket %d\n", fd);
+
+ struct Welcome welcome;
+ welcome.replyType = 2;
+ welcome.numStations = htons(num_stations);
+ int bytes_to_send = sizeof(struct Welcome);
+ if (send_all(fd, &welcome, &bytes_to_send) == -1) {
+ perror("send_all (in init_user_routine)");
+ return -1;
+ }
+
+ return 1;
+}
+
+void handle_setstation_command(int sockfd) {
+ // get the station number
+ uint16_t station_number = -1;
+ int bytes_to_read = sizeof(uint16_t);
+ if (recv_all(sockfd, &station_number, &bytes_to_read) == -1) {
+ perror("recv_all");
+ destroy_user(sockfd);
+ }
+ station_number = ntohs(station_number);
+
+ // check if user has a udpPort to stream to
+ if (user_data[sockfd_to_user[sockfd]].udpPort == -1) {
+ if (l) printf("received a SETSTATION from socket %d before HELLO command. sending INVALID reply.\n", sockfd);
+ // send back in invalid command and drop user
+ char * message = "must send Hello message first";
+ send_invalid_reply(sockfd, strlen(message), message);
+ destroy_user(sockfd);
+ return;
+ }
+
+ if (l) printf("received a SETSTATION from socket %d with station_number %u\n", sockfd, station_number);
+
+ // check if station num is in range
+ if (station_number >= num_stations || station_number < 0) {
+ if (l) printf("station number invalid from socket %d. sending INVALID reply.\n", sockfd);
+
+ // send back in invalid command and drop user
+ char * message = "station number out of range";
+ send_invalid_reply(sockfd, strlen(message), message);
+ destroy_user(sockfd);
+ return;
+ }
+
+ update_user_station(sockfd, station_number);
+ send_announce_reply(sockfd, station_number);
+}
diff --git a/snowcast_server b/snowcast_server
index 2587920..76e7ac8 100755
--- a/snowcast_server
+++ b/snowcast_server
Binary files differ