diff --git a/test/functional/test_framework/p2p.py b/test/functional/test_framework/p2p.py index 986eaf1e88e..8102da7a7f7 100755 --- a/test/functional/test_framework/p2p.py +++ b/test/functional/test_framework/p2p.py @@ -22,9 +22,11 @@ P2PTxInvStore: A p2p interface class that inherits from P2PDataStore, and keeps import asyncio from collections import defaultdict +import ipaddress from io import BytesIO import logging import platform +import socket import struct import sys import threading @@ -76,6 +78,9 @@ from test_framework.messages import ( MAGIC_BYTES, sha256, ) +from test_framework.netutil import ( + set_ephemeral_port_range, +) from test_framework.util import ( assert_not_equal, MAX_NODES, @@ -793,8 +798,22 @@ class NetworkThread(threading.Thread): # connections, we can accomplish this by providing different # `proto` functions - listener = await cls.network_event_loop.create_server(peer_protocol, addr, port) - port = listener.sockets[0].getsockname()[1] + if port == 0: + # Manually create the socket in order to set the range to be + # used for the port before the bind() call. + if ipaddress.ip_address(addr).version == 4: + address_family = socket.AF_INET + else: + address_family = socket.AF_INET6 + s = socket.socket(address_family) + set_ephemeral_port_range(s) + s.bind((addr, 0)) + s.listen() + listener = await cls.network_event_loop.create_server(peer_protocol, sock=s) + port = listener.sockets[0].getsockname()[1] + else: + listener = await cls.network_event_loop.create_server(peer_protocol, addr, port) + logger.debug("Listening server on %s:%d should be started" % (addr, port)) cls.listeners[(addr, port)] = listener