Commit 361129da authored by Julien Muchembled's avatar Julien Muchembled

Always kill child processes gracefully

parent 0769f25f
import logging, errno, os, subprocess
import logging, errno, os
from . import utils
here = os.path.realpath(os.path.dirname(__file__))
......@@ -21,7 +21,7 @@ def openvpn(iface, encrypt, *args, **kw):
if not encrypt:
args += '--cipher', 'none'
logging.debug('%r', args)
return subprocess.Popen(args, **kw)
return utils.Popen(args, **kw)
def server(iface, max_clients, dh_path, pipe_fd, port, proto, encrypt, *args, **kw):
......@@ -80,4 +80,4 @@ def router(subnet, hello_interval, table, log_path, state_path, pidfile,
if e.errno != errno.ENOENT:
raise
logging.info('%r', cmd)
return subprocess.Popen(cmd, **kw)
return utils.Popen(cmd, **kw)
import logging, random, socket, subprocess, threading, time
import logging, random, socket, subprocess, time
from collections import deque
from itertools import chain
from . import plib, utils
......@@ -126,21 +126,15 @@ class TunnelManager(object):
self._client_count + self._refresh_count)]:
self._kill(prefix)
def _kill(self, prefix, kill=False):
def _kill(self, prefix):
logging.info('Killing the connection with %u/%u...',
int(prefix, 2), len(prefix))
connection = self._connection_dict.pop(prefix)
self.freeInterface(connection.iface)
p = connection.process
try:
getattr(p, 'kill' if kill else 'terminate')()
connection.process.stop()
except OSError:
pass # we already polled an exited process
else:
t = threading.Timer(5, p.kill)
kill or t.start()
p.wait()
t.cancel()
logging.trace('Connection with %u/%u killed',
int(prefix, 2), len(prefix))
......@@ -280,7 +274,7 @@ class TunnelManager(object):
def killAll(self):
for prefix in self._connection_dict.keys():
self._kill(prefix, True)
self._kill(prefix)
def handleTunnelEvent(self, msg):
try:
......
import argparse, errno, logging, os, shlex
import signal, struct, socket, textwrap, time
import argparse, errno, logging, os, shlex, signal, socket
import struct, subprocess, textwrap, threading, time
from OpenSSL import crypto
logging_levels = logging.WARNING, logging.INFO, logging.DEBUG, 5
......@@ -96,6 +96,17 @@ class ArgParser(argparse.ArgumentParser):
ca /etc/re6stnet/ca.crt""", **kw)
class Popen(subprocess.Popen):
def stop(self):
self.terminate()
t = threading.Timer(5, self.kill)
t.start()
r = self.wait()
t.cancel()
return r
def makedirs(path):
try:
os.makedirs(path)
......
......@@ -214,13 +214,13 @@ def main():
if config.client:
cleanup.append(plib.client('re6stnet', config.client,
config.encrypt, '--ping-restart', str(timeout),
*config.openvpn_args).kill)
*config.openvpn_args).stop)
elif server_tunnels:
required('dh')
for iface, (port, proto) in server_tunnels.iteritems():
cleanup.append(plib.server(iface, config.max_clients,
config.dh, write_pipe, port, proto, config.encrypt,
'--ping-exit', str(timeout), *config.openvpn_args).kill)
'--ping-exit', str(timeout), *config.openvpn_args).stop)
ip('addr', my_ip, 'dev', config.main_interface)
if_rt = ['ip', '-6', 'route', 'del',
......@@ -253,7 +253,7 @@ def main():
os.path.join(config.log, 'babeld.log'),
os.path.join(config.state, 'babeld.state'),
config.babel_pidfile, tunnel_interfaces,
*config.babel_args).terminate)
*config.babel_args).stop)
if config.up:
r = os.system(config.up)
if r:
......
Markdown is supported
0%
or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment