Skip to content

Commit

Permalink
Added --external-ip option
Browse files Browse the repository at this point in the history
This is the equivalent of the -externalip option of bitcoind.
It allows the public IP address of your node to be explicitly given,
instead of asking the peer to detect it automatically.
This is useful when running from behind dual WAN connections,
assymetric routing, or any other situation in which you want
inbound connections to come in on a different IP address than outbound.
  • Loading branch information
Krellan committed Nov 21, 2014
1 parent e9b4018 commit e18de9c
Show file tree
Hide file tree
Showing 2 changed files with 34 additions and 2 deletions.
4 changes: 4 additions & 0 deletions p2pool/main.py
Original file line number Diff line number Diff line change
Expand Up @@ -178,6 +178,7 @@ def parse(host):
connect_addrs=connect_addrs,
desired_outgoing_conns=args.p2pool_outgoing_conns,
advertise_ip=args.advertise_ip,
external_ip=args.p2pool_external_ip,
)
node.p2p_node.start()

Expand Down Expand Up @@ -413,6 +414,9 @@ def run():
p2pool_group.add_argument('--outgoing-conns', metavar='CONNS',
help='outgoing connections (default: 6)',
type=int, action='store', default=6, dest='p2pool_outgoing_conns')
p2pool_group.add_argument('--external-ip', metavar='ADDR[:PORT]',
help='specify your own public IP address instead of asking peers to discover it, useful for running dual WAN or asymmetric routing',
type=str, action='store', default=None, dest='p2pool_external_ip')
parser.add_argument('--disable-advertise',
help='''don't advertise local IP address as being available for incoming connections. useful for running a dark node, along with multiple -n ADDR's and --outgoing-conns 0''',
action='store_false', default=True, dest='advertise_ip')
Expand Down
32 changes: 30 additions & 2 deletions p2pool/p2p.py
Original file line number Diff line number Diff line change
Expand Up @@ -104,6 +104,33 @@ def _timeout(self):
print 'Connection timed out, disconnecting from %s:%i' % self.addr
self.disconnect()

def sendAdvertisement(self):
if self.node.serverfactory.listen_port is not None:
host=self.node.external_ip
port=self.node.serverfactory.listen_port.getHost().port
if host is not None:
if ':' in host:
host, port_str = host.split(':')
port = int(port_str)
if p2pool.DEBUG:
print 'Advertising for incoming connections: %s:%i' % (host, port)
# Advertise given external IP address, just as if there were another peer behind us, with that address, who asked us to advertise it for them
self.send_addrs(addrs=[
dict(
address=dict(
services=self.other_services,
address=host,
port=port,
),
timestamp=int(time.time()),
),
])
else:
if p2pool.DEBUG:
print 'Advertising for incoming connections'
# Ask peer to advertise what it believes our IP address to be
self.send_addrme(port=port)

message_version = pack.ComposedType([
('version', pack.IntType(32)),
('services', pack.IntType(64)),
Expand Down Expand Up @@ -153,7 +180,7 @@ def new_dataReceived(data):

if self.node.advertise_ip:
self._stop_thread2 = deferral.run_repeatedly(lambda: [
self.send_addrme(port=self.node.serverfactory.listen_port.getHost().port) if self.node.serverfactory.listen_port is not None else None,
self.sendAdvertisement(),
random.expovariate(1/(100*len(self.node.peers) + 1))][-1])

if best_share_hash is not None:
Expand Down Expand Up @@ -582,7 +609,7 @@ def proto_disconnected(self, proto, reason):
self.node.lost_conn(proto, reason)

class Node(object):
def __init__(self, best_share_hash_func, port, net, addr_store={}, connect_addrs=set(), desired_outgoing_conns=10, max_outgoing_attempts=30, max_incoming_conns=50, preferred_storage=1000, known_txs_var=variable.Variable({}), mining_txs_var=variable.Variable({}), advertise_ip=True):
def __init__(self, best_share_hash_func, port, net, addr_store={}, connect_addrs=set(), desired_outgoing_conns=10, max_outgoing_attempts=30, max_incoming_conns=50, preferred_storage=1000, known_txs_var=variable.Variable({}), mining_txs_var=variable.Variable({}), advertise_ip=True, external_ip=None):
self.best_share_hash_func = best_share_hash_func
self.port = port
self.net = net
Expand All @@ -592,6 +619,7 @@ def __init__(self, best_share_hash_func, port, net, addr_store={}, connect_addrs
self.known_txs_var = known_txs_var
self.mining_txs_var = mining_txs_var
self.advertise_ip = advertise_ip
self.external_ip = external_ip

self.traffic_happened = variable.Event()
self.nonce = random.randrange(2**64)
Expand Down

0 comments on commit e18de9c

Please sign in to comment.