Revert "(Cthulhu88) New Netplay MITM Part 2"

This reverts commit 34c374737c1c09497bf28af090a045656ac07bde.
This commit is contained in:
twinaphex 2021-11-12 18:58:40 +01:00
parent 196cc8b33d
commit 70ee3fbca7
5 changed files with 176 additions and 120 deletions

View File

@ -40,6 +40,7 @@
#define NETPLAY_HOST_LONGSTR_LEN 256
#define NETPLAY_MITM_MAX_PENDING 8
#define NETPLAY_MITM_ID_SIZE 16
enum rarch_netplay_ctl_state
{
@ -187,22 +188,14 @@ struct netplay_host_list
size_t size;
};
#pragma pack(push, 1)
typedef struct mitm_id
{
uint32_t magic;
uint8_t unique[12];
} mitm_id_t;
#pragma pack(pop)
struct netplay_mitm_pending
{
int *fds;
mitm_id_t *ids;
uint8_t *ids[NETPLAY_MITM_MAX_PENDING];
retro_time_t *timeouts;
mitm_id_t id_buf;
size_t id_recvd;
int current;
int next;
};
typedef struct
@ -230,7 +223,7 @@ typedef struct
bool in_netplay;
bool netplay_client_deferred;
bool is_mitm;
mitm_id_t mitm_session_id;
uint8_t mitm_id[NETPLAY_MITM_ID_SIZE];
struct netplay_mitm_pending mitm_pending;
bool has_set_netplay_mode;
bool has_set_netplay_ip_address;
@ -350,6 +343,7 @@ void deinit_netplay(void);
/**
* init_netplay
* @direct_host : Host to connect to directly, if applicable (client only)
* @server : server address to connect to (client only)
* @port : TCP port to host on/connect to
*
@ -359,7 +353,7 @@ void deinit_netplay(void);
*
* Returns: true (1) if successful, otherwise false (0).
**/
bool init_netplay(const char *server, unsigned port);
bool init_netplay(void *direct_host, const char *server, unsigned port);
bool init_netplay_deferred(const char* server, unsigned port);

View File

@ -91,10 +91,6 @@
#define FULL_MAGIC 0x46554C4C /* FULL */
#define POKE_MAGIC 0x504F4B45 /* POKE */
/* MITM magics */
#define MITM_SESSION_MAGIC 0x52415453 /* RATS */
#define MITM_CONNECT_MAGIC 0x52415443 /* RATC */
#define MAX_CHAT_SIZE 256
#define CHAT_FRAME_TIME 600
@ -2176,7 +2172,7 @@ bool netplay_send(
/* Can only be that this is simply too big
* for our buffer, in which case we just
* need to do a blocking send */
if (!socket_send_all_blocking(sockfd, buf, len, true))
if (!socket_send_all_blocking(sockfd, buf, len, false))
return false;
return true;
}
@ -2434,7 +2430,7 @@ static bool netplay_full(netplay_t *netplay, int sockfd)
This is fine; the header is just a warning
for the client. */
socket_send_all_nonblocking(sockfd, header,
sizeof(header), true);
sizeof(header), false);
return true;
}
@ -5805,55 +5801,49 @@ static int init_tcp_connection(const struct addrinfo *res,
host, port);
dmsg = msg;
}
else
#endif
#else
dmsg = "Failed to connect to host.";
#endif
}
else
{
#ifdef __NETPLAY_MITM_NEW
if (use_mitm)
{
if (!socket_connect(fd, (void*)res, false))
{
mitm_id_t new_session = {0};
mitm_id_t invalid_session = {0};
net_driver_state_t *net_st = &networking_driver_st;
/* To request a new session,
we send the magic with the rest of the ID zeroed. */
new_session.magic = htonl(MITM_SESSION_MAGIC);
/* Relay server should provide us with our session ID. */
if (socket_send_all_blocking(fd,
&new_session, sizeof(new_session), true) &&
socket_receive_all_blocking(fd,
&net_st->mitm_session_id, sizeof(net_st->mitm_session_id)) &&
ntohl(net_st->mitm_session_id.magic) == MITM_SESSION_MAGIC &&
memcmp(&net_st->mitm_session_id.unique, &invalid_session.unique,
sizeof(net_st->mitm_session_id.unique)))
if (socket_receive_all_blocking(fd, net_st->mitm_id, sizeof(net_st->mitm_id)))
{
/* Initialize data for handling tunneled client connections. */
int *fds;
mitm_id_t *ids;
uint8_t *ids;
retro_time_t *timeouts;
fds = malloc(
NETPLAY_MITM_MAX_PENDING * sizeof(*fds));
ids = malloc(
NETPLAY_MITM_MAX_PENDING * sizeof(*ids));
NETPLAY_MITM_MAX_PENDING * NETPLAY_MITM_ID_SIZE * sizeof(*ids));
timeouts = malloc(
NETPLAY_MITM_MAX_PENDING * sizeof(*timeouts));
if (fds && ids && timeouts)
{
size_t i;
memset(fds, -1,
NETPLAY_MITM_MAX_PENDING * sizeof(*fds));
for (i = 0; i < NETPLAY_MITM_MAX_PENDING; i++, ids += NETPLAY_MITM_ID_SIZE)
net_st->mitm_pending.ids[i] = ids;
net_st->mitm_pending.fds = fds;
net_st->mitm_pending.ids = ids;
net_st->mitm_pending.timeouts = timeouts;
net_st->mitm_pending.id_recvd = 0;
net_st->mitm_pending.current = 0;
net_st->mitm_pending.next = -1;
return fd;
}
@ -5877,13 +5867,14 @@ static int init_tcp_connection(const struct addrinfo *res,
host, port);
dmsg = msg;
}
else
#endif
#else
dmsg = "Failed to connect to relay server.";
#endif
}
}
else
{
#endif
#if defined(HAVE_INET6) && defined(IPPROTO_IPV6) && defined(IPV6_V6ONLY)
/* Make sure we accept connections on both IPv6 and IPv4 */
if (res->ai_family == AF_INET6)
@ -5891,7 +5882,7 @@ static int init_tcp_connection(const struct addrinfo *res,
int on = 0;
if (setsockopt(fd, IPPROTO_IPV6, IPV6_V6ONLY,
(const char*)&on, sizeof(on)) < 0)
RARCH_WARN("Failed to listen on both IPv6 and IPv4.\n");
RARCH_WARN("Failed to listen on both IPv6 and IPv4\n");
}
#endif
if (socket_bind(fd, (void*)res))
@ -5905,16 +5896,16 @@ static int init_tcp_connection(const struct addrinfo *res,
if (!getnameinfo(res->ai_addr, res->ai_addrlen,
NULL, 0, port, sizeof(port), NI_NUMERICSERV))
{
snprintf(msg, sizeof(msg),
"Failed to bind port %s.",
port);
snprintf(msg, sizeof(msg), "Failed to bind port %s.", port);
dmsg = msg;
}
else
#else
dmsg = "Failed to bind port.";
#endif
dmsg = "Failed to bind port.";
}
#ifdef __NETPLAY_MITM_NEW
}
#endif
}
socket_close(fd);
@ -6025,12 +6016,6 @@ try_ipv4:
return false;
}
if (!socket_nonblock(fd))
{
socket_close(fd);
return false;
}
if (server)
{
netplay->connections[0].active = true;
@ -6044,13 +6029,13 @@ try_ipv4:
return true;
}
static bool init_socket(netplay_t *netplay,
const char *server, const char *mitm, uint16_t port)
static bool init_socket(netplay_t *netplay, void *direct_host,
const char *server, uint16_t port)
{
if (!network_init())
return false;
if (!init_tcp_socket(netplay, server, mitm, port))
if (!init_tcp_socket(netplay, server, NULL, port))
return false;
if (netplay->is_server && netplay->nat_traversal)
@ -6226,8 +6211,8 @@ static bool netplay_init_buffers(netplay_t *netplay)
/**
* netplay_new:
* @direct_host : Netplay host discovered from scanning.
* @server : IP address of server.
* @mitm : IP address of the MITM/tunnel server.
* @port : Port of server.
* @stateless_mode : Shall we use stateless mode?
* @check_frames : Frequency with which to check CRCs.
@ -6241,21 +6226,21 @@ static bool netplay_init_buffers(netplay_t *netplay)
*
* Returns: new netplay data.
*/
netplay_t *netplay_new(const char *server, const char *mitm, uint16_t port,
netplay_t *netplay_new(void *direct_host, const char *server, uint16_t port,
bool stateless_mode, int check_frames,
const struct retro_callbacks *cb, bool nat_traversal, const char *nick,
uint64_t quirks)
{
netplay_t *netplay = calloc(1, sizeof(*netplay));
netplay_t *netplay = (netplay_t*)calloc(1, sizeof(*netplay));
if (!netplay)
return NULL;
netplay->listen_fd = -1;
netplay->tcp_port = port;
netplay->cbs = *cb;
netplay->is_server = !server;
netplay->is_server = (direct_host == NULL && server == NULL);
netplay->is_connected = false;
netplay->nat_traversal = (!server && !mitm) ? nat_traversal : false;
netplay->nat_traversal = netplay->is_server ? nat_traversal : false;
netplay->stateless_mode = stateless_mode;
netplay->check_frames = check_frames;
netplay->crc_validity_checked = false;
@ -6281,10 +6266,15 @@ netplay_t *netplay_new(const char *server, const char *mitm, uint16_t port,
? nick : RARCH_DEFAULT_NICK,
sizeof(netplay->nick));
if (!init_socket(netplay, server, mitm, port) ||
!netplay_init_buffers(netplay))
if (!init_socket(netplay, direct_host, server, port))
{
netplay_free(netplay);
free(netplay);
return NULL;
}
if (!netplay_init_buffers(netplay))
{
free(netplay);
return NULL;
}
@ -6314,7 +6304,30 @@ netplay_t *netplay_new(const char *server, const char *mitm, uint16_t port,
netplay->self_mode = NETPLAY_CONNECTION_INIT;
}
/* FIXME: Not really the right place to do this,
* socket initialization needs to be fixed in general. */
if (netplay->is_server)
{
if (!socket_nonblock(netplay->listen_fd))
goto error;
}
else
{
if (!socket_nonblock(netplay->connections[0].fd))
goto error;
}
return netplay;
error:
if (netplay->listen_fd >= 0)
socket_close(netplay->listen_fd);
if (netplay->connections && netplay->connections[0].fd >= 0)
socket_close(netplay->connections[0].fd);
free(netplay);
return NULL;
}
/**
@ -7300,6 +7313,34 @@ static void netplay_announce_cb(retro_task_t *task,
}
}
if (mitm_ip && mitm_port)
{
ip_len = (unsigned)strlen(mitm_ip);
port_len = (unsigned)strlen(mitm_port);
/* Enable Netplay client mode */
if (netplay_driver_ctl(RARCH_NETPLAY_CTL_IS_DATA_INITED, NULL))
{
command_event(CMD_EVENT_NETPLAY_DEINIT, NULL);
net_st->is_mitm = true;
host_room->host_method = NETPLAY_HOST_METHOD_MITM;
}
netplay_driver_ctl(RARCH_NETPLAY_CTL_ENABLE_CLIENT, NULL);
host_string = (char*)calloc(1, ip_len + port_len + 2);
memcpy(host_string, mitm_ip, ip_len);
memcpy(host_string + ip_len, "|", 1);
memcpy(host_string + ip_len + 1, mitm_port, port_len);
/* Enable Netplay */
command_event(CMD_EVENT_NETPLAY_INIT_DIRECT_DEFERRED, (void*)host_string);
command_event(CMD_EVENT_NETPLAY_INIT, (void*)host_string);
free(host_string);
}
#ifdef HAVE_DISCORD
if (discord_state_get_ptr()->inited)
{
@ -7561,10 +7602,11 @@ void deinit_netplay(void)
free(net_st->mitm_pending.fds);
net_st->mitm_pending.fds = NULL;
}
if (net_st->mitm_pending.ids)
if (net_st->mitm_pending.ids[0])
{
free(net_st->mitm_pending.ids);
net_st->mitm_pending.ids = NULL;
free(net_st->mitm_pending.ids[0]);
memset(net_st->mitm_pending.ids, 0,
sizeof(net_st->mitm_pending.ids));
}
if (net_st->mitm_pending.timeouts)
{
@ -7574,16 +7616,17 @@ void deinit_netplay(void)
core_unset_netplay_callbacks();
}
bool init_netplay(const char *server, unsigned port)
bool init_netplay(void *direct_host, const char *server, unsigned port)
{
struct retro_callbacks cbs = {0};
uint64_t serialization_quirks = 0;
uint64_t quirks = 0;
settings_t *settings = config_get_ptr();
net_driver_state_t *net_st = &networking_driver_st;
const char *mitm = NULL;
bool _netplay_is_client = net_st->netplay_is_client;
bool _netplay_enabled = net_st->netplay_enabled;
if (!net_st->netplay_enabled)
if (!_netplay_enabled)
return false;
core_set_default_callbacks(&cbs);
@ -7608,31 +7651,34 @@ bool init_netplay(const char *server, unsigned port)
if (serialization_quirks & NETPLAY_QUIRK_MAP_PLATFORM_DEPENDENT)
quirks |= NETPLAY_QUIRK_PLATFORM_DEPENDENT;
if (!net_st->netplay_is_client)
if (!_netplay_is_client)
{
server = NULL;
if (!port)
port = RARCH_DEFAULT_PORT;
runloop_msg_queue_push(
msg_hash_to_str(MSG_WAITING_FOR_CLIENT),
0, 180, false,
NULL, MESSAGE_QUEUE_ICON_DEFAULT, MESSAGE_QUEUE_CATEGORY_INFO);
}
else
{
if (net_st->netplay_client_deferred)
{
server = (const char*)net_st->server_address_deferred;
port = net_st->server_port_deferred;
}
if (settings->bools.netplay_public_announce)
netplay_announce();
}
net_st->data = netplay_new(
server, mitm, port,
net_st->data = (netplay_t*)netplay_new(
_netplay_is_client
? direct_host
: NULL,
_netplay_is_client
? (!net_st->netplay_client_deferred
? server
: net_st->server_address_deferred)
: NULL,
_netplay_is_client ? (!net_st->netplay_client_deferred
? port
: net_st->server_port_deferred)
: (port != 0 ? port : RARCH_DEFAULT_PORT),
settings->bools.netplay_stateless_mode,
settings->ints.netplay_check_frames,
&cbs,
settings->bools.netplay_nat_traversal,
settings->bools.netplay_nat_traversal && !settings->bools.netplay_use_mitm_server,
#ifdef HAVE_DISCORD
discord_get_own_username()
? discord_get_own_username()
@ -7641,21 +7687,21 @@ bool init_netplay(const char *server, unsigned port)
settings->paths.username,
quirks);
if (!net_st->data)
if (net_st->data)
{
RARCH_WARN("%s\n", msg_hash_to_str(MSG_NETPLAY_FAILED));
runloop_msg_queue_push(
msg_hash_to_str(MSG_NETPLAY_FAILED),
0, 180, false,
NULL, MESSAGE_QUEUE_ICON_DEFAULT, MESSAGE_QUEUE_CATEGORY_INFO);
return false;
if ( net_st->data->is_server
&& !settings->bools.netplay_start_as_spectator)
netplay_toggle_play_spectate(net_st->data);
return true;
}
if ( net_st->data->is_server
&& !settings->bools.netplay_start_as_spectator)
netplay_toggle_play_spectate(net_st->data);
RARCH_WARN("%s\n", msg_hash_to_str(MSG_NETPLAY_FAILED));
return true;
runloop_msg_queue_push(
msg_hash_to_str(MSG_NETPLAY_FAILED),
0, 180, false,
NULL, MESSAGE_QUEUE_ICON_DEFAULT, MESSAGE_QUEUE_CATEGORY_INFO);
return false;
}
/**

View File

@ -760,8 +760,8 @@ bool netplay_wait_and_init_serialization(netplay_t *netplay);
/**
* netplay_new:
* @direct_host : Netplay host discovered from scanning.
* @server : IP address of server.
* @mitm : IP address of the MITM/tunnel server.
* @port : Port of server.
* @stateless_mode : Shall we run in stateless mode?
* @check_frames : Frequency with which to check CRCs.
@ -775,7 +775,8 @@ bool netplay_wait_and_init_serialization(netplay_t *netplay);
*
* Returns: new netplay data.
*/
netplay_t *netplay_new(const char *server, const char *mitm, uint16_t port,
netplay_t *netplay_new(void *direct_host,
const char *server, uint16_t port,
bool stateless_mode, int check_frames,
const struct retro_callbacks *cb,
bool nat_traversal, const char *nick,

View File

@ -18,6 +18,6 @@
#ifndef __RARCH_NETPLAY_PROTOCOL_H
#define __RARCH_NETPLAY_PROTOCOL_H
#define NETPLAY_PROTOCOL_VERSION 5
#define NETPLAY_PROTOCOL_VERSION 6
#endif

View File

@ -5239,11 +5239,11 @@ bool command_event(enum event_command cmd, void *data)
/* init netplay manually */
case CMD_EVENT_NETPLAY_INIT:
{
bool success;
char *hostname = (char*)data;
char *netplay_server = NULL;
unsigned netplay_port = 0;
unsigned netplay_port = 0;
if (p_rarch->connect_host)
if (p_rarch->connect_host && !hostname)
{
struct string_list *addr_port = string_split(p_rarch->connect_host, "|");
@ -5281,7 +5281,22 @@ bool command_event(enum event_command cmd, void *data)
command_event(CMD_EVENT_NETPLAY_DEINIT, NULL);
success = init_netplay(netplay_server, netplay_port);
if (!init_netplay(
NULL,
hostname
? hostname
: netplay_server, netplay_port))
{
command_event(CMD_EVENT_NETPLAY_DEINIT, NULL);
if (p_rarch->connect_host)
{
free(p_rarch->connect_host);
p_rarch->connect_host = NULL;
}
return false;
}
if (p_rarch->connect_host)
{
@ -5289,12 +5304,6 @@ bool command_event(enum event_command cmd, void *data)
p_rarch->connect_host = NULL;
}
if (!success)
{
command_event(CMD_EVENT_NETPLAY_DEINIT, NULL);
return false;
}
/* Disable rewind & SRAM autosave if it was enabled
* TODO/FIXME: Add a setting for these tweaks */
#ifdef HAVE_REWIND
@ -5308,28 +5317,34 @@ bool command_event(enum event_command cmd, void *data)
/* Initialize netplay via lobby when content is loaded */
case CMD_EVENT_NETPLAY_INIT_DIRECT:
{
bool success;
/* Expected to be address|port */
struct string_list *hostname = string_split((char *)data, "|");
unsigned netplay_port = !string_is_empty(hostname->elems[1].data) ?
strtoul(hostname->elems[1].data, NULL, 10) :
settings->uints.netplay_port;
/* buf is expected to be address|port */
static struct string_list *hostname = NULL;
char *buf = (char *)data;
unsigned netplay_port = settings->uints.netplay_port;
hostname = string_split(buf, "|");
command_event(CMD_EVENT_NETPLAY_DEINIT, NULL);
RARCH_LOG("[Netplay]: Connecting to %s:%d (direct)\n",
hostname->elems[0].data, netplay_port);
hostname->elems[0].data, !string_is_empty(hostname->elems[1].data)
? atoi(hostname->elems[1].data)
: netplay_port);
success = init_netplay(hostname->elems[0].data, netplay_port);
string_list_free(hostname);
if (!success)
if (!init_netplay(
NULL,
hostname->elems[0].data,
!string_is_empty(hostname->elems[1].data)
? atoi(hostname->elems[1].data)
: netplay_port))
{
command_event(CMD_EVENT_NETPLAY_DEINIT, NULL);
string_list_free(hostname);
return false;
}
string_list_free(hostname);
/* Disable rewind if it was enabled
TODO/FIXME: Add a setting for these tweaks */
#ifdef HAVE_REWIND