Merge lp:~alfred-54/divmod.org/divmod.org into lp:divmod.org

Proposed by Alfred Morgan on 2013-04-15
Status: Rejected
Rejected by: Jean-Paul Calderone on 2013-07-10
Proposed branch: lp:~alfred-54/divmod.org/divmod.org
Merge into: lp:divmod.org
Diff against target: 274 lines (+98/-75)
4 files modified
Vertex/vertex/q2q.py (+76/-67)
Vertex/vertex/q2qclient.py (+2/-2)
Vertex/vertex/q2qstandalone.py (+2/-2)
Vertex/vertex/test/test_q2q.py (+18/-4)
To merge this branch: bzr merge lp:~alfred-54/divmod.org/divmod.org
Reviewer Review Type Date Requested Status
Divmod-dev 2013-04-15 Pending
Review via email: mp+158833@code.launchpad.net

Description of the Change

* completed juice to amp transition
* cleanup client connections to keep the reactor clean
* WRITE will return ConnectionDone when no connection is found

OS X 10.8 and Windows 7 trial vertex both return PASSED (skips=5, successes=52)

To post a comment you must log in.
lp:~alfred-54/divmod.org/divmod.org updated on 2013-05-07
2705. By Alfred Morgan on 2013-05-07

attempt to advertise public ports instead of private ones.

Jean-Paul Calderone (exarkun) wrote :

Just doing some house-keeping here. Vertex has moved to <http://github.com/twisted/vertex>. These changes will not make it into lp:divmod.org because Vertex is no longer there. See <https://github.com/twisted/vertex/tree/alfred_test_fixes_and_cleanup>.

Unmerged revisions

2705. By Alfred Morgan on 2013-05-07

attempt to advertise public ports instead of private ones.

2704. By Alfred Morgan on 2013-04-14

WRITE will return ConnectionDone when no connection is found

2703. By Alfred Morgan on 2013-04-14

cleanup client connections to keep the reactor clean

2702. By Alfred Morgan on 2013-04-09

completed juice to amp transition

Preview Diff

