Use shim in Listener/Deci2Server

This commit is contained in:
Tyler Wilding 2020-09-07 19:59:44 -04:00
parent 1ab8329e3c
commit 84e0bee6f4
8 changed files with 88 additions and 81 deletions

View file

@ -42,6 +42,9 @@ add_subdirectory(asset_tool)
# build type_system library for compiler/decompiler
add_subdirectory(common/type_system)
# build cross platform socket library
add_subdirectory(common/cross_sockets)
# build decompiler
add_subdirectory(decompiler)

View file

@ -76,11 +76,10 @@ add_executable(gk ${RUNTIME_SOURCE} main.cpp)
# can be used to test other things.
add_library(runtime ${RUNTIME_SOURCE})
IF (WIN32)
# set stuff for windows
target_link_libraries(gk mman)
target_link_libraries(gk cross_sockets mman)
ELSE()
# set stuff for other systems
target_link_libraries(gk pthread)
target_link_libraries(gk cross_sockets)
ENDIF()

View file

@ -4,15 +4,22 @@
* Works with deci2.cpp (sceDeci2) to implement the networking on target
*/
// TODO-WINDOWS
#ifdef __linux__
#include <cstdio>
#include <cassert>
#include <utility>
// TODO - i think im not including the dependency right..?
#include "common/cross_sockets/xsocket.h"
#ifdef __linux
#include <sys/socket.h>
#include <netinet/tcp.h>
#include <unistd.h>
#include <cassert>
#include <utility>
#elif _WIN32
#define WIN32_LEAN_AND_MEAN
#include <WS2tcpip.h>
#endif
#include "common/listener_common.h"
#include "common/versions.h"
@ -33,38 +40,39 @@ Deci2Server::~Deci2Server() {
delete[] buffer;
if (server_fd >= 0) {
close(server_fd);
}
if (new_sock >= 0) {
close(new_sock);
}
close_server_socket();
close_socket(new_sock);
}
/*!
* Start waiting for the Listener to connect
*/
bool Deci2Server::init() {
server_fd = socket(AF_INET, SOCK_STREAM, 0);
if (server_fd < 0) {
server_fd = -1;
server_socket = socket(AF_INET, SOCK_STREAM, 0);
if (server_socket < 0) {
server_socket = -1;
return false;
}
#ifdef __linux
int server_socket_opt = SO_REUSEADDR | SO_REUSEPORT;
int server_socket_tcp_level = SOL_TCP;
#elif _WIN32
int server_socket_opt = SO_REUSEADDR | SO_BROADCAST;
int server_socket_tcp_level = IPPROTO_IP;
#endif
int opt = 1;
if (setsockopt(server_fd, SOL_SOCKET, SO_REUSEADDR | SO_REUSEPORT, &opt, sizeof(opt))) {
if (set_socket_option(server_socket, SOL_SOCKET, server_socket_opt, opt, sizeof(opt))) {
printf("[Deci2Server] Failed to setsockopt 1\n");
close(server_fd);
server_fd = -1;
close_server_socket();
return false;
}
int one = 1;
if (setsockopt(server_fd, SOL_TCP, TCP_NODELAY, &one, sizeof(one))) {
if (set_socket_option(server_socket, server_socket_tcp_level, TCP_NODELAY, one, sizeof(one))) {
printf("[Deci2Server] Failed to setsockopt 2\n");
close(server_fd);
server_fd = -1;
close_server_socket();
return false;
}
@ -72,10 +80,9 @@ bool Deci2Server::init() {
timeout.tv_sec = 0;
timeout.tv_usec = 100000;
if (setsockopt(server_fd, SOL_SOCKET, SO_RCVTIMEO, (char*)&timeout, sizeof(timeout)) < 0) {
if (setsockopt(server_socket, SOL_SOCKET, SO_RCVTIMEO, (char*)&timeout, sizeof(timeout)) < 0) {
printf("[Deci2Server] Failed to setsockopt 3\n");
close(server_fd);
server_fd = -1;
close_server_socket();
return false;
}
@ -83,17 +90,15 @@ bool Deci2Server::init() {
addr.sin_addr.s_addr = INADDR_ANY;
addr.sin_port = htons(DECI2_PORT);
if (bind(server_fd, (sockaddr*)&addr, sizeof(addr)) < 0) {
if (bind(server_socket, (sockaddr*)&addr, sizeof(addr)) < 0) {
printf("[Deci2Server] Failed to bind\n");
close(server_fd);
server_fd = -1;
close_server_socket();
return false;
}
if (listen(server_fd, 0) < 0) {
if (listen(server_socket, 0) < 0) {
printf("[Deci2Server] Failed to listen\n");
close(server_fd);
server_fd = -1;
close_server_socket();
return false;
}
@ -104,6 +109,11 @@ bool Deci2Server::init() {
return true;
}
void Deci2Server::close_server_socket() {
close_socket(server_socket);
server_socket = -1;
}
/*!
* Return true if the listener is connected.
*/
@ -129,7 +139,7 @@ void Deci2Server::send_data(void* buf, u16 len) {
} else {
uint16_t prog = 0;
while (prog < len) {
auto wrote = write(new_sock, (char*)(buf) + prog, len - prog);
int wrote = write_to_socket(new_sock, (char*)(buf) + prog, len - prog);
prog += wrote;
if (!server_connected || want_exit()) {
unlock();
@ -186,7 +196,7 @@ void Deci2Server::run() {
while (got < desired_size) {
assert(got + desired_size < BUFFER_SIZE);
auto x = read(new_sock, buffer + got, desired_size - got);
auto x = read_from_socket(new_sock, buffer + got, desired_size - got);
if (want_exit()) {
return;
}
@ -237,7 +247,7 @@ void Deci2Server::run() {
// receive from network
if (hdr->rsvd < hdr->len) {
auto x = read(new_sock, buffer + hdr->rsvd, hdr->len - hdr->rsvd);
auto x = read_from_socket(new_sock, buffer + hdr->rsvd, hdr->len - hdr->rsvd);
if (want_exit()) {
return;
}
@ -256,13 +266,12 @@ void Deci2Server::run() {
void Deci2Server::accept_thread_func() {
socklen_t l = sizeof(addr);
while (!kill_accept_thread) {
new_sock = accept(server_fd, (sockaddr*)&addr, &l);
new_sock = accept(server_socket, (sockaddr*)&addr, &l);
if (new_sock >= 0) {
u32 versions[2] = {versions::GOAL_VERSION_MAJOR, versions::GOAL_VERSION_MINOR};
send(new_sock, &versions, 8, 0); // todo, check result?
write_to_socket(new_sock, (char*)&versions, 8); // todo, check result?
server_connected = true;
return;
}
}
}
#endif

View file

@ -4,11 +4,14 @@
* Works with deci2.cpp (sceDeci2) to implement the networking on target
*/
#ifdef __linux__
#ifndef JAK1_DECI2SERVER_H
#define JAK1_DECI2SERVER_H
#ifdef __linux
#include <netinet/in.h>
#elif _WIN32
#include <Windows.h>
#endif
#include <thread>
#include <mutex>
#include <condition_variable>
@ -32,11 +35,12 @@ class Deci2Server {
void run();
private:
void close_server_socket();
void accept_thread_func();
bool kill_accept_thread = false;
char* buffer = nullptr;
int server_fd = -1;
sockaddr_in addr;
int server_socket = -1;
struct sockaddr_in addr = {};
int new_sock = -1;
bool server_initialized = false;
bool accept_thread_running = false;
@ -52,4 +56,3 @@ class Deci2Server {
};
#endif // JAK1_DECI2SERVER_H
#endif

View file

@ -1,12 +1,6 @@
add_subdirectory(util)
add_subdirectory(goos)
IF (WIN32)
# TODO - implement windows listener
message("Windows Listener Not Implemented!")
ELSE()
add_subdirectory(listener)
ENDIF()
add_subdirectory(listener)
add_library(compiler
SHARED
@ -26,12 +20,10 @@ add_library(compiler
compiler/Compiler.cpp
)
add_executable(goalc main.cpp
)
add_executable(goalc main.cpp)
IF (WIN32)
set(CMAKE_WINDOWS_EXPORT_ALL_SYMBOLS ON)
target_link_libraries(compiler util goos type_system mman)
target_link_libraries(compiler cross_sockets util goos type_system mman)
ELSE()
target_link_libraries(compiler cross_sockets util goos goalc type_system)
ENDIF()
target_link_libraries(goalc util goos compiler type_system)

View file

@ -3,13 +3,20 @@
* The Listener can connect to a Deci2Server for debugging.
*/
// TODO-Windows
#ifdef __linux__
#include <stdexcept>
#ifdef __linux
#include <netinet/tcp.h>
#include <arpa/inet.h>
#include <unistd.h>
#elif _WIN32
#define WIN32_LEAN_AND_MEAN
#include <WinSock2.h>
#include <WS2tcpip.h>
#endif
// TODO - i think im not including the dependency right..?
#include "common/cross_sockets/xsocket.h"
#include <stdexcept>
#include <cassert>
#include "Listener.h"
#include "common/versions.h"
@ -27,7 +34,7 @@ Listener::~Listener() {
delete[] m_buffer;
if (socket_fd >= 0) {
close(socket_fd);
close_socket(socket_fd);
}
}
@ -53,7 +60,7 @@ bool Listener::connect_to_target(const std::string& ip, int port) {
}
if (socket_fd >= 0) {
close(socket_fd);
close_socket(socket_fd);
}
// construct socket
@ -70,16 +77,16 @@ bool Listener::connect_to_target(const std::string& ip, int port) {
timeout.tv_usec = 100000;
if (setsockopt(socket_fd, SOL_SOCKET, SO_RCVTIMEO, (char*)&timeout, sizeof(timeout)) < 0) {
printf("[Listener] setsockopt failed\n");
close(socket_fd);
close_socket(socket_fd);
socket_fd = -1;
return false;
}
// set nodelay, which makes small rapid messages faster, but large messages slower
int one = 1;
if (setsockopt(socket_fd, SOL_TCP, TCP_NODELAY, &one, sizeof(one))) {
if (set_socket_option(socket_fd, TCP_SOCKET_LEVEL, TCP_NODELAY, one, sizeof(one))) {
printf("[Listener] failed to TCP_NODELAY\n");
close(socket_fd);
close_socket(socket_fd);
socket_fd = -1;
return false;
}
@ -90,7 +97,7 @@ 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_fd);
close_socket(socket_fd);
socket_fd = -1;
return false;
}
@ -99,7 +106,7 @@ bool Listener::connect_to_target(const std::string& ip, int port) {
int rv = connect(socket_fd, (sockaddr*)&server_address, sizeof(server_address));
if (rv < 0) {
printf("[Listener] Failed to connect\n");
close(socket_fd);
close_socket(socket_fd);
socket_fd = -1;
return false;
}
@ -110,7 +117,7 @@ bool Listener::connect_to_target(const std::string& ip, int port) {
int prog = 0;
bool ok = true;
while (prog < 8) {
auto r = read(socket_fd, version_buffer + prog, 8 - prog);
auto r = read_from_socket(socket_fd, (char*)version_buffer + prog, 8 - prog);
if (r < 0) {
ok = false;
break;
@ -124,7 +131,7 @@ bool Listener::connect_to_target(const std::string& ip, int port) {
}
if (!ok) {
printf("[Listener] Failed to get version number\n");
close(socket_fd);
close_socket(socket_fd);
socket_fd = -1;
return false;
}
@ -138,7 +145,7 @@ 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_fd);
close_socket(socket_fd);
socket_fd = -1;
return false;
}
@ -155,7 +162,7 @@ void Listener::receive_func() {
int rcvd_desired = sizeof(ListenerMessageHeader);
char buff[sizeof(ListenerMessageHeader)];
while (rcvd < rcvd_desired) {
auto got = read(socket_fd, buff + rcvd, rcvd_desired - rcvd);
auto got = read_from_socket(socket_fd, buff + rcvd, rcvd_desired - rcvd);
rcvd += got > 0 ? got : 0;
// kick us out if we got a bogus read result
@ -188,7 +195,7 @@ void Listener::receive_func() {
while (rcvd < hdr->deci2_header.len) {
if (!m_connected)
return;
int got = read(socket_fd, ack_recv_buff + ack_recv_prog, hdr->deci2_header.len - rcvd);
int got = read_from_socket(socket_fd, ack_recv_buff + ack_recv_prog, hdr->deci2_header.len - rcvd);
got = got > 0 ? got : 0;
rcvd += got;
ack_recv_prog += got;
@ -210,7 +217,7 @@ void Listener::receive_func() {
return;
}
int got = read(socket_fd, str_buff + msg_prog, hdr->deci2_header.len - rcvd);
int got = read_from_socket(socket_fd, str_buff + msg_prog, hdr->deci2_header.len - rcvd);
got = got > 0 ? got : 0;
rcvd += got;
msg_prog += got;
@ -242,4 +249,3 @@ void Listener::receive_func() {
}
} // namespace listener
#endif

View file

@ -18,9 +18,8 @@ add_executable(goalc-test
IF (WIN32)
set(gtest_force_shared_crt ON CACHE BOOL "" FORCE)
# TODO - implement windows listener
message("Windows Listener Not Implemented!")
target_link_libraries(goalc-test mman goos util runtime compiler type_system gtest)
# TODO - split out these declarations for platform specific includes
target_link_libraries(goalc-test cross_sockets listener mman goos util runtime compiler type_system gtest)
ELSE()
target_link_libraries(goalc-test goos util listener runtime compiler type_system gtest)
target_link_libraries(goalc-test cross_sockets goos util listener runtime compiler type_system gtest)
ENDIF()

View file

@ -1,5 +1,3 @@
#ifdef __linux__
#include "gtest/gtest.h"
#include "goalc/listener/Listener.h"
#include "game/system/Deci2Server.h"
@ -126,5 +124,3 @@ TEST(Listener, ListenerMultipleDecis) {
l.disconnect();
}
}
#endif