rc: transmission.c: rewrite transmission FW rules and watchdog script

- avoid problems while starting/stopping in the GUI (and also in other cases)
- use chain_in_accept as ACCEPT string (for log, if enabled)
- remove FW rules if start of transmission daemon failed
- some other fixes
arm-master
pedro 3 years ago
parent 4360bb8527
commit 069770f5e3

@ -1318,8 +1318,7 @@ static const nvset_t nvset_list[] = {
{ "bt_blocklist", V_01 },
{ "bt_blocklist_url", V_LENGTH(0, 80) },
{ "bt_sleep", V_RANGE(1, 60) },
{ "bt_check", V_01 },
{ "bt_check_time", V_RANGE(1, 55) },
{ "bt_check_time", V_RANGE(0, 55) },
{ "bt_dl_queue_enable", V_01 },
{ "bt_dl_queue_size", V_RANGE(1, 30) },
{ "bt_ul_queue_enable", V_01 },

@ -142,11 +142,6 @@ endif
# system info
install -m 0700 sysinfo $(INSTALLDIR)/usr/sbin
# BTGUI
ifeq ($(TCONFIG_BT),y)
install -m 0755 btcheck $(INSTALLDIR)/usr/bin
endif
# network discovery script for status-devices page
ifeq ($(or $(TCONFIG_BCMARM),$(TCONFIG_MIPSR2)),y)
install -m 0755 discovery.sh $(INSTALLDIR)/usr/sbin

@ -1,37 +0,0 @@
#!/bin/sh
# Script for checking/adding transmission to cron
BTON=$(nvram get bt_enable)
BTCH=$(nvram get bt_check)
case "$1" in
addcru)
ISCRU=$(cru l | grep btinside | wc -l)
INTERVAL=$(nvram get bt_check_time)
[ "$BTON" -eq 1 ] && {
[ "$BTCH" -eq 1 ] && {
[ "$ISCRU" -eq 0 ] && {
cru a btinside "*/$INTERVAL * * * * /usr/bin/btcheck check"
} || {
cru d btinside
cru a btinside "*/$INTERVAL * * * * /usr/bin/btcheck check"
}
} || {
[ "$ISCRU" -eq 1 ] && cru d btinside
}
} || {
[ "$ISCRU" -eq 1 ] && cru d btinside
}
;;
check)
[ "$BTON" -eq 1 -a "$BTCH" -eq 1 -a "$(nvram get g_upgrade)" != "1" -a "$(nvram get g_reboot)" != "1" ] && {
pidof transmission-daemon >/dev/null || {
logger -t btcheck "Transmission stopped? Starting..."
service bittorrent restart
}
}
;;
esac
exit 0

