Compare commits

...

3 Commits

Author SHA1 Message Date
fe742c928d firewall.py: don't die if a given sysctl doesn't exist.
Instead, get a list of known sysctls in the interesting prefix (net.inet.ip)
and check if there's an entry in the list for each sysctl we want to change.
If there isn't, then don't try to change it.

This fixes a problem with FreeBSD, which doesn't have
net.inet.ip.scopedroute but also doesn't need it.  Probably also fixes MacOS
10.5, which probably didn't have that either, but I don't know for sure.

Reported by Ed Maste.
2010-10-16 20:11:30 -06:00
10ce1ee5d4 ipfw: use 'delete' instead of 'del' to avoid a warning on freebsd.
'del' is an abbreviation that happened to work because of substring matching
in earlier versions of ipfw, but apparently they're planning to remove the
substring matching eventually.  In any case, 'delete' has always worked, so
there's no downside to using that.

Reported by Ed Maste.
2010-10-05 13:29:12 -04:00
a32305a275 server.py: don't send partial hostwatch lists.
If hostwatch has a lot of stuff to say all at once, it would come in more
than one recv() packet, and server.py would send each packet individually as
a CMD_HOST_LIST message.  Unfortunately, client.py (rightly) expects each
CMD_HOST_LIST message to be complete, ie. a correct sequence of rows.

So now server.py makes sure of this.  If there's a leftover bit (ie. an
unterminated line), it saves it for later.

Bug reported by user "Duke" on the mailing list.
2010-10-04 02:47:43 -07:00
2 changed files with 33 additions and 14 deletions

View File

@ -81,17 +81,19 @@ def ipfw_rule_exists(n):
return found return found
def sysctl_get(name): _oldctls = {}
argv = ['sysctl', '-n', name] def _fill_oldctls(prefix):
argv = ['sysctl', prefix]
p = ssubprocess.Popen(argv, stdout = ssubprocess.PIPE) p = ssubprocess.Popen(argv, stdout = ssubprocess.PIPE)
line = p.stdout.readline() for line in p.stdout:
assert(line[-1] == '\n')
(k,v) = line[:-1].split(': ', 1)
_oldctls[k] = v
rv = p.wait() rv = p.wait()
if rv: if rv:
raise Fatal('%r returned %d' % (argv, rv)) raise Fatal('%r returned %d' % (argv, rv))
if not line: if not line:
raise Fatal('%r returned no data' % (argv,)) raise Fatal('%r returned no data' % (argv,))
assert(line[-1] == '\n')
return line[:-1]
def _sysctl_set(name, val): def _sysctl_set(name, val):
@ -100,11 +102,19 @@ def _sysctl_set(name, val):
rv = ssubprocess.call(argv, stdout = open('/dev/null', 'w')) rv = ssubprocess.call(argv, stdout = open('/dev/null', 'w'))
_oldctls = [] _changedctls = []
def sysctl_set(name, val): def sysctl_set(name, val):
oldval = sysctl_get(name) PREFIX = 'net.inet.ip'
if str(val) != str(oldval): assert(name.startswith(PREFIX + '.'))
_oldctls.append((name, oldval)) val = str(val)
if not _oldctls:
_fill_oldctls(PREFIX)
if not (name in _oldctls):
debug1('>> No such sysctl: %r\n' % name)
return
oldval = _oldctls[name]
if val != oldval:
_changedctls.append(name)
return _sysctl_set(name, val) return _sysctl_set(name, val)
@ -122,10 +132,11 @@ def do_ipfw(port, subnets):
# cleanup any existing rules # cleanup any existing rules
if ipfw_rule_exists(port): if ipfw_rule_exists(port):
ipfw('del', sport) ipfw('delete', sport)
while _oldctls: while _changedctls:
(name,oldval) = _oldctls.pop() name = _changedctls.pop()
oldval = _oldctls[name]
_sysctl_set(name, oldval) _sysctl_set(name, oldval)
if subnets: if subnets:

View File

@ -133,12 +133,20 @@ def main():
mux.send(0, ssnet.CMD_ROUTES, routepkt) mux.send(0, ssnet.CMD_ROUTES, routepkt)
hw = Hostwatch() hw = Hostwatch()
hw.leftover = ''
def hostwatch_ready(): def hostwatch_ready():
assert(hw.pid) assert(hw.pid)
content = hw.sock.recv(4096) content = hw.sock.recv(4096)
if content: if content:
mux.send(0, ssnet.CMD_HOST_LIST, content) lines = (hw.leftover + content).split('\n')
if lines[-1]:
# no terminating newline: entry isn't complete yet!
hw.leftover = lines.pop()
lines.append('')
else:
hw.leftover = ''
mux.send(0, ssnet.CMD_HOST_LIST, '\n'.join(lines))
else: else:
raise Fatal('hostwatch process died') raise Fatal('hostwatch process died')