Peer discovery updates

- allow loopback addresses, now you can bind different loopback IP
addresses on a single system and they will auto-cross-connect
- always listen for discovery on 0.0.0.0
- [network] - bind now also applies for the TCP socket as well as UDP
socket
- closing socket iterator fix
This commit is contained in:
Peter Šurda 2017-08-09 17:34:47 +02:00
parent e071efac1a
commit 0b07b1c89a
Signed by: PeterSurda
GPG Key ID: 0C5F50C0B5F37D87
6 changed files with 24 additions and 10 deletions

View File

@ -20,7 +20,7 @@ BMConfigDefaults = {
}, },
"network": { "network": {
"asyncore": True, "asyncore": True,
"bind": None, "bind": '',
}, },
"inventory": { "inventory": {
"storage": "sqlite", "storage": "sqlite",

View File

@ -28,6 +28,8 @@ class AnnounceThread(threading.Thread, StoppableThread):
def announceSelf(self): def announceSelf(self):
for connection in BMConnectionPool().udpSockets.values(): for connection in BMConnectionPool().udpSockets.values():
if not connection.announcing:
continue
for stream in state.streamsInWhichIAmParticipating: for stream in state.streamsInWhichIAmParticipating:
addr = (stream, state.Peer('127.0.0.1', BMConfigParser().safeGetInt("bitmessagesettings", "port")), time.time()) addr = (stream, state.Peer('127.0.0.1', BMConfigParser().safeGetInt("bitmessagesettings", "port")), time.time())
connection.append_write_buf(BMProto.assembleAddr([addr])) connection.append_write_buf(BMProto.assembleAddr([addr]))

View File

@ -8,9 +8,14 @@ import state
def getDiscoveredPeer(stream): def getDiscoveredPeer(stream):
try: try:
return random.choice(state.discoveredPeers.keys()) peer = random.choice(state.discoveredPeers.keys())
except (IndexError, KeyError): except (IndexError, KeyError):
raise ValueError raise ValueError
try:
del state.discoveredPeers[peer]
except KeyError:
pass
return peer
def chooseConnection(stream): def chooseConnection(stream):
haveOnion = BMConfigParser().safeGet("bitmessagesettings", "socksproxytype")[0:5] == 'SOCKS' haveOnion = BMConfigParser().safeGet("bitmessagesettings", "socksproxytype")[0:5] == 'SOCKS'

View File

@ -113,7 +113,7 @@ class BMConnectionPool(object):
BMConfigParser().get("bitmessagesettings", "socksproxytype") == "none": BMConfigParser().get("bitmessagesettings", "socksproxytype") == "none":
# python doesn't like bind + INADDR_ANY? # python doesn't like bind + INADDR_ANY?
#host = socket.INADDR_ANY #host = socket.INADDR_ANY
host = '' host = BMConfigParser().get("network", "bind")
return host return host
def startListening(self): def startListening(self):
@ -126,9 +126,12 @@ class BMConnectionPool(object):
def startUDPSocket(self, bind=None): def startUDPSocket(self, bind=None):
if bind is None: if bind is None:
host = self.getListeningIP() host = self.getListeningIP()
udpSocket = network.udp.UDPSocket(host=host) udpSocket = network.udp.UDPSocket(host=host, announcing=True)
else: else:
udpSocket = network.udp.UDPSocket(host=bind) if bind is False:
udpSocket = network.udp.UDPSocket(announcing=False)
else:
udpSocket = network.udp.UDPSocket(host=bind, announcing=True)
self.udpSockets[udpSocket.listening.host] = udpSocket self.udpSockets[udpSocket.listening.host] = udpSocket
def loop(self): def loop(self):
@ -192,19 +195,20 @@ class BMConnectionPool(object):
self.startListening() self.startListening()
logger.info('Listening for incoming connections.') logger.info('Listening for incoming connections.')
if not self.udpSockets: if not self.udpSockets:
if BMConfigParser().safeGet("network", "bind") is None: if BMConfigParser().safeGet("network", "bind") == '':
self.startUDPSocket() self.startUDPSocket()
else: else:
for bind in re.sub("[^\w.]+", " ", BMConfigParser().safeGet("network", "bind")).split(): for bind in re.sub("[^\w.]+", " ", BMConfigParser().safeGet("network", "bind")).split():
self.startUDPSocket(bind) self.startUDPSocket(bind)
self.startUDPSocket(False)
logger.info('Starting UDP socket(s).') logger.info('Starting UDP socket(s).')
else: else:
if self.listeningSockets: if self.listeningSockets:
for i in self.listeningSockets: for i in self.listeningSockets.values():
i.handle_close() i.handle_close()
logger.info('Stopped listening for incoming connections.') logger.info('Stopped listening for incoming connections.')
if self.udpSockets: if self.udpSockets:
for i in self.udpSockets: for i in self.udpSockets.values():
i.handle_close() i.handle_close()
logger.info('Stopped udp sockets.') logger.info('Stopped udp sockets.')

View File

@ -17,7 +17,7 @@ class UDPSocket(BMProto):
port = 8444 port = 8444
announceInterval = 60 announceInterval = 60
def __init__(self, host=None, sock=None): def __init__(self, host=None, sock=None, announcing=False):
super(BMProto, self).__init__(sock=sock) super(BMProto, self).__init__(sock=sock)
self.verackReceived = True self.verackReceived = True
self.verackSent = True self.verackSent = True
@ -49,6 +49,7 @@ class UDPSocket(BMProto):
ObjectTracker.__init__(self) ObjectTracker.__init__(self)
self.connecting = False self.connecting = False
self.connected = True self.connected = True
self.announcing = announcing
self.set_state("bm_header", expectBytes=protocol.Header.size) self.set_state("bm_header", expectBytes=protocol.Header.size)
def set_socket_reuse(self): def set_socket_reuse(self):

View File

@ -37,6 +37,8 @@ OBJECT_GETPUBKEY = 0
OBJECT_PUBKEY = 1 OBJECT_PUBKEY = 1
OBJECT_MSG = 2 OBJECT_MSG = 2
OBJECT_BROADCAST = 3 OBJECT_BROADCAST = 3
OBJECT_I2P = 0x493250
OBJECT_ADDR = 0x61646472
eightBytesOfRandomDataUsedToDetectConnectionsToSelf = pack( eightBytesOfRandomDataUsedToDetectConnectionsToSelf = pack(
'>Q', random.randrange(1, 18446744073709551615)) '>Q', random.randrange(1, 18446744073709551615))
@ -108,7 +110,7 @@ def checkIPv4Address(host, hostStandardFormat, private=False):
if host[0] == '\x7F': # 127/8 if host[0] == '\x7F': # 127/8
if not private: if not private:
logger.debug('Ignoring IP address in loopback range: ' + hostStandardFormat) logger.debug('Ignoring IP address in loopback range: ' + hostStandardFormat)
return False return hostStandardFormat if private else False
if host[0] == '\x0A': # 10/8 if host[0] == '\x0A': # 10/8
if not private: if not private:
logger.debug('Ignoring IP address in private range: ' + hostStandardFormat) logger.debug('Ignoring IP address in private range: ' + hostStandardFormat)