[package] allow restarting of server process only and add a killcients
authorFlorian Fainelli <florian@openwrt.org>
Mon, 23 Nov 2009 18:03:30 +0000 (18:03 +0000)
committerFlorian Fainelli <florian@openwrt.org>
Mon, 23 Nov 2009 18:03:30 +0000 (18:03 +0000)
function (#6027)

SVN-Revision: 18499

net/sslh/Makefile
net/sslh/files/sslh.init
net/sslh/patches/002-fork_fix.patch [new file with mode: 0644]

index a5052f74c010f8c57635d7b0648ce9f5fd31fbd0..15d26bfa9b6013985440d72fbeab4680b5342612 100644 (file)
@@ -9,7 +9,7 @@ include $(TOPDIR)/rules.mk
 
 PKG_NAME:=sslh
 PKG_VERSION:=1.6i
-PKG_RELEASE:=2
+PKG_RELEASE:=3
 
 PKG_SOURCE:=$(PKG_NAME)-$(PKG_VERSION).tar.gz
 PKG_SOURCE_URL:=http://rutschle.net/tech/
index 56b7d22606be9276afd4a382384181e7f047f5b4..b4b9e5afcc304191965a644976383bff9d531a92 100644 (file)
@@ -5,6 +5,8 @@ NAME=sslh
 PROG=/usr/sbin/sslh
 START=95
 PIDCOUNT=0
+EXTRA_COMMANDS="killclients"
+EXTRA_HELP="   killclients Kill ${NAME} processes except servers and yourself"
 
 sslh_start()
 {
@@ -23,23 +25,23 @@ sslh_start()
        local val
        # A) listen parameter
        config_get val "${section}" listen
-       [ ! -z "${val}" ] && append args "-p ${val}"
+       [ -n "${val}" ] && append args "-p ${val}"
        # B) ssh parameter
        config_get val "${section}" ssh
-       [ ! -z "${val}" ] && append args "-s ${val}"
+       [ -n "${val}" ] && append args "-s ${val}"
        # C) ssl parameter
        config_get val "${section}" ssl
-       [ ! -z "${val}" ] && append args "-l ${val}"
+       [ -n "${val}" ] && append args "-l ${val}"
        # D) timeout (for ssh, then ssl is assumed)
        config_get val "${section}" timeout
-       [ ! -z "${val}" ] && append args "-t ${val}"
+       [ -n "${val}" ] && append args "-t ${val}"
        # E) verbose parameter
        local verbosed
        config_get_bool verbosed "${section}" verbose 0
        [ "${verbosed}" -ne 0 ] && append args "-v"
 
        # execute program and return its exit code
-       [ "${verbosed}" -ne 0 ] && echo "${NAME}: section ${section} starting ${PROG} ${args}"
+       [ "${verbosed}" -ne 0 ] && echo "${initscript}: section ${section} started via ${PROG} ${args}"
        ${PROG} ${args}
        return $?
 }
@@ -55,27 +57,88 @@ stop()
        local pidfile
        local rc=0
 
-       # killing all known processes
+       # killing all server processes
        for pidfile in `ls /var/run/${NAME}.*.pid`
         do
-               start-stop-daemon -K -s KILL -p "${pidfile}" -n "${NAME}"
+               start-stop-daemon -K -s KILL -p "${pidfile}" -n "${NAME}" >/dev/null
                [ $? -ne 0 ] && rc=1
                rm -f "${pidfile}"
        done
+       [ -z "${pidfile}" ] && echo "${initscript}: no pid files, if you get problems with start then try killclients"
+       [ ${rc} -ne 0 ] && echo "${initscript}: inconsistency in pid files, if you get problems with start then try killclients"
+}
 
-       # kill orphaned processes
-       if [ ${rc} -ne 0 ]
-        then
-               echo "${NAME}: inconsistency in pid files killing all orphaned processes"
-               for pid in `pidof sslh`
-                do
-                       # check if correct program
-                       ps | grep "${pid}" | grep "${PROG}" >/dev/null
-                       [ $? -ne 0 ] && continue
+killclients()
+{
+       local ignore=''
+       local server
+       local pid
+       local connection
+       local proto
+       local address
+
+       # if this script is run from inside a client session, then ignore that session
+       pid="$$"
+       while [ "${pid}" -ne 0 ]
+        do
+               # get parent process id
+               pid=`cut -d ' ' -f 4 "/proc/${pid}/stat"`
+               [ "${pid}" -eq 0 ] && break
+
+               # check if pid is connected to a client connection
+               # a) get established connection for pid
+               connection=`netstat -tupn 2>/dev/null | sed "s/[ ]\+/ /g" | grep -e "ESTABLISHED ${pid}/"`
+               [ -z "${connection}" ] && continue
+               #    get connection details for foreign address
+               proto=`echo ${connection} | cut -d ' ' -f 1`
+               address=`echo ${connection} | cut -d ' ' -f 5`
+
+               # b) get pid for foreign address, only possible if foreign address is from this machine itself
+               connection=`netstat -tupn 2>/dev/null | sed "s/[ ]\+/ /g" | grep -e "^${proto}.*${address}.*ESTABLISHED.*/${NAME}"`
+               [ -z "${connection}" ] && continue
+               #    check that the local address (field 4) corresponds to the foreign address of the previous connection
+               server=`echo ${connection} | cut -d ' ' -f 4`
+               [ "${server}" != "${address}" ] && continue
+               #    get pid from connection
+               server=`echo ${connection} | cut -d ' ' -f 7 | cut -d '/' -f 1`
+
+               # check if client connection
+               ps | grep -e "^[ ]*${server} " | grep -e "${PROG}" >/dev/null
+               if [ $? -eq 0 ]
+                then
+                       append ignore "${server}"
+                       break
+               fi
+       done
 
-                       # kill process
-                       echo "Killing ${pid}..."
-                       kill -s KILL ${pid}
+       # get all server pids that should be ignored
+       for server in `cat /var/run/${NAME}.*.pid`
+        do
+               append ignore "${server}"
+       done
+
+       # get all running pids and kill client connections
+       local skip
+       for pid in `pidof "${NAME}"`
+        do
+               # check if correct program
+               ps | grep -e "^[ ]*${pid} " | grep -e "${PROG}" >/dev/null
+               [ $? -ne 0 ] && continue
+
+               # check if pid should be ignored (servers, ourself)
+               skip=0
+               for server in ${ignore}
+                do
+                       if [ "${pid}" == "${server}" ]
+                        then
+                               skip=1
+                               break
+                       fi
                done
-       fi
+               [ "${skip}" -ne 0 ] && continue
+
+               # kill process
+               echo "${initscript}: Killing ${pid}..."
+               kill -KILL ${pid}
+       done
 }
diff --git a/net/sslh/patches/002-fork_fix.patch b/net/sslh/patches/002-fork_fix.patch
new file mode 100644 (file)
index 0000000..f404a79
--- /dev/null
@@ -0,0 +1,10 @@
+--- a/sslh.c
++++ b/sslh.c
+@@ -469,6 +469,7 @@
+       if (!fork())
+       {
++         close(listen_socket);
+          start_shoveler(in_socket);
+          exit(0);
+       }