summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
-rw-r--r--ChangeLog4
-rw-r--r--doc/de/autogen/user/weechat_options.txt5
-rw-r--r--doc/en/autogen/user/weechat_options.txt5
-rw-r--r--doc/fr/autogen/user/weechat_options.txt5
-rw-r--r--doc/it/autogen/user/weechat_options.txt5
-rw-r--r--po/cs.po6
-rw-r--r--po/de.po7
-rw-r--r--po/es.po7
-rw-r--r--po/fr.po9
-rw-r--r--po/hu.po6
-rw-r--r--po/it.po6
-rw-r--r--po/pl.po7
-rw-r--r--po/pt_BR.po5
-rw-r--r--po/ru.po6
-rw-r--r--po/weechat.pot5
-rw-r--r--src/core/wee-config.c6
-rw-r--r--src/core/wee-config.h1
-rw-r--r--src/core/wee-hook.c22
-rw-r--r--src/core/wee-hook.h4
-rw-r--r--src/core/wee-network.c135
20 files changed, 235 insertions, 21 deletions
diff --git a/ChangeLog b/ChangeLog
index 6a23f3d6a..7d16dbaf8 100644
--- a/ChangeLog
+++ b/ChangeLog
@@ -1,12 +1,14 @@
WeeChat ChangeLog
=================
Sébastien Helleu <flashcode@flashtux.org>
-v0.3.4-dev, 2010-11-14
+v0.3.4-dev, 2010-11-18
Version 0.3.4 (under dev!)
--------------------------
+* core: fix infinite loop on gnutls handshake when connecting with SSL to server
+ on wrong port or server with SSL problems (bug #27487)
* core: fix data sent to callback of hook_process (some data was sometimes
missing), use a 64KB buffer for child output and send data to callback only
when buffer is full
diff --git a/doc/de/autogen/user/weechat_options.txt b/doc/de/autogen/user/weechat_options.txt
index 46e216972..7a044afe8 100644
--- a/doc/de/autogen/user/weechat_options.txt
+++ b/doc/de/autogen/user/weechat_options.txt
@@ -588,6 +588,11 @@
** Typ: Zeichenkette
** Werte: beliebige Zeichenkette (Standardwert: `"%h/ssl/CAs.pem"`)
+* *weechat.network.gnutls_handshake_timeout*
+** Beschreibung: `timeout (in seconds) for gnutls handshake`
+** Typ: integer
+** Werte: 1 .. 2147483647 (Standardwert: `30`)
+
* *weechat.plugin.autoload*
** Beschreibung: `Eine durch Kommata getrennte Liste der Erweiterungen die beim Programmstart automatisch geladen werden sollen, "*" lädt alle gefundenen Erweiterungen. Beginnt der Name hingegen mit "!" wird die Erweiterung nicht geladen. Suchmuster können mit einem Joker ("*") beginnen oder enden um mehrere Erweiterungen zu laden (Beispiele: "*" oder "*,!lua,!tcl")`
** Typ: Zeichenkette
diff --git a/doc/en/autogen/user/weechat_options.txt b/doc/en/autogen/user/weechat_options.txt
index 225cd21c1..c7ef6665f 100644
--- a/doc/en/autogen/user/weechat_options.txt
+++ b/doc/en/autogen/user/weechat_options.txt
@@ -588,6 +588,11 @@
** type: string
** values: any string (default value: `"%h/ssl/CAs.pem"`)
+* *weechat.network.gnutls_handshake_timeout*
+** description: `timeout (in seconds) for gnutls handshake`
+** type: integer
+** values: 1 .. 2147483647 (default value: `30`)
+
* *weechat.plugin.autoload*
** description: `comma separated list of plugins to load automatically at startup, "*" means all plugins found, a name beginning with "!" is a negative value to prevent a plugin from being loaded, names can start or end with "*" to match several plugins (examples: "*" or "*,!lua,!tcl")`
** type: string
diff --git a/doc/fr/autogen/user/weechat_options.txt b/doc/fr/autogen/user/weechat_options.txt
index 0bbf00937..8a3fe004e 100644
--- a/doc/fr/autogen/user/weechat_options.txt
+++ b/doc/fr/autogen/user/weechat_options.txt
@@ -588,6 +588,11 @@
** type: chaîne
** valeurs: toute chaîne (valeur par défaut: `"%h/ssl/CAs.pem"`)
+* *weechat.network.gnutls_handshake_timeout*
+** description: `délai d'attente maximum (en secondes) pour la poignée de main (handshake) gnutls`
+** type: entier
+** valeurs: 1 .. 2147483647 (valeur par défaut: `30`)
+
* *weechat.plugin.autoload*
** description: `liste des extensions à charger automatiquement au démarrage (séparées par des virgules), "*" signifie toutes les extensions trouvées, un nom commençant par "!" est une valeur négative pour empêcher une extension d'être chargée, les noms peuvent commencer ou se terminer par "*" pour indiquer plusieurs extensions (exemples: "*" ou "*,!lua,!tcl")`
** type: chaîne
diff --git a/doc/it/autogen/user/weechat_options.txt b/doc/it/autogen/user/weechat_options.txt
index cfc22c7b6..139fd70e4 100644
--- a/doc/it/autogen/user/weechat_options.txt
+++ b/doc/it/autogen/user/weechat_options.txt
@@ -588,6 +588,11 @@
** tipo: stringa
** valori: qualsiasi stringa (valore predefinito: `"%h/ssl/CAs.pem"`)
+* *weechat.network.gnutls_handshake_timeout*
+** descrizione: `timeout (in seconds) for gnutls handshake`
+** tipo: intero
+** valori: 1 .. 2147483647 (valore predefinito: `30`)
+
* *weechat.plugin.autoload*
** descrizione: `elenco separato da virgole di plugin da caricare automaticamente all'avvio, "*" equivale a tutti i plugin trovati. un nome che comincia con "!" è un valore negativo per impedire il caricamento di un plugin, i nomi possono iniziare o finire con "*" per corrispondere a più plugin (esempi: "*" oppure "*,!lua,!tcl")`
** tipo: stringa
diff --git a/po/cs.po b/po/cs.po
index db44a6d3b..2bc82850f 100644
--- a/po/cs.po
+++ b/po/cs.po
@@ -20,7 +20,7 @@ msgid ""
msgstr ""
"Project-Id-Version: WeeChat 0.3.4-dev\n"
"Report-Msgid-Bugs-To: flashcode@flashtux.org\n"
-"POT-Creation-Date: 2010-11-12 21:37+0100\n"
+"POT-Creation-Date: 2010-11-18 17:28+0100\n"
"PO-Revision-Date: 2010-11-06 11:55+0100\n"
"Last-Translator: Jiri Golembiovsky <golemj@gmail.com>\n"
"Language-Team: weechat-dev <weechat-dev@nongnu.org>\n"
@@ -2261,6 +2261,10 @@ msgstr ""
"cesta pro hledání pluginů (\"%h\" bude nahrazeno domácím adresářem WeeChat, "
"\"~/.weechat\" je výchozí)"
+#, fuzzy
+msgid "timeout (in seconds) for gnutls handshake"
+msgstr "časový limit (v sekundách) před vzdaním SASL autentizace"
+
msgid ""
"comma separated list of plugins to load automatically at startup, \"*\" "
"means all plugins found, a name beginning with \"!\" is a negative value to "
diff --git a/po/de.po b/po/de.po
index 64356eda3..016ad08b1 100644
--- a/po/de.po
+++ b/po/de.po
@@ -22,7 +22,7 @@ msgid ""
msgstr ""
"Project-Id-Version: WeeChat 0.3.3-dev\n"
"Report-Msgid-Bugs-To: flashcode@flashtux.org\n"
-"POT-Creation-Date: 2010-11-12 21:37+0100\n"
+"POT-Creation-Date: 2010-11-18 17:28+0100\n"
"PO-Revision-Date: 2010-11-06 11:55+0100\n"
"Last-Translator: Nils G.\n"
"Language-Team: weechat-dev <weechat-dev@nongnu.org>\n"
@@ -2363,6 +2363,11 @@ msgstr ""
"Suchpfad für Erweiterungen (\"%h\"' wird durch das WeeChat-Basisverzeichnis "
"ersetzt, voreingestellt ist \"~/.weechat\")"
+#, fuzzy
+msgid "timeout (in seconds) for gnutls handshake"
+msgstr ""
+"Zeitüberschreitung (in Sekunden) bis zum Abbruch der SASL Authentifizierung"
+
msgid ""
"comma separated list of plugins to load automatically at startup, \"*\" "
"means all plugins found, a name beginning with \"!\" is a negative value to "
diff --git a/po/es.po b/po/es.po
index 80107bfe0..5f4033dbf 100644
--- a/po/es.po
+++ b/po/es.po
@@ -21,7 +21,7 @@ msgid ""
msgstr ""
"Project-Id-Version: WeeChat 0.3.4-dev\n"
"Report-Msgid-Bugs-To: flashcode@flashtux.org\n"
-"POT-Creation-Date: 2010-11-12 21:37+0100\n"
+"POT-Creation-Date: 2010-11-18 17:28+0100\n"
"PO-Revision-Date: 2010-11-06 11:56+0100\n"
"Last-Translator: Elián Hanisch <lambdae2@gmail.com>\n"
"Language-Team: weechat-dev <weechat-dev@nongnu.org>\n"
@@ -2288,6 +2288,11 @@ msgstr ""
"ruta para encontrar plugins (\"%h\" será reemplazado por el directorio raíz "
"de WeeChat, \"~/.weechat\" por defecto)"
+#, fuzzy
+msgid "timeout (in seconds) for gnutls handshake"
+msgstr ""
+"tiempo de espera (en segundos) antes de abandonar la autenticación por SASL"
+
msgid ""
"comma separated list of plugins to load automatically at startup, \"*\" "
"means all plugins found, a name beginning with \"!\" is a negative value to "
diff --git a/po/fr.po b/po/fr.po
index 12e23826c..09cbe9faf 100644
--- a/po/fr.po
+++ b/po/fr.po
@@ -21,8 +21,8 @@ msgid ""
msgstr ""
"Project-Id-Version: WeeChat 0.3.4-dev\n"
"Report-Msgid-Bugs-To: flashcode@flashtux.org\n"
-"POT-Creation-Date: 2010-11-12 21:37+0100\n"
-"PO-Revision-Date: 2010-11-13 10:12+0100\n"
+"POT-Creation-Date: 2010-11-18 17:28+0100\n"
+"PO-Revision-Date: 2010-11-18 17:29+0100\n"
"Last-Translator: Sebastien Helleu <flashcode@flashtux.org>\n"
"Language-Team: weechat-dev <weechat-dev@nongnu.org>\n"
"Language: French\n"
@@ -2321,6 +2321,11 @@ msgstr ""
"fichier contenant les autorités de certification (\"%h\" sera remplacé par "
"le répertoire de base WeeChat, par défaut: \"~/.weechat\")"
+msgid "timeout (in seconds) for gnutls handshake"
+msgstr ""
+"délai d'attente maximum (en secondes) pour la poignée de main (handshake) "
+"gnutls"
+
msgid ""
"comma separated list of plugins to load automatically at startup, \"*\" "
"means all plugins found, a name beginning with \"!\" is a negative value to "
diff --git a/po/hu.po b/po/hu.po
index 4f096fbb3..9da554090 100644
--- a/po/hu.po
+++ b/po/hu.po
@@ -20,7 +20,7 @@ msgid ""
msgstr ""
"Project-Id-Version: WeeChat 0.3.4-dev\n"
"Report-Msgid-Bugs-To: flashcode@flashtux.org\n"
-"POT-Creation-Date: 2010-11-12 21:37+0100\n"
+"POT-Creation-Date: 2010-11-18 17:28+0100\n"
"PO-Revision-Date: 2010-11-05 17:17+0100\n"
"Last-Translator: Andras Voroskoi <voroskoi@frugalware.org>\n"
"Language-Team: weechat-dev <weechat-dev@nongnu.org>\n"
@@ -2104,6 +2104,10 @@ msgstr ""
"könyvtára, alapértelmezésben ~/.weechat, kerül)"
#, fuzzy
+msgid "timeout (in seconds) for gnutls handshake"
+msgstr "SSL használata a a kapcsolathoz"
+
+#, fuzzy
msgid ""
"comma separated list of plugins to load automatically at startup, \"*\" "
"means all plugins found, a name beginning with \"!\" is a negative value to "
diff --git a/po/it.po b/po/it.po
index d75e4f90d..b5d53c182 100644
--- a/po/it.po
+++ b/po/it.po
@@ -20,7 +20,7 @@ msgid ""
msgstr ""
"Project-Id-Version: WeeChat 0.3.4-dev\n"
"Report-Msgid-Bugs-To: flashcode@flashtux.org\n"
-"POT-Creation-Date: 2010-11-12 21:37+0100\n"
+"POT-Creation-Date: 2010-11-18 17:28+0100\n"
"PO-Revision-Date: 2010-11-06 11:56+0100\n"
"Last-Translator: Marco Paolone <marcopaolone@gmail.com>\n"
"Language-Team: weechat-dev <weechat-dev@nongnu.org>\n"
@@ -2301,6 +2301,10 @@ msgstr ""
"percorso per la ricerca dei plugin (\"%h\" sarà sostituito dalla home di "
"WeeChat, \"~/.weechat come predefinita)"
+#, fuzzy
+msgid "timeout (in seconds) for gnutls handshake"
+msgstr "timeout (in secondi) prima di annullare l'autenticazione SASL"
+
msgid ""
"comma separated list of plugins to load automatically at startup, \"*\" "
"means all plugins found, a name beginning with \"!\" is a negative value to "
diff --git a/po/pl.po b/po/pl.po
index 014d3f817..8b25e4ea6 100644
--- a/po/pl.po
+++ b/po/pl.po
@@ -21,7 +21,7 @@ msgid ""
msgstr ""
"Project-Id-Version: WeeChat 0.3.4-dev\n"
"Report-Msgid-Bugs-To: flashcode@flashtux.org\n"
-"POT-Creation-Date: 2010-11-12 21:37+0100\n"
+"POT-Creation-Date: 2010-11-18 17:28+0100\n"
"PO-Revision-Date: 2010-11-06 11:56+0100\n"
"Last-Translator: Krzysztof Koroscik <soltys@szluug.org>\n"
"Language-Team: weechat-dev <weechat-dev@nongnu.org>\n"
@@ -2289,6 +2289,11 @@ msgstr ""
"ścieżka wyszukiwania wtyczek (\"%h\" zostanie zastąpione katalogiem domowym "
"WeeChat - domyślnie \"~/.weechat\")"
+#, fuzzy
+msgid "timeout (in seconds) for gnutls handshake"
+msgstr ""
+"czas oczekiwania (w sekundach) przed zaprzestaniem uwierzytelniania SASL"
+
msgid ""
"comma separated list of plugins to load automatically at startup, \"*\" "
"means all plugins found, a name beginning with \"!\" is a negative value to "
diff --git a/po/pt_BR.po b/po/pt_BR.po
index ed7d86c72..0ea8a77da 100644
--- a/po/pt_BR.po
+++ b/po/pt_BR.po
@@ -20,7 +20,7 @@ msgid ""
msgstr ""
"Project-Id-Version: WeeChat 0.3.4-dev\n"
"Report-Msgid-Bugs-To: flashcode@flashtux.org\n"
-"POT-Creation-Date: 2010-11-12 21:37+0100\n"
+"POT-Creation-Date: 2010-11-18 17:28+0100\n"
"PO-Revision-Date: 2010-11-13 09:26+0100\n"
"Last-Translator: Ivan Sichmann Freitas <ivansichfreitas@gmail.com>\n"
"Language-Team: weechat-dev <weechat-dev@nongnu.org>\n"
@@ -1843,6 +1843,9 @@ msgid ""
"WeeChat home, \"~/.weechat\" by default)"
msgstr ""
+msgid "timeout (in seconds) for gnutls handshake"
+msgstr ""
+
msgid ""
"comma separated list of plugins to load automatically at startup, \"*\" "
"means all plugins found, a name beginning with \"!\" is a negative value to "
diff --git a/po/ru.po b/po/ru.po
index 955c4d8fd..eb0f9543c 100644
--- a/po/ru.po
+++ b/po/ru.po
@@ -20,7 +20,7 @@ msgid ""
msgstr ""
"Project-Id-Version: WeeChat 0.3.4-dev\n"
"Report-Msgid-Bugs-To: flashcode@flashtux.org\n"
-"POT-Creation-Date: 2010-11-12 21:37+0100\n"
+"POT-Creation-Date: 2010-11-18 17:28+0100\n"
"PO-Revision-Date: 2010-11-05 17:17+0100\n"
"Last-Translator: Pavel Shevchuk <stlwrt@gmail.com>\n"
"Language-Team: weechat-dev <weechat-dev@nongnu.org>\n"
@@ -2119,6 +2119,10 @@ msgstr ""
"умолчанию - ~/.weechat)"
#, fuzzy
+msgid "timeout (in seconds) for gnutls handshake"
+msgstr "использовать SSL при связи с сервером"
+
+#, fuzzy
msgid ""
"comma separated list of plugins to load automatically at startup, \"*\" "
"means all plugins found, a name beginning with \"!\" is a negative value to "
diff --git a/po/weechat.pot b/po/weechat.pot
index 7aa5aff52..5f675f7d9 100644
--- a/po/weechat.pot
+++ b/po/weechat.pot
@@ -7,7 +7,7 @@ msgid ""
msgstr ""
"Project-Id-Version: PACKAGE VERSION\n"
"Report-Msgid-Bugs-To: flashcode@flashtux.org\n"
-"POT-Creation-Date: 2010-11-12 21:37+0100\n"
+"POT-Creation-Date: 2010-11-18 17:28+0100\n"
"PO-Revision-Date: YEAR-MO-DA HO:MI+ZONE\n"
"Last-Translator: FULL NAME <EMAIL@ADDRESS>\n"
"Language-Team: LANGUAGE <LL@li.org>\n"
@@ -1783,6 +1783,9 @@ msgid ""
"WeeChat home, \"~/.weechat\" by default)"
msgstr ""
+msgid "timeout (in seconds) for gnutls handshake"
+msgstr ""
+
msgid ""
"comma separated list of plugins to load automatically at startup, \"*\" "
"means all plugins found, a name beginning with \"!\" is a negative value to "
diff --git a/src/core/wee-config.c b/src/core/wee-config.c
index f0324af09..cb3526758 100644
--- a/src/core/wee-config.c
+++ b/src/core/wee-config.c
@@ -186,6 +186,7 @@ struct t_config_option *config_history_display_default;
/* config, network section */
struct t_config_option *config_network_gnutls_ca_file;
+struct t_config_option *config_network_gnutls_handshake_timeout;
/* config, plugin section */
@@ -2034,6 +2035,11 @@ config_weechat_init_options ()
N_("file containing the certificate authorities (\"%h\" will be "
"replaced by WeeChat home, \"~/.weechat\" by default)"),
NULL, 0, 0, "%h/ssl/CAs.pem", NULL, 0, NULL, NULL, NULL, NULL, NULL, NULL);
+ config_network_gnutls_handshake_timeout = config_file_new_option (
+ weechat_config_file, ptr_section,
+ "gnutls_handshake_timeout", "integer",
+ N_("timeout (in seconds) for gnutls handshake"),
+ NULL, 1, INT_MAX, "30", NULL, 0, NULL, NULL, NULL, NULL, NULL, NULL);
/* plugin */
ptr_section = config_file_new_section (weechat_config_file, "plugin",
diff --git a/src/core/wee-config.h b/src/core/wee-config.h
index 99046f5a0..d84476384 100644
--- a/src/core/wee-config.h
+++ b/src/core/wee-config.h
@@ -207,6 +207,7 @@ extern struct t_config_option *config_history_max_visited_buffers;
extern struct t_config_option *config_history_display_default;
extern struct t_config_option *config_network_gnutls_ca_file;
+extern struct t_config_option *config_network_gnutls_handshake_timeout;
extern struct t_config_option *config_plugin_autoload;
extern struct t_config_option *config_plugin_debug;
diff --git a/src/core/wee-hook.c b/src/core/wee-hook.c
index d7c674a11..e1c852b17 100644
--- a/src/core/wee-hook.c
+++ b/src/core/wee-hook.c
@@ -1687,6 +1687,10 @@ hook_connect (struct t_weechat_plugin *plugin, const char *proxy, const char *ad
new_hook_connect->child_write = -1;
new_hook_connect->child_pid = 0;
new_hook_connect->hook_fd = NULL;
+ new_hook_connect->handshake_hook_fd = NULL;
+ new_hook_connect->handshake_hook_timer = NULL;
+ new_hook_connect->handshake_fd_flags = 0;
+ new_hook_connect->handshake_ip_address = NULL;
hook_add_to_list (new_hook);
@@ -2695,6 +2699,12 @@ unhook (struct t_hook *hook)
free (HOOK_CONNECT(hook, local_hostname));
if (HOOK_CONNECT(hook, hook_fd))
unhook (HOOK_CONNECT(hook, hook_fd));
+ if (HOOK_CONNECT(hook, handshake_hook_fd))
+ unhook (HOOK_CONNECT(hook, handshake_hook_fd));
+ if (HOOK_CONNECT(hook, handshake_hook_timer))
+ unhook (HOOK_CONNECT(hook, handshake_hook_timer));
+ if (HOOK_CONNECT(hook, handshake_ip_address))
+ free (HOOK_CONNECT(hook, handshake_ip_address));
if (HOOK_CONNECT(hook, child_pid) > 0)
{
kill (HOOK_CONNECT(hook, child_pid), SIGKILL);
@@ -3001,6 +3011,14 @@ hook_add_to_infolist_type (struct t_infolist *infolist,
return 0;
if (!infolist_new_var_pointer (ptr_item, "hook_fd", HOOK_CONNECT(ptr_hook, hook_fd)))
return 0;
+ if (!infolist_new_var_pointer (ptr_item, "handshake_hook_fd", HOOK_CONNECT(ptr_hook, handshake_hook_fd)))
+ return 0;
+ if (!infolist_new_var_pointer (ptr_item, "handshake_hook_timer", HOOK_CONNECT(ptr_hook, handshake_hook_timer)))
+ return 0;
+ if (!infolist_new_var_integer (ptr_item, "handshake_fd_flags", HOOK_CONNECT(ptr_hook, handshake_fd_flags)))
+ return 0;
+ if (!infolist_new_var_string (ptr_item, "handshake_ip_address", HOOK_CONNECT(ptr_hook, handshake_ip_address)))
+ return 0;
}
break;
case HOOK_TYPE_PRINT:
@@ -3332,6 +3350,10 @@ hook_print_log ()
log_printf (" child_write . . . . . : %d", HOOK_CONNECT(ptr_hook, child_write));
log_printf (" child_pid . . . . . . : %d", HOOK_CONNECT(ptr_hook, child_pid));
log_printf (" hook_fd . . . . . . . : 0x%lx", HOOK_CONNECT(ptr_hook, hook_fd));
+ log_printf (" handshake_hook_fd . . : 0x%lx", HOOK_CONNECT(ptr_hook, handshake_hook_fd));
+ log_printf (" handshake_hook_timer. : 0x%lx", HOOK_CONNECT(ptr_hook, handshake_hook_timer));
+ log_printf (" handshake_fd_flags. . : %d", HOOK_CONNECT(ptr_hook, handshake_fd_flags));
+ log_printf (" handshake_ip_address. : '%s'", HOOK_CONNECT(ptr_hook, handshake_ip_address));
}
break;
case HOOK_TYPE_PRINT:
diff --git a/src/core/wee-hook.h b/src/core/wee-hook.h
index e842865f3..2cd9fd760 100644
--- a/src/core/wee-hook.h
+++ b/src/core/wee-hook.h
@@ -226,6 +226,10 @@ struct t_hook_connect
int child_write; /* to write data in pipe for child */
pid_t child_pid; /* pid of child process (connecting) */
struct t_hook *hook_fd; /* pointer to fd hook */
+ struct t_hook *handshake_hook_fd; /* fd hook for handshake */
+ struct t_hook *handshake_hook_timer; /* timer for handshake timeout */
+ int handshake_fd_flags; /* socket flags saved for handshake */
+ char *handshake_ip_address; /* ip address (used for handshake) */
};
/* hook print */
diff --git a/src/core/wee-network.c b/src/core/wee-network.c
index cdb4bbe05..972cbfdac 100644
--- a/src/core/wee-network.c
+++ b/src/core/wee-network.c
@@ -27,6 +27,7 @@
#endif
#include <unistd.h>
+#include <fcntl.h>
#include <stdlib.h>
#include <string.h>
#include <sys/types.h>
@@ -726,6 +727,94 @@ network_connect_child (struct t_hook *hook_connect)
}
/*
+ * network_connect_gnutls_handshake_fd_cb: callback for gnutls handshake
+ * (used to not block WeeChat if
+ * handshake takes some time to finish)
+ */
+
+#ifdef HAVE_GNUTLS
+int
+network_connect_gnutls_handshake_fd_cb (void *arg_hook_connect, int fd)
+{
+ struct t_hook *hook_connect;
+ int rc, direction, flags;
+
+ /* make C compiler happy */
+ (void) fd;
+
+ hook_connect = (struct t_hook *)arg_hook_connect;
+
+ rc = gnutls_handshake (*HOOK_CONNECT(hook_connect, gnutls_sess));
+
+ if ((rc == GNUTLS_E_AGAIN) || (rc == GNUTLS_E_INTERRUPTED))
+ {
+ direction = gnutls_record_get_direction (*HOOK_CONNECT(hook_connect, gnutls_sess));
+ flags = HOOK_FD(HOOK_CONNECT(hook_connect, handshake_hook_fd), flags);
+ if ((((flags & HOOK_FD_FLAG_READ) == HOOK_FD_FLAG_READ)
+ && (direction != 0))
+ || (((flags & HOOK_FD_FLAG_WRITE) == HOOK_FD_FLAG_WRITE)
+ && (direction != 1)))
+ {
+ HOOK_FD(HOOK_CONNECT(hook_connect, handshake_hook_fd), flags) =
+ (direction) ? HOOK_FD_FLAG_WRITE: HOOK_FD_FLAG_READ;
+ }
+ }
+ else if (rc != GNUTLS_E_SUCCESS)
+ {
+ (void) (HOOK_CONNECT(hook_connect, callback))
+ (hook_connect->callback_data,
+ WEECHAT_HOOK_CONNECT_GNUTLS_HANDSHAKE_ERROR,
+ rc,
+ gnutls_strerror (rc),
+ HOOK_CONNECT(hook_connect, handshake_ip_address));
+ unhook (hook_connect);
+ }
+ else
+ {
+ fcntl (HOOK_CONNECT(hook_connect, sock), F_SETFL,
+ HOOK_CONNECT(hook_connect, handshake_fd_flags));
+ unhook (HOOK_CONNECT(hook_connect, handshake_hook_fd));
+ (void) (HOOK_CONNECT(hook_connect, callback))
+ (hook_connect->callback_data, WEECHAT_HOOK_CONNECT_OK, 0, NULL,
+ HOOK_CONNECT(hook_connect, handshake_ip_address));
+ unhook (hook_connect);
+ }
+
+ return WEECHAT_RC_OK;
+}
+#endif
+
+/*
+ * network_connect_gnutls_handshake_timer_cb: timer for timeout on handshake
+ */
+
+#ifdef HAVE_GNUTLS
+int
+network_connect_gnutls_handshake_timer_cb (void *arg_hook_connect,
+ int remaining_calls)
+{
+ struct t_hook *hook_connect;
+
+ /* make C compiler happy */
+ (void) remaining_calls;
+
+ hook_connect = (struct t_hook *)arg_hook_connect;
+
+ HOOK_CONNECT(hook_connect, handshake_hook_timer) = NULL;
+
+ (void) (HOOK_CONNECT(hook_connect, callback))
+ (hook_connect->callback_data,
+ WEECHAT_HOOK_CONNECT_GNUTLS_HANDSHAKE_ERROR,
+ GNUTLS_E_EXPIRED,
+ gnutls_strerror (GNUTLS_E_EXPIRED),
+ HOOK_CONNECT(hook_connect, handshake_ip_address));
+ unhook (hook_connect);
+
+ return WEECHAT_RC_OK;
+}
+#endif
+
+/*
* network_connect_child_read_cb: read connection progress from child process
*/
@@ -737,7 +826,7 @@ network_connect_child_read_cb (void *arg_hook_connect, int fd)
int num_read;
long size_ip;
#ifdef HAVE_GNUTLS
- int rc;
+ int rc, direction;
#endif
/* make C compiler happy */
@@ -780,21 +869,47 @@ network_connect_child_read_cb (void *arg_hook_connect, int fd)
#ifdef HAVE_GNUTLS
if (HOOK_CONNECT(hook_connect, gnutls_sess))
{
+ /*
+ * the socket needs to be non-blocking since the call to
+ * gnutls_handshake can block
+ */
+ HOOK_CONNECT(hook_connect, handshake_fd_flags) =
+ fcntl (HOOK_CONNECT(hook_connect, sock), F_GETFL);
+ fcntl (HOOK_CONNECT(hook_connect, sock), F_SETFL,
+ HOOK_CONNECT(hook_connect, handshake_fd_flags) | O_NONBLOCK);
gnutls_transport_set_ptr (*HOOK_CONNECT(hook_connect, gnutls_sess),
(gnutls_transport_ptr) ((unsigned long) HOOK_CONNECT(hook_connect, sock)));
- if (HOOK_CONNECT(hook_connect, gnutls_dhkey_size) > 0) {
+ if (HOOK_CONNECT (hook_connect, gnutls_dhkey_size) > 0)
+ {
gnutls_dh_set_prime_bits (*HOOK_CONNECT(hook_connect, gnutls_sess),
(unsigned int) HOOK_CONNECT(hook_connect, gnutls_dhkey_size));
}
- while (1)
+ rc = gnutls_handshake (*HOOK_CONNECT(hook_connect, gnutls_sess));
+ if ((rc == GNUTLS_E_AGAIN) || (rc == GNUTLS_E_INTERRUPTED))
{
- rc = gnutls_handshake (*HOOK_CONNECT(hook_connect, gnutls_sess));
- if ((rc == GNUTLS_E_SUCCESS)
- || ((rc != GNUTLS_E_AGAIN) && (rc != GNUTLS_E_INTERRUPTED)))
- break;
- usleep (1000);
+ /*
+ * gnutls was unable to proceed with the handshake without
+ * blocking: non fatal error, we just have to wait for an
+ * event about handshake
+ */
+ direction = gnutls_record_get_direction (*HOOK_CONNECT(hook_connect, gnutls_sess));
+ HOOK_CONNECT(hook_connect, handshake_ip_address) = ip_address;
+ HOOK_CONNECT(hook_connect, handshake_hook_fd) =
+ hook_fd (hook_connect->plugin,
+ HOOK_CONNECT(hook_connect, sock),
+ (!direction ? 1 : 0), (direction ? 1 : 0), 0,
+ //1, 1, 0,
+ &network_connect_gnutls_handshake_fd_cb,
+ hook_connect);
+ HOOK_CONNECT(hook_connect, handshake_hook_timer) =
+ hook_timer (hook_connect->plugin,
+ CONFIG_INTEGER(config_network_gnutls_handshake_timeout) * 1000,
+ 0, 1,
+ &network_connect_gnutls_handshake_timer_cb,
+ hook_connect);
+ return WEECHAT_RC_OK;
}
- if (rc != GNUTLS_E_SUCCESS)
+ else if (rc != GNUTLS_E_SUCCESS)
{
(void) (HOOK_CONNECT(hook_connect, callback))
(hook_connect->callback_data,
@@ -807,6 +922,8 @@ network_connect_child_read_cb (void *arg_hook_connect, int fd)
free (ip_address);
return WEECHAT_RC_OK;
}
+ fcntl (HOOK_CONNECT(hook_connect, sock), F_SETFL,
+ HOOK_CONNECT(hook_connect, handshake_fd_flags));
}
#endif
}