Merge lp:~martin-v/zodb/ipv6 into lp:zodb

Proposed by Martin v. Löwis
Status: Needs review
Proposed branch: lp:~martin-v/zodb/ipv6
Merge into: lp:zodb
Diff against target: 173 lines (+71/-5)
6 files modified
doc/zeo.txt (+3/-0)
src/ZEO/tests/ConnectionTests.py (+16/-0)
src/ZEO/tests/testZEO.py (+2/-2)
src/ZEO/zrpc/client.py (+14/-2)
src/ZEO/zrpc/server.py (+32/-1)
src/ZEO/zrpc/smac.py (+4/-0)
To merge this branch: bzr merge lp:~martin-v/zodb/ipv6
Reviewer Review Type Date Requested Status
Jim Fulton Approve
Hanno Schlichting Pending
Christian Theune Pending
Review via email: mp+35945@code.launchpad.net

Description of the change

This adds IPv6 support to ZEO. It relies on the ZConfig changes in https://code.launchpad.net/~martin-v/zconfig/ipv6/+merge/35944.

On the server side, the major change is the interpretation of listen addresses. '' now indicates wild-card-IPv4-and-IPv6. For wildcard IPv4, 0.0.0.0 needs to be specified (which used to work before as well), for wildcard IPv6, :: must be used. On systems that don't support dual-stack sockets, '' continues to mean 0.0.0.0. To bind ZEO explicitly to an IPv6 address, [addr]:port needs to be used.

On the client side, there are two major changes:

- IPv6 addresses can now be specified, using [addr]:port (or ('addr', port) in the API).

- DNS usage has changed. The client RPC now looks up all addresses, in the order recommended by the operating system (i.e. through getaddrinfo). The resulting list is considered a sublist of the regular fail-over address list, i.e. all addresses are being contacted simultaneously, and the first one connecting is used. This was discussed with Christian Theune at the DZUG sprint.

As tests, the connection tests now include IPv6 versions of all tests.

The only other change to the tests was a doctest which now prints 127.0.0.1 instead of localhost.

To post a comment you must log in.
lp:~martin-v/zodb/ipv6 updated
3957. By Martin v. Löwis

Remove debugging code.

3958. By Martin v. Löwis

Only check for IPPROTO_IPV6 if socket creation succeeded.
Look for AttributeError, not NameError, when checking IPPROTO_IPV6 presence.

Revision history for this message
Jim Fulton (jim-zope) wrote :

> - DNS usage has changed. The client RPC now looks up all addresses, in
> the order recommended by the operating system (i.e. through
> getaddrinfo). The resulting list is considered a sublist of the
> regular fail-over address list, i.e. all addresses are being
> contacted simultaneously, and the first one connecting is used. This
> was discussed with Christian Theune at the DZUG sprint.

What is the rational for this?

Why would a user want this?

Revision history for this message
Jim Fulton (jim-zope) wrote :

I should note that I have limited confidence in the thread-tastic
abstraction-astronomic implementation of the client-storage connection
logic. :) I plan to reimplement it with a simpler event-based approach
and, in the mean time, an leery of asking it to work harder.

Revision history for this message
Jim Fulton (jim-zope) wrote :

I'm fanatical about source lines being less than or equal to 80
characters in length. :)

Revision history for this message
Martin v. Löwis (martin-v) wrote :

Re: DNS. Users currently configure DNS names in zrpc clients to contact ZEO servers, so I guess there is a rationale for that (i.e. users want to use names instead of addresses - in particular with IPv6).

Now, if you allow DNS names, the question is what lookups should you do. The common approach is to look for both AAAA and A, and process them in the order in which the operating system returns them. This is what all client software supporting IPv6 does, so it's also what users expect it to do.

So now that we have one or more IPv6 addresses per name, and one or more IPv4 addresses, which ones should we use? zrpc currently supports connecting to multiple addresses simultaneously, and then taking the one that comes back first. With multiple addresses coming out of DNS, it can speed-up connection establishment when they are tried simultaneously. There is also precedence in other client software doing this, e.g. Apple Safari. As you might have to test each address sequentially, you can just as well do so in parallel.

