From 2c261ce996f6786244a37189a17dee0b80ce4fbf Mon Sep 17 00:00:00 2001 From: Brian Warner Date: Wed, 7 Mar 2007 18:43:17 -0700 Subject: [PATCH] change node startup to put all local addresses in the PBURL, including 127.0.0.1. This should facilitate testing on both connected and disconnected systems. --- src/allmydata/node.py | 18 ++++++++++++------ src/allmydata/test/test_iputil.py | 12 ++++++++---- src/allmydata/util/iputil.py | 22 ++++++++++++++++++++++ 3 files changed, 42 insertions(+), 10 deletions(-) diff --git a/src/allmydata/node.py b/src/allmydata/node.py index bbb03e33..6933c3bb 100644 --- a/src/allmydata/node.py +++ b/src/allmydata/node.py @@ -2,7 +2,8 @@ from twisted.application import service import os.path from foolscap import Tub -from allmydata.util.iputil import get_local_ip_for +from foolscap.eventual import fireEventually +from allmydata.util.iputil import get_local_addresses from allmydata.util import idlib from twisted.python import log @@ -58,7 +59,7 @@ class Node(service.MultiService): def log(self, msg): log.msg(self.short_nodeid + ": " + msg) - def _setup_tub(self, local_ip): + def _setup_tub(self, local_addresses): # we can't get a dynamically-assigned portnum until our Tub is # running, which means after startService. l = self.tub.getListeners()[0] @@ -68,14 +69,18 @@ class Node(service.MultiService): f = open(local_ip_filename, "r") local_ip = f.read() f.close() - self.tub.setLocation("%s:%d" % (local_ip, portnum)) + if local_ip not in local_addresses: + local_addresses.append(local_ip) if not os.path.exists(self._portnumfile): # record which port we're listening on, so we can grab the same # one next time f = open(self._portnumfile, "w") f.write("%d\n" % portnum) f.close() - self.tub.setLocation("%s:%d" % (local_ip, l.getPortnum())) + location = ",".join(["%s:%d" % (ip, portnum) + for ip in local_addresses]) + self.log("Tub location set to %s" % location) + self.tub.setLocation(location) return self.tub def tub_ready(self): @@ -89,7 +94,8 @@ class Node(service.MultiService): def startService(self): # note: this class can only be started and stopped once. service.MultiService.startService(self) - local_ip = get_local_ip_for() - self._setup_tub(local_ip) + local_addresses = get_local_addresses() + self._setup_tub(local_addresses) self.tub_ready() self.log("%s running" % self.NODETYPE) + diff --git a/src/allmydata/test/test_iputil.py b/src/allmydata/test/test_iputil.py index 7a064a4f..fa8bde07 100644 --- a/src/allmydata/test/test_iputil.py +++ b/src/allmydata/test/test_iputil.py @@ -1,14 +1,18 @@ from twisted.trial import unittest -from allmydata.util.iputil import get_local_addresses +from allmydata.util import iputil class ListAddresses(unittest.TestCase): - def test_list(self): - d = get_local_addresses() + def test_list_async(self): + d = iputil.get_local_addresses_async() def _check(addresses): self.failUnless(len(addresses) >= 1) # always have localhost self.failUnless("127.0.0.1" in addresses) - print addresses d.addCallbacks(_check) return d + def test_list(self): + addresses = iputil.get_local_addresses() + self.failUnless(len(addresses) >= 1) # always have localhost + self.failUnless("127.0.0.1" in addresses) + diff --git a/src/allmydata/util/iputil.py b/src/allmydata/util/iputil.py index 6c52c64e..2e31ad53 100644 --- a/src/allmydata/util/iputil.py +++ b/src/allmydata/util/iputil.py @@ -1,6 +1,7 @@ # adapted from nattraverso.ipdiscover +import os from cStringIO import StringIO import re import socket @@ -15,6 +16,27 @@ def get_local_addresses(): # eventually I want to use somebody else's cross-platform library for # this. For right now, I'm running ifconfig and grepping for the 'inet ' # lines. + + cmd = "ifconfig" + p = os.popen("ifconfig") + addresses = [] + for line in p.readlines(): + # linux shows: " inet addr:1.2.3.4 Bcast:1.2.3.255..." + # OS-X shows: " inet 1.2.3.4 ..." + m = re.match("^\s+inet\s+[a-z:]*([\d\.]+)\s", line) + if m: + addresses.append(m.group(1)) + return addresses + +def get_local_addresses_async(): + """Return a Deferred that fires with a list of IPv4 addresses (as + dotted-quad strings) that are currently configured on this host. + """ + # eventually I want to use somebody else's cross-platform library for + # this. For right now, I'm running ifconfig and grepping for the 'inet ' + # lines. + + # I'd love to do this synchronously. cmd = "ifconfig" d = getProcessOutput("ifconfig") def _parse(output): -- 2.45.2