Skip to content

Commit

Permalink
Merge pull request #5126 from fishface60/ephemeral-ports
Browse files Browse the repository at this point in the history
Support Ephemeral ports
  • Loading branch information
cwisniew authored Jan 20, 2025
2 parents 07769ec + a7f5f06 commit b02a6a5
Show file tree
Hide file tree
Showing 42 changed files with 91 additions and 73 deletions.
Original file line number Diff line number Diff line change
Expand Up @@ -20,7 +20,7 @@
import org.apache.logging.log4j.LogManager;
import org.apache.logging.log4j.Logger;

public abstract class AbstractServer implements Server {
public abstract class AbstractServer {

private static final Logger log = LogManager.getLogger(AbstractServer.class);

Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -15,7 +15,7 @@
package net.rptools.clientserver.simple.server;

/** A server implementation that never receives connections */
public class NilServer extends AbstractServer {
public final class NilServer extends AbstractServer implements Server {
@Override
public void start() {}

Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -16,7 +16,7 @@

import java.io.IOException;

public interface Server extends AutoCloseable {
public sealed interface Server extends AutoCloseable permits NilServer, SocketServer, WebRTCServer {
void start() throws IOException;

void close();
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -25,7 +25,7 @@
/**
* @author drice
*/
public class SocketServer extends AbstractServer {
public final class SocketServer extends AbstractServer implements Server {

private static final Logger log = LogManager.getLogger(SocketServer.class);
private final int port;
Expand All @@ -39,6 +39,9 @@ public SocketServer(int port) {
@Override
public void start() throws IOException {
var serverSocket = new ServerSocket(port);
if (serverSocket.getLocalPort() == -1) {
throw new AssertionError("Socket not bound yet");
}
// If the above throws, it will be as though we never started.

socket = serverSocket;
Expand Down Expand Up @@ -70,6 +73,16 @@ public String getError() {
return null;
}

/** Get the port of the socket the server is running on or -1. */
public int getPort() {
// NOTE: We do not use this.port because the socket's bound port can be different
if (socket == null || socket.isClosed()) {
return -1;
}

return socket.getLocalPort();
}

////
// Threads
private static class ListeningThread extends Thread {
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -29,7 +29,7 @@
import org.java_websocket.client.WebSocketClient;
import org.java_websocket.handshake.ServerHandshake;

public class WebRTCServer extends AbstractServer {
public final class WebRTCServer extends AbstractServer implements Server {
private static final Logger log = LogManager.getLogger(WebRTCServer.class);

public interface Listener {
Expand Down
2 changes: 1 addition & 1 deletion src/main/java/net/rptools/maptool/client/AppActions.java
Original file line number Diff line number Diff line change
Expand Up @@ -2210,7 +2210,7 @@ protected void executeAction() {
StartServerDialogPreferences serverProps =
new StartServerDialogPreferences(); // data retrieved from
// Preferences.userRoot()
if (serverProps.getPort() == 0 || serverProps.getPort() > 65535) {
if (serverProps.getPort() > 65535) {
MapTool.showError("ServerDialog.error.port.outOfRange");
return;
}
Expand Down
2 changes: 1 addition & 1 deletion src/main/java/net/rptools/maptool/client/MapTool.java
Original file line number Diff line number Diff line change
Expand Up @@ -188,7 +188,7 @@ public class MapTool {
var campaign = CampaignFactory.createBasicCampaign();
var policy = new ServerPolicy();

server = new MapToolServer("", new Campaign(campaign), null, false, policy, playerDB);
server = new MapToolServer(null, new Campaign(campaign), null, false, policy, playerDB);
client = new MapToolClient(server, campaign, playerDB.getPlayer(), connections.clientSide());
} catch (NoSuchAlgorithmException | InvalidKeySpecException e) {
throw new RuntimeException("Unable to create default personal server", e);
Expand Down
67 changes: 36 additions & 31 deletions src/main/java/net/rptools/maptool/server/MapToolServer.java
Original file line number Diff line number Diff line change
Expand Up @@ -29,9 +29,12 @@
import net.rptools.clientserver.simple.DisconnectHandler;
import net.rptools.clientserver.simple.MessageHandler;
import net.rptools.clientserver.simple.connection.Connection;
import net.rptools.clientserver.simple.server.NilServer;
import net.rptools.clientserver.simple.server.Router;
import net.rptools.clientserver.simple.server.Server;
import net.rptools.clientserver.simple.server.ServerObserver;
import net.rptools.clientserver.simple.server.SocketServer;
import net.rptools.clientserver.simple.server.WebRTCServer;
import net.rptools.maptool.client.AppConstants;
import net.rptools.maptool.client.MapTool;
import net.rptools.maptool.client.MapToolRegistry;
Expand Down Expand Up @@ -70,7 +73,7 @@ public enum State {
}

@Nonnull private final String serviceIdentifier;
private final Server server;
@Nonnull private final Server server;
private final MessageHandler messageHandler;
private final Router router;
private final ServerConfig config;
Expand All @@ -84,7 +87,7 @@ public enum State {
private final AssetProducerThread assetProducerThread;

private final boolean useUPnP;
private final ServiceAnnouncer announcer;
@Nullable private ServiceAnnouncer announcer;
private Campaign campaign;
private ServerPolicy policy;
private HeartbeatThread heartbeatThread;
Expand All @@ -94,7 +97,7 @@ public enum State {
private State currentState;

public MapToolServer(
String id,
@Nullable String id,
Campaign campaign,
@Nullable ServerConfig config,
boolean useUPnP,
Expand All @@ -106,11 +109,6 @@ public MapToolServer(
this.policy = new ServerPolicy(policy);
this.playerDatabase = playerDb;

this.announcer =
config == null
? null
: new ServiceAnnouncer(id, config.getPort(), AppConstants.SERVICE_GROUP);

server = ConnectionFactory.getInstance().createServer(this.config);
messageHandler = new ServerMessageHandler(this);
this.router = new Router();
Expand Down Expand Up @@ -205,7 +203,11 @@ public String getName() {
}

public int getPort() {
return config == null ? -1 : config.getPort();
return switch (server) {
case NilServer s -> -1;
case SocketServer s -> s.getPort();
case WebRTCServer s -> -1;
};
}

/**
Expand Down Expand Up @@ -354,23 +356,9 @@ public void stop() {
return;
}

server.close();
for (var connection : router.removeAll()) {
connection.removeDisconnectHandler(onConnectionDisconnected);
connection.close();
}

assetManagerMap.clear();

if (heartbeatThread != null) {
heartbeatThread.shutdown();
}
if (assetProducerThread != null) {
assetProducerThread.shutdown();
}

if (announcer != null) {
announcer.stop();
announcer = null;
}

// Unregister ourselves
Expand All @@ -383,10 +371,25 @@ public void stop() {
}

// Close UPnP port mapping if used
if (useUPnP && config != null) {
int port = config.getPort();
int port;
if (useUPnP && (port = getPort()) != -1) {
UPnPUtil.closePort(port);
}

server.close();
for (var connection : router.removeAll()) {
connection.removeDisconnectHandler(onConnectionDisconnected);
connection.close();
}

assetManagerMap.clear();

if (heartbeatThread != null) {
heartbeatThread.shutdown();
}
if (assetProducerThread != null) {
assetProducerThread.shutdown();
}
}

public void start() throws IOException {
Expand All @@ -406,12 +409,13 @@ public void start() throws IOException {
}

// Use UPnP to open port in router
if (useUPnP && config != null) {
int port = getPort();
if (useUPnP && port != -1) {
MapTool.getFrame()
.showFilledGlassPane(
new StaticMessageDialog(I18N.getText("msg.info.server.upnp.discovering")));
try {
UPnPUtil.openPort(config.getPort());
UPnPUtil.openPort(port);
} finally {
MapTool.getFrame().hideGlassPane();
}
Expand All @@ -422,11 +426,11 @@ public void start() throws IOException {
try {
MapToolRegistry.RegisterResponse result =
MapToolRegistry.getInstance()
.registerInstance(config.getServerName(), config.getPort(), config.getUseWebRTC());
.registerInstance(config.getServerName(), port, config.getUseWebRTC());
if (result == MapToolRegistry.RegisterResponse.NAME_EXISTS) {
MapTool.showError("msg.error.alreadyRegistered");
} else {
heartbeatThread = new HeartbeatThread(config.getPort());
heartbeatThread = new HeartbeatThread(port);
heartbeatThread.start();
}
// TODO: I don't like this
Expand All @@ -435,7 +439,8 @@ public void start() throws IOException {
}
}

if (announcer != null) {
if (serviceIdentifier != null && port != -1) {
announcer = new ServiceAnnouncer(serviceIdentifier, port, AppConstants.SERVICE_GROUP);
announcer.start();
}

Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -742,7 +742,7 @@ Preferences.label.loadMRU = Load last campaign on start
Preferences.label.loadMRU.tooltip = Start MapTool with the last campaign you were using

ServerDialog.error.port = You must enter a numeric port.
ServerDialog.error.port.outOfRange = Port range must be between 1 and 65535.
ServerDialog.error.port.outOfRange = Port range must be between 0 and 65535.
ServerDialog.error.portNumberException = Port from RPTools registry is not numeric?! Web server bug?
ServerDialog.error.server = You must enter a server name or IP address.
ServerDialog.error.serverNotFound = Server "{0}" not found.
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -714,7 +714,7 @@ Preferences.combo.themes.filter.dark = Dark
Preferences.combo.themes.filter.light = Light

ServerDialog.error.port = You must enter a numeric port.
ServerDialog.error.port.outOfRange = Port range must be between 1 and 65535.
ServerDialog.error.port.outOfRange = Port range must be between 0 and 65535.
ServerDialog.error.portNumberException = Port from RPTools registry is not numeric?\! Web server bug?
ServerDialog.error.server = You must enter a server name or IP address.
ServerDialog.error.serverNotFound = Server "{0}" not found.
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -742,7 +742,7 @@ Preferences.label.loadMRU = Load last campaign on start
Preferences.label.loadMRU.tooltip = Start MapTool with the last campaign you were using

ServerDialog.error.port = You must enter a numeric port.
ServerDialog.error.port.outOfRange = Port range must be between 1 and 65535.
ServerDialog.error.port.outOfRange = Port range must be between 0 and 65535.
ServerDialog.error.portNumberException = Port from RPTools registry is not numeric?\! Web server bug?
ServerDialog.error.server = You must enter a server name or IP address.
ServerDialog.error.serverNotFound = Server "{0}" not found.
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -714,7 +714,7 @@ Preferences.combo.themes.filter.dark = Dark
Preferences.combo.themes.filter.light = Light

ServerDialog.error.port = Du skal angive en numerisk port.
ServerDialog.error.port.outOfRange = Port range must be between 1 and 65535.
ServerDialog.error.port.outOfRange = Port range must be between 0 and 65535.
ServerDialog.error.portNumberException = Port from RPTools registry is not numeric?\! Web server bug?
ServerDialog.error.server = You must enter a server name or IP address.
ServerDialog.error.serverNotFound = Serveren "{0}" blev ikke fundet.
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -742,7 +742,7 @@ Preferences.label.loadMRU = Load last campaign on start
Preferences.label.loadMRU.tooltip = Start MapTool with the last campaign you were using

ServerDialog.error.port = Du skal angive en numerisk port.
ServerDialog.error.port.outOfRange = Port range must be between 1 and 65535.
ServerDialog.error.port.outOfRange = Port range must be between 0 and 65535.
ServerDialog.error.portNumberException = Port from RPTools registry is not numeric?\! Web server bug?
ServerDialog.error.server = You must enter a server name or IP address.
ServerDialog.error.serverNotFound = Serveren "{0}" blev ikke fundet.
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -714,7 +714,7 @@ Preferences.combo.themes.filter.dark = Dunkel
Preferences.combo.themes.filter.light = Hell

ServerDialog.error.port = Du musst eine Zahl als Port angeben.
ServerDialog.error.port.outOfRange = Der Port-Bereich muss zwischen 1 und 65535 liegen.
ServerDialog.error.port.outOfRange = Der Port-Bereich muss zwischen 0 und 65535 liegen.
ServerDialog.error.portNumberException = Port aus der RPTools Registrierung ist keine Zahl?\! Webserver Fehler?
ServerDialog.error.server = Servernamen oder IP-Adresse eingeben.
ServerDialog.error.serverNotFound = Server "{0}" nicht gefunden.
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -742,7 +742,7 @@ Preferences.label.loadMRU = Letzte Kampagne beim Start l
Preferences.label.loadMRU.tooltip = Starte MapTool mit letzter verwendeter Kampagne

ServerDialog.error.port = Du musst eine Zahl als Port angeben.
ServerDialog.error.port.outOfRange = Der Port-Bereich muss zwischen 1 und 65535 liegen.
ServerDialog.error.port.outOfRange = Der Port-Bereich muss zwischen 0 und 65535 liegen.
ServerDialog.error.portNumberException = Port aus der RPTools Registrierung ist keine Zahl?\! Webserver Fehler?
ServerDialog.error.server = Servernamen oder IP-Adresse eingeben.
ServerDialog.error.serverNotFound = Server "{0}" nicht gefunden.
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -718,7 +718,7 @@ Preferences.combo.themes.filter.dark = Dark
Preferences.combo.themes.filter.light = Light

ServerDialog.error.port = You must enter a numeric port.
ServerDialog.error.port.outOfRange = Port range must be between 1 and 65535.
ServerDialog.error.port.outOfRange = Port range must be between 0 and 65535.
ServerDialog.error.portNumberException = Port from RPTools registry is not numeric?\! Web server bug?
ServerDialog.error.server = You must enter a server name or IP address.
ServerDialog.error.serverNotFound = Server "{0}" not found.
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -746,7 +746,7 @@ Preferences.label.loadMRU = Load last campaign on start
Preferences.label.loadMRU.tooltip = Start MapTool with the last campaign you were using

ServerDialog.error.port = You must enter a numeric port.
ServerDialog.error.port.outOfRange = Port range must be between 1 and 65535.
ServerDialog.error.port.outOfRange = Port range must be between 0 and 65535.
ServerDialog.error.portNumberException = Port from RPTools registry is not numeric?\! Web server bug?
ServerDialog.error.server = You must enter a server name or IP address.
ServerDialog.error.serverNotFound = Server "{0}" not found.
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -745,7 +745,7 @@ Preferences.label.loadMRU = Load last campaign on start
Preferences.label.loadMRU.tooltip = Start MapTool with the last campaign you were using

ServerDialog.error.port = You must enter a numeric port.
ServerDialog.error.port.outOfRange = Port range must be between 1 and 65535.
ServerDialog.error.port.outOfRange = Port range must be between 0 and 65535.
ServerDialog.error.portNumberException = Port from RPTools registry is not numeric?\! Web server bug?
ServerDialog.error.server = You must enter a server name or IP address.
ServerDialog.error.serverNotFound = Server "{0}" not found.
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -714,7 +714,7 @@ Preferences.combo.themes.filter.dark = Dark
Preferences.combo.themes.filter.light = Light

ServerDialog.error.port = Debes ingresar un puerto numérico.
ServerDialog.error.port.outOfRange = Port range must be between 1 and 65535.
ServerDialog.error.port.outOfRange = Port range must be between 0 and 65535.
ServerDialog.error.portNumberException = El puerto desde el registro de RPTools no es numérico?\! Error de servidor web?
ServerDialog.error.server = You must enter a server name or IP address.
ServerDialog.error.serverNotFound = Servidor "{0}" no se encuentra.
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -742,7 +742,7 @@ Preferences.label.loadMRU = Load last campaign on start
Preferences.label.loadMRU.tooltip = Start MapTool with the last campaign you were using

ServerDialog.error.port = Debes ingresar un puerto numérico.
ServerDialog.error.port.outOfRange = Port range must be between 1 and 65535.
ServerDialog.error.port.outOfRange = Port range must be between 0 and 65535.
ServerDialog.error.portNumberException = El puerto desde el registro de RPTools no es numérico?\! Error de servidor web?
ServerDialog.error.server = You must enter a server name or IP address.
ServerDialog.error.serverNotFound = Servidor "{0}" no se encuentra.
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -714,7 +714,7 @@ Preferences.combo.themes.filter.dark = Dark
Preferences.combo.themes.filter.light = Light

ServerDialog.error.port = Vous devez entrer un port numérique.
ServerDialog.error.port.outOfRange = Le numéro de port doit être compris entre 1 et 65535.
ServerDialog.error.port.outOfRange = Le numéro de port doit être compris entre 0 et 65535.
ServerDialog.error.portNumberException = Le port issu du registre RPTools n'est pas numérique?\! Un bug du serveur Web?
ServerDialog.error.server = Vous devez entrer un serveur ou une adresse IP.
ServerDialog.error.serverNotFound = Serveur\: {0} introuvable.
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -742,7 +742,7 @@ Preferences.label.loadMRU = Load last campaign on start
Preferences.label.loadMRU.tooltip = Start MapTool with the last campaign you were using

ServerDialog.error.port = Vous devez entrer un port numérique.
ServerDialog.error.port.outOfRange = Le numéro de port doit être compris entre 1 et 65535.
ServerDialog.error.port.outOfRange = Le numéro de port doit être compris entre 0 et 65535.
ServerDialog.error.portNumberException = Le port issu du registre RPTools n'est pas numérique?\! Un bug du serveur Web?
ServerDialog.error.server = Vous devez entrer un serveur ou une adresse IP.
ServerDialog.error.serverNotFound = Serveur\: {0} introuvable.
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -714,7 +714,7 @@ Preferences.combo.themes.filter.dark = Scuro
Preferences.combo.themes.filter.light = Chiaro

ServerDialog.error.port = Devi inserire il numero di una porta.
ServerDialog.error.port.outOfRange = L'intervallo delle porte deve essere compreso tra 1 e 65535.
ServerDialog.error.port.outOfRange = L'intervallo delle porte deve essere compreso tra 0 e 65535.
ServerDialog.error.portNumberException = La porta dal registro di RPTools non è numerica?\! Bug del server web?
ServerDialog.error.server = Devi inserire un nome server o un indirizzo IP.
ServerDialog.error.serverNotFound = Server "{0}" non trovato.
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -742,7 +742,7 @@ Preferences.label.loadMRU = Load last campaign on start
Preferences.label.loadMRU.tooltip = Start MapTool with the last campaign you were using

ServerDialog.error.port = Devi inserire il numero di una porta.
ServerDialog.error.port.outOfRange = L'intervallo delle porte deve essere compreso tra 1 e 65535.
ServerDialog.error.port.outOfRange = L'intervallo delle porte deve essere compreso tra 0 e 65535.
ServerDialog.error.portNumberException = La porta dal registro di RPTools non è numerica?\! Bug del server web?
ServerDialog.error.server = Devi inserire un nome server o un indirizzo IP.
ServerDialog.error.serverNotFound = Server "{0}" non trovato.
Expand Down
Loading

0 comments on commit b02a6a5

Please sign in to comment.