In addition, it was easier to implement that way. If you think it's undesirable, I can try to come up with a way to do them sequentially.

Revision history for this message
Martin v. Löwis (martin-v) wrote :

Re: line length. Will redo.

Revision history for this message
Jim Fulton (jim-zope) wrote :
Download full text (3.6 KiB)

Meta comment: I'm new to IPv6, so if I ask dumb questions or say dumb
things, please be patient. :)

> Re: DNS. Users currently configure DNS names in zrpc clients to contact ZEO
> servers, so I guess there is a rationale for that (i.e. users want to use
> names instead of addresses - in particular with IPv6).

Yup. +1 on supporting names. :)

> Now, if you allow DNS names, the question is what lookups should you do. The
> common approach is to look for both AAAA and A, and process them in the order
> in which the operating system returns them. This is what all client software
> supporting IPv6 does, so it's also what users expect it to do.

Maybe I'm missinterpreting what you mean by "process".

I'd be surprised is "all client software" tried each address returned.
I would expect most client software to simply use an address in bind
or connect and get watever address is prefered for the type of socket
they created.

> So now that we have one or more IPv6 addresses per name, and one or more IPv4
> addresses, which ones should we use? zrpc currently supports connecting to
> multiple addresses simultaneously, and then taking the one that comes back
> first.

It's slightly more complicated, but yeah. :)

> With multiple addresses coming out of DNS, it can speed-up connection
> establishment when they are tried simultaneously.

I'm not sure what you mean here. But yeah, if you're going to do
multiple things, doing them in parallel is generally a good strategy.

> There is also precedence in
> other client software doing this, e.g. Apple Safari. As you might have to test
> each address sequentially, you can just as well do so in parallel.
>
> In addition, it was easier to implement that way. If you think it's
> undesirable, I can try to come up with a way to do them
> sequentially.

I'm not clear on what was easier to implement.

I'll try to guess. :)

I see a number of possible issues that this might try to solve.

1. Given a host name, you have to decide whether to bind or connect
   using a v4 or v6 socket.

2. If multiple machines have the same host name, maybe you want to
   treat them as a high-availability pool and connect to whichever one
   is providing the desired service.

   Is there any other reason why there would be multiple v4 addresses
   or multiple v6 addresses for the same host name. (Leaving aside a
   host having obe v4 address and one v6 address)?

Are these the problems you're trying to solve?

For 1, it would be just as easy to grab the first result from
getaddrinfo.

BTW, the patch for the server always uses a v4 socket if a host name
is given, but perhaps I don't understand how v6 interacts with bind.

For 2, I can see real benefits in giving multiple redundant servers
the same host name.

What I'm worried about having clients connect to the same server more
than once. There are 2 reasons for this:

1. It becomes ambiguous whether a v4 or v6 socket will be used.

2. As I mentioned earlier, the ZEO client connection logic has issues.
   We use ZRS to provide a primary secondary replication scheme.
   We used to have primaries and secondaries listen on the same port
   and apps that wanted writable connections would eit...

Read more...

Revision history for this message
Jim Fulton (jim-zope) wrote :

How did you see my comments? Did you get email, or did you poll?

I didn't see your replies until I checked back.

Revision history for this message
Martin v. Löwis (martin-v) wrote :
Download full text (5.2 KiB)

> Maybe I'm missinterpreting what you mean by "process".
>
> I'd be surprised is "all client software" tried each address returned.
> I would expect most client software to simply use an address in bind
> or connect and get watever address is prefered for the type of socket
> they created.

With IPv6, it is now common and recommended that each host gets at least
two addresses: one for IPv4 and one for IPv6 (dual stack). In addition,
some systems have multiple IPv6 addresses (e.g. assigned by various
tunneling systems). It's not universally clear that any of these
addresses is better than any other: it depends, in particular, on the
client connectivity (IPv6 available or not, IPv4 available or not).

