Compare commits

...

1 Commits

3 changed files with 49 additions and 23 deletions

View File

@@ -46,6 +46,7 @@ import org.qortal.api.websocket.ChatMessagesWebSocket;
import org.qortal.api.websocket.PresenceWebSocket; import org.qortal.api.websocket.PresenceWebSocket;
import org.qortal.api.websocket.TradeBotWebSocket; import org.qortal.api.websocket.TradeBotWebSocket;
import org.qortal.api.websocket.TradeOffersWebSocket; import org.qortal.api.websocket.TradeOffersWebSocket;
import org.qortal.network.Network;
import org.qortal.settings.Settings; import org.qortal.settings.Settings;
public class ApiService { public class ApiService {
@@ -118,13 +119,13 @@ public class ApiService {
ServerConnector portUnifiedConnector = new ServerConnector(this.server, ServerConnector portUnifiedConnector = new ServerConnector(this.server,
new DetectorConnectionFactory(sslConnectionFactory), new DetectorConnectionFactory(sslConnectionFactory),
httpConnectionFactory); httpConnectionFactory);
portUnifiedConnector.setHost(Settings.getInstance().getBindAddress()); portUnifiedConnector.setHost(Network.getInstance().getBindAddress());
portUnifiedConnector.setPort(Settings.getInstance().getApiPort()); portUnifiedConnector.setPort(Settings.getInstance().getApiPort());
this.server.addConnector(portUnifiedConnector); this.server.addConnector(portUnifiedConnector);
} else { } else {
// Non-SSL // Non-SSL
InetAddress bindAddr = InetAddress.getByName(Settings.getInstance().getBindAddress()); InetAddress bindAddr = InetAddress.getByName(Network.getInstance().getBindAddress());
InetSocketAddress endpoint = new InetSocketAddress(bindAddr, Settings.getInstance().getApiPort()); InetSocketAddress endpoint = new InetSocketAddress(bindAddr, Settings.getInstance().getApiPort());
this.server = new Server(endpoint); this.server = new Server(endpoint);
} }

View File

@@ -108,6 +108,8 @@ public class Network {
private ServerSocketChannel serverChannel; private ServerSocketChannel serverChannel;
private Iterator<SelectionKey> channelIterator = null; private Iterator<SelectionKey> channelIterator = null;
private String bindAddress = null;
// volatile because value is updated inside any one of the EPC threads // volatile because value is updated inside any one of the EPC threads
private volatile long nextConnectTaskTimestamp = 0L; // ms - try first connect once NTP syncs private volatile long nextConnectTaskTimestamp = 0L; // ms - try first connect once NTP syncs
@@ -138,25 +140,42 @@ public class Network {
// Grab P2P port from settings // Grab P2P port from settings
int listenPort = Settings.getInstance().getListenPort(); int listenPort = Settings.getInstance().getListenPort();
// Grab P2P bind address from settings // Grab P2P bind addresses from settings
try { String[] bindAddresses = Settings.getInstance().getBindAddresses();
InetAddress bindAddr = InetAddress.getByName(Settings.getInstance().getBindAddress()); for (int i=0; i<bindAddresses.length; i++) {
InetSocketAddress endpoint = new InetSocketAddress(bindAddr, listenPort);
channelSelector = Selector.open(); String bindAddress = bindAddresses[i];
try {
LOGGER.info(String.format("Binding to address %s", bindAddress));
InetAddress bindAddr = InetAddress.getByName(bindAddress);
InetSocketAddress endpoint = new InetSocketAddress(bindAddr, listenPort);
channelSelector = Selector.open();
// Set up listen socket
serverChannel = ServerSocketChannel.open();
serverChannel.configureBlocking(false);
serverChannel.setOption(StandardSocketOptions.SO_REUSEADDR, true);
serverChannel.bind(endpoint, LISTEN_BACKLOG);
serverChannel.register(channelSelector, SelectionKey.OP_ACCEPT);
this.bindAddress = bindAddress; // Store the selected address, so that it can be used by other parts of the app
break; // We don't want to bind to more than one address
} catch (UnknownHostException e) {
LOGGER.error(String.format("Can't bind listen socket to address %s", bindAddress));
if (i == bindAddresses.length-1) { // Only throw an exception if all addresses have been tried
throw new IOException("Can't bind listen socket to address", e);
}
} catch (IOException e) {
LOGGER.error(String.format("Can't create listen socket: %s", e.getMessage()));
if (i == bindAddresses.length-1) { // Only throw an exception if all addresses have been tried
throw new IOException("Can't create listen socket", e);
}
}
// Set up listen socket
serverChannel = ServerSocketChannel.open();
serverChannel.configureBlocking(false);
serverChannel.setOption(StandardSocketOptions.SO_REUSEADDR, true);
serverChannel.bind(endpoint, LISTEN_BACKLOG);
serverChannel.register(channelSelector, SelectionKey.OP_ACCEPT);
} catch (UnknownHostException e) {
LOGGER.error(String.format("Can't bind listen socket to address %s", Settings.getInstance().getBindAddress()));
throw new IOException("Can't bind listen socket to address", e);
} catch (IOException e) {
LOGGER.error(String.format("Can't create listen socket: %s", e.getMessage()));
throw new IOException("Can't create listen socket", e);
} }
// Load all known peers from repository // Load all known peers from repository
@@ -179,6 +198,10 @@ public class Network {
return instance; return instance;
} }
public String getBindAddress() {
return this.bindAddress;
}
public byte[] getMessageMagic() { public byte[] getMessageMagic() {
return Settings.getInstance().isTestNet() ? TESTNET_MESSAGE_MAGIC : MAINNET_MESSAGE_MAGIC; return Settings.getInstance().isTestNet() ? TESTNET_MESSAGE_MAGIC : MAINNET_MESSAGE_MAGIC;
} }

View File

@@ -46,8 +46,10 @@ public class Settings {
// General // General
private String localeLang = Locale.getDefault().getLanguage(); private String localeLang = Locale.getDefault().getLanguage();
// Common to all networking (API/P2P) // Common to all networking (API/P2P). They are tried in order until one successfully binds.
private String bindAddress = "::"; // Use IPv6 wildcard to listen on all local addresses private String[] bindAddresses = new String[] {
"::", "0.0.0.0"
};
// UI servers // UI servers
private int uiPort = 12388; private int uiPort = 12388;
@@ -376,8 +378,8 @@ public class Settings {
return this.isTestNet ? TESTNET_LISTEN_PORT : MAINNET_LISTEN_PORT; return this.isTestNet ? TESTNET_LISTEN_PORT : MAINNET_LISTEN_PORT;
} }
public String getBindAddress() { public String[] getBindAddresses() {
return this.bindAddress; return this.bindAddresses;
} }
public int getMinBlockchainPeers() { public int getMinBlockchainPeers() {