[PATCH] infinite loop during connection setup
Dennis Preiser <[email protected]> Sun, 18 Oct 2015 15:49:58 +0200
| Newsgroups | gmane.network.tin.devel |
|---|---|
| Message-ID | <[email protected]> |
--SUOF0GtieIMvvwua
Content-Type: text/plain; charset=utf-8
Content-Disposition: inline
Content-Transfer-Encoding: 8bit
Recently I encountered a bug when using tin with stunnel. When stunnel
is running but the network is down (in my case WIFI was switched off)
tin goes right after startup into an infinite loop:
get_server() -> reconnect() -> nntp_open() -> server_init() ->
get_respcode() -> get_only_respcode() -> tin_fgets() -> tin_read() ->
get_server() -> reconnect() …
Here is a basic setup to reproduce:
stunnel.conf:
| [nntp]
| client = yes
| accept = 127.0.0.1:1119
| connect = news.example.com:563
newsrctable:
| 127.0.0.1 ~/.newsrcs alias
.newsauth
| 127.0.0.1 pass user
Start stunnel, make sure network is down and start tin as follows:
tin -p 1119 -A -g alias
If tin was build without --enable-debug, it takes about 10 seconds until
a Segmentation fault.
Attached a patch with a possible fix.
Dennis
--SUOF0GtieIMvvwua
Content-Type: text/plain; charset=us-ascii
Content-Disposition: attachment; filename="2015-10-18.diff"
diff -urp tin-2.3.1_r9/src/nntplib.c tin-2.3.1_r10/src/nntplib.c
--- tin-2.3.1_r9/src/nntplib.c 2014-12-24 09:41:24.000000000 +0100
+++ tin-2.3.1_r10/src/nntplib.c 2015-10-18 14:56:29.000000000 +0200
@@ -821,17 +821,20 @@ reconnect(
signal_context = cReconnect;
/*
- * Exit tin if the user says no to reconnect. The exit code stops tin from trying
- * to disconnect again - the connection is already dead
+ * Exit tin if there are no more tries or if the user says no to reconnect.
+ * The exit code stops tin from trying to disconnect again - the connection
+ * is already dead
*/
- if (!tinrc.auto_reconnect && prompt_yn(_(txt_reconnect_to_news_server), TRUE) != 1) {
+ if (!retry || (!tinrc.auto_reconnect && prompt_yn(_(txt_reconnect_to_news_server), TRUE) != 1)) {
if (!strncmp("POST", last_put, 4)) {
unlink(backup_article_name(article_name));
rename_file(article_name, dead_article);
if (tinrc.keep_dead_articles)
append_file(dead_article, dead_articles);
}
- tin_done(NNTP_ERROR_EXIT); /* user said no to reconnect */
+ if (!retry)
+ error_message(2, _("NNTP connection error. Exiting..."));
+ tin_done(NNTP_ERROR_EXIT); /* user said no to reconnect or no more retries */
}
/*
@@ -861,17 +864,7 @@ reconnect(
DEBUG_IO((stderr, _("Resend last command (%s)\n"), buf));
put_server(buf);
did_reconnect = TRUE;
- return 0;
- }
-
- if (--retry == 0) { /* No more tries? */
- if (!strncmp("POST", buf, 4)) {
- unlink(backup_article_name(article_name));
- rename_file(article_name, dead_article);
- if (tinrc.keep_dead_articles)
- append_file(dead_article, dead_articles);
- }
- tin_done(NNTP_ERROR_EXIT);
+ retry = 0;
}
return retry;
@@ -896,7 +889,7 @@ get_server(
char *string,
int size)
{
- int retry = NNTP_TRY_RECONNECT;
+ static int retry_cnt = NNTP_TRY_RECONNECT;
reconnected_in_last_get_server = FALSE;
errno = 0;
@@ -947,7 +940,7 @@ get_server(
strcpy(last_put, "MODE READER");
nntp_caps.type = BROKEN;
}
- retry = reconnect(retry); /* Will abort when out of tries */
+ retry_cnt = reconnect(retry_cnt--); /* Will abort when out of tries */
reconnected_in_last_get_server = TRUE;
} else {
/*
@@ -962,6 +955,7 @@ get_server(
# if defined(HAVE_ALARM) && defined(SIGALRM)
alarm(0);
# endif /* HAVE_ALARM && SIGALRM */
+ retry_cnt = NNTP_TRY_RECONNECT;
return string;
}
--SUOF0GtieIMvvwua
Content-Type: text/plain; charset="utf-8"
MIME-Version: 1.0
Content-Transfer-Encoding: base64
Content-Disposition: inline
X19fX19fX19fX19fX19fX19fX19fX19fX19fX19fX19fX19fX19fX19fX19fX18KdGluLWRldiBt
YWlsaW5nIGxpc3QKdGluLWRldkB0aW4ub3JnCmh0dHA6Ly9saXN0cy50aW4ub3JnL2NnaS1iaW4v
bWFpbG1hbi9saXN0aW5mby90aW4tZGV2Cg==
--SUOF0GtieIMvvwua--