Skip to content

Commit

Permalink
Allow the server to communicate through a local socket
Browse files Browse the repository at this point in the history
Local sockets correspond to UNIX domain sockets on UNIX and named pipes on
Windows.  No networking operations are attempted in this case (not event the
UDP announcements), and the server is strictly restricted to serving the
socket.
  • Loading branch information
lmoureaux committed Feb 12, 2022
1 parent 971ef1f commit f038fa7
Show file tree
Hide file tree
Showing 17 changed files with 197 additions and 89 deletions.
58 changes: 35 additions & 23 deletions client/clinet.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -16,6 +16,7 @@
#endif

// Qt
#include <QLocalSocket>
#include <QString>
#include <QTcpSocket>
#include <QTimer>
Expand Down Expand Up @@ -132,37 +133,48 @@ static int try_to_connect(const QUrl &url, char *errbuf, int errbufsize)
(void) fc_strlcpy(
errbuf, _("Canceled previous connection, trying new connection."),
errbufsize);
client.conn.sock->abort();
if (auto tcp = qobject_cast<QTcpSocket *>(client.conn.sock)) {
tcp->abort();
} else if (auto local =
qobject_cast<QLocalSocket *>(client.conn.sock)) {
local->abort();
}
connect_to = url_copy;
} else {
(void) fc_strlcpy(errbuf, _("Connection in progress."), errbufsize);
return -1;
}
}

// Reset
if (client.conn.sock) {
client.conn.sock->disconnect(client.conn.sock);
client.conn.sock->deleteLater();
}
client.conn.used = true; // Now there will be a connection :)
client.conn.sock->disconnect(client.conn.sock);

// Connect
if (!client.conn.sock) {
client.conn.sock = new QTcpSocket;
auto sock = new QTcpSocket;
client.conn.sock = sock;
QObject::connect(
sock,
QOverload<QAbstractSocket::SocketError>::of(&QAbstractSocket::error),
[] {
if (client.conn.sock != nullptr) {
log_debug("%s", qUtf8Printable(client.conn.sock->errorString()));
real_output_window_append(client.conn.sock->errorString(), NULL,
-1);
}
client.conn.used = false;
});
QObject::connect(sock, &QTcpSocket::connected,
[userName = url.userName()] {
make_connection(client.conn.sock, userName);
});
sock->connectToHost(url.host(), url.port());
}
QObject::connect(
client.conn.sock,
QOverload<QAbstractSocket::SocketError>::of(&QAbstractSocket::error),
[] {
if (client.conn.sock != nullptr) {
log_debug("%s", qUtf8Printable(client.conn.sock->errorString()));
real_output_window_append(client.conn.sock->errorString(), NULL,
-1);
}
client.conn.used = false;
});
QObject::connect(client.conn.sock, &QTcpSocket::connected,
[userName = url.userName()] {
make_connection(client.conn.sock, userName);
});

