add names to IPS listen sockets
This commit is contained in:
+82
-24
@@ -62,8 +62,8 @@ string IPStackSimulator::str_for_tcp_connection(shared_ptr<const IPClient> c,
|
|||||||
}
|
}
|
||||||
|
|
||||||
IPStackSimulator::IPStackSimulator(
|
IPStackSimulator::IPStackSimulator(
|
||||||
std::shared_ptr<struct event_base> base,
|
shared_ptr<struct event_base> base,
|
||||||
std::shared_ptr<ServerState> state)
|
shared_ptr<ServerState> state)
|
||||||
: base(base),
|
: base(base),
|
||||||
state(state),
|
state(state),
|
||||||
pcap_text_log_file(state->ip_stack_debug ? fopen("IPStackSimulator-Log.txt", "wt") : nullptr) {
|
pcap_text_log_file(state->ip_stack_debug ? fopen("IPStackSimulator-Log.txt", "wt") : nullptr) {
|
||||||
@@ -77,20 +77,29 @@ IPStackSimulator::~IPStackSimulator() {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
void IPStackSimulator::listen(const std::string& socket_path) {
|
void IPStackSimulator::listen(const string& name, const string& socket_path) {
|
||||||
this->add_socket(::listen(socket_path, 0, SOMAXCONN));
|
int fd = ::listen(socket_path, 0, SOMAXCONN);
|
||||||
|
ip_stack_simulator_log.info("Listening on Unix socket %s on fd %d as %s", socket_path.c_str(), fd, name.c_str());
|
||||||
|
this->add_socket(name, fd);
|
||||||
}
|
}
|
||||||
|
|
||||||
void IPStackSimulator::listen(const std::string& addr, int port) {
|
void IPStackSimulator::listen(const string& name, const string& addr, int port) {
|
||||||
this->add_socket(::listen(addr, port, SOMAXCONN));
|
if (port == 0) {
|
||||||
|
this->listen(name, addr);
|
||||||
|
} else {
|
||||||
|
int fd = ::listen(addr, port, SOMAXCONN);
|
||||||
|
string netloc_str = render_netloc(addr, port);
|
||||||
|
ip_stack_simulator_log.info("Listening on TCP interface %s on fd %d as %s", netloc_str.c_str(), fd, name.c_str());
|
||||||
|
this->add_socket(name, fd);
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
void IPStackSimulator::listen(int port) {
|
void IPStackSimulator::listen(const string& name, int port) {
|
||||||
this->add_socket(::listen("", port, SOMAXCONN));
|
this->listen(name, "", port);
|
||||||
}
|
}
|
||||||
|
|
||||||
void IPStackSimulator::add_socket(int fd) {
|
void IPStackSimulator::add_socket(const string& name, int fd) {
|
||||||
this->listeners.emplace(
|
unique_listener l(
|
||||||
evconnlistener_new(
|
evconnlistener_new(
|
||||||
this->base.get(),
|
this->base.get(),
|
||||||
IPStackSimulator::dispatch_on_listen_accept,
|
IPStackSimulator::dispatch_on_listen_accept,
|
||||||
@@ -99,6 +108,7 @@ void IPStackSimulator::add_socket(int fd) {
|
|||||||
0,
|
0,
|
||||||
fd),
|
fd),
|
||||||
evconnlistener_free);
|
evconnlistener_free);
|
||||||
|
this->listening_sockets.emplace(piecewise_construct, forward_as_tuple(fd), forward_as_tuple(name, std::move(l)));
|
||||||
}
|
}
|
||||||
|
|
||||||
uint32_t IPStackSimulator::connect_address_for_remote_address(uint32_t remote_addr) {
|
uint32_t IPStackSimulator::connect_address_for_remote_address(uint32_t remote_addr) {
|
||||||
@@ -112,10 +122,28 @@ uint32_t IPStackSimulator::connect_address_for_remote_address(uint32_t remote_ad
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
IPStackSimulator::IPClient::IPClient(struct bufferevent* bev)
|
IPStackSimulator::IPClient::IPClient(shared_ptr<IPStackSimulator> sim, struct bufferevent* bev)
|
||||||
: bev(bev, bufferevent_free),
|
: sim(sim),
|
||||||
ipv4_addr(0) {
|
bev(bev, bufferevent_free),
|
||||||
this->mac_addr.clear(0);
|
mac_addr(0),
|
||||||
|
ipv4_addr(0),
|
||||||
|
idle_timeout_event(event_new(sim->base.get(), -1, EV_TIMEOUT, &IPStackSimulator::IPClient::dispatch_on_idle_timeout, this), event_free) {
|
||||||
|
struct timeval tv = usecs_to_timeval(60 * 1000 * 1000);
|
||||||
|
event_add(this->idle_timeout_event.get(), &tv);
|
||||||
|
}
|
||||||
|
|
||||||
|
void IPStackSimulator::IPClient::dispatch_on_idle_timeout(evutil_socket_t, short, void* ctx) {
|
||||||
|
reinterpret_cast<IPStackSimulator::IPClient*>(ctx)->on_idle_timeout();
|
||||||
|
}
|
||||||
|
|
||||||
|
void IPStackSimulator::IPClient::on_idle_timeout() {
|
||||||
|
auto sim = this->sim.lock();
|
||||||
|
if (sim) {
|
||||||
|
ip_stack_simulator_log.info("Idle timeout expired on virtual network %d", bufferevent_getfd(this->bev.get()));
|
||||||
|
sim->disconnect_client(this->bev.get());
|
||||||
|
} else {
|
||||||
|
ip_stack_simulator_log.info("Idle timeout expired on virtual network %d, but simulator is missing", bufferevent_getfd(this->bev.get()));
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
static void flush_and_free_bufferevent(struct bufferevent* bev) {
|
static void flush_and_free_bufferevent(struct bufferevent* bev) {
|
||||||
@@ -139,6 +167,11 @@ IPStackSimulator::IPClient::TCPConnection::TCPConnection()
|
|||||||
bytes_received(0),
|
bytes_received(0),
|
||||||
bytes_sent(0) {}
|
bytes_sent(0) {}
|
||||||
|
|
||||||
|
void IPStackSimulator::disconnect_client(struct bufferevent* bev) {
|
||||||
|
ip_stack_simulator_log.info("Virtual network %d disconnected", bufferevent_getfd(bev));
|
||||||
|
this->bev_to_client.erase(bev);
|
||||||
|
}
|
||||||
|
|
||||||
void IPStackSimulator::dispatch_on_listen_accept(
|
void IPStackSimulator::dispatch_on_listen_accept(
|
||||||
struct evconnlistener* listener, evutil_socket_t fd,
|
struct evconnlistener* listener, evutil_socket_t fd,
|
||||||
struct sockaddr* address, int socklen, void* ctx) {
|
struct sockaddr* address, int socklen, void* ctx) {
|
||||||
@@ -149,12 +182,21 @@ void IPStackSimulator::dispatch_on_listen_accept(
|
|||||||
void IPStackSimulator::on_listen_accept(struct evconnlistener* listener,
|
void IPStackSimulator::on_listen_accept(struct evconnlistener* listener,
|
||||||
evutil_socket_t fd, struct sockaddr*, int) {
|
evutil_socket_t fd, struct sockaddr*, int) {
|
||||||
int listen_fd = evconnlistener_get_fd(listener);
|
int listen_fd = evconnlistener_get_fd(listener);
|
||||||
ip_stack_simulator_log.info("Virtual network fd %d connected via fd %d", fd, listen_fd);
|
|
||||||
|
const ListeningSocket* listening_socket;
|
||||||
|
try {
|
||||||
|
listening_socket = &this->listening_sockets.at(listen_fd);
|
||||||
|
} catch (const out_of_range&) {
|
||||||
|
ip_stack_simulator_log.info("Virtual network %d connected via unknown listener %d; disconnecting", fd, listen_fd);
|
||||||
|
close(fd);
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
|
ip_stack_simulator_log.info("Virtual network %d connected via %s", fd, listening_socket->name.c_str());
|
||||||
|
|
||||||
struct bufferevent* bev = bufferevent_socket_new(this->base.get(), fd,
|
struct bufferevent* bev = bufferevent_socket_new(this->base.get(), fd,
|
||||||
BEV_OPT_CLOSE_ON_FREE | BEV_OPT_DEFER_CALLBACKS);
|
BEV_OPT_CLOSE_ON_FREE | BEV_OPT_DEFER_CALLBACKS);
|
||||||
shared_ptr<IPClient> c(new IPClient(bev));
|
shared_ptr<IPClient> c(new IPClient(this->shared_from_this(), bev));
|
||||||
c->sim = this;
|
|
||||||
this->bev_to_client.emplace(make_pair(bev, c));
|
this->bev_to_client.emplace(make_pair(bev, c));
|
||||||
|
|
||||||
bufferevent_setcb(bev, &IPStackSimulator::dispatch_on_client_input, nullptr,
|
bufferevent_setcb(bev, &IPStackSimulator::dispatch_on_client_input, nullptr,
|
||||||
@@ -218,16 +260,14 @@ void IPStackSimulator::dispatch_on_client_error(
|
|||||||
struct bufferevent* bev, short events, void* ctx) {
|
struct bufferevent* bev, short events, void* ctx) {
|
||||||
reinterpret_cast<IPStackSimulator*>(ctx)->on_client_error(bev, events);
|
reinterpret_cast<IPStackSimulator*>(ctx)->on_client_error(bev, events);
|
||||||
}
|
}
|
||||||
void IPStackSimulator::on_client_error(struct bufferevent* bev,
|
void IPStackSimulator::on_client_error(struct bufferevent* bev, short events) {
|
||||||
short events) {
|
|
||||||
if (events & BEV_EVENT_ERROR) {
|
if (events & BEV_EVENT_ERROR) {
|
||||||
int err = EVUTIL_SOCKET_ERROR();
|
int err = EVUTIL_SOCKET_ERROR();
|
||||||
ip_stack_simulator_log.warning("Virtual network caused error %d (%s)", err,
|
ip_stack_simulator_log.warning("Virtual network caused error %d (%s)", err,
|
||||||
evutil_socket_error_to_string(err));
|
evutil_socket_error_to_string(err));
|
||||||
}
|
}
|
||||||
if (events & (BEV_EVENT_EOF | BEV_EVENT_ERROR)) {
|
if (events & (BEV_EVENT_EOF | BEV_EVENT_ERROR)) {
|
||||||
ip_stack_simulator_log.info("Virtual network fd %d disconnected", bufferevent_getfd(bev));
|
this->disconnect_client(bev);
|
||||||
this->bev_to_client.erase(bev);
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -971,7 +1011,12 @@ void IPStackSimulator::dispatch_on_resend_push(evutil_socket_t, short, void* ctx
|
|||||||
if (!c.get()) {
|
if (!c.get()) {
|
||||||
ip_stack_simulator_log.warning("Resend push event triggered for deleted client; ignoring");
|
ip_stack_simulator_log.warning("Resend push event triggered for deleted client; ignoring");
|
||||||
} else {
|
} else {
|
||||||
c->sim->on_resend_push(c, *conn);
|
auto sim = c->sim.lock();
|
||||||
|
if (!sim) {
|
||||||
|
ip_stack_simulator_log.warning("Resend push event triggered for client on deleted simulator; ignoring");
|
||||||
|
} else {
|
||||||
|
sim->on_resend_push(c, *conn);
|
||||||
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -985,7 +1030,12 @@ void IPStackSimulator::dispatch_on_server_input(struct bufferevent*, void* ctx)
|
|||||||
if (!c.get()) {
|
if (!c.get()) {
|
||||||
ip_stack_simulator_log.warning("Server input event triggered for deleted client; ignoring");
|
ip_stack_simulator_log.warning("Server input event triggered for deleted client; ignoring");
|
||||||
} else {
|
} else {
|
||||||
c->sim->on_server_input(c, *conn);
|
auto sim = c->sim.lock();
|
||||||
|
if (!sim) {
|
||||||
|
ip_stack_simulator_log.warning("Server input event triggered for client on deleted simulator; ignoring");
|
||||||
|
} else {
|
||||||
|
sim->on_server_input(c, *conn);
|
||||||
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -994,6 +1044,9 @@ void IPStackSimulator::on_server_input(shared_ptr<IPClient> c, IPClient::TCPConn
|
|||||||
ip_stack_simulator_log.debug("Server input event: 0x%zX bytes to read",
|
ip_stack_simulator_log.debug("Server input event: 0x%zX bytes to read",
|
||||||
evbuffer_get_length(buf));
|
evbuffer_get_length(buf));
|
||||||
|
|
||||||
|
struct timeval tv = usecs_to_timeval(60 * 1000 * 1000);
|
||||||
|
event_add(c->idle_timeout_event.get(), &tv);
|
||||||
|
|
||||||
evbuffer_add_buffer(conn.pending_data.get(), buf);
|
evbuffer_add_buffer(conn.pending_data.get(), buf);
|
||||||
this->send_pending_push_frame(c, conn);
|
this->send_pending_push_frame(c, conn);
|
||||||
}
|
}
|
||||||
@@ -1005,7 +1058,12 @@ void IPStackSimulator::dispatch_on_server_error(
|
|||||||
if (!c.get()) {
|
if (!c.get()) {
|
||||||
ip_stack_simulator_log.warning("Server error event triggered for deleted client; ignoring");
|
ip_stack_simulator_log.warning("Server error event triggered for deleted client; ignoring");
|
||||||
} else {
|
} else {
|
||||||
c->sim->on_server_error(c, *conn, events);
|
auto sim = c->sim.lock();
|
||||||
|
if (!sim) {
|
||||||
|
ip_stack_simulator_log.warning("Server error event triggered for client on deleted simulator; ignoring");
|
||||||
|
} else {
|
||||||
|
sim->on_server_error(c, *conn, events);
|
||||||
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|||||||
+30
-20
@@ -12,17 +12,17 @@
|
|||||||
#include "ServerState.hh"
|
#include "ServerState.hh"
|
||||||
#include "Text.hh"
|
#include "Text.hh"
|
||||||
|
|
||||||
class IPStackSimulator {
|
class IPStackSimulator : public std::enable_shared_from_this<IPStackSimulator> {
|
||||||
public:
|
public:
|
||||||
IPStackSimulator(
|
IPStackSimulator(
|
||||||
std::shared_ptr<struct event_base> base,
|
std::shared_ptr<struct event_base> base,
|
||||||
std::shared_ptr<ServerState> state);
|
std::shared_ptr<ServerState> state);
|
||||||
~IPStackSimulator();
|
~IPStackSimulator();
|
||||||
|
|
||||||
void listen(const std::string& socket_path);
|
void listen(const std::string& name, const std::string& socket_path);
|
||||||
void listen(const std::string& addr, int port);
|
void listen(const std::string& name, const std::string& addr, int port);
|
||||||
void listen(int port);
|
void listen(const std::string& name, int port);
|
||||||
void add_socket(int fd);
|
void add_socket(const std::string& name, int fd);
|
||||||
|
|
||||||
static uint32_t connect_address_for_remote_address(uint32_t remote_addr);
|
static uint32_t connect_address_for_remote_address(uint32_t remote_addr);
|
||||||
|
|
||||||
@@ -36,7 +36,7 @@ private:
|
|||||||
using unique_event = std::unique_ptr<struct event, void (*)(struct event*)>;
|
using unique_event = std::unique_ptr<struct event, void (*)(struct event*)>;
|
||||||
|
|
||||||
struct IPClient {
|
struct IPClient {
|
||||||
IPStackSimulator* sim;
|
std::weak_ptr<IPStackSimulator> sim;
|
||||||
|
|
||||||
unique_bufferevent bev;
|
unique_bufferevent bev;
|
||||||
parray<uint8_t, 6> mac_addr;
|
parray<uint8_t, 6> mac_addr;
|
||||||
@@ -73,10 +73,24 @@ private:
|
|||||||
};
|
};
|
||||||
std::unordered_map<uint64_t, TCPConnection> tcp_connections;
|
std::unordered_map<uint64_t, TCPConnection> tcp_connections;
|
||||||
|
|
||||||
IPClient(struct bufferevent* bev);
|
unique_event idle_timeout_event;
|
||||||
|
|
||||||
|
IPClient(std::shared_ptr<IPStackSimulator> sim, struct bufferevent* bev);
|
||||||
|
|
||||||
|
static void dispatch_on_idle_timeout(evutil_socket_t fd, short events, void* ctx);
|
||||||
|
void on_idle_timeout();
|
||||||
};
|
};
|
||||||
|
|
||||||
std::unordered_set<unique_listener> listeners;
|
struct ListeningSocket {
|
||||||
|
std::string name;
|
||||||
|
unique_listener listener;
|
||||||
|
|
||||||
|
ListeningSocket(const std::string& name, unique_listener&& l)
|
||||||
|
: name(name),
|
||||||
|
listener(std::move(l)) {}
|
||||||
|
};
|
||||||
|
|
||||||
|
std::unordered_map<int, ListeningSocket> listening_sockets;
|
||||||
std::unordered_map<struct bufferevent*, std::shared_ptr<IPClient>> bev_to_client;
|
std::unordered_map<struct bufferevent*, std::shared_ptr<IPClient>> bev_to_client;
|
||||||
|
|
||||||
parray<uint8_t, 6> host_mac_address_bytes;
|
parray<uint8_t, 6> host_mac_address_bytes;
|
||||||
@@ -84,10 +98,10 @@ private:
|
|||||||
|
|
||||||
FILE* pcap_text_log_file;
|
FILE* pcap_text_log_file;
|
||||||
|
|
||||||
static uint64_t tcp_conn_key_for_connection(
|
void disconnect_client(struct bufferevent* bev);
|
||||||
const IPClient::TCPConnection& conn);
|
|
||||||
static uint64_t tcp_conn_key_for_client_frame(
|
static uint64_t tcp_conn_key_for_connection(const IPClient::TCPConnection& conn);
|
||||||
const IPv4Header& ipv4, const TCPHeader& tcp);
|
static uint64_t tcp_conn_key_for_client_frame(const IPv4Header& ipv4, const TCPHeader& tcp);
|
||||||
static uint64_t tcp_conn_key_for_client_frame(const FrameInfo& fi);
|
static uint64_t tcp_conn_key_for_client_frame(const FrameInfo& fi);
|
||||||
|
|
||||||
static std::string str_for_ipv4_netloc(uint32_t addr, uint16_t port);
|
static std::string str_for_ipv4_netloc(uint32_t addr, uint16_t port);
|
||||||
@@ -103,8 +117,7 @@ private:
|
|||||||
|
|
||||||
static void dispatch_on_client_input(struct bufferevent* bev, void* ctx);
|
static void dispatch_on_client_input(struct bufferevent* bev, void* ctx);
|
||||||
void on_client_input(struct bufferevent* bev);
|
void on_client_input(struct bufferevent* bev);
|
||||||
static void dispatch_on_client_error(struct bufferevent* bev, short events,
|
static void dispatch_on_client_error(struct bufferevent* bev, short events, void* ctx);
|
||||||
void* ctx);
|
|
||||||
void on_client_error(struct bufferevent* bev, short events);
|
void on_client_error(struct bufferevent* bev, short events);
|
||||||
|
|
||||||
void on_client_frame(std::shared_ptr<IPClient> c, const std::string& frame);
|
void on_client_frame(std::shared_ptr<IPClient> c, const std::string& frame);
|
||||||
@@ -112,18 +125,15 @@ private:
|
|||||||
void on_client_udp_frame(std::shared_ptr<IPClient> c, const FrameInfo& fi);
|
void on_client_udp_frame(std::shared_ptr<IPClient> c, const FrameInfo& fi);
|
||||||
void on_client_tcp_frame(std::shared_ptr<IPClient> c, const FrameInfo& fi);
|
void on_client_tcp_frame(std::shared_ptr<IPClient> c, const FrameInfo& fi);
|
||||||
|
|
||||||
static void dispatch_on_resend_push(evutil_socket_t fd, short events,
|
static void dispatch_on_resend_push(evutil_socket_t fd, short events, void* ctx);
|
||||||
void* ctx);
|
|
||||||
void on_resend_push(std::shared_ptr<IPClient> c, IPClient::TCPConnection& conn);
|
void on_resend_push(std::shared_ptr<IPClient> c, IPClient::TCPConnection& conn);
|
||||||
|
|
||||||
static void dispatch_on_server_input(struct bufferevent* bev, void* ctx);
|
static void dispatch_on_server_input(struct bufferevent* bev, void* ctx);
|
||||||
void on_server_input(std::shared_ptr<IPClient> c, IPClient::TCPConnection& conn);
|
void on_server_input(std::shared_ptr<IPClient> c, IPClient::TCPConnection& conn);
|
||||||
static void dispatch_on_server_error(struct bufferevent* bev, short events,
|
static void dispatch_on_server_error(struct bufferevent* bev, short events, void* ctx);
|
||||||
void* ctx);
|
|
||||||
void on_server_error(std::shared_ptr<IPClient> c, IPClient::TCPConnection& conn, short events);
|
void on_server_error(std::shared_ptr<IPClient> c, IPClient::TCPConnection& conn, short events);
|
||||||
|
|
||||||
void send_pending_push_frame(
|
void send_pending_push_frame(std::shared_ptr<IPClient> c, IPClient::TCPConnection& conn);
|
||||||
std::shared_ptr<IPClient> c, IPClient::TCPConnection& conn);
|
|
||||||
void send_tcp_frame(
|
void send_tcp_frame(
|
||||||
std::shared_ptr<IPClient> c,
|
std::shared_ptr<IPClient> c,
|
||||||
IPClient::TCPConnection& conn,
|
IPClient::TCPConnection& conn,
|
||||||
|
|||||||
+2
-3
@@ -2042,16 +2042,15 @@ int main(int argc, char** argv) {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
#ifndef PHOSG_WINDOWS
|
|
||||||
if (!state->ip_stack_addresses.empty()) {
|
if (!state->ip_stack_addresses.empty()) {
|
||||||
config_log.info("Starting IP stack simulator");
|
config_log.info("Starting IP stack simulator");
|
||||||
ip_stack_simulator.reset(new IPStackSimulator(base, state));
|
ip_stack_simulator.reset(new IPStackSimulator(base, state));
|
||||||
for (const auto& it : state->ip_stack_addresses) {
|
for (const auto& it : state->ip_stack_addresses) {
|
||||||
auto netloc = parse_netloc(it);
|
auto netloc = parse_netloc(it);
|
||||||
ip_stack_simulator->listen(netloc.first, netloc.second);
|
string spec = (netloc.second == 0) ? ("T-IPS-" + netloc.first) : string_printf("T-IPS-%hu", netloc.second);
|
||||||
|
ip_stack_simulator->listen(spec, netloc.first, netloc.second);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
#endif
|
|
||||||
|
|
||||||
} else {
|
} else {
|
||||||
throw logic_error("invalid behavior");
|
throw logic_error("invalid behavior");
|
||||||
|
|||||||
+9
-5
@@ -233,11 +233,15 @@ void Server::listen(
|
|||||||
int port,
|
int port,
|
||||||
GameVersion version,
|
GameVersion version,
|
||||||
ServerBehavior behavior) {
|
ServerBehavior behavior) {
|
||||||
int fd = ::listen(addr, port, SOMAXCONN);
|
if (port == 0) {
|
||||||
string netloc_str = render_netloc(addr, port);
|
this->listen(addr_str, addr, version, behavior);
|
||||||
server_log.info("Listening on TCP interface %s on fd %d as %s",
|
} else {
|
||||||
netloc_str.c_str(), fd, addr_str.c_str());
|
int fd = ::listen(addr, port, SOMAXCONN);
|
||||||
this->add_socket(addr_str, fd, version, behavior);
|
string netloc_str = render_netloc(addr, port);
|
||||||
|
server_log.info("Listening on TCP interface %s on fd %d as %s",
|
||||||
|
netloc_str.c_str(), fd, addr_str.c_str());
|
||||||
|
this->add_socket(addr_str, fd, version, behavior);
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
void Server::listen(const std::string& addr_str, int port, GameVersion version, ServerBehavior behavior) {
|
void Server::listen(const std::string& addr_str, int port, GameVersion version, ServerBehavior behavior) {
|
||||||
|
|||||||
@@ -127,11 +127,13 @@
|
|||||||
// clients to connect, set this to ["/tmp/dolphin-tap"] and configure Dolphin
|
// clients to connect, set this to ["/tmp/dolphin-tap"] and configure Dolphin
|
||||||
// to use the tapserver type of broadband adapter. You do not need to install
|
// to use the tapserver type of broadband adapter. You do not need to install
|
||||||
// or run tapserver. See README.md for details on how to get PSO to connect
|
// or run tapserver. See README.md for details on how to get PSO to connect
|
||||||
// via this interface.
|
// via this interface. You can also add numbers or "address:port" strings to
|
||||||
// If you're doing unusual things, you can also add numbers or "address:port"
|
// this list to listen for tapserver connections on a TCP port.
|
||||||
// strings to this list to listen for tapserver connections on a TCP port.
|
// On Windows, Unix sockets are not available, so you can only use TCP sockets
|
||||||
// This feature requires Unix sockets, so this option does nothing when
|
// here. You can get Dolphin to connect locally by adding a port to this list
|
||||||
// newserv runs under Windows.
|
// and configuring Dolphin to connect to the same port. For example, you could
|
||||||
|
// set this to ["127.0.0.1:5059"], and configure Dolphin's tapserver BBA to
|
||||||
|
// connect to 127.0.0.1:5059.
|
||||||
"IPStackListen": [],
|
"IPStackListen": [],
|
||||||
|
|
||||||
// Other servers to support proxying to. If this is empty for any game
|
// Other servers to support proxying to. If this is empty for any game
|
||||||
|
|||||||
Reference in New Issue
Block a user