Skip to content

Commit

Permalink
add user_state[.cpp|.hpp] comments and docstrings
Browse files Browse the repository at this point in the history
  • Loading branch information
pereira0x committed Dec 15, 2023
1 parent 34442b2 commit 275384c
Show file tree
Hide file tree
Showing 2 changed files with 44 additions and 28 deletions.
62 changes: 36 additions & 26 deletions src/client/user_state.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -29,33 +29,33 @@ UserState::~UserState() {
}

void UserState::setupUdpSocket() {
// Create a UDP socket
// Create a UDP socket, AF_INET for IPv4, SOCK_DGRAM for UDP, 0 for IP
if ((this->udpSocketFD = socket(AF_INET, SOCK_DGRAM, 0)) == -1) {
throw FatalError("Failed to create a UDP socket", errno);
}
}

void UserState::resolveServerAddress(std::string &hostname, std::string &port) {
struct addrinfo hints;
int addr_res;
const char *host = hostname.c_str();
const char *port_str = port.c_str();

// Get UDP address
memset(&hints, 0, sizeof hints);
hints.ai_family = AF_INET; // IPv4
hints.ai_socktype = SOCK_DGRAM; // UDP socket
struct addrinfo hints; // address info hints
int addr_res; // address resolution result
const char *host = hostname.c_str(); // host string
const char *port_str = port.c_str(); // port string

memset(&hints, 0, sizeof hints); // clear hints
hints.ai_family = AF_INET; // IPv4
hints.ai_socktype = SOCK_DGRAM; // UDP socket

// check if address is valid
if ((addr_res = getaddrinfo(host, port_str, &hints, &this->serverUdpAddr)) !=
0) {
throw FatalError(std::string("Failed to get address for UDP connection: ") +
gai_strerror(addr_res));
}

// Get TCP address
memset(&hints, 0, sizeof hints);
memset(&hints, 0, sizeof hints); // clear hints
hints.ai_family = AF_INET; // IPv4
hints.ai_socktype = SOCK_STREAM; // TCP socket

// check if address is valid
if ((addr_res = getaddrinfo(host, port_str, &hints, &this->serverTcpAddr)) !=
0) {
Expand All @@ -75,15 +75,15 @@ void UserState::waitForUdpPacket(UdpPacket &packet) {

void UserState::sendUdpPacketAndWaitForReply(UdpPacket &request,
UdpPacket &response) {
int triesLeft = UDP_RESEND_TRIES;
int triesLeft = UDP_RESEND_TRIES; // number of tries left
while (triesLeft > 0) {
--triesLeft;
try {
this->sendUdpPacket(request);
this->waitForUdpPacket(response);
return;
} catch (ConnectionTimeoutException &e) {
if (triesLeft == 0) {
} catch (ConnectionTimeoutException &e) { // timeout
if (triesLeft == 0) { // no more tries left
throw;
}
}
Expand All @@ -92,21 +92,23 @@ void UserState::sendUdpPacketAndWaitForReply(UdpPacket &request,

void UserState::sendTcpPacketAndWaitForReply(TcpPacket &out_packet,
TcpPacket &in_packet) {
// NOTE: We only want the socket to be open while sending the packet
try {
openTcpSocket();
sendTcpPacket(out_packet);
waitForTcpPacket(in_packet);
} catch (...) {
closeTcpSocket();
closeTcpSocket(); // close socket on error
throw;
}
closeTcpSocket();
closeTcpSocket(); // close socket on success
};

void UserState::sendTcpPacket(TcpPacket &packet) {
// Connect to the server using the TCP socket
if (connect(tcpSocketFD, serverTcpAddr->ai_addr, serverTcpAddr->ai_addrlen) !=
0) {
throw ConnectionTimeoutException();
throw ConnectionTimeoutException(); // timeout
}
packet.send(tcpSocketFD);
}
Expand All @@ -116,19 +118,28 @@ void UserState::waitForTcpPacket(TcpPacket &packet) {
}

void UserState::openTcpSocket() {
// Create a TCP socket, AF_INET for IPv4, SOCK_STREAM for TCP, 0 for IP
if ((this->tcpSocketFD = socket(AF_INET, SOCK_STREAM, 0)) == -1) {
throw FatalError("Failed to create a TCP socket", errno);
}
struct timeval read_timeout;
read_timeout.tv_sec = TCP_READ_TIMEOUT_SECONDS;
read_timeout.tv_usec = 0;

struct timeval read_timeout; // timeout on read operations
read_timeout.tv_sec = TCP_READ_TIMEOUT_SECONDS; // seconds to wait
read_timeout.tv_usec = 0; // microseconds to wait

// Set socket options, SOL_SOCKET for socket-level options, SO_RCVTIMEO for a
// timeout on read operations
if (setsockopt(this->tcpSocketFD, SOL_SOCKET, SO_RCVTIMEO, &read_timeout,
sizeof(read_timeout)) < 0) {
throw FatalError("Failed to set TCP read timeout socket option", errno);
}
struct timeval write_timeout;
write_timeout.tv_sec = TCP_WRITE_TIMEOUT_SECONDS;
write_timeout.tv_usec = 0;

struct timeval write_timeout; // timeout on write operations
write_timeout.tv_sec = TCP_WRITE_TIMEOUT_SECONDS; // seconds to wait
write_timeout.tv_usec = 0; // microseconds to wait

// Set socket options, SOL_SOCKET for socket-level options, SO_SNDTIMEO for a
// timeout on write operations
if (setsockopt(this->tcpSocketFD, SOL_SOCKET, SO_SNDTIMEO, &write_timeout,
sizeof(write_timeout)) < 0) {
throw FatalError("Failed to set TCP send timeout socket option", errno);
Expand All @@ -137,8 +148,7 @@ void UserState::openTcpSocket() {

void UserState::closeTcpSocket() {
if (close(this->tcpSocketFD) != 0) {
if (errno == EBADF) {
// was already closed
if (errno == EBADF) { // invalid file descriptor, it was already closed
return;
}
throw FatalError("Failed to close TCP socket", errno);
Expand Down
10 changes: 8 additions & 2 deletions src/client/user_state.hpp
Original file line number Diff line number Diff line change
Expand Up @@ -29,7 +29,7 @@ class UserState {
void setupUdpSocket();

/**
* @brief Resolves the server address.
* @brief Resolves the server address, for both UDP and TCP.
*
* @param hostname The hostname of the server.
* @param port The port of the server.
Expand Down Expand Up @@ -99,6 +99,12 @@ class UserState {
*/
void sendUdpPacketAndWaitForReply(UdpPacket &request, UdpPacket &response);

/**
* @brief Sends a TCP packet and waits for a reply.
*
* @param request The packet to send.
* @param response The packet to receive.
*/
void sendTcpPacketAndWaitForReply(TcpPacket &request, TcpPacket &response);

/**
Expand Down Expand Up @@ -162,7 +168,7 @@ class UserState {
void setPassword(std::string __password) { this->password = __password; }

/**
* @brief Checks if there is a logged in user.
* @brief Checks if there is a logged in user.s
*/
bool isLoggedIn() { return !this->userID.empty(); }
};
Expand Down

0 comments on commit 275384c

Please sign in to comment.