@ -124,6 +124,8 @@ public class Network {
private final List < PeerAddress > selfPeers = new ArrayList < > ( ) ;
private final List < PeerAddress > selfPeers = new ArrayList < > ( ) ;
private String bindAddress = null ;
private final ExecuteProduceConsume networkEPC ;
private final ExecuteProduceConsume networkEPC ;
private Selector channelSelector ;
private Selector channelSelector ;
private ServerSocketChannel serverChannel ;
private ServerSocketChannel serverChannel ;
@ -159,9 +161,19 @@ 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
List < String > bindAddresses = new ArrayList < > ( ) ;
if ( Settings . getInstance ( ) . getBindAddress ( ) ! = null ) {
bindAddresses . add ( Settings . getInstance ( ) . getBindAddress ( ) ) ;
}
if ( Settings . getInstance ( ) . getBindAddressFallback ( ) ! = null ) {
bindAddresses . add ( Settings . getInstance ( ) . getBindAddressFallback ( ) ) ;
}
for ( int i = 0 ; i < bindAddresses . size ( ) ; i + + ) {
try {
try {
InetAddress bindAddr = InetAddress . getByName ( Settings . getInstance ( ) . getBindAddress ( ) ) ;
String bindAddress = bindAddresses . get ( i ) ;
InetAddress bindAddr = InetAddress . getByName ( bindAddress ) ;
InetSocketAddress endpoint = new InetSocketAddress ( bindAddr , listenPort ) ;
InetSocketAddress endpoint = new InetSocketAddress ( bindAddr , listenPort ) ;
channelSelector = Selector . open ( ) ;
channelSelector = Selector . open ( ) ;
@ -172,13 +184,21 @@ public class Network {
serverChannel . setOption ( StandardSocketOptions . SO_REUSEADDR , true ) ;
serverChannel . setOption ( StandardSocketOptions . SO_REUSEADDR , true ) ;
serverChannel . bind ( endpoint , LISTEN_BACKLOG ) ;
serverChannel . bind ( endpoint , LISTEN_BACKLOG ) ;
serverSelectionKey = serverChannel . register ( channelSelector , SelectionKey . OP_ACCEPT ) ;
serverSelectionKey = 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 ) {
} catch ( UnknownHostException e ) {
LOGGER . error ( "Can't bind listen socket to address {}" , Settings . getInstance ( ) . getBindAddress ( ) ) ;
LOGGER . error ( "Can't bind listen socket to address {}" , Settings . getInstance ( ) . getBindAddress ( ) ) ;
if ( i = = bindAddresses . size ( ) - 1 ) { // Only throw an exception if all addresses have been tried
throw new IOException ( "Can't bind listen socket to address" , e ) ;
throw new IOException ( "Can't bind listen socket to address" , e ) ;
}
} catch ( IOException e ) {
} catch ( IOException e ) {
LOGGER . error ( "Can't create listen socket: {}" , e . getMessage ( ) ) ;
LOGGER . error ( "Can't create listen socket: {}" , e . getMessage ( ) ) ;
if ( i = = bindAddresses . size ( ) - 1 ) { // Only throw an exception if all addresses have been tried
throw new IOException ( "Can't create listen socket" , e ) ;
throw new IOException ( "Can't create listen socket" , e ) ;
}
}
}
}
// Load all known peers from repository
// Load all known peers from repository
synchronized ( this . allKnownPeers ) {
synchronized ( this . allKnownPeers ) {
@ -228,6 +248,10 @@ public class Network {
return this . maxPeers ;
return this . maxPeers ;
}
}
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 ;
}
}
@ -1556,7 +1580,7 @@ public class Network {
this . isShuttingDown = true ;
this . isShuttingDown = true ;
// Close listen socket to prevent more incoming connections
// Close listen socket to prevent more incoming connections
if ( this . serverChannel . isOpen ( ) ) {
if ( this . serverChannel ! = null & & this . serverChannel . isOpen ( ) ) {
try {
try {
this . serverChannel . close ( ) ;
this . serverChannel . close ( ) ;
} catch ( IOException e ) {
} catch ( IOException e ) {