mirror of
https://github.com/open-goal/jak-project
synced 2026-07-10 07:07:04 -04:00
Corrections to fix linux, and further cleanup
This commit is contained in:
@@ -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) {
|
||||
|
||||
@@ -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);
|
||||
|
||||
@@ -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
@@ -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;
|
||||
|
||||
@@ -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;
|
||||
|
||||
|
||||
@@ -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()) {
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
Reference in New Issue
Block a user