client.conn.sock->connectToHost(url.host(), url.port());
return 0;
}
} // namespace
Expand Down Expand Up @@ -192,7 +204,7 @@ int connect_to_server(const QUrl &url, char *errbuf, int errbufsize)
/**
Called after a connection is completed (e.g., in try_to_connect).
*/
void make_connection(QTcpSocket *sock, const QString &username)
void make_connection(QIODevice *sock, const QString &username)
{
struct packet_server_join_req req;

Expand Down Expand Up @@ -260,7 +272,7 @@ void disconnect_from_server()
*/
static int read_from_connection(struct connection *pc, bool block)
{
QTcpSocket *socket = pc->sock;
auto socket = pc->sock;
bool have_data_for_server =
(pc->used && pc->send_buffer && 0 < pc->send_buffer->ndata);

Expand All @@ -276,7 +288,7 @@ static int read_from_connection(struct connection *pc, bool block)

if (block) {
// Wait (and block the main event loop) until we get some data
socket->waitForReadyRead();
socket->waitForReadyRead(-1);
}

// Consume everything
Expand All @@ -301,7 +313,7 @@ static int read_from_connection(struct connection *pc, bool block)
This function is called when the client received a new input from the
server.
*/
void input_from_server(QTcpSocket *sock)
void input_from_server(QIODevice *sock)
{
int nb;

Expand Down
6 changes: 3 additions & 3 deletions client/clinet.h
Original file line number Diff line number Diff line change
Expand Up @@ -11,15 +11,15 @@
#pragma once

// Forward declarations
class QTcpSocket;
class QIODevice;
class QString;
class QUrl;

int connect_to_server(const QUrl &url, char *errbuf, int errbufsize);

void make_connection(QTcpSocket *sock, const QString &username);
void make_connection(QIODevice *sock, const QString &username);

void input_from_server(QTcpSocket *sock);
void input_from_server(QIODevice *sock);
void disconnect_from_server();

void try_to_autoconnect(const QUrl &url);
4 changes: 2 additions & 2 deletions client/gui-qt/fc_client.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -277,7 +277,7 @@ enum client_pages fc_client::current_page() { return page; }
/**
Add notifier for server input
*/
void fc_client::add_server_source(QTcpSocket *sock)
void fc_client::add_server_source(QIODevice *sock)
{
connect(sock, &QIODevice::readyRead, this, &fc_client::server_input);

Expand All @@ -300,7 +300,7 @@ void fc_client::closeEvent(QCloseEvent *event)
*/
void fc_client::server_input()
{
if (auto *socket = dynamic_cast<QTcpSocket *>(sender())) {
if (auto *socket = dynamic_cast<QIODevice *>(sender())) {
input_from_server(socket);
}
}
Expand Down
2 changes: 1 addition & 1 deletion client/gui-qt/fc_client.h
Original file line number Diff line number Diff line change
Expand Up @@ -112,7 +112,7 @@ class fc_client : public QMainWindow {
~fc_client() override;
QWidget *pages[static_cast<int>(PAGE_GAME) + 2];
void fc_main(QApplication *);
void add_server_source(QTcpSocket *socket);
void add_server_source(QIODevice *socket);

enum client_pages current_page();

Expand Down
2 changes: 1 addition & 1 deletion client/gui-qt/gui_main.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -177,7 +177,7 @@ void qtg_sound_bell()
This function is called after the client succesfully has connected
to the server.
*/
void qtg_add_net_input(QTcpSocket *sock) { king()->add_server_source(sock); }
void qtg_add_net_input(QIODevice *sock) { king()->add_server_source(sock); }

/**
Stop waiting for any server network data. See add_net_input().
Expand Down
2 changes: 1 addition & 1 deletion client/gui-qt/qtg_cxxside.h
Original file line number Diff line number Diff line change
Expand Up @@ -84,7 +84,7 @@ void qtg_canvas_put_text(QPixmap *pcanvas, int canvas_x, int canvas_y,

void qtg_set_rulesets(int num_rulesets, QStringList rulesets);
void qtg_options_extra_init();
void qtg_add_net_input(QTcpSocket *sock);
void qtg_add_net_input(QIODevice *sock);
void qtg_remove_net_input();
void qtg_real_conn_list_dialog_update(void *unused);
void qtg_close_connection_dialog();
Expand Down
2 changes: 1 addition & 1 deletion client/gui_interface.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -291,7 +291,7 @@ void options_extra_init(void) { funcs.options_extra_init(); }
/**
Call add_net_input callback
*/
void add_net_input(QTcpSocket *sock) { funcs.add_net_input(sock); }
void add_net_input(QIODevice *sock) { funcs.add_net_input(sock); }

/**
Call remove_net_input callback
Expand Down
2 changes: 1 addition & 1 deletion client/gui_interface.h
Original file line number Diff line number Diff line change
Expand Up @@ -92,7 +92,7 @@ struct gui_funcs {

void (*set_rulesets)(int num_rulesets, QStringList rulesets);
void (*options_extra_init)();
void (*add_net_input)(QTcpSocket *sock);
void (*add_net_input)(QIODevice *sock);
void (*remove_net_input)();
void (*real_conn_list_dialog_update)(void *unused);
void (*close_connection_dialog)();
Expand Down
4 changes: 2 additions & 2 deletions client/include/gui_main_g.h
Original file line number Diff line number Diff line change
Expand Up @@ -11,7 +11,7 @@
#pragma once

// Forward declarations
class QTcpSocket;
class QIODevice;

// utility
#include "support.h" // bool type
Expand All @@ -28,7 +28,7 @@ GUI_FUNC_PROTO(void, options_extra_init, void)

GUI_FUNC_PROTO(void, real_conn_list_dialog_update, void *)
GUI_FUNC_PROTO(void, sound_bell, void)
GUI_FUNC_PROTO(void, add_net_input, QTcpSocket *)
GUI_FUNC_PROTO(void, add_net_input, QIODevice *)
GUI_FUNC_PROTO(void, remove_net_input, void)

GUI_FUNC_PROTO(void, set_unit_icon, int idx, struct unit *punit)
Expand Down
21 changes: 15 additions & 6 deletions common/networking/connection.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -16,6 +16,7 @@
#endif

// Qt
#include <QLocalSocket>
#include <QTcpSocket>

// utility
Expand Down Expand Up @@ -54,7 +55,7 @@ static void default_conn_close_callback(struct connection *pconn)
{
fc_assert_msg(conn_close_callback != default_conn_close_callback,
"Closing a socket (%s) before calling "
"close_socket_set_callback().",
"connections_set_close_callback().",
conn_description(pconn));
}

Expand All @@ -69,13 +70,13 @@ void connections_set_close_callback(conn_close_fn_t func)
/**
Call the conn_close_callback.
*/
void connection_close(struct connection *pconn, const char *reason)
void connection_close(struct connection *pconn, const QString &reason)
{
fc_assert_ret(NULL != pconn);

if (NULL != reason && pconn->closing_reason.isEmpty()) {
// NB: we don't overwrite the original reason.
pconn->closing_reason = QString::fromUtf8(reason);
pconn->closing_reason = reason;
}

(*conn_close_callback)(pconn);
Expand Down Expand Up @@ -110,7 +111,7 @@ static bool buffer_ensure_free_extra_space(struct socket_packet_buffer *buf,
>0 : number of bytes read
=0 : non-blocking sockets only; no data read, would block
*/
int read_socket_data(QTcpSocket *sock, struct socket_packet_buffer *buffer)
int read_socket_data(QIODevice *sock, struct socket_packet_buffer *buffer)
{
int didget;

Expand Down Expand Up @@ -187,7 +188,11 @@ void flush_connection_send_buffer_all(struct connection *pc)
}
}
if (pc && pc->sock) {
pc->sock->flush();
if (auto socket = qobject_cast<QLocalSocket *>(pc->sock)) {
socket->flush();
} else if (auto socket = qobject_cast<QTcpSocket *>(pc->sock)) {
socket->flush();
}
}
}

Expand All @@ -204,7 +209,11 @@ static void flush_connection_send_buffer_packets(struct connection *pc)
}
}
if (pc && pc->sock) {
pc->sock->flush();
if (auto socket = qobject_cast<QLocalSocket *>(pc->sock)) {
socket->flush();
} else if (auto socket = qobject_cast<QTcpSocket *>(pc->sock)) {
socket->flush();
}
}
}

Expand Down
9 changes: 5 additions & 4 deletions common/networking/connection.h
Original file line number Diff line number Diff line change
Expand Up @@ -30,7 +30,8 @@
#include "fc_types.h"

// Forward declarations
class QTcpSocket;
class QIODevice;
class QString;

struct conn_pattern_list;
struct genhash;
Expand Down Expand Up @@ -126,7 +127,7 @@ struct packet_header {
***********************************************************/
struct connection {
int id; /* used for server/client communication */
QTcpSocket *sock = nullptr;
QIODevice *sock = nullptr;
bool used;
bool established; // have negotiated initial packets
struct packet_header packet_header;
Expand Down Expand Up @@ -261,9 +262,9 @@ struct connection {

typedef void (*conn_close_fn_t)(struct connection *pconn);
void connections_set_close_callback(conn_close_fn_t func);
void connection_close(struct connection *pconn, const char *reason);
void connection_close(struct connection *pconn, const QString &reason);

int read_socket_data(QTcpSocket *sock, struct socket_packet_buffer *buffer);
int read_socket_data(QIODevice *sock, struct socket_packet_buffer *buffer);
void flush_connection_send_buffer_all(struct connection *pc);
bool connection_send_data(struct connection *pconn,
const unsigned char *data, int len);
Expand Down
2 changes: 1 addition & 1 deletion server/connecthand.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -957,7 +957,7 @@ bool connection_delegate_restore(struct connection *pconn)
Close a connection. Use this in the server to take care of delegation
stuff (reset the username of the controlled connection).
*/
void connection_close_server(struct connection *pconn, const char *reason)
void connection_close_server(struct connection *pconn, const QString &reason)
{
// Restore possible delegations before the connection is closed.
connection_delegate_restore(pconn);
Expand Down
5 changes: 4 additions & 1 deletion server/connecthand.h
Original file line number Diff line number Diff line change
Expand Up @@ -15,6 +15,8 @@

#include "fc_types.h"

class QString;

struct connection;
struct conn_list;
struct packet_authentication_reply;
Expand Down Expand Up @@ -44,4 +46,5 @@ bool connection_delegate_take(struct connection *pconn,
struct player *pplayer);
bool connection_delegate_restore(struct connection *pconn);

void connection_close_server(struct connection *pconn, const char *reason);
void connection_close_server(struct connection *pconn,
const QString &reason);
Loading

0 comments on commit f038fa7

Please sign in to comment.