From f2fbf688b04e1db5aa96cabc17affbb71d78edca Mon Sep 17 00:00:00 2001 From: Brian Warner Date: Thu, 30 Nov 2006 16:23:39 -0700 Subject: [PATCH] start on client what-is-my-ipaddress functionality --- allmydata/client.py | 22 ++++++++++++++--- allmydata/util/__init__.py | 0 allmydata/util/iputil.py | 48 ++++++++++++++++++++++++++++++++++++++ client.tac | 3 ++- 4 files changed, 69 insertions(+), 4 deletions(-) create mode 100644 allmydata/util/__init__.py create mode 100644 allmydata/util/iputil.py diff --git a/allmydata/client.py b/allmydata/client.py index d410dd9f..3a3b3882 100644 --- a/allmydata/client.py +++ b/allmydata/client.py @@ -1,8 +1,13 @@ +import os.path from foolscap import Tub, Referenceable from twisted.application import service from twisted.python import log -import os.path +from allmydata.util.iputil import get_local_ip_for + +from twisted.internet import reactor +from twisted.internet.base import BlockingResolver +reactor.installResolver(BlockingResolver()) class Storage(service.MultiService, Referenceable): pass @@ -10,8 +15,9 @@ class Storage(service.MultiService, Referenceable): class Client(service.MultiService): CERTFILE = "client.pem" - def __init__(self, queen_pburl): + def __init__(self, queen_host, queen_pburl): service.MultiService.__init__(self) + self.queen_host = queen_host self.queen_pburl = queen_pburl if os.path.exists(self.CERTFILE): self.tub = Tub(certData=open(self.CERTFILE, "rb").read()) @@ -20,14 +26,23 @@ class Client(service.MultiService): f = open(self.CERTFILE, "wb") f.write(self.tub.getCertData()) f.close() + self.tub.setServiceParent(self) self.queen = None # self.queen is either None or a RemoteReference self.urls = {} + + def _setup_services(self, local_ip): + portnum = 0 + l = self.tub.listenOn("tcp:%d" % portnum) + self.tub.setLocation("%s:%d" % (local_ip, l.getPortnum())) s = Storage() s.setServiceParent(self) - #self.urls["storage"] = self.tub.registerReference(s, "storage") + self.urls["storage"] = self.tub.registerReference(s, "storage") def startService(self): + # note: this class can only be started and stopped once. service.MultiService.startService(self) + d = get_local_ip_for(self.queen_host) + d.addCallback(self._setup_services) if self.queen_pburl: self.connector = self.tub.connectTo(self.queen_pburl, self._got_queen) @@ -37,6 +52,7 @@ class Client(service.MultiService): def stopService(self): if self.queen_pburl: self.connector.stopConnecting() + service.MultiService.stopService(self) def _got_queen(self, queen): log.msg("connected to queen") diff --git a/allmydata/util/__init__.py b/allmydata/util/__init__.py new file mode 100644 index 00000000..e69de29b diff --git a/allmydata/util/iputil.py b/allmydata/util/iputil.py new file mode 100644 index 00000000..a8daa01d --- /dev/null +++ b/allmydata/util/iputil.py @@ -0,0 +1,48 @@ + +# adapted from nattraverso.ipdiscover + +from twisted.internet import reactor +from twisted.internet.protocol import DatagramProtocol +#from twisted.internet.error import CannotListenError +#from twisted.internet.interfaces import IReactorMulticast +#from amdlib.util.nattraverso.utils import is_rfc1918_ip, is_bogus_ip + +def get_local_ip_for(target): + """Find out what our IP address is for use by a given target. + + Returns a Deferred which will be fired with a string that holds the IP + address which could be used by 'target' to connect to us. It might work + for them, it might not. + + The reactor must be running before you can call this, because we must + perform a DNS lookup on the target. + + """ + d = reactor.resolve(target) + def _resolved(target_ipaddr): + udpprot = DatagramProtocol() + port = reactor.listenUDP(0, udpprot) + udpprot.transport.connect(target_ipaddr, 7) + localip = udpprot.transport.getHost().host + port.stopListening() + return localip + d.addCallback(_resolved) + return d + + + +def BROKEN_get_local_ip_for(target_ipaddr): + """Find out what our IP address is for use by a given target. + + Returns a Deferred which will be fired with a string that holds the IP + address which could be used by 'target' to connect to us. It might work + for them, it might not. 'target' must be an IP address. + + """ + udpprot = DatagramProtocol() + port = reactor.listenUDP(0, udpprot) + udpprot.transport.connect(target_ipaddr, 7) + localip = udpprot.transport.getHost().host + port.stopListening() + + return localip diff --git a/client.tac b/client.tac index eda14e66..035156d8 100644 --- a/client.tac +++ b/client.tac @@ -3,8 +3,9 @@ from allmydata import client from twisted.application import service +queen_host = "yumyum" queen_pburl = "" -c = client.Client(queen_pburl) +c = client.Client(queen_host, queen_pburl) application = service.Application("allmydata_client") c.setServiceParent(application) -- 2.45.2