The new resolver API recommended for use it getaddrinfo(3). It gives you
a list of addrinfo(family, socktype, proto, canonname, addr), mixing
IPv4 and IPv6 addresses. Today, systems have a policy (e.g.
/etc/gai.conf) to determine in which order to return them (e.g. IPv6
global first, then IPv4, then IPv6 tunnel). Applications must not
normally chose for themselves whether they want IPv4 or IPv6
connections, but should let the system decide.

In turn, you can't actually create the socket until getaddrinfo
returns, as it will tell you what socket family to use. Hence
the typically connect code looks like this:

  for family,address in getaddrinfo():
     try:
         s = socket.socket(family)
         s.connect(address, port)
     except socket.error:
         continue
  if not s:
     raise "None of these addresses worked"

The IPv6 server code is entirely different: typically, you either
bind to all addresses (v4 and v6) of a system (preferably using
dual-stack sockets using a wildcard address), or you bind to a (list
of) specifically configured addresses; no DNS involved. When binding
to a list of addresses, you need to create multiple server sockets.
IIUC, ZEO currently doesn't support that (and IMO doesn't need to).

>> With multiple addresses coming out of DNS, it can speed-up connection
>> establishment when they are tried simultaneously.
>
> I'm not sure what you mean here. But yeah, if you're going to do
> multiple things, doing them in parallel is generally a good strategy.

See above: the for loop can run in parallel.

>> In addition, it was easier to implement that way. If you think it's
>> undesirable, I can try to come up with a way to do them
>> sequentially.
>
> I'm not clear on what was easier to implement.
>
> I'll try to guess. :)
>
> I see a number of possible issues that this might try to solve.
>
> 1. Given a host name, you have to decide whether to bind or connect
> using a v4 or v6 socket.

No, you would need to iterate over all getaddrinfo results either way.

> 2. If multiple machines have the same host name, maybe you want to
> treat them as a high-availability pool and connect to whichever one
> is providing the desired service.

That is now possible, but only a side effect. But yes, it was easier
to treat a list of addresses returned from DNS as a high-availability
pool - easier than modifying ConnectWrapper to execute the loop.

> Is there any other reason why there would be multiple v4 addresses
> ...

Read more...

Revision history for this message
Martin v. Löwis (martin-v) wrote :

Am 27.09.2010 19:01, schrieb Jim Fulton:
> How did you see my comments? Did you get email, or did you poll?

I got an email, and then replied over the web.

> I didn't see your replies until I checked back.

Hmm. Did you email-reply? This one has your address in the CC.

Revision history for this message
Jim Fulton (jim-zope) wrote :

On Mon, Sep 27, 2010 at 2:13 PM, "Martin v. Löwis" <martin@v.loewis.de> wrote:
> Am 27.09.2010 19:01, schrieb Jim Fulton:
>> How did you see my comments? Did you get email, or did you poll?
>
> I got an email, and then replied over the web.
>
>> I didn't see your replies until I checked back.
>
> Hmm. Did you email-reply? This one has your address in the CC.

Nope.

<shrug>

Fortunately, I got this one and the previous one via email. :)

Jim

--
Jim Fulton

Revision history for this message
Jim Fulton (jim-zope) wrote :
Download full text (6.9 KiB)

On Mon, Sep 27, 2010 at 2:12 PM, "Martin v. Löwis" <martin@v.loewis.de> wrote:
>> Maybe I'm missinterpreting what you mean by "process".
>>
>> I'd be surprised is "all client software" tried each address returned.
>> I would expect most client software to simply use an address in bind
>> or connect and get watever address is prefered for the type of socket
>> they created.
>
> With IPv6, it is now common and recommended that each host gets at least
> two addresses: one for IPv4 and one for IPv6 (dual stack).

Makes sense.

> In addition,
> some systems have multiple IPv6 addresses (e.g. assigned by various
> tunneling systems).

Hm. Sounds complicated. :)

> It's not universally clear that any of these
> addresses is better than any other: it depends, in particular, on the
> client connectivity (IPv6 available or not, IPv4 available or not).

Hm.

> The new resolver API recommended for use it getaddrinfo(3). It gives you
> a list of addrinfo(family, socktype, proto, canonname, addr), mixing
> IPv4 and IPv6 addresses. Today, systems have a policy (e.g.
> /etc/gai.conf) to determine in which order to return them (e.g. IPv6
> global first, then IPv4, then IPv6 tunnel). Applications must not
> normally chose for themselves whether they want IPv4 or IPv6
> connections, but should let the system decide.
>
> In turn, you can't actually create the socket until getaddrinfo
> returns, as it will tell you what socket family to use. Hence
> the typically connect code looks like this:
>
>  for family,address in getaddrinfo():
>     try:
>         s = socket.socket(family)
>         s.connect(address, port)
>     except socket.error:
>         continue
>  if not s:
>     raise "None of these addresses worked"

I'm hoping there's a missing break or return in there somewhere. :)

> The IPv6 server code is entirely different: typically, you either
> bind to all addresses (v4 and v6) of a system (preferably using
> dual-stack sockets using a wildcard address), or you bind to a (list
> of) specifically configured addresses; no DNS involved.

I wonder why the asymmetry. Or, at least, why it wouldn't at least
make sense to at least listen for both v4 and v6 for the same host name.

> When binding
> to a list of addresses, you need to create multiple server sockets.

OK.

> IIUC, ZEO currently doesn't support that

Right.

> (and IMO doesn't need to).

Not sure wrt IPv6.

I have wanted to be able to listen on both a TCP socket and a
unix-domain socket. There's nothing hard about this for ZEO per se,
but figuring how to spell this in ZConfig schema has been just enough
of a pain to make it not happen. :)

>>> With multiple addresses coming out of DNS, it can speed-up connection
>>> establishment when they are tried simultaneously.
>>
>> I'm not sure what you mean here.  But yeah, if you're going to do
>> multiple things, doing them in parallel is generally a good strategy.
>
> See above: the for loop can run in parallel.
>
>>> In addition, it was easier to implement that way. If you think it's
>>> undesirable, I can try to come up with a way to do them
>>> sequentially.
>>
>> I'm not clear on what was easier to implement.
>>
>> I'll try to guess. :)
>>
>> I see a...

Read more...

Revision history for this message
Martin v. Löwis (martin-v) wrote :

>> The IPv6 server code is entirely different: typically, you either
>> bind to all addresses (v4 and v6) of a system (preferably using
>> dual-stack sockets using a wildcard address), or you bind to a (list
>> of) specifically configured addresses; no DNS involved.
>
> I wonder why the asymmetry. Or, at least, why it wouldn't at least
> make sense to at least listen for both v4 and v6 for the same host name.

It always was asymmetric: you can use a wildcard address on the server,
but not on the client, as a special feature of the socket API.

Some servers support binding to multiple explicit interfaces (e.g.
Apache Listen), but I'm not aware of a precedent that supports
DNS in that part of the configuration, and supports DNS returning
multiple addresses (i.e. expanding them to multiple Listen statements).

> I have wanted to be able to listen on both a TCP socket and a
> unix-domain socket. There's nothing hard about this for ZEO per se,
> but figuring how to spell this in ZConfig schema has been just enough
> of a pain to make it not happen. :)

Ok. So do you want me to change the patch to bind to multiple addresses?

I think StorageServer would need to change, to support multiple
addresses, and also multiple Dispatcher objects.

> I don't mind trying multiple paths (addresses) to do the low-level
> connections, but I'm worried about making multiple connections to the
> same server.

I could try to find out how to prevent that: it should be possible
to keep track what DNS names each connection originated from, and then
close any redundant connections that get connected (assuming zrpc
can deal with connections on which no data gets transmitted).

> I'm good with merging the branch. Do you want to do this (using some
> LP tool)? Or do you want me to?

I would rather see you merge the patch. However, if you want me to
make some modifications first, we can also wait (I won't be able to
work on this really for the next two weeks).

Revision history for this message
Jim Fulton (jim-zope) wrote :

On Mon, Sep 27, 2010 at 3:56 PM, "Martin v. Löwis" <martin@v.loewis.de> wrote:
>>> The IPv6 server code is entirely different: typically, you either
>>> bind to all addresses (v4 and v6) of a system (preferably using
>>> dual-stack sockets using a wildcard address), or you bind to a (list
>>> of) specifically configured addresses; no DNS involved.
>>
>> I wonder why the asymmetry.  Or, at least, why it wouldn't at least
>> make sense to at least listen for both v4 and v6 for the same host name.
>
> It always was asymmetric: you can use a wildcard address on the server,
> but not on the client, as a special feature of the socket API.
>
> Some servers support binding to multiple explicit interfaces (e.g.
> Apache Listen), but I'm not aware of a precedent that supports
> DNS in that part of the configuration, and supports DNS returning
> multiple addresses (i.e. expanding them to multiple Listen statements).
>
>> I have wanted to be able to listen on both a TCP socket and a
>> unix-domain socket.  There's nothing hard about this for ZEO per se,
>> but figuring how to spell this in ZConfig schema has been just enough
>> of a pain to make it not happen. :)
>
> Ok. So do you want me to change the patch to bind to multiple addresses?

No. I was just mentioning that I'd considered adding support for listening
on multiple addresses.

...

>> I don't mind trying multiple paths (addresses) to do the low-level
>> connections, but I'm worried about making multiple connections to the
>> same server.
>
> I could try to find out how to prevent that: it should be possible
> to keep track what DNS names each connection originated from, and then
> close any redundant connections that get connected (assuming zrpc
> can deal with connections on which no data gets transmitted).

Nah. The connection logic is already too complicated.
I plan a major refactoring of it down the road.

>> I'm good with merging the branch.  Do you want to do this (using some
>> LP tool)? Or do you want me to?
>
> I would rather see you merge the patch.

Cool. That seems easier.

> However, if you want me to
> make some modifications first, we can also wait (I won't be able to
> work on this really for the next two weeks).

No, I'm fine with it as it is.

Thanks.

Jim

--
Jim Fulton

Revision history for this message
Jim Fulton (jim-zope) wrote :

Merged to trunk. This will be in ZODB 3.10b7.

review: Approve

Unmerged revisions

3958. By Martin v. Löwis

Only check for IPPROTO_IPV6 if socket creation succeeded.
Look for AttributeError, not NameError, when checking IPPROTO_IPV6 presence.

3957. By Martin v. Löwis

Remove debugging code.

3956. By Martin v. Löwis

Adjust test case to display numeric IP instead of hostname.

3955. By Martin v. Löwis

Add IPv6 support.

Preview Diff

[H/L] Next/Prev Comment, [J/K] Next/Prev File, [N/P] Next/Prev Hunk
=== modified file 'doc/zeo.txt'
--- doc/zeo.txt 2008-01-19 18:53:09 +0000
+++ doc/zeo.txt 2010-09-19 09:56:47 +0000
@@ -164,6 +164,9 @@
164be used to with a system that arranges to provide hot backups of164be used to with a system that arranges to provide hot backups of
165servers in the case of failure.165servers in the case of failure.
166166
167If a single address resolves to multiple IPv4 or IPv6 addresses,
168the client will connect to an arbitrary of these addresses.
169
167Authentication170Authentication
168~~~~~~~~~~~~~~171~~~~~~~~~~~~~~
169172
170173
=== modified file 'src/ZEO/tests/ConnectionTests.py'
--- src/ZEO/tests/ConnectionTests.py 2010-07-11 14:17:01 +0000
+++ src/ZEO/tests/ConnectionTests.py 2010-09-19 09:56:47 +0000
@@ -16,6 +16,7 @@
16import sys16import sys
17import time17import time
18import random18import random
19import socket
19import asyncore20import asyncore
20import threading21import threading
21import logging22import logging
@@ -1197,3 +1198,18 @@
1197 c.close()1198 c.close()
1198 except:1199 except:
1199 pass1200 pass
1201
1202# Run IPv6 tests if V6 sockets are supported
1203try:
1204 socket.socket(socket.AF_INET6, socket.SOCK_STREAM)
1205except (socket.error, AttributeError):
1206 pass
1207else:
1208 class V6Setup:
1209 def _getAddr(self):
1210 return '::1', forker.get_port(self)
1211
1212 _g = globals()
1213 for name, value in _g.items():
1214 if isinstance(value, type) and issubclass(value, CommonSetupTearDown):
1215 _g[name+"V6"] = type(name+"V6", (V6Setup, value), {})
12001216
=== modified file 'src/ZEO/tests/testZEO.py'
--- src/ZEO/tests/testZEO.py 2010-09-16 20:19:20 +0000
+++ src/ZEO/tests/testZEO.py 2010-09-19 09:56:47 +0000
@@ -1148,13 +1148,13 @@
1148 ... # doctest: +ELLIPSIS +NORMALIZE_WHITESPACE1148 ... # doctest: +ELLIPSIS +NORMALIZE_WHITESPACE
1149 ZEO.ClientStorage CRITICAL client1149 ZEO.ClientStorage CRITICAL client
1150 Client has seen newer transactions than server!1150 Client has seen newer transactions than server!
1151 ZEO.zrpc ERROR (...) CW: error in notifyConnected (('localhost', ...))1151 ZEO.zrpc ERROR (...) CW: error in notifyConnected (('127.0.0.1', ...))
1152 Traceback (most recent call last):1152 Traceback (most recent call last):
1153 ...1153 ...
1154 ClientStorageError: client Client has seen newer transactions than server!1154 ClientStorageError: client Client has seen newer transactions than server!
1155 ZEO.ClientStorage CRITICAL client1155 ZEO.ClientStorage CRITICAL client
1156 Client has seen newer transactions than server!1156 Client has seen newer transactions than server!
1157 ZEO.zrpc ERROR (...) CW: error in notifyConnected (('localhost', ...))1157 ZEO.zrpc ERROR (...) CW: error in notifyConnected (('127.0.0.1', ...))
1158 Traceback (most recent call last):1158 Traceback (most recent call last):
1159 ...1159 ...
1160 ClientStorageError: client Client has seen newer transactions than server!1160 ClientStorageError: client Client has seen newer transactions than server!
11611161
=== modified file 'src/ZEO/zrpc/client.py'
--- src/ZEO/zrpc/client.py 2010-09-09 18:38:51 +0000
+++ src/ZEO/zrpc/client.py 2010-09-19 09:56:47 +0000
@@ -188,7 +188,7 @@
188 if (len(addr) == 2188 if (len(addr) == 2
189 and isinstance(addr[0], types.StringType)189 and isinstance(addr[0], types.StringType)
190 and isinstance(addr[1], types.IntType)):190 and isinstance(addr[1], types.IntType)):
191 return socket.AF_INET191 return socket.AF_INET # also denotes IPv6
192192
193 # not anything I know about193 # not anything I know about
194 return None194 return None
@@ -436,10 +436,22 @@
436 del wrappers436 del wrappers
437 return 0437 return 0
438438
439 def _expand_addrlist(self):
440 for domain, (host, port) in self.addrlist:
441 # AF_INET really means either IPv4 or IPv6,
442 # possibly indirected by DNS. By design, DNS lookup is deferred until
443 # connections get established, so that DNS reconfiguration can affect failover
444 if domain == socket.AF_INET:
445 for family, socktype, proto, cannoname, sockaddr in socket.getaddrinfo(host, port):
446 # for IPv6, drop flowinfo, and restrict addresses to [host]:port
447 yield family, sockaddr[:2]
448 else:
449 yield domain, addr
450
439 def _create_wrappers(self):451 def _create_wrappers(self):
440 # Create socket wrappers452 # Create socket wrappers
441 wrappers = {} # keys are active wrappers453 wrappers = {} # keys are active wrappers
442 for domain, addr in self.addrlist:454 for domain, addr in self._expand_addrlist():
443 wrap = ConnectWrapper(domain, addr, self.mgr, self.client)455 wrap = ConnectWrapper(domain, addr, self.mgr, self.client)
444 wrap.connect_procedure()456 wrap.connect_procedure()
445 if wrap.state == "notified":457 if wrap.state == "notified":
446458
=== modified file 'src/ZEO/zrpc/server.py'
--- src/ZEO/zrpc/server.py 2010-06-21 14:33:46 +0000
+++ src/ZEO/zrpc/server.py 2010-09-19 09:56:47 +0000
@@ -15,6 +15,23 @@
15import socket15import socket
16import types16import types
1717
18# _has_dualstack: True if the dual-stack sockets are supported
19try:
20 # Check whether IPv6 sockets can be created
21 s = socket.socket(socket.AF_INET6, socket.SOCK_STREAM)
22except (socket.error, AttributeError):
23 _has_dualstack = False
24else:
25 # Check whether enabling dualstack (disabling v6only) works
26 try:
27 s.setsockopt(socket.IPPROTO_IPV6, socket.IPV6_V6ONLY, False)
28 except (socket.error, AttributeError):
29 _has_dualstack = False
30 else:
31 _has_dualstack = True
32 s.close()
33 del s
34
18from ZEO.zrpc.connection import Connection35from ZEO.zrpc.connection import Connection
19from ZEO.zrpc.log import log36from ZEO.zrpc.log import log
20import ZEO.zrpc.log37import ZEO.zrpc.log
@@ -35,7 +52,18 @@
3552
36 def _open_socket(self):53 def _open_socket(self):
37 if type(self.addr) == types.TupleType:54 if type(self.addr) == types.TupleType:
38 self.create_socket(socket.AF_INET, socket.SOCK_STREAM)55 if self.addr[0] == '' and _has_dualstack:
56 # Wildcard listen on all interfaces, both IPv4 and IPv6 if possible
57 self.create_socket(socket.AF_INET6, socket.SOCK_STREAM)
58 self.socket.setsockopt(socket.IPPROTO_IPV6, socket.IPV6_V6ONLY, False)
59 elif ':' in self.addr[0]:
60 self.create_socket(socket.AF_INET6, socket.SOCK_STREAM)
61 if _has_dualstack:
62 # On Linux, IPV6_V6ONLY is off by default.
63 # If the user explicitly asked for IPv6, don't bind to IPv4
64 self.socket.setsockopt(socket.IPPROTO_IPV6, socket.IPV6_V6ONLY, True)
65 else:
66 self.create_socket(socket.AF_INET, socket.SOCK_STREAM)
39 else:67 else:
40 self.create_socket(socket.AF_UNIX, socket.SOCK_STREAM)68 self.create_socket(socket.AF_UNIX, socket.SOCK_STREAM)
41 self.set_reuse_addr()69 self.set_reuse_addr()
@@ -56,6 +84,9 @@
56 log("accepted failed: %s" % msg)84 log("accepted failed: %s" % msg)
57 return85 return
5886
87 # Drop flow-info from IPv6 addresses
88 addr = addr[:2]
89
59 # We could short-circuit the attempt below in some edge cases90 # We could short-circuit the attempt below in some edge cases
60 # and avoid a log message by checking for addr being None.91 # and avoid a log message by checking for addr being None.
61 # Unfortunately, our test for the code below,92 # Unfortunately, our test for the code below,
6293
=== modified file 'src/ZEO/zrpc/smac.py'
--- src/ZEO/zrpc/smac.py 2010-06-21 14:33:46 +0000
+++ src/ZEO/zrpc/smac.py 2010-09-19 09:56:47 +0000
@@ -120,6 +120,10 @@
120120
121 self.__super_init(sock, map)121 self.__super_init(sock, map)
122122
123 # asyncore overwrites addr with the getpeername result
124 # restore our value
125 self.addr = addr
126
123 def setSessionKey(self, sesskey):127 def setSessionKey(self, sesskey):
124 log("set session key %r" % sesskey)128 log("set session key %r" % sesskey)
125129

Subscribers

People subscribed via source and target branches

to all changes: