Browse Source

connectd: Update connection list with new address

If we're already attempting to connect to a peer, we would ignore
new connection requests. This is problematic if your node has bad
connection details for the node -- you can't update it while inflight.

This patch appends new connection suggestions to the list of connections
to try.

Fixes #4154
ppa-prep
niftynei 4 years ago
committed by neil saitug
parent
commit
4a3ee19a22
  1. 11
      connectd/connectd.c
  2. 33
      tests/plugins/slow_start.py
  3. 24
      tests/test_connection.py

11
connectd/connectd.c

@ -1457,8 +1457,17 @@ static void try_connect_peer(struct daemon *daemon,
return;
/* If we're trying to connect it right now, that's OK. */
if (find_connecting(daemon, id))
if ((connect = find_connecting(daemon, id))) {
/* If we've been passed in new connection details
* for this connection, update our addrhint + add
* to addresses to check */
if (addrhint) {
connect->addrhint = tal_steal(connect, addrhint);
tal_arr_expand(&connect->addrs, *addrhint);
}
return;
}
/* Start an array of addresses to try. */
addrs = tal_arr(tmpctx, struct wireaddr_internal, 0);

33
tests/plugins/slow_start.py

@ -0,0 +1,33 @@
#!/usr/bin/env python3
"""This plugin is used to check that updated connection hints work properly.
"""
from pyln.client import Plugin
import socket
import time
plugin = Plugin()
@plugin.async_method('waitconn')
def wait_connection(request, plugin):
sock = socket.socket(socket.AF_INET, socket.SOCK_STREAM)
sock.bind(('localhost', 0))
sock.listen(1)
print("listening for connections on port {}".format(sock.getsockname()[1]))
# We are a one and done socket connection!
conn, client_addr = sock.accept()
try:
print("connection from {}".format(client_addr))
time.sleep(3)
finally:
conn.close()
print("closing socket")
sock.close()
plugin.run()

24
tests/test_connection.py

@ -111,6 +111,30 @@ def test_reconnect_channel_peers(node_factory, executor):
fut3.result(10)
def test_connection_moved(node_factory, executor):
slow_start = os.path.join(os.getcwd(), 'tests/plugins/slow_start.py')
options = {'may_reconnect': True, 'plugin': slow_start}
l1, l2 = node_factory.get_nodes(2, opts=options)
# Set up the plugin to wait for a connection
executor.submit(l1.rpc.waitconn)
log = l1.daemon.wait_for_log('listening for connections')
match = re.search(r'on port (\d*)', log)
assert match and len(match.groups()) == 1
hang_port = match.groups()[0]
# Attempt connection
fut_hang = executor.submit(l1.rpc.connect, l2.info['id'],
'localhost', hang_port)
l1.daemon.wait_for_log('connection from')
# Provide correct connection details
l1.rpc.connect(l2.info['id'], 'localhost', l2.port)
# If we failed to update the connection, this call will error
fut_hang.result(TIMEOUT)
def test_balance(node_factory):
l1, l2 = node_factory.line_graph(2, fundchannel=True)
p1 = only_one(l1.rpc.getpeer(peer_id=l2.info['id'], level='info')['channels'])

Loading…
Cancel
Save