summary |
shortlog |
log |
commit | commitdiff |
tree
raw |
patch |
inline | side by side (from parent 1:
a59afe0)
A number of relatively simple changes, with no overall functional change
except for a few diagnostic messages.
* Attach the address-family code and a name string to the
`InetAddress' class. This will mean that we can add new address
families without breaking things.
* Make `testaddrs' (and related variables) be a dictionary, mapping
address families to addresses, rather than just a lone address.
* Ensure that the networks in a peer assignment belong to the same
family. They will do for now, because there's only one.
* Have `kickpeers' maintain a local IP address for each family, rather
than just a single one.
### Address manipulation.
class InetAddress (object):
### Address manipulation.
class InetAddress (object):
+ AF = S.AF_INET
+ AFNAME = 'IPv4'
def __init__(me, addrstr, maskstr = None):
me.addr = me._addrstr_to_int(addrstr)
if maskstr is None:
def __init__(me, addrstr, maskstr = None):
me.addr = me._addrstr_to_int(addrstr)
if maskstr is None:
## this service are largely going to be satellite notes, I don't think
## scalability's going to be a problem.
## this service are largely going to be satellite notes, I don't think
## scalability's going to be a problem.
-TESTADDR = InetAddress('1.2.3.4')
+TESTADDRS = [InetAddress('1.2.3.4')]
CONFSYNTAX = [
('COMMENT', RX.compile(r'^\s*($|[;#])')),
CONFSYNTAX = [
('COMMENT', RX.compile(r'^\s*($|[;#])')),
if T._debug: print '# reread config'
## Initial state.
if T._debug: print '# reread config'
## Initial state.
groups = {}
grpname = None
grplist = []
groups = {}
grpname = None
grplist = []
raise ConfigError(me._file, lno,
"invalid IP address `%s': %s" %
(astr, e))
raise ConfigError(me._file, lno,
"invalid IP address `%s': %s" %
(astr, e))
- if testaddr is not None:
- raise ConfigError(me._file, lno, 'duplicate test-address')
- testaddr = a
+ if a.AF in testaddrs:
+ raise ConfigError(me._file, lno,
+ 'duplicate %s test-address' % a.AFNAME)
+ testaddrs[a.AF] = a
else:
raise ConfigError(me._file, lno,
"unknown global option `%s'" % name)
else:
raise ConfigError(me._file, lno,
"unknown global option `%s'" % name)
## Check for an explicit target address.
if i >= len(spec) or spec[i].find('/') >= 0:
peer = None
## Check for an explicit target address.
if i >= len(spec) or spec[i].find('/') >= 0:
peer = None
else:
try:
peer = parse_address(spec[i])
else:
try:
peer = parse_address(spec[i])
raise ConfigError(me._file, lno,
"invalid IP address `%s': %s" %
(spec[i], e))
raise ConfigError(me._file, lno,
"invalid IP address `%s': %s" %
(spec[i], e))
i += 1
## Parse the list of local networks.
i += 1
## Parse the list of local networks.
if not nets:
raise ConfigError(me._file, lno, 'no networks defined')
if not nets:
raise ConfigError(me._file, lno, 'no networks defined')
+ ## Make sure that the addresses are consistent.
+ for net in nets:
+ if af is None:
+ af = net.AF
+ elif net.AF != af:
+ raise ConfigError(me._file, lno,
+ "net %s doesn't match" % net)
+
## Add this entry to the list.
grplist.append((name, peer, nets))
## Add this entry to the list.
grplist.append((name, peer, nets))
- ## Fill in the default test address if necessary.
- if testaddr is None: testaddr = TESTADDR
+ ## Fill in the default test addresses if necessary.
+ for a in TESTADDRS: testaddrs.setdefault(a.AF, a)
## Done.
if grpname is not None: groups[grpname] = grplist
## Done.
if grpname is not None: groups[grpname] = grplist
+ me.testaddrs = testaddrs
me.groups = groups
### This will be a configuration file.
CF = None
def cmd_showconfig():
me.groups = groups
### This will be a configuration file.
CF = None
def cmd_showconfig():
- T.svcinfo('test-addr=%s' % CF.testaddr)
+ T.svcinfo('test-addr=%s' %
+ ' '.join(str(a)
+ for a in sorted(CF.testaddrs.itervalues(),
+ key = lambda a: a.AFNAME)))
def cmd_showgroups():
for g in sorted(CF.groups.iterkeys()):
T.svcinfo(g)
def cmd_showgroups():
for g in sorted(CF.groups.iterkeys()):
T.svcinfo(g)
"""
Return the local IP address used for talking to PEER.
"""
"""
Return the local IP address used for talking to PEER.
"""
- sk = S.socket(S.AF_INET, S.SOCK_DGRAM)
+ sk = S.socket(peer.AF, S.SOCK_DGRAM)
try:
try:
sk.connect(peer.sockaddr(1))
addr = sk.getsockname()
try:
try:
sk.connect(peer.sockaddr(1))
addr = sk.getsockname()
- return InetAddress.from_sockaddr(addr)[0]
+ return type(peer).from_sockaddr(addr)[0]
except S.error:
return None
finally:
except S.error:
return None
finally:
## Find the current list of peers.
peers = SM.list()
## Find the current list of peers.
peers = SM.list()
- ## Work out the primary IP address.
+ ## Work out the primary IP addresses.
+ locals = {}
- addr = localaddr(CF.testaddr)
- if addr is None:
- upness = False
- else:
- addr = None
+ for af, remote in CF.testaddrs.iteritems():
+ local = localaddr(remote)
+ if local is not None: locals[af] = local
+ if not locals: upness = False
- elif addr: print '# local address = %s' % straddr(addr)
- else: print '# offline'
+ elif not locals: print '# offline'
+ else:
+ for local in locals.itervalues():
+ print '# local %s address = %s' % (local.AFNAME, local)
## Now decide what to do.
changes = []
## Now decide what to do.
changes = []
want = None
matchp = False
for t, p, nn in pp:
want = None
matchp = False
for t, p, nn in pp:
- if p is None or not upness: ip = addr
+ af = nn[0].AF
+ if p is None or not upness: ip = locals.get(af)
else: ip = localaddr(p)
if T._debug:
info = 'peer = %s; target = %s; nets = %s; local = %s' % (
else: ip = localaddr(p)
if T._debug:
info = 'peer = %s; target = %s; nets = %s; local = %s' % (