[H/L] Next/Prev Comment, [J/K] Next/Prev File, [N/P] Next/Prev Hunk
1=== modified file 'Vertex/vertex/q2q.py'
2--- Vertex/vertex/q2q.py 2012-03-14 23:42:53 +0000
3+++ Vertex/vertex/q2q.py 2013-05-07 05:25:33 +0000
4@@ -1132,21 +1132,19 @@
5
6 result = [] # list of listener dicts
7
8+ d = defer.Deferred()
9 if srvfacts:
10+ def appendTCPMethod(addr, TCPMethod):
11+ localMethods.append(TCPMethod("%s:%d" % addr))
12 log.msg("local factories found for inbound request: %r" % (srvfacts,))
13 localMethods = []
14 publicIP = self._determinePublicIP()
15 privateIP = self._determinePrivateIP()
16 if self.service.inboundTCPPort is not None:
17 tcpPort = self.service.inboundTCPPort.getHost().port
18- localMethods.append(TCPMethod(
19- '%s:%d' %
20- (publicIP, tcpPort)))
21+ appendTCPMethod((publicIP, tcpPort), TCPMethod)
22 if publicIP != privateIP:
23- localMethods.append(TCPMethod(
24- '%s:%d' %
25- (privateIP, tcpPort)))
26-
27+ appendTCPMethod((privateIP, tcpPort), TCPMethod)
28 if not self.service.udpEnabled:
29 log.msg("udp not enabled -- but I so want to send udp traffic!")
30 elif udp_source is None:
31@@ -1162,66 +1160,70 @@
32 "local public IP: %s, local private IP: %s"
33 % (remoteUDPHost, remoteUDPPort, publicIP, privateIP) )
34
35- # Seed my NAT from my shared UDP port
36- udpPort = self.service.dispatcher.seedNAT(udp_source, self.service.sharedUDPPortnum)
37-
38- if remoteUDPHost == publicIP and publicIP != privateIP:
39- log.msg(
40- "Remote IP matches local, public IP %r;"
41- " preferring internal IP %r" % (publicIP, privateIP))
42- localMethods.append(
43- PTCPMethod("%s:%d" % (privateIP, udpPort)))
44- localMethods.append(
45- PTCPMethod("%s:%d" % (publicIP, udpPort)))
46-
47- # XXX CLEANUP!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!
48- # !!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!
49- # !!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!
50- privateUDPPort = self.service.dispatcher.seedNAT(udp_source)
51- localMethods.append(
52- PTCPMethod('%s:%d' % (publicIP, privateUDPPort)))
53-
54- udpxPort = self.service.dispatcher.seedNAT(udp_source)
55- localMethods.append(
56- RPTCPMethod("%s:%d" % (publicIP, udpxPort)))
57-
58- if self.service.virtualEnabled:
59- localMethods.append(VirtualMethod())
60- log.msg('responding to inbound with local methods: %r' % (localMethods,))
61-
62- for serverFactory, description in srvfacts:
63- expiryTime, listenID = self.service.mapListener(
64- to, From, protocol, serverFactory)
65- result.append(dict(id=listenID,
66- expires=expiryTime,
67- methods=localMethods,
68- description=description))
69-
70- # We've looked for our local factory. Let's see if we have any
71- # listening protocols elsewhere.
72-
73-
74- key = (to, protocol)
75- if key in self.service.listeningClients:
76- args = dict(From=From,
77- to=to,
78- protocol=protocol,
79- udp_source=udp_source)
80- DL = []
81- lclients = self.service.listeningClients[key]
82- log.msg("listeners found for %s:%r" % (to, protocol))
83- for listener, listenCert, desc in lclients:
84- log.msg("relaying inbound to %r via %r" % (to, listener))
85- DL.append(listener.callRemote(Inbound, **args).addCallback(
86- self._massageClientInboundResponse, listener, result))
87-
88- def allListenerResponses(x):
89- log.msg("all inbound responses received: %s" % (pformat(result),))
90+ @d.addCallback
91+ def cb_methods(x):
92+ # Seed my NAT from my shared UDP port
93+ localUDP = self.service.dispatcher.seedNAT(udp_source, self.service.sharedUDPPortnum)
94+ return self._determinePublicUDPPortNumber(localUDP)
95+ @d.addCallback
96+ def cb_shared(pubAddr):
97+ udpAddrIP, udpPort = pubAddr
98+ if remoteUDPHost == publicIP and publicIP != privateIP:
99+ log.msg(
100+ "Remote IP matches local, public IP %r;"
101+ " preferring internal IP %r" % (publicIP, privateIP))
102+ appendTCPMethod((privateIP, udpPort), PTCPMethod)
103+ appendTCPMethod((publicIP, udpPort), PTCPMethod)
104+ # XXX CLEANUP!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!
105+ # !!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!
106+ # !!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!
107+ localUDP = self.service.dispatcher.seedNAT(udp_source)
108+ return self._determinePublicUDPPortNumber(localUDP).addCallback(appendTCPMethod, PTCPMethod)
109+ @d.addCallback
110+ def cb_PTCP(x):
111+ localUDP = self.service.dispatcher.seedNAT(udp_source)
112+ return self._determinePublicUDPPortNumber(localUDP).addCallback(appendTCPMethod, RPTCPMethod)
113+ @d.addCallback
114+ def cb_complete(x):
115+ if self.service.virtualEnabled:
116+ localMethods.append(VirtualMethod())
117+ log.msg('responding to inbound with local methods: %r' % (localMethods,))
118+
119+ for serverFactory, description in srvfacts:
120+ expiryTime, listenID = self.service.mapListener(
121+ to, From, protocol, serverFactory)
122+ result.append(dict(id=listenID,
123+ expires=expiryTime,
124+ methods=localMethods,
125+ description=description))
126+
127+ # We've looked for our local factory. Let's see if we have any
128+ # listening protocols elsewhere.
129+ @d.addCallback
130+ def listeningProtocolsCB(x):
131+ key = (to, protocol)
132+ if key in self.service.listeningClients:
133+ args = dict(From=From,
134+ to=to,
135+ protocol=protocol,
136+ udp_source=udp_source)
137+ DL = []
138+ lclients = self.service.listeningClients[key]
139+ log.msg("listeners found for %s:%r" % (to, protocol))
140+ for listener, listenCert, desc in lclients:
141+ log.msg("relaying inbound to %r via %r" % (to, listener))
142+ DL.append(listener.callRemote(Inbound, **args).addCallback(
143+ self._massageClientInboundResponse, listener, result))
144+
145+ def allListenerResponses(x):
146+ log.msg("all inbound responses received: %s" % (pformat(result),))
147+ return dict(listeners=result)
148+ return defer.DeferredList(DL).addCallback(allListenerResponses)
149+ else:
150+ log.msg("no listenening clients for %s:%r. local methods: %r" % (to,protocol, result))
151 return dict(listeners=result)
152- return defer.DeferredList(DL).addCallback(allListenerResponses)
153- else:
154- log.msg("no listenening clients for %s:%r. local methods: %r" % (to,protocol, result))
155- return dict(listeners=result)
156+ d.callback(None)
157+ return d
158
159
160 def _massageClientInboundResponse(self, inboundResponse, listener, result):
161@@ -1243,6 +1245,13 @@
162 listenerInfo['certificate'] = allowedCertificate
163 result.append(listenerInfo)
164
165+ def _determinePublicUDPPortNumber(self, localUDP):
166+ d = defer.Deferred()
167+ addressDiscoveryFactory = _AddressDiscoveryFactory(d)
168+ gp = self.transport.getPeer()
169+ self.service.dispatcher.connectPTCP(gp.host, gp.port, addressDiscoveryFactory, localUDP)
170+ return d
171+
172 def _determinePublicIP(self):
173 reservePublicIP = None
174 if self.service.publicIP is not None:
175@@ -1309,7 +1318,7 @@
176 """
177 id = int(box['id'])
178 if id not in self.connections:
179- raise error.ConnectionDone()
180+ return error.ConnectionDone()
181 connection = self.connections[id]
182 data = box['body']
183 connection.dataReceived(data)
184
185=== modified file 'Vertex/vertex/q2qclient.py'
186--- Vertex/vertex/q2qclient.py 2010-04-17 15:10:09 +0000
187+++ Vertex/vertex/q2qclient.py 2013-05-07 05:25:33 +0000
188@@ -310,8 +310,8 @@
189
190 class UserAdder(AMP):
191 def connectionMade(self):
192- self.d = AddUser(name=self.factory.name,
193- password=self.factory.password).do(self)
194+ self.d = self.callRemote(AddUser, name=self.factory.name,
195+ password=self.factory.password)
196
197
198 class UserAdderFactory(protocol.ClientFactory):
199
200=== modified file 'Vertex/vertex/q2qstandalone.py'
201--- Vertex/vertex/q2qstandalone.py 2010-04-17 15:10:09 +0000
202+++ Vertex/vertex/q2qstandalone.py 2013-05-07 05:25:33 +0000
203@@ -12,13 +12,13 @@
204
205 class IdentityAdmin(AMP):
206
207- def command_ADD_USER(self, name, password):
208+ def _add_user(self, name, password):
209 # all security is transport security
210 theDomain = self.transport.getQ2QHost().domain
211 self.factory.store.addUser(theDomain, name, password)
212 return {}
213
214- command_ADD_USER.command = AddUser
215+ AddUser.responder(_add_user)
216
217 class IdentityAdminFactory:
218 def __init__(self, certstore):
219
220=== modified file 'Vertex/vertex/test/test_q2q.py'
221--- Vertex/vertex/test/test_q2q.py 2012-03-12 18:30:09 +0000
222+++ Vertex/vertex/test/test_q2q.py 2013-05-07 05:25:33 +0000
223@@ -33,7 +33,8 @@
224 class FakeConnectTCP:
225 implements(IResolverSimple)
226
227- def __init__(self, connectTCP):
228+ def __init__(self, tester, connectTCP):
229+ self.tester = tester
230 self._connectTCP = connectTCP
231 self.hostPortToHostPort = {}
232 self.hostToLocalHost = {}
233@@ -50,9 +51,22 @@
234 self.hostPortToHostPort[(localIP, fakePortNumber)] = (localIP, realPortNumber)
235 self.hostPortToHostPort[(hostname, fakePortNumber)] = (hostname, realPortNumber)
236
237+ def _cleanupClient(self, client):
238+ client.transport.closingDeferred = defer.Deferred()
239+ transport_connectionLost = client.transport.connectionLost
240+ def connectionLost(*args, **kwargs):
241+ transport_connectionLost(*args, **kwargs)
242+ if not client.transport.closingDeferred.called:
243+ client.transport.closingDeferred.callback(None)
244+ client.transport.connectionLost = connectionLost
245+ self.tester.addCleanup(lambda: client.transport.closingDeferred)
246+
247 def connectTCP(self, host, port, *args, **kw):
248 localhost, localport = self.hostPortToHostPort.get((host,port), (host, port))
249- return self._connectTCP(localhost, localport, *args, **kw)
250+ client = self._connectTCP(localhost, localport, *args, **kw)
251+ self._cleanupClient(client)
252+ self.tester.addCleanup(client.transport.loseConnection)
253+ return client
254
255 def getHostSync(self,name):
256 result = self.hostToLocalHost[name]
257@@ -335,7 +349,7 @@
258 # A mapping of host names to port numbers Our connectTCP will always
259 # connect to 127.0.0.1 and on a port which is a value in this
260 # dictionary.
261- fakeDNS = FakeConnectTCP(reactor.connectTCP)
262+ fakeDNS = FakeConnectTCP(self, reactor.connectTCP)
263 reactor.connectTCP = fakeDNS.connectTCP
264
265 # ALSO WE MUST DO OTHER SIMILAR THINGS
266@@ -627,7 +641,7 @@
267 def connected(proto):
268 d1 = self.assertFailure(proto.callRemote(Fatal), FatalError)
269 def noMoreCalls(_):
270- self.assertFailure(proto.callRemote(Flag),
271+ return self.assertFailure(proto.callRemote(Flag),
272 ConnectionDone)
273 d1.addCallback(noMoreCalls)
274 return d1

Subscribers

People subscribed via source and target branches

to all changes: