Corrections to fix linux, and further cleanup

This commit is contained in:
Tyler Wilding
2020-09-08 19:15:14 -04:00
parent 4b6223a6d0
commit fff501d786
6 changed files with 62 additions and 52 deletions
+20 -11
View File
@@ -7,8 +7,9 @@
#include <WinSock2.h>
#include <WS2tcpip.h>
#endif
#include <errno.h>
#include <stdio.h>
#include <string.h>
int open_socket(int af, int type, int protocol) {
#ifdef __linux
@@ -38,28 +39,36 @@ void close_socket(int sock) {
#endif
}
int set_socket_option(int socket, int level, int optname, const char* optval, int optlen) {
#ifdef __linux
return setsockopt(socket, level, optname, optval, optlen);
#elif _WIN32
int ret = setsockopt(socket, level, optname, optval, optlen);
int set_socket_option(int socket, int level, int optname, const void* optval, int optlen) {
int ret = setsockopt(socket, level, optname, (char*)&optval, optlen);
if (ret < 0) {
printf("Failed to setsockopt(%d, %d, %d, _, _) - Error: %s\n", socket, level, optname,
strerror(errno));
}
#ifdef _WIN32
if (ret < 0) {
int err = WSAGetLastError();
printf("Failed to setsockopt - Err: %d\n", err);
printf("WSAGetLastError: %d\n", err);
}
return ret;
#endif
return ret;
}
int set_socket_timeout(int socket, int microSeconds) {
int set_socket_timeout(int socket, long microSeconds) {
#ifdef __linux
timeval timeout = {};
struct timeval timeout = {};
timeout.tv_sec = 0;
timeout.tv_usec = microSeconds;
int ret = setsockopt(socket, SOL_SOCKET, SO_RCVTIMEO, (struct timeval*)&timeout, sizeof(timeout));
if (ret < 0) {
printf("Failed to setsockopt(%d, %d, %d, _, _) - Error: %s\n", socket, SOL_SOCKET, SO_RCVTIMEO,
strerror(errno));
}
return ret;
#elif _WIN32
unsigned long timeout = microSeconds / 1000; // milliseconds
return set_socket_option(socket, SOL_SOCKET, SO_RCVTIMEO, &timeout, sizeof(timeout));
#endif
return set_socket_option(socket, SOL_SOCKET, SO_RCVTIMEO, (char*)&timeout, sizeof(timeout));
}
int write_to_socket(int socket, const char* buf, int len) {
+2 -2
View File
@@ -14,7 +14,7 @@ const int TCP_SOCKET_LEVEL = IPPROTO_TCP;
int open_socket(int af, int type, int protocol);
void close_socket(int sock);
int set_socket_option(int socket, int level, int optname, const char* optval, int optlen);
int set_socket_timeout(int socket, int microSeconds);
int set_socket_option(int socket, int level, int optname, const void* optval, int optlen);
int set_socket_timeout(int socket, long microSeconds);
int write_to_socket(int socket, const char* buf, int len);
int read_from_socket(int socket, char* buf, int len);
+5 -5
View File
@@ -56,28 +56,28 @@ bool Deci2Server::init() {
#ifdef __linux
int server_socket_opt = SO_REUSEADDR | SO_REUSEPORT;
int server_socket_tcp_level = SOL_TCP;
#elif _WIN32
int server_socket_opt = SO_EXCLUSIVEADDRUSE;
int server_socket_tcp_level = IPPROTO_TCP;
#endif
char opt = 1;
int opt = 1;
if (set_socket_option(server_socket, SOL_SOCKET, server_socket_opt, &opt, sizeof(opt)) < 0) {
close_server_socket();
return false;
}
printf("[Deci2Server] Created Socket Options\n");
if (set_socket_option(server_socket, server_socket_tcp_level, TCP_NODELAY, &opt, sizeof(opt)) <
0) {
if (set_socket_option(server_socket, TCP_SOCKET_LEVEL, TCP_NODELAY, &opt, sizeof(opt)) < 0) {
close_server_socket();
return false;
}
printf("[Deci2Server] Created TCP Socket Options\n");
if (set_socket_timeout(server_socket, 100000) < 0) {
close_server_socket();
return false;
}
printf("[Deci2Server] Created Socket Timeout\n");
addr.sin_family = AF_INET;
addr.sin_addr.s_addr = INADDR_ANY;
+28 -29
View File
@@ -33,8 +33,8 @@ Listener::~Listener() {
disconnect();
delete[] m_buffer;
if (socket_fd >= 0) {
close_socket(socket_fd);
if (listen_socket >= 0) {
close_socket(listen_socket);
}
}
@@ -59,31 +59,29 @@ bool Listener::connect_to_target(const std::string& ip, int port) {
throw std::runtime_error("attempted a Listener::connect_to_target when already connected!");
}
if (socket_fd >= 0) {
close_socket(socket_fd);
if (listen_socket >= 0) {
close_socket(listen_socket);
}
// construct socket
socket_fd = open_socket(AF_INET, SOCK_STREAM, 0);
if (socket_fd < 0) {
listen_socket = open_socket(AF_INET, SOCK_STREAM, 0);
if (listen_socket < 0) {
printf("[Listener] Failed to create socket.\n");
socket_fd = -1;
listen_socket = -1;
return false;
}
if (set_socket_timeout(socket_fd, 100000) < 0) {
printf("[Listener] setsockopt failed\n");
close_socket(socket_fd);
socket_fd = -1;
if (set_socket_timeout(listen_socket, 100000) < 0) {
close_socket(listen_socket);
listen_socket = -1;
return false;
}
// set nodelay, which makes small rapid messages faster, but large messages slower
char one = 1;
if (set_socket_option(socket_fd, TCP_SOCKET_LEVEL, TCP_NODELAY, &one, sizeof(one))) {
printf("[Listener] failed to TCP_NODELAY\n");
close_socket(socket_fd);
socket_fd = -1;
int one = 1;
if (set_socket_option(listen_socket, TCP_SOCKET_LEVEL, TCP_NODELAY, &one, sizeof(one))) {
close_socket(listen_socket);
listen_socket = -1;
return false;
}
@@ -93,17 +91,17 @@ bool Listener::connect_to_target(const std::string& ip, int port) {
server_address.sin_port = htons(port);
if (inet_pton(AF_INET, ip.c_str(), &server_address.sin_addr) <= 0) {
printf("[Listener] Invalid IP address.\n");
close_socket(socket_fd);
socket_fd = -1;
close_socket(listen_socket);
listen_socket = -1;
return false;
}
// connect!
int rv = connect(socket_fd, (sockaddr*)&server_address, sizeof(server_address));
int rv = connect(listen_socket, (sockaddr*)&server_address, sizeof(server_address));
if (rv < 0) {
printf("[Listener] Failed to connect\n");
close_socket(socket_fd);
socket_fd = -1;
close_socket(listen_socket);
listen_socket = -1;
return false;
}
@@ -113,7 +111,7 @@ bool Listener::connect_to_target(const std::string& ip, int port) {
int prog = 0;
bool ok = true;
while (prog < 8) {
auto r = read_from_socket(socket_fd, (char*)version_buffer + prog, 8 - prog);
auto r = read_from_socket(listen_socket, (char*)version_buffer + prog, 8 - prog);
if (r < 0) {
ok = false;
break;
@@ -127,8 +125,8 @@ bool Listener::connect_to_target(const std::string& ip, int port) {
}
if (!ok) {
printf("[Listener] Failed to get version number\n");
close_socket(socket_fd);
socket_fd = -1;
close_socket(listen_socket);
listen_socket = -1;
return false;
}
@@ -141,8 +139,8 @@ bool Listener::connect_to_target(const std::string& ip, int port) {
return true;
} else {
printf(", expected %d.%d. Cannot connect.\n", GOAL_VERSION_MAJOR, GOAL_VERSION_MINOR);
close_socket(socket_fd);
socket_fd = -1;
close_socket(listen_socket);
listen_socket = -1;
return false;
}
}
@@ -158,7 +156,7 @@ void Listener::receive_func() {
int rcvd_desired = sizeof(ListenerMessageHeader);
char buff[sizeof(ListenerMessageHeader)];
while (rcvd < rcvd_desired) {
auto got = read_from_socket(socket_fd, buff + rcvd, rcvd_desired - rcvd);
auto got = read_from_socket(listen_socket, buff + rcvd, rcvd_desired - rcvd);
rcvd += got > 0 ? got : 0;
// kick us out if we got a bogus read result
@@ -191,7 +189,7 @@ void Listener::receive_func() {
while (rcvd < hdr->deci2_header.len) {
if (!m_connected)
return;
int got = read_from_socket(socket_fd, ack_recv_buff + ack_recv_prog,
int got = read_from_socket(listen_socket, ack_recv_buff + ack_recv_prog,
hdr->deci2_header.len - rcvd);
got = got > 0 ? got : 0;
rcvd += got;
@@ -214,7 +212,8 @@ void Listener::receive_func() {
return;
}
int got = read_from_socket(socket_fd, str_buff + msg_prog, hdr->deci2_header.len - rcvd);
int got =
read_from_socket(listen_socket, str_buff + msg_prog, hdr->deci2_header.len - rcvd);
got = got > 0 ? got : 0;
rcvd += got;
msg_prog += got;
+1 -1
View File
@@ -29,7 +29,7 @@ class Listener {
char* m_buffer = nullptr; //! buffer for incoming messages
bool m_connected = false; //! do we think we are connected?
bool receive_thread_running = false; //! is the receive thread unjoined?
int socket_fd = -1; //! socket
int listen_socket = -1; //! socket
bool got_ack = false;
bool waiting_for_ack = false;
+6 -4
View File
@@ -55,9 +55,10 @@ TEST(Listener, DeciThenListener) {
Listener l;
EXPECT_FALSE(s.check_for_listener());
EXPECT_FALSE(s.check_for_listener());
EXPECT_TRUE(l.connect_to_target());
bool connected = l.connect_to_target();
EXPECT_TRUE(connected);
// TODO - some sort of backoff and retry would be better
while (!s.check_for_listener()) {
while (connected && !s.check_for_listener()) {
}
EXPECT_TRUE(s.check_for_listener());
@@ -85,9 +86,10 @@ TEST(Listener, ListenerThenDeci) {
Deci2Server s(always_false);
EXPECT_TRUE(s.init());
EXPECT_FALSE(s.check_for_listener());
EXPECT_TRUE(l.connect_to_target());
bool connected = l.connect_to_target();
EXPECT_TRUE(connected);
// TODO - some sort of backoff and retry would be better
while (!s.check_for_listener()) {
while (connected && !s.check_for_listener()) {
}
}
}