|  |  |  | @ -12,6 +12,8 @@ | 
		
	
		
			
				|  |  |  |  | #include <fcntl.h> | 
		
	
		
			
				|  |  |  |  | #include <stdio.h> | 
		
	
		
			
				|  |  |  |  | 
 | 
		
	
		
			
				|  |  |  |  | // The greated file descriptor is needed for polling the sockets.
 | 
		
	
		
			
				|  |  |  |  | // It needs to be global for the whole process.
 | 
		
	
		
			
				|  |  |  |  | int max_fd = -1; | 
		
	
		
			
				|  |  |  |  | 
 | 
		
	
		
			
				|  |  |  |  | struct Connection* | 
		
	
	
		
			
				
					|  |  |  | @ -54,6 +56,57 @@ connection_new(unsigned int source_port, const char* source_ip, unsigned int des | 
		
	
		
			
				|  |  |  |  |     return conn; | 
		
	
		
			
				|  |  |  |  | } | 
		
	
		
			
				|  |  |  |  | 
 | 
		
	
		
			
				|  |  |  |  | struct Connection* | 
		
	
		
			
				|  |  |  |  | connection_poll_ready(struct Client* client) { | 
		
	
		
			
				|  |  |  |  | 
 | 
		
	
		
			
				|  |  |  |  |     // Add all the connections' socket file descriptors to a watch list
 | 
		
	
		
			
				|  |  |  |  |     fd_set read_fds; | 
		
	
		
			
				|  |  |  |  |     FD_ZERO(&read_fds); | 
		
	
		
			
				|  |  |  |  |     for(int i = 0; i < 2; i++) | 
		
	
		
			
				|  |  |  |  |         if(client->conns[i]) | 
		
	
		
			
				|  |  |  |  |             FD_SET(client->conns[i]->sockfd, &read_fds); | 
		
	
		
			
				|  |  |  |  | 
 | 
		
	
		
			
				|  |  |  |  |     //struct timeval timeout = {0, 0};
 | 
		
	
		
			
				|  |  |  |  |     int result = select(max_fd + 1, &read_fds, NULL, NULL, NULL); | 
		
	
		
			
				|  |  |  |  | 
 | 
		
	
		
			
				|  |  |  |  |     // Check for socket polling errors
 | 
		
	
		
			
				|  |  |  |  |     if(result < 0) { | 
		
	
		
			
				|  |  |  |  |         perror("message polling failed"); | 
		
	
		
			
				|  |  |  |  | 	exit(EXIT_FAILURE); | 
		
	
		
			
				|  |  |  |  |     } | 
		
	
		
			
				|  |  |  |  | 
 | 
		
	
		
			
				|  |  |  |  |     // Return a null connection if nothing was received on any of them
 | 
		
	
		
			
				|  |  |  |  |     if (result == 0) | 
		
	
		
			
				|  |  |  |  |         return NULL; | 
		
	
		
			
				|  |  |  |  | 
 | 
		
	
		
			
				|  |  |  |  |     // Return the first connection with something to read
 | 
		
	
		
			
				|  |  |  |  |     for(int i = 0; i < 2; i++) | 
		
	
		
			
				|  |  |  |  |         if(FD_ISSET(client->conns[i]->sockfd, &read_fds)) | 
		
	
		
			
				|  |  |  |  |             return client->conns[i]; | 
		
	
		
			
				|  |  |  |  | 
 | 
		
	
		
			
				|  |  |  |  |     // Return a null connection if somehow none of them have anything to read
 | 
		
	
		
			
				|  |  |  |  |     return NULL; | 
		
	
		
			
				|  |  |  |  | 
 | 
		
	
		
			
				|  |  |  |  | } | 
		
	
		
			
				|  |  |  |  | 
 | 
		
	
		
			
				|  |  |  |  | void | 
		
	
		
			
				|  |  |  |  | connection_read(struct Connection* conn, union Message* resp) { | 
		
	
		
			
				|  |  |  |  | 
 | 
		
	
		
			
				|  |  |  |  |     int recvb = recvfrom(conn->sockfd, resp, sizeof(union Message), 0, (struct sockaddr*)&conn->remote_addr, &conn->addrlen); | 
		
	
		
			
				|  |  |  |  | 
 | 
		
	
		
			
				|  |  |  |  |     // Check for socket read errors
 | 
		
	
		
			
				|  |  |  |  |     if(recvb < 0) { | 
		
	
		
			
				|  |  |  |  |         perror("reading socket failed"); | 
		
	
		
			
				|  |  |  |  |         exit(EXIT_FAILURE); | 
		
	
		
			
				|  |  |  |  |     } | 
		
	
		
			
				|  |  |  |  | 
 | 
		
	
		
			
				|  |  |  |  |     // Check for message errors
 | 
		
	
		
			
				|  |  |  |  |     if(message_validate(resp) != MESSAGEERR_NONE) { | 
		
	
		
			
				|  |  |  |  |         perror("invalid message"); | 
		
	
		
			
				|  |  |  |  |         exit(EXIT_FAILURE); | 
		
	
		
			
				|  |  |  |  |     } | 
		
	
		
			
				|  |  |  |  | } | 
		
	
		
			
				|  |  |  |  | 
 | 
		
	
		
			
				|  |  |  |  | void | 
		
	
		
			
				|  |  |  |  | req_send(struct Connection* conn, union Request* req, size_t length) { | 
		
	
		
			
				|  |  |  |  |     sendto(conn->sockfd, req, length, 0, (struct sockaddr*)&conn->remote_addr, conn->addrlen); | 
		
	
	
		
			
				
					|  |  |  | 
 |