@ -1048,12 +1048,6 @@ static void nat_table(void)
ipt_write("-A WANPREROUTING -p tcp --dport %s -j DNAT --to-destination %s\n", nvram_safe_get("ftp_port"), lanaddr[0]);
#endif
#ifdef TCONFIG_BT
/* BT Client ports from WAN interface */
if (nvram_get_int("bt_enable") && nvram_match("bt_rpc_wan", "1"))
ipt_write("-A WANPREROUTING -p tcp --dport %s -j DNAT --to-destination %s\n", nvram_safe_get("bt_port_gui"), lanaddr[0]);
#endif
if (wanup || wan2up
#ifdef TCONFIG_MULTIWAN
|| wan3up || wan4up
@ -1334,15 +1328,6 @@ static void filter_input(void)
if (nvram_invmatch("dr_wan_rx", "0"))
ipt_write("-A INPUT -p udp --dport 520 -j ACCEPT\n");
#ifdef TCONFIG_BT
/* BT Client ports from WAN interface */
if (nvram_match("bt_enable", "1")) {
ipt_write("-A INPUT -p tcp --dport %s -j ACCEPT\n", nvram_safe_get("bt_port"));
if (nvram_match("bt_rpc_wan", "1"))
ipt_write("-A INPUT -p tcp --dport %s -j ACCEPT\n", nvram_safe_get("bt_port_gui"));
}
#endif
#ifdef TCONFIG_PPTPD
/* Add for pptp server */
if (nvram_match("pptpd_enable", "1"))
@ -2230,6 +2215,11 @@ int start_firewall(void)
run_nginx_firewall_script();
#endif
#ifdef TCONFIG_BT
/* Open BT port/GUI WAN access */
run_bt_firewall_script();
#endif
#ifdef TCONFIG_OPENVPN
run_ovpn_firewall_scripts();
#endif

@ -522,6 +522,7 @@ extern int nvram_nvram2file(const char *name, const char *filename);
#ifdef TCONFIG_BT
extern void start_bittorrent(int force);
extern void stop_bittorrent(void);
extern void run_bt_firewall_script(void);
#endif
/* nfs.c */

@ -3567,8 +3567,6 @@ TOP:
#ifdef TCONFIG_BT
if ((strcmp(service, "bittorrent") == 0) || (strcmp(service, "transmission") == 0) || (strcmp(service, "transmission_da") == 0)) {
if (act_stop) stop_bittorrent();
stop_firewall();
start_firewall(); /* always restarted */
if (act_start) start_bittorrent(1); /* force (re)start */
goto CLEAR;
}

@ -14,15 +14,68 @@
#define tr_dir "/etc/transmission"
#define tr_settings tr_dir"/settings.json"
#define tr_fw_script tr_dir"/tr-fw.sh"
#define tr_fw_del_script tr_dir"/tr-clear-fw-tmp.sh"
#define tr_child_pid tr_dir"/child.pid"
/* needed by logmsg() */
#define LOGMSG_DISABLE DISABLE_SYSLOG_OSM
#define LOGMSG_NVDEBUG "transmission_debug"
static int rmem_max = 0;
static int wmem_max = 0;
static pid_t pidof_child = 0;
static void setup_tr_watchdog(void)
{
FILE *fp;
char buffer[64], buffer2[64];
int nvi;
if ((nvi = nvram_get_int("bt_check_time")) > 0) {
memset(buffer, 0, sizeof(buffer));
snprintf(buffer, sizeof(buffer), tr_dir"/watchdog.sh");
if ((fp = fopen(buffer, "w"))) {
fprintf(fp, "#!/bin/sh\n"
"[ -z \"$(pidof transmission-daemon)\" -a \"$(nvram get g_upgrade)\" != \"1\" -a \"$(nvram get g_reboot)\" != \"1\" ] && {\n"
" logger -t transmission-watchdog transmission-daemon stopped? Starting...\n"
" service bittorrent restart\n"
"}\n");
fclose(fp);
chmod(buffer, (S_IRUSR | S_IWUSR | S_IXUSR));
memset(buffer2, 0, sizeof(buffer2));
snprintf(buffer2, sizeof(buffer2), "*/%d * * * * %s", nvi, buffer);
eval("cru", "a", "CheckTransmission", buffer2);
}
}
}
static void build_tr_firewall(void)
{
FILE *p;
/* create firewall script */
if (!(p = fopen(tr_fw_script, "w"))) {
perror(tr_fw_script);
return;
}
chains_log_detection();
/* open BT port */
fprintf(p, "#!/bin/sh\n"
"iptables -A INPUT -p tcp --dport %s -j %s\n",
nvram_safe_get("bt_port"), chain_in_accept);
/* GUI WAN access */
if (nvram_get_int("bt_rpc_wan"))
fprintf(p, "iptables -A INPUT -p tcp --dport %s -j %s\n"
"iptables -t nat -A WANPREROUTING -p tcp --dport %s -j DNAT --to-destination %s\n", /* nat table */
nvram_safe_get("bt_port_gui"), chain_in_accept,
nvram_safe_get("bt_port_gui"), nvram_safe_get("lan_ipaddr"));
fclose(p);
chmod(tr_fw_script, 0744);
}
void start_bittorrent(int force)
{
@ -31,6 +84,7 @@ void start_bittorrent(int force)
char *whitelistEnabled;
char buf[256], buf2[64];
int n;
pid_t pidof_child = 0;
/* only if enabled or forced */
if (!nvram_get_int("bt_enable") && force == 0)
@ -39,8 +93,9 @@ void start_bittorrent(int force)
if (serialize_restart("transmission-da", 1))
return;
if (pidof_child > 0) { /* fork is still up */
logmsg(LOG_WARNING, "*** %s: another process (PID: %d) still up, aborting ...", __FUNCTION__, pidof_child);
memset(buf2, 0, sizeof(buf2));
if (f_read_string(tr_child_pid, buf2, sizeof(buf2)) > 0 && atoi(buf2) > 0 && ppid(atoi(buf2)) > 0) { /* fork is still up */
logmsg(LOG_WARNING, "%s: another process (PID: %s) still up, aborting ...", __FUNCTION__, buf2);
return;
}
@ -68,7 +123,7 @@ void start_bittorrent(int force)
if (nvram_match("bt_binary", "internal")) { pn = "/usr/bin"; }
else if (nvram_match("bt_binary", "optware") ) { pn = "/opt/bin"; }
else { pn = nvram_safe_get( "bt_binary_custom"); }
else { pn = nvram_safe_get("bt_binary_custom"); }
if (nvram_get_int("bt_auth")) {
pl = "true";
@ -169,21 +224,8 @@ void start_bittorrent(int force)
chmod(tr_settings, 0644);
/* backup original buffers values */
if (rmem_max == 0) {
memset(buf, 0, sizeof(buf));
f_read_string("/proc/sys/net/core/rmem_max", buf, sizeof(buf));
rmem_max = atoi(buf);
}
if (wmem_max == 0) {
memset(buf, 0, sizeof(buf));
f_read_string("/proc/sys/net/core/wmem_max", buf, sizeof(buf));
wmem_max = atoi(buf);
}
/* tune buffers */
f_write_procsysnet("core/rmem_max", "4194304");
f_write_procsysnet("core/wmem_max", "2080768");
/* create firewall script */
build_tr_firewall();
/* fork new process */
if (fork() != 0)
@ -191,6 +233,15 @@ void start_bittorrent(int force)
pidof_child = getpid();
/* write child pid to a file */
memset(buf2, 0, sizeof(buf2));
snprintf(buf2, sizeof(buf2), "%d", pidof_child);
f_write_string(tr_child_pid, buf2, 0, 0);
/* tune buffers */
f_write_procsysnet("core/rmem_max", "4194304");
f_write_procsysnet("core/wmem_max", "2080768");
/* wait a given time for partition to be mounted, etc */
n = atoi(nvram_safe_get("bt_sleep"));
if (n > 0)
@ -232,6 +283,8 @@ void start_bittorrent(int force)
system(buf);
}
run_bt_firewall_script();
memset(buf2, 0, sizeof(buf2));
if (nvram_get_int("bt_log"))
snprintf(buf2, sizeof(buf2), "-e %s/transmission.log", nvram_safe_get("bt_log_path"));
@ -245,15 +298,17 @@ void start_bittorrent(int force)
system(buf);
sleep(1);
if (pidof("transmission-da") > 0)
if (pidof("transmission-da") > 0) {
logmsg(LOG_INFO, "transmission-daemon started");
else
logmsg(LOG_ERR, "starting transmission-daemon failed ...");
sleep(2);
eval("/usr/bin/btcheck", "addcru");
pidof_child = 0; /* reset pid */
setup_tr_watchdog();
f_write_string(tr_child_pid, "0", 0, 0);
}
else {
logmsg(LOG_ERR, "starting transmission-daemon failed - check configuration ...");
f_write_string(tr_child_pid, "0", 0, 0);
stop_bittorrent();
}
/* terminate the child */
exit(0);
@ -263,19 +318,28 @@ void stop_bittorrent(void)
{
pid_t pid;
char buf[16];
int n = 10;
int n = 10, m = atoi(nvram_safe_get("bt_sleep")) + 10;
if (serialize_restart("transmission-da", 0))
return;
/* wait for child of start_bittorrent to finish (if any) */
memset(buf, 0, sizeof(buf));
while (f_read_string(tr_child_pid, buf, sizeof(buf)) > 0 && atoi(buf) > 0 && ppid(atoi(buf)) > 0 && (m-- > 0)) {
logmsg(LOG_DEBUG, "*** %s: waiting for child process of start_bittorrent to end, %d secs left ...", __FUNCTION__, m);
sleep(1);
}
eval("cru", "d", "CheckTransmission");
if (pidof("transmission-da") > 0) {
logmsg(LOG_INFO, "Terminating transmission-daemon ...");
logmsg(LOG_INFO, "terminating transmission-daemon ...");
killall_tk_period_wait("transmission-da", 50);
sleep(1);
while ((pid = pidof("transmission-da")) > 0 && (n-- > 0)) {
logmsg(LOG_WARNING, "Killing transmission-daemon ...");
/* Reap the zombie if it has terminated */
logmsg(LOG_WARNING, "killing transmission-daemon ...");
/* reap the zombie if it has terminated */
waitpid(pid, NULL, WNOHANG);
sleep(1);
}
@ -283,16 +347,35 @@ void stop_bittorrent(void)
if (n < 10)
logmsg(LOG_WARNING, "transmission-daemon forcefully stopped");
else
logmsg(LOG_INFO, "transmission-daemon successfully stopped");
logmsg(LOG_INFO, "transmission-daemon stopped");
}
/* restore buffers */
run_del_firewall_script(tr_fw_script, tr_fw_del_script);
/* restore default buffers */
memset(buf, 0, sizeof(buf));
snprintf(buf, sizeof(buf), "%d", rmem_max);
if (f_read_string("/proc/sys/net/core/rmem_default", buf, sizeof(buf)) > 0 && atoi(buf) > 0);
f_write_procsysnet("core/rmem_max", buf);
memset(buf, 0, sizeof(buf));
snprintf(buf, sizeof(buf), "%d", wmem_max);
if (f_read_string("/proc/sys/net/core/wmem_default", buf, sizeof(buf)) > 0 && atoi(buf) > 0);
f_write_procsysnet("core/wmem_max", buf);
eval("/usr/bin/btcheck", "addcru");
/* clean-up */
system("/bin/rm -rf "tr_dir);
}
void run_bt_firewall_script(void)
{
FILE *fp;
/* first remove existing firewall rule(s) */
run_del_firewall_script(tr_fw_script, tr_fw_del_script);
/* then (re-)add firewall rule(s) */
if ((fp = fopen(tr_fw_script, "r"))) {
fclose(fp);
logmsg(LOG_DEBUG, "*** %s: running firewall script: %s", __FUNCTION__, tr_fw_script);
eval(tr_fw_script);
}
}

@ -1473,7 +1473,6 @@ struct nvram_tuple router_defaults[] = {
{ "bt_blocklist", "0" , 0 },
{ "bt_blocklist_url", "http://list.iblocklist.com/?list=bt_level1" , 0 },
{ "bt_sleep", "10" , 0 },
{ "bt_check", "1" , 0 },
{ "bt_check_time", "15" , 0 },
{ "bt_dl_queue_enable", "0" , 0 },
{ "bt_dl_queue_size", "5" , 0 },

@ -19,7 +19,7 @@
<script>
// <% nvram("bt_enable,bt_binary,bt_binary_custom,bt_custom,bt_port,bt_dir,bt_settings,bt_settings_custom,bt_incomplete,bt_autoadd,bt_rpc_enable,bt_rpc_wan,bt_auth,bt_login,bt_password,bt_port_gui,bt_dl_enable,bt_dl,bt_ul_enable,bt_ul,bt_peer_limit_global,bt_peer_limit_per_torrent,bt_ul_slot_per_torrent,bt_ratio_enable,bt_ratio,bt_ratio_idle_enable,bt_ratio_idle,bt_dht,bt_pex,bt_lpd,bt_utp,bt_blocklist,bt_blocklist_url,bt_sleep,bt_check,bt_check_time,bt_dl_queue_enable,bt_dl_queue_size,bt_ul_queue_enable,bt_ul_queue_size,bt_message,bt_log,bt_log_path"); %>
// <% nvram("bt_enable,bt_binary,bt_binary_custom,bt_custom,bt_port,bt_dir,bt_settings,bt_settings_custom,bt_incomplete,bt_autoadd,bt_rpc_enable,bt_rpc_wan,bt_auth,bt_login,bt_password,bt_port_gui,bt_dl_enable,bt_dl,bt_ul_enable,bt_ul,bt_peer_limit_global,bt_peer_limit_per_torrent,bt_ul_slot_per_torrent,bt_ratio_enable,bt_ratio,bt_ratio_idle_enable,bt_ratio_idle,bt_dht,bt_pex,bt_lpd,bt_utp,bt_blocklist,bt_blocklist_url,bt_sleep,bt_check_time,bt_dl_queue_enable,bt_dl_queue_size,bt_ul_queue_enable,bt_ul_queue_size,bt_message,bt_log,bt_log_path"); %>
/* CIFS-BEGIN */
// <% statfs("/cifs1", "cifs1"); %>
@ -50,7 +50,6 @@ function verifyFields(focused, quiet) {
E('_bt_login').disabled = !a || !b;
E('_bt_password').disabled = !a | !b;
E('_f_bt_rpc_wan').disabled = !a || !b;
E('_bt_check_time').disabled = !E('_f_bt_check').checked;
E('_bt_dl').disabled = !E('_f_bt_dl_enable').checked;
E('_bt_ul').disabled = !E('_f_bt_ul_enable').checked;
E('_bt_ratio').disabled = !E('_f_bt_ratio_enable').checked;
@ -75,7 +74,7 @@ function verifyFields(focused, quiet) {
elem.display('_bt_binary_custom', (E('_bt_binary').value == 'custom'));
if (!v_length('_bt_custom', quiet, 0, 2048)) ok = 0;
if (!v_range('_bt_check_time', quiet || !ok, 1, 55)) ok = 0;
if (!v_range('_bt_check_time', quiet || !ok, 0, 55)) ok = 0;
if (!v_range('_bt_sleep', quiet || !ok, 1, 60)) ok = 0;
if (!v_range('_bt_peer_limit_global', quiet || !ok, 10, 1000)) ok = 0;
if (!v_range('_bt_peer_limit_per_torrent', quiet || !ok, 1, 200)) ok = 0;
@ -177,7 +176,6 @@ function save(nomsg) {
fom.bt_enable.value = fom._f_bt_enable.checked ? 1 : 0;
fom.bt_incomplete.value = fom._f_bt_incomplete.checked ? 1 : 0;
fom.bt_autoadd.value = fom._f_bt_autoadd.checked ? 1 : 0;
fom.bt_check.value = fom._f_bt_check.checked ? 1 : 0;
fom.bt_rpc_enable.value = fom._f_bt_rpc_enable.checked ? 1 : 0;
fom.bt_auth.value = fom._f_bt_auth.checked ? 1 : 0;
fom.bt_rpc_wan.value = fom._f_bt_rpc_wan.checked ? 1 : 0;
@ -231,7 +229,6 @@ function init() {
<input type="hidden" name="bt_enable">
<input type="hidden" name="bt_incomplete">
<input type="hidden" name="bt_autoadd">
<input type="hidden" name="bt_check">
<input type="hidden" name="bt_rpc_enable">
<input type="hidden" name="bt_auth">
<input type="hidden" name="bt_rpc_wan">
@ -275,8 +272,7 @@ function init() {
['optware','Optware/Entware (/opt/bin)'],
['custom','Custom'] ], value: nvram.bt_binary },
{ name: 'bt_binary_custom', type: 'text', maxlen: 40, size: 40, value: nvram.bt_binary_custom } ] },
{ title: 'Keep alive', name: 'f_bt_check', type: 'checkbox', value: nvram.bt_check == 1 },
{ title: 'Check alive every', indent: 2, name: 'bt_check_time', type: 'text', maxlen: 5, size: 7, value: nvram.bt_check_time, suffix: ' <small>minutes; range: 1 - 55; default: 15<\/small>' },
{ title: 'Poll Interval', name: 'bt_check_time', type: 'text', maxlen: 5, size: 7, value: nvram.bt_check_time, suffix: ' <small>minutes; range: 0 - 55; default: 15; 0 to disable<\/small>' },
{ title: 'Delay at startup', name: 'bt_sleep', type: 'text', maxlen: 5, size: 7, value: nvram.bt_sleep, suffix: ' <small>seconds; range: 1 - 60; default: 10<\/small>' },
{ title: 'Listening port', name: 'bt_port', type: 'text', maxlen: 5, size: 7, value: nvram.bt_port },
{ title: 'Download directory', name: 'bt_dir', type: 'text', maxlen: 40, size: 40, value: nvram.bt_dir },

Loading…
Cancel
Save