openwrt/package/network/services/dropbear/files/dropbear.init
Stijn Tintel 1c308bbbf5 dropbear: add option to set receive window size
The default receive window size in dropbear is hardcoded to 24576 byte
to limit memory usage. This value was chosen for 100Mbps networks, and
limits the throughput of scp on faster networks. It also severely limits
scp throughput on high-latency links.

Add an option to set the receive window size so that people can improve
performance without having to recompile dropbear.

Setting the window size to the highest value supported by dropbear
improves throughput from my build machine to an APU2 on the same LAN
from 7MB/s to 7.9MB/s, and to an APU2 over a link with ~65ms latency
from 320KB/s to 7.5MB/s.

Signed-off-by: Stijn Tintel <stijn@linux-ipv6.be>
2018-02-18 02:59:57 +01:00

204 lines
4.7 KiB
Bash
Executable File

#!/bin/sh /etc/rc.common
# Copyright (C) 2006-2010 OpenWrt.org
# Copyright (C) 2006 Carlos Sobrinho
START=50
STOP=50
USE_PROCD=1
PROG=/usr/sbin/dropbear
NAME=dropbear
PIDCOUNT=0
EXTRA_COMMANDS="killclients"
EXTRA_HELP=" killclients Kill ${NAME} processes except servers and yourself"
append_ports()
{
local ipaddrs="$1"
local port="$2"
[ -z "$ipaddrs" ] && {
procd_append_param command -p "$port"
return
}
for addr in $ipaddrs; do
procd_append_param command -p "$addr:$port"
done
}
validate_section_dropbear()
{
uci_validate_section dropbear dropbear "${1}" \
'PasswordAuth:bool:1' \
'enable:bool:1' \
'Interface:string' \
'GatewayPorts:bool:0' \
'RootPasswordAuth:bool:1' \
'RootLogin:bool:1' \
'rsakeyfile:file' \
'BannerFile:file' \
'Port:list(port):22' \
'SSHKeepAlive:uinteger:300' \
'IdleTimeout:uinteger:0' \
'MaxAuthTries:uinteger:3' \
'RecvWindowSize:uinteger:0' \
'mdns:bool:1'
}
dropbear_instance()
{
local PasswordAuth enable Interface GatewayPorts \
RootPasswordAuth RootLogin rsakeyfile \
BannerFile Port SSHKeepAlive IdleTimeout \
MaxAuthTries RecvWindowSize mdns ipaddrs
validate_section_dropbear "${1}" || {
echo "validation failed"
return 1
}
[ -n "${Interface}" ] && {
network_get_ipaddrs_all ipaddrs "${Interface}" || {
echo "interface ${Interface} has no physdev or physdev has no suitable ip"
return 1
}
}
[ "${enable}" = "0" ] && return 1
PIDCOUNT="$(( ${PIDCOUNT} + 1))"
local pid_file="/var/run/${NAME}.${PIDCOUNT}.pid"
procd_open_instance
procd_set_param command "$PROG" -F -P "$pid_file"
[ "${PasswordAuth}" -eq 0 ] && procd_append_param command -s
[ "${GatewayPorts}" -eq 1 ] && procd_append_param command -a
[ "${RootPasswordAuth}" -eq 0 ] && procd_append_param command -g
[ "${RootLogin}" -eq 0 ] && procd_append_param command -w
[ -n "${rsakeyfile}" ] && procd_append_param command -r "${rsakeyfile}"
[ -n "${BannerFile}" ] && procd_append_param command -b "${BannerFile}"
append_ports "${ipaddrs}" "${Port}"
[ "${IdleTimeout}" -ne 0 ] && procd_append_param command -I "${IdleTimeout}"
[ "${SSHKeepAlive}" -ne 0 ] && procd_append_param command -K "${SSHKeepAlive}"
[ "${MaxAuthTries}" -ne 0 ] && procd_append_param command -T "${MaxAuthTries}"
[ "${RecvWindowSize}" -gt 0 -a "${RecvWindowSize}" -le 1048576 ] && \
procd_append_param command -W "${RecvWindowSize}"
[ "${mdns}" -ne 0 ] && procd_add_mdns "ssh" "tcp" "$Port" "daemon=dropbear"
procd_set_param respawn
procd_close_instance
}
keygen()
{
for keytype in rsa; do
# check for keys
key=dropbear/dropbear_${keytype}_host_key
[ -f /tmp/$key -o -s /etc/$key ] || {
# generate missing keys
mkdir -p /tmp/dropbear
[ -x /usr/bin/dropbearkey ] && {
/usr/bin/dropbearkey -t $keytype -f /tmp/$key 2>&- >&- && exec /etc/rc.common "$initscript" start
} &
exit 0
}
done
lock /tmp/.switch2jffs
mkdir -p /etc/dropbear
mv /tmp/dropbear/dropbear_* /etc/dropbear/
lock -u /tmp/.switch2jffs
chown root /etc/dropbear
chmod 0700 /etc/dropbear
}
load_interfaces()
{
config_get interface "$1" Interface
config_get enable "$1" enable 1
[ "${enable}" = "1" ] && interfaces=" ${interface} ${interfaces}"
}
start_service()
{
[ -s /etc/dropbear/dropbear_rsa_host_key ] || keygen
. /lib/functions.sh
. /lib/functions/network.sh
config_load "${NAME}"
config_foreach dropbear_instance dropbear
}
service_triggers()
{
local interfaces
procd_add_config_trigger "config.change" "dropbear" /etc/init.d/dropbear reload
config_load "${NAME}"
config_foreach load_interfaces dropbear
[ -n "${interfaces}" ] && {
for n in $interfaces ; do
procd_add_interface_trigger "interface.*" $n /etc/init.d/dropbear reload
done
}
procd_add_validation validate_section_dropbear
}
killclients()
{
local ignore=''
local server
local pid
# 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 client connection
grep -F -q -e "${PROG}" "/proc/${pid}/cmdline" && {
append ignore "${pid}"
break
}
done
# 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, otherwise process next pid
grep -F -q -e "${PROG}" "/proc/${pid}/cmdline" || {
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
[ "${skip}" -ne 0 ] && continue
# kill process
echo "${initscript}: Killing ${pid}..."
kill -KILL ${pid}
done
}