tor-commits
Threads by month
- ----- 2025 -----
- May
- April
- March
- February
- January
- ----- 2024 -----
- December
- November
- October
- September
- August
- July
- June
- May
- April
- March
- February
- January
- ----- 2023 -----
- December
- November
- October
- September
- August
- July
- June
- May
- April
- March
- February
- January
- ----- 2022 -----
- December
- November
- October
- September
- August
- July
- June
- May
- April
- March
- February
- January
- ----- 2021 -----
- December
- November
- October
- September
- August
- July
- June
- May
- April
- March
- February
- January
- ----- 2020 -----
- December
- November
- October
- September
- August
- July
- June
- May
- April
- March
- February
- January
- ----- 2019 -----
- December
- November
- October
- September
- August
- July
- June
- May
- April
- March
- February
- January
- ----- 2018 -----
- December
- November
- October
- September
- August
- July
- June
- May
- April
- March
- February
- January
- ----- 2017 -----
- December
- November
- October
- September
- August
- July
- June
- May
- April
- March
- February
- January
- ----- 2016 -----
- December
- November
- October
- September
- August
- July
- June
- May
- April
- March
- February
- January
- ----- 2015 -----
- December
- November
- October
- September
- August
- July
- June
- May
- April
- March
- February
- January
- ----- 2014 -----
- December
- November
- October
- September
- August
- July
- June
- May
- April
- March
- February
- January
- ----- 2013 -----
- December
- November
- October
- September
- August
- July
- June
- May
- April
- March
- February
- January
- ----- 2012 -----
- December
- November
- October
- September
- August
- July
- June
- May
- April
- March
- February
- January
- ----- 2011 -----
- December
- November
- October
- September
- August
- July
- June
- May
- April
- March
- February
January 2015
- 20 participants
- 934 discussions

[translation/tails-iuk_completed] Update translations for tails-iuk_completed
by translation@torproject.org 24 Jan '15
by translation@torproject.org 24 Jan '15
24 Jan '15
commit 00837f4a917d4ee4efe1db7bbff3eb76cdc2908e
Author: Translation commit bot <translation(a)torproject.org>
Date: Sat Jan 24 08:15:55 2015 +0000
Update translations for tails-iuk_completed
---
fr.po | 17 +++++++++--------
1 file changed, 9 insertions(+), 8 deletions(-)
diff --git a/fr.po b/fr.po
index c303984..83687db 100644
--- a/fr.po
+++ b/fr.po
@@ -6,17 +6,18 @@
# bassmax, 2013
# Alex <chioubaca(a)gmail.com>, 2014
# tneskovic <antoine_ecuador(a)yahoo.fr>, 2014
-# Emmanuel Simond <emanediteur(a)gmail.com>, 2014
+# Emmanuel Simond, 2014
# monsieurtino <monsieurtino(a)mailoo.org>, 2014
# rike, 2014
# Towinet, 2013-2014
+# Transfix <kafyekeo(a)gmail.com>, 2015
msgid ""
msgstr ""
"Project-Id-Version: The Tor Project\n"
"Report-Msgid-Bugs-To: Tails developers <tails(a)boum.org>\n"
-"POT-Creation-Date: 2014-09-18 21:27-0700\n"
-"PO-Revision-Date: 2014-09-19 09:58+0000\n"
-"Last-Translator: runasand <runa.sandvik(a)gmail.com>\n"
+"POT-Creation-Date: 2015-01-13 14:19+0100\n"
+"PO-Revision-Date: 2015-01-24 08:00+0000\n"
+"Last-Translator: Transfix <kafyekeo(a)gmail.com>\n"
"Language-Team: French (http://www.transifex.com/projects/p/torproject/language/fr/)\n"
"MIME-Version: 1.0\n"
"Content-Type: text/plain; charset=UTF-8\n"
@@ -44,11 +45,11 @@ msgstr "<b>N'a pas pu déterminer si une mise à jour est disponible depuis notr
#: ../lib/Tails/IUK/Frontend.pm:234
msgid "no automatic upgrade is available from our website for this version"
-msgstr "aucune mise à niveau automatique n'est disponible depuis notre site Web pour cette version"
+msgstr "aucune mise à jour automatique n'est disponible depuis notre site Web pour cette version"
#: ../lib/Tails/IUK/Frontend.pm:240
msgid "your device was not created using Tails Installer"
-msgstr "votre dispositif n'a pas été créé en utilisant l'installateur de Tails"
+msgstr "votre dispositif n'a pas été créé en utilisant l'installeur Tails"
#: ../lib/Tails/IUK/Frontend.pm:245
msgid "Tails was started from a DVD or a read-only device"
@@ -121,11 +122,11 @@ msgstr "Mise à jour disponible"
#: ../lib/Tails/IUK/Frontend.pm:386
msgid "Upgrade now"
-msgstr "Mettre à niveau maintenant"
+msgstr "Mettre à jour maintenant"
#: ../lib/Tails/IUK/Frontend.pm:387
msgid "Upgrade later"
-msgstr "Mettre à niveau plus tard"
+msgstr "Mettre à jour plus tard"
#: ../lib/Tails/IUK/Frontend.pm:395
#, perl-brace-format
1
0

24 Jan '15
commit 87acc580281ceda2f4fe25eac5e28b0a37360adf
Author: Translation commit bot <translation(a)torproject.org>
Date: Sat Jan 24 08:15:51 2015 +0000
Update translations for tails-iuk
---
fr.po | 17 +++++++++--------
1 file changed, 9 insertions(+), 8 deletions(-)
diff --git a/fr.po b/fr.po
index c303984..83687db 100644
--- a/fr.po
+++ b/fr.po
@@ -6,17 +6,18 @@
# bassmax, 2013
# Alex <chioubaca(a)gmail.com>, 2014
# tneskovic <antoine_ecuador(a)yahoo.fr>, 2014
-# Emmanuel Simond <emanediteur(a)gmail.com>, 2014
+# Emmanuel Simond, 2014
# monsieurtino <monsieurtino(a)mailoo.org>, 2014
# rike, 2014
# Towinet, 2013-2014
+# Transfix <kafyekeo(a)gmail.com>, 2015
msgid ""
msgstr ""
"Project-Id-Version: The Tor Project\n"
"Report-Msgid-Bugs-To: Tails developers <tails(a)boum.org>\n"
-"POT-Creation-Date: 2014-09-18 21:27-0700\n"
-"PO-Revision-Date: 2014-09-19 09:58+0000\n"
-"Last-Translator: runasand <runa.sandvik(a)gmail.com>\n"
+"POT-Creation-Date: 2015-01-13 14:19+0100\n"
+"PO-Revision-Date: 2015-01-24 08:00+0000\n"
+"Last-Translator: Transfix <kafyekeo(a)gmail.com>\n"
"Language-Team: French (http://www.transifex.com/projects/p/torproject/language/fr/)\n"
"MIME-Version: 1.0\n"
"Content-Type: text/plain; charset=UTF-8\n"
@@ -44,11 +45,11 @@ msgstr "<b>N'a pas pu déterminer si une mise à jour est disponible depuis notr
#: ../lib/Tails/IUK/Frontend.pm:234
msgid "no automatic upgrade is available from our website for this version"
-msgstr "aucune mise à niveau automatique n'est disponible depuis notre site Web pour cette version"
+msgstr "aucune mise à jour automatique n'est disponible depuis notre site Web pour cette version"
#: ../lib/Tails/IUK/Frontend.pm:240
msgid "your device was not created using Tails Installer"
-msgstr "votre dispositif n'a pas été créé en utilisant l'installateur de Tails"
+msgstr "votre dispositif n'a pas été créé en utilisant l'installeur Tails"
#: ../lib/Tails/IUK/Frontend.pm:245
msgid "Tails was started from a DVD or a read-only device"
@@ -121,11 +122,11 @@ msgstr "Mise à jour disponible"
#: ../lib/Tails/IUK/Frontend.pm:386
msgid "Upgrade now"
-msgstr "Mettre à niveau maintenant"
+msgstr "Mettre à jour maintenant"
#: ../lib/Tails/IUK/Frontend.pm:387
msgid "Upgrade later"
-msgstr "Mettre à niveau plus tard"
+msgstr "Mettre à jour plus tard"
#: ../lib/Tails/IUK/Frontend.pm:395
#, perl-brace-format
1
0

[translation/liveusb-creator_completed] Update translations for liveusb-creator_completed
by translation@torproject.org 23 Jan '15
by translation@torproject.org 23 Jan '15
23 Jan '15
commit d179a1d13be6e4529846ba1d5b1dcedc046d78ee
Author: Translation commit bot <translation(a)torproject.org>
Date: Fri Jan 23 21:45:21 2015 +0000
Update translations for liveusb-creator_completed
---
fr/fr.po | 57 +++++++++++++++++++++++++++++++--------------------------
1 file changed, 31 insertions(+), 26 deletions(-)
diff --git a/fr/fr.po b/fr/fr.po
index f16c0cd..8d1ce23 100644
--- a/fr/fr.po
+++ b/fr/fr.po
@@ -6,6 +6,7 @@
# bassmax, 2014
# Alex <chioubaca(a)gmail.com>, 2014
# arpalord <arpalord(a)gmail.com>, 2012
+# 5boro <bastien.pontet(a)gmail.com>, 2015
# Charles-Antoine Couret, 2009
# Charles-Antoine Couret <cacouret(a)wanadoo.fr>, 2009
# Emmanuel Simond, 2014
@@ -20,9 +21,9 @@ msgid ""
msgstr ""
"Project-Id-Version: The Tor Project\n"
"Report-Msgid-Bugs-To: \n"
-"POT-Creation-Date: 2014-12-01 18:01+0100\n"
-"PO-Revision-Date: 2014-12-03 11:44+0000\n"
-"Last-Translator: runasand <runa.sandvik(a)gmail.com>\n"
+"POT-Creation-Date: 2015-01-13 18:07+0100\n"
+"PO-Revision-Date: 2015-01-23 21:42+0000\n"
+"Last-Translator: 5boro <bastien.pontet(a)gmail.com>\n"
"Language-Team: French (http://www.transifex.com/projects/p/torproject/language/fr/)\n"
"MIME-Version: 1.0\n"
"Content-Type: text/plain; charset=UTF-8\n"
@@ -35,17 +36,17 @@ msgstr ""
msgid "%(distribution)s Installer"
msgstr "Installateur %(distribution)s"
-#: ../liveusb/gui.py:773
+#: ../liveusb/gui.py:775
#, python-format
msgid "%(filename)s selected"
msgstr "%(filename)s sélectionné"
-#: ../liveusb/gui.py:423
+#: ../liveusb/gui.py:425
#, python-format
msgid "%(size)s %(label)s"
msgstr "%(size)s %(label)s"
-#: ../liveusb/gui.py:429
+#: ../liveusb/gui.py:431
#, python-format
msgid "%(vendor)s %(model)s (%(details)s) - %(device)s"
msgstr "%(vendor)s %(model)s (%(details)s) - %(device)s"
@@ -140,7 +141,7 @@ msgstr "Cloner\n&&\nMettre à jour"
msgid "Creating %sMB persistent overlay"
msgstr "Création du volume persistant de %s Mo"
-#: ../liveusb/gui.py:551
+#: ../liveusb/gui.py:553
msgid ""
"Device is not yet mounted, so we cannot determine the amount of free space."
msgstr "L'appareil n'est pas encore monté, nous ne pouvons donc pas déterminer la quantité d'espace libre disponible."
@@ -150,11 +151,11 @@ msgstr "L'appareil n'est pas encore monté, nous ne pouvons donc pas déterminer
msgid "Download %(distribution)s"
msgstr "Télécharger %(distribution)s"
-#: ../liveusb/gui.py:747
+#: ../liveusb/gui.py:749
msgid "Download complete!"
msgstr "Téléchargement terminé !"
-#: ../liveusb/gui.py:751
+#: ../liveusb/gui.py:753
msgid "Download failed: "
msgstr "Échec du téléchargement : "
@@ -215,7 +216,7 @@ msgstr "Si vous ne choisissez pas une image Live existante, la version sélectio
msgid "Install Tails"
msgstr "Installer Tails"
-#: ../liveusb/gui.py:614
+#: ../liveusb/gui.py:616
msgid "Installation complete!"
msgstr "Installation terminée !"
@@ -224,7 +225,7 @@ msgstr "Installation terminée !"
msgid "Installation complete! (%s)"
msgstr "Installation terminée ! (%s)"
-#: ../liveusb/gui.py:615
+#: ../liveusb/gui.py:617
msgid "Installation was completed. Press OK to close this program."
msgstr "L'installation est terminée. Appuyez sur OK pour fermer ce programme."
@@ -252,7 +253,7 @@ msgstr "Assurez-vous que votre clé USB est branchée et qu'elle est formatée a
msgid "Mount %s exists after unmounting"
msgstr "Le montage %s existe après démontage"
-#: ../liveusb/gui.py:557
+#: ../liveusb/gui.py:559
#, python-format
msgid "No free space on device %(device)s"
msgstr "Espace libre insuffisant sur le périphérique %(device)s"
@@ -268,11 +269,11 @@ msgid ""
"%dMB ISO + %dMB overlay > %dMB free space"
msgstr "Pas assez d'espace libre sur le périphérique.\n%dMB ISO + %dMB de superposition > %dMB d'espace libre"
-#: ../liveusb/gui.py:538
+#: ../liveusb/gui.py:540
msgid "Partition is FAT16; Restricting overlay size to 2G"
msgstr "La partition est de type FAT16, la taille du volume est donc restreinte à 2 Go"
-#: ../liveusb/gui.py:534
+#: ../liveusb/gui.py:536
msgid "Partition is FAT32; Restricting overlay size to 4G"
msgstr "La partition est en FAT32; Restriction de la taille du volume à 4Go."
@@ -281,7 +282,7 @@ msgstr "La partition est en FAT32; Restriction de la taille du volume à 4Go."
msgid "Partitioning device %(device)s"
msgstr "Partitionnement du périphérique %(device)s"
-#: ../liveusb/gui.py:605
+#: ../liveusb/gui.py:607
msgid "Persistent Storage"
msgstr "Stockage persistant"
@@ -289,15 +290,15 @@ msgstr "Stockage persistant"
msgid "Persistent Storage (0 MB)"
msgstr "Stockage Persistant (0 Mo)"
-#: ../liveusb/gui.py:667 ../liveusb/gui.py:696
+#: ../liveusb/gui.py:669 ../liveusb/gui.py:698
msgid "Please confirm your device selection"
msgstr "Veuillez confirmer le périphérique sélectionné"
-#: ../liveusb/gui.py:451
+#: ../liveusb/gui.py:453
msgid "Refreshing releases..."
msgstr "Raffraîchissement des versions..."
-#: ../liveusb/gui.py:456
+#: ../liveusb/gui.py:458
msgid "Releases updated!"
msgstr "Version mise à jour!"
@@ -315,7 +316,7 @@ msgstr "Suppression du système d'exploitation Live existant"
msgid "Resetting Master Boot Record of %s"
msgstr "Réinitialisation du « Master Boot Record » de %s"
-#: ../liveusb/gui.py:758
+#: ../liveusb/gui.py:760
msgid "Select Live ISO"
msgstr "Sélectionnez l'ISO Live"
@@ -343,7 +344,7 @@ msgstr "Synchronisation des données sur le disque..."
msgid "Target Device"
msgstr "Périphérique Cible"
-#: ../liveusb/gui.py:761
+#: ../liveusb/gui.py:763
msgid ""
"The selected file is unreadable. Please fix its permissions or select "
"another file."
@@ -391,6 +392,10 @@ msgstr "C'eci est la console d'état, où tous les messages sont écrits."
msgid "Trying to continue anyway."
msgstr "On tente de continuer malgré tout."
+#: ../liveusb/gui.py:407
+msgid "USB drive found"
+msgstr "Lecteur USB détecté"
+
#: ../liveusb/creator.py:954
#, python-format
msgid "Unable to change volume label: %(message)s"
@@ -423,7 +428,7 @@ msgid ""
"Unable to get Win32_LogicalDisk; win32com query did not return any results"
msgstr "Impossible d'avoir accès à « Win32_LogicalDisk » ; la requête « win32com » n'a pas fourni de résultat."
-#: ../liveusb/gui.py:660
+#: ../liveusb/gui.py:662
msgid "Unable to mount device"
msgstr "Impossible de monter le périphérique"
@@ -447,7 +452,7 @@ msgid ""
"Unable to reset MBR. You may not have the `syslinux` package installed."
msgstr "Impossible de réinitialiser le MBR. Le paquet `syslinux` n'est sans doute pas installé."
-#: ../liveusb/gui.py:767
+#: ../liveusb/gui.py:769
msgid ""
"Unable to use the selected file. You may have better luck if you move your "
"ISO to the root of your drive (ie: C:\\)"
@@ -539,7 +544,7 @@ msgstr "Vérification de la somme de contrôle SHA256 de l'image du Live CD..."
msgid "Verifying filesystem..."
msgstr "Vérification du système de fichiers..."
-#: ../liveusb/gui.py:694
+#: ../liveusb/gui.py:696
msgid ""
"Warning: Creating a new persistent overlay will delete your existing one."
msgstr "Attention : la création d'une nouvelle zone de stockage persistant supprimera celle déjà existante."
@@ -556,14 +561,14 @@ msgstr "Attention : cet outil doit être exécuté en tant qu'Administrateur. P
msgid "Wrote to device at %(speed)d MB/sec"
msgstr "Écriture sur le périphérique effectuée à %(speed)d Mo/sec"
-#: ../liveusb/gui.py:668
+#: ../liveusb/gui.py:670
#, python-format
msgid ""
"You are going to install Tails on the %(size)s %(vendor)s %(model)s device "
"(%(device)s). All data on the selected device will be lost. Continue?"
msgstr "Vous allez installer Tails sur le périphérique %(size)s %(vendor)s %(model)s (%(device)s). Toutes les données sur ce périphérique seront perdues. Continuer?"
-#: ../liveusb/gui.py:684
+#: ../liveusb/gui.py:686
#, python-format
msgid ""
"You are going to upgrade Tails on the %(parent_size)s %(vendor)s %(model)s "
@@ -577,7 +582,7 @@ msgid ""
"ext4 filesystem"
msgstr "Vous utilisez une version obsolète de syslinux-extlinux, qui ne permet pas d'utiliser le système de fichiers ext4"
-#: ../liveusb/gui.py:752
+#: ../liveusb/gui.py:754
msgid "You can try again to resume your download"
msgstr "Vous pouvez essayer de reprendre votre téléchargement"
1
0

[translation/liveusb-creator] Update translations for liveusb-creator
by translation@torproject.org 23 Jan '15
by translation@torproject.org 23 Jan '15
23 Jan '15
commit 78fd46ad703c78f9257283707f8ccb6c3a1d990a
Author: Translation commit bot <translation(a)torproject.org>
Date: Fri Jan 23 21:45:17 2015 +0000
Update translations for liveusb-creator
---
fr/fr.po | 7 ++++---
1 file changed, 4 insertions(+), 3 deletions(-)
diff --git a/fr/fr.po b/fr/fr.po
index 23c82e1..8d1ce23 100644
--- a/fr/fr.po
+++ b/fr/fr.po
@@ -6,6 +6,7 @@
# bassmax, 2014
# Alex <chioubaca(a)gmail.com>, 2014
# arpalord <arpalord(a)gmail.com>, 2012
+# 5boro <bastien.pontet(a)gmail.com>, 2015
# Charles-Antoine Couret, 2009
# Charles-Antoine Couret <cacouret(a)wanadoo.fr>, 2009
# Emmanuel Simond, 2014
@@ -21,8 +22,8 @@ msgstr ""
"Project-Id-Version: The Tor Project\n"
"Report-Msgid-Bugs-To: \n"
"POT-Creation-Date: 2015-01-13 18:07+0100\n"
-"PO-Revision-Date: 2015-01-14 08:41+0000\n"
-"Last-Translator: runasand <runa.sandvik(a)gmail.com>\n"
+"PO-Revision-Date: 2015-01-23 21:42+0000\n"
+"Last-Translator: 5boro <bastien.pontet(a)gmail.com>\n"
"Language-Team: French (http://www.transifex.com/projects/p/torproject/language/fr/)\n"
"MIME-Version: 1.0\n"
"Content-Type: text/plain; charset=UTF-8\n"
@@ -393,7 +394,7 @@ msgstr "On tente de continuer malgré tout."
#: ../liveusb/gui.py:407
msgid "USB drive found"
-msgstr ""
+msgstr "Lecteur USB détecté"
#: ../liveusb/creator.py:954
#, python-format
1
0

23 Jan '15
commit 8f9fb3e8fae31e3c14811911f23537cfecc6b780
Author: Nick Mathewson <nickm(a)torproject.org>
Date: Fri Jan 23 11:35:05 2015 -0500
Try to fix some more memory leaks in the unit tests
---
src/test/test_address.c | 2 +-
src/test/test_config.c | 1 +
2 files changed, 2 insertions(+), 1 deletion(-)
diff --git a/src/test/test_address.c b/src/test/test_address.c
index f16f18e..f98cc12 100644
--- a/src/test/test_address.c
+++ b/src/test/test_address.c
@@ -228,7 +228,7 @@ test_address_get_if_addrs_ifaddrs(void *arg)
done:
SMARTLIST_FOREACH(results, tor_addr_t *, t, tor_free(t));
- tor_free(results);
+ smartlist_free(results);
return;
}
diff --git a/src/test/test_config.c b/src/test/test_config.c
index b1f5017..b63b78e 100644
--- a/src/test/test_config.c
+++ b/src/test/test_config.c
@@ -176,6 +176,7 @@ test_config_addressmap(void *arg)
done:
config_free_lines(get_options_mutable()->AddressMap);
get_options_mutable()->AddressMap = NULL;
+ addressmap_free_all();
}
static int
1
0

23 Jan '15
commit 614fbf1812690eb1cc2f52289d72ad2839f0ef9c
Author: Nick Mathewson <nickm(a)torproject.org>
Date: Fri Jan 23 11:26:40 2015 -0500
Fix some memory leaks in new address tests
---
src/test/test_address.c | 9 ++++++---
1 file changed, 6 insertions(+), 3 deletions(-)
diff --git a/src/test/test_address.c b/src/test/test_address.c
index 971618d..f16f18e 100644
--- a/src/test/test_address.c
+++ b/src/test/test_address.c
@@ -200,6 +200,9 @@ test_address_ifaddrs_to_smartlist(void *arg)
tor_free(ipv4_sockaddr_local);
tor_free(ipv4_sockaddr_remote);
tor_free(ipv6_sockaddr);
+ tor_free(ifa->ifa_name);
+ tor_free(ifa_ipv4->ifa_name);
+ tor_free(ifa_ipv6->ifa_name);
tor_free(ifa);
tor_free(ifa_ipv4);
tor_free(ifa_ipv6);
@@ -346,7 +349,7 @@ static void
test_address_ifreq_to_smartlist(void *arg)
{
smartlist_t *results = NULL;
- tor_addr_t *tor_addr = NULL;
+ const tor_addr_t *tor_addr = NULL;
struct sockaddr_in *sockaddr = NULL;
struct sockaddr_in *sockaddr_eth1 = NULL;
struct sockaddr_in *sockaddr_to_check = NULL;
@@ -392,7 +395,7 @@ test_address_ifreq_to_smartlist(void *arg)
sockaddr_eth1 = (struct sockaddr_in *) &(ifr_next->ifr_ifru.ifru_addr);
sockaddr_in_from_string("192.168.10.55",sockaddr_eth1);
-
+ SMARTLIST_FOREACH(results, tor_addr_t *, t, tor_free(t));
smartlist_free(results);
results = ifreq_to_smartlist((struct ifreq *)ifc->ifc_buf,ifc->ifc_len);
@@ -416,8 +419,8 @@ test_address_ifreq_to_smartlist(void *arg)
done:
tor_free(sockaddr_to_check);
+ SMARTLIST_FOREACH(results, tor_addr_t *, t, tor_free(t));
smartlist_free(results);
- tor_free(tor_addr);
tor_free(ifc);
tor_free(ifr);
return;
1
0

23 Jan '15
commit 7322de15dc2f0858291f40df1a55a66c80b7fda9
Author: Nick Mathewson <nickm(a)torproject.org>
Date: Fri Jan 23 11:15:53 2015 -0500
Split the slow unit tests into their own binary
This can run in parallel with the faster ones and the other tests.
---
.gitignore | 2 +
changes/ticket13243 | 3 +
src/test/include.am | 22 ++-
src/test/test.c | 271 +---------------------------
src/test/test_crypto.c | 393 -----------------------------------------
src/test/test_crypto_slow.c | 410 +++++++++++++++++++++++++++++++++++++++++++
src/test/test_slow.c | 29 +++
src/test/test_util.c | 369 --------------------------------------
src/test/test_util_slow.c | 388 ++++++++++++++++++++++++++++++++++++++++
src/test/testing_common.c | 298 +++++++++++++++++++++++++++++++
10 files changed, 1151 insertions(+), 1034 deletions(-)
diff --git a/.gitignore b/.gitignore
index e63576c..0cdf2c4 100644
--- a/.gitignore
+++ b/.gitignore
@@ -160,11 +160,13 @@ cscope.*
/src/test/bench
/src/test/bench.exe
/src/test/test
+/src/test/test-slow
/src/test/test-bt-cl
/src/test/test-child
/src/test/test-ntor-cl
/src/test/test_workqueue
/src/test/test.exe
+/src/test/test-slow.exe
/src/test/test-bt-cl.exe
/src/test/test-child.exe
/src/test/test-ntor-cl.exe
diff --git a/changes/ticket13243 b/changes/ticket13243
new file mode 100644
index 0000000..ad6e4de
--- /dev/null
+++ b/changes/ticket13243
@@ -0,0 +1,3 @@
+ o Testing:
+ - Move the slower unit tests into a new "./src/test/test-slow" binary
+ that can be run independently of the other tests. Closes ticket 13243.
diff --git a/src/test/include.am b/src/test/include.am
index d206033..595be0b 100644
--- a/src/test/include.am
+++ b/src/test/include.am
@@ -1,8 +1,12 @@
-TESTS += src/test/test
+TESTS += src/test/test src/test/test-slow
noinst_PROGRAMS+= src/test/bench
if UNITTESTS_ENABLED
-noinst_PROGRAMS+= src/test/test src/test/test-child src/test/test_workqueue
+noinst_PROGRAMS+= \
+ src/test/test \
+ src/test/test-slow \
+ src/test/test-child \
+ src/test/test_workqueue
endif
src_test_AM_CPPFLAGS = -DSHARE_DATADIR="\"$(datadir)\"" \
@@ -57,8 +61,17 @@ src_test_test_SOURCES = \
src/test/test_status.c \
src/test/test_threads.c \
src/test/test_util.c \
+ src/test/testing_common.c \
src/ext/tinytest.c
+src_test_test_slow_SOURCES = \
+ src/test/test_slow.c \
+ src/test/test_crypto_slow.c \
+ src/test/test_util_slow.c \
+ src/test/testing_common.c \
+ src/ext/tinytest.c
+
+
src_test_test_CFLAGS = $(AM_CFLAGS) $(TEST_CFLAGS)
src_test_test_CPPFLAGS= $(src_test_AM_CPPFLAGS)
@@ -80,6 +93,11 @@ src_test_test_LDADD = src/or/libtor-testing.a src/common/libor-testing.a \
@TOR_OPENSSL_LIBS@ @TOR_LIB_WS32@ @TOR_LIB_GDI@ @CURVE25519_LIBS@ \
@TOR_SYSTEMD_LIBS@
+src_test_test_slow_CPPFLAGS = $(src_test_test_CPPFLAGS)
+src_test_test_slow_CFLAGS = $(src_test_test_CFLAGS)
+src_test_test_slow_LDADD = $(src_test_test_LDADD)
+src_test_test_slow_LDFLAGS = $(src_test_test_LDFLAGS)
+
src_test_bench_LDFLAGS = @TOR_LDFLAGS_zlib@ @TOR_LDFLAGS_openssl@ \
@TOR_LDFLAGS_libevent@
src_test_bench_LDADD = src/or/libtor.a src/common/libor.a \
diff --git a/src/test/test.c b/src/test/test.c
index d752336..ff4f517 100644
--- a/src/test/test.c
+++ b/src/test/test.c
@@ -3,10 +3,6 @@
* Copyright (c) 2007-2015, The Tor Project, Inc. */
/* See LICENSE for licensing information */
-/* Ordinarily defined in tor_main.c; this bit is just here to provide one
- * since we're not linking to tor_main.c */
-const char tor_git_revision[] = "";
-
/**
* \file test.c
* \brief Unit tests for many pieces of the lower level Tor modules.
@@ -67,171 +63,6 @@ double fabs(double x);
#include "crypto_curve25519.h"
#include "onion_ntor.h"
-#ifdef USE_DMALLOC
-#include <dmalloc.h>
-#include <openssl/crypto.h>
-#include "main.h"
-#endif
-
-/** Set to true if any unit test has failed. Mostly, this is set by the macros
- * in test.h */
-int have_failed = 0;
-
-/** Temporary directory (set up by setup_directory) under which we store all
- * our files during testing. */
-static char temp_dir[256];
-#ifdef _WIN32
-#define pid_t int
-#endif
-static pid_t temp_dir_setup_in_pid = 0;
-
-/** Select and create the temporary directory we'll use to run our unit tests.
- * Store it in <b>temp_dir</b>. Exit immediately if we can't create it.
- * idempotent. */
-static void
-setup_directory(void)
-{
- static int is_setup = 0;
- int r;
- char rnd[256], rnd32[256];
- if (is_setup) return;
-
-/* Due to base32 limitation needs to be a multiple of 5. */
-#define RAND_PATH_BYTES 5
- crypto_rand(rnd, RAND_PATH_BYTES);
- base32_encode(rnd32, sizeof(rnd32), rnd, RAND_PATH_BYTES);
-
-#ifdef _WIN32
- {
- char buf[MAX_PATH];
- const char *tmp = buf;
- const char *extra_backslash = "";
- /* If this fails, we're probably screwed anyway */
- if (!GetTempPathA(sizeof(buf),buf))
- tmp = "c:\\windows\\temp\\";
- if (strcmpend(tmp, "\\")) {
- /* According to MSDN, it should be impossible for GetTempPath to give us
- * an answer that doesn't end with \. But let's make sure. */
- extra_backslash = "\\";
- }
- tor_snprintf(temp_dir, sizeof(temp_dir),
- "%s%stor_test_%d_%s", tmp, extra_backslash,
- (int)getpid(), rnd32);
- r = mkdir(temp_dir);
- }
-#else
- tor_snprintf(temp_dir, sizeof(temp_dir), "/tmp/tor_test_%d_%s",
- (int) getpid(), rnd32);
- r = mkdir(temp_dir, 0700);
- if (!r) {
- /* undo sticky bit so tests don't get confused. */
- r = chown(temp_dir, getuid(), getgid());
- }
-#endif
- if (r) {
- fprintf(stderr, "Can't create directory %s:", temp_dir);
- perror("");
- exit(1);
- }
- is_setup = 1;
- temp_dir_setup_in_pid = getpid();
-}
-
-/** Return a filename relative to our testing temporary directory */
-const char *
-get_fname(const char *name)
-{
- static char buf[1024];
- setup_directory();
- if (!name)
- return temp_dir;
- tor_snprintf(buf,sizeof(buf),"%s/%s",temp_dir,name);
- return buf;
-}
-
-/* Remove a directory and all of its subdirectories */
-static void
-rm_rf(const char *dir)
-{
- struct stat st;
- smartlist_t *elements;
-
- elements = tor_listdir(dir);
- if (elements) {
- SMARTLIST_FOREACH_BEGIN(elements, const char *, cp) {
- char *tmp = NULL;
- tor_asprintf(&tmp, "%s"PATH_SEPARATOR"%s", dir, cp);
- if (0 == stat(tmp,&st) && (st.st_mode & S_IFDIR)) {
- rm_rf(tmp);
- } else {
- if (unlink(tmp)) {
- fprintf(stderr, "Error removing %s: %s\n", tmp, strerror(errno));
- }
- }
- tor_free(tmp);
- } SMARTLIST_FOREACH_END(cp);
- SMARTLIST_FOREACH(elements, char *, cp, tor_free(cp));
- smartlist_free(elements);
- }
- if (rmdir(dir))
- fprintf(stderr, "Error removing directory %s: %s\n", dir, strerror(errno));
-}
-
-/** Remove all files stored under the temporary directory, and the directory
- * itself. Called by atexit(). */
-static void
-remove_directory(void)
-{
- if (getpid() != temp_dir_setup_in_pid) {
- /* Only clean out the tempdir when the main process is exiting. */
- return;
- }
-
- rm_rf(temp_dir);
-}
-
-/** Define this if unit tests spend too much time generating public keys*/
-#undef CACHE_GENERATED_KEYS
-
-static crypto_pk_t *pregen_keys[5] = {NULL, NULL, NULL, NULL, NULL};
-#define N_PREGEN_KEYS ARRAY_LENGTH(pregen_keys)
-
-/** Generate and return a new keypair for use in unit tests. If we're using
- * the key cache optimization, we might reuse keys: we only guarantee that
- * keys made with distinct values for <b>idx</b> are different. The value of
- * <b>idx</b> must be at least 0, and less than N_PREGEN_KEYS. */
-crypto_pk_t *
-pk_generate(int idx)
-{
-#ifdef CACHE_GENERATED_KEYS
- tor_assert(idx < N_PREGEN_KEYS);
- if (! pregen_keys[idx]) {
- pregen_keys[idx] = crypto_pk_new();
- tor_assert(!crypto_pk_generate_key(pregen_keys[idx]));
- }
- return crypto_pk_dup_key(pregen_keys[idx]);
-#else
- crypto_pk_t *result;
- (void) idx;
- result = crypto_pk_new();
- tor_assert(!crypto_pk_generate_key(result));
- return result;
-#endif
-}
-
-/** Free all storage used for the cached key optimization. */
-static void
-free_pregenerated_keys(void)
-{
- unsigned idx;
- for (idx = 0; idx < N_PREGEN_KEYS; ++idx) {
- if (pregen_keys[idx]) {
- crypto_pk_free(pregen_keys[idx]);
- pregen_keys[idx] = NULL;
- }
- }
-}
-
/** Run unit tests for the onion handshake code. */
static void
test_onion_handshake(void *arg)
@@ -1258,23 +1089,6 @@ test_stats(void *arg)
tor_free(s);
}
-static void *
-passthrough_test_setup(const struct testcase_t *testcase)
-{
- return testcase->setup_data;
-}
-static int
-passthrough_test_cleanup(const struct testcase_t *testcase, void *ptr)
-{
- (void)testcase;
- (void)ptr;
- return 1;
-}
-
-const struct testcase_setup_t passthrough_setup = {
- passthrough_test_setup, passthrough_test_cleanup
-};
-
#define ENT(name) \
{ #name, test_ ## name , 0, NULL, NULL }
#define FORK(name) \
@@ -1335,7 +1149,7 @@ extern struct testcase_t status_tests[];
extern struct testcase_t thread_tests[];
extern struct testcase_t util_tests[];
-static struct testgroup_t testgroups[] = {
+struct testgroup_t testgroups[] = {
{ "", test_array },
{ "accounting/", accounting_tests },
{ "addr/", addr_tests },
@@ -1379,86 +1193,3 @@ static struct testgroup_t testgroups[] = {
END_OF_GROUPS
};
-/** Main entry point for unit test code: parse the command line, and run
- * some unit tests. */
-int
-main(int c, const char **v)
-{
- or_options_t *options;
- char *errmsg = NULL;
- int i, i_out;
- int loglevel = LOG_ERR;
- int accel_crypto = 0;
-
-#ifdef USE_DMALLOC
- {
- int r = CRYPTO_set_mem_ex_functions(tor_malloc_, tor_realloc_, tor_free_);
- tor_assert(r);
- }
-#endif
-
- update_approx_time(time(NULL));
- options = options_new();
- tor_threads_init();
- init_logging(1);
- configure_backtrace_handler(get_version());
-
- for (i_out = i = 1; i < c; ++i) {
- if (!strcmp(v[i], "--warn")) {
- loglevel = LOG_WARN;
- } else if (!strcmp(v[i], "--notice")) {
- loglevel = LOG_NOTICE;
- } else if (!strcmp(v[i], "--info")) {
- loglevel = LOG_INFO;
- } else if (!strcmp(v[i], "--debug")) {
- loglevel = LOG_DEBUG;
- } else if (!strcmp(v[i], "--accel")) {
- accel_crypto = 1;
- } else {
- v[i_out++] = v[i];
- }
- }
- c = i_out;
-
- {
- log_severity_list_t s;
- memset(&s, 0, sizeof(s));
- set_log_severity_config(loglevel, LOG_ERR, &s);
- add_stream_log(&s, "", fileno(stdout));
- }
-
- options->command = CMD_RUN_UNITTESTS;
- if (crypto_global_init(accel_crypto, NULL, NULL)) {
- printf("Can't initialize crypto subsystem; exiting.\n");
- return 1;
- }
- crypto_set_tls_dh_prime(NULL);
- crypto_seed_rng(1);
- rep_hist_init();
- network_init();
- setup_directory();
- options_init(options);
- options->DataDirectory = tor_strdup(temp_dir);
- options->EntryStatistics = 1;
- if (set_options(options, &errmsg) < 0) {
- printf("Failed to set initial options: %s\n", errmsg);
- tor_free(errmsg);
- return 1;
- }
-
- atexit(remove_directory);
-
- have_failed = (tinytest_main(c, v, testgroups) != 0);
-
- free_pregenerated_keys();
-#ifdef USE_DMALLOC
- tor_free_all(0);
- dmalloc_log_unfreed();
-#endif
-
- if (have_failed)
- return 1;
- else
- return 0;
-}
-
diff --git a/src/test/test_crypto.c b/src/test/test_crypto.c
index 8426c71..e9fb8bf 100644
--- a/src/test/test_crypto.c
+++ b/src/test/test_crypto.c
@@ -5,7 +5,6 @@
#include "orconfig.h"
#define CRYPTO_CURVE25519_PRIVATE
-#define CRYPTO_S2K_PRIVATE
#include "or.h"
#include "test.h"
#include "aes.h"
@@ -14,8 +13,6 @@
#include "crypto_curve25519.h"
#include "crypto_ed25519.h"
#include "ed25519_vectors.inc"
-#include "crypto_s2k.h"
-#include "crypto_pwbox.h"
extern const char AUTHORITY_SIGNKEY_3[];
extern const char AUTHORITY_SIGNKEY_A_DIGEST[];
@@ -712,379 +709,6 @@ test_crypto_formats(void *arg)
tor_free(data3);
}
-/** Run unit tests for our secret-to-key passphrase hashing functionality. */
-static void
-test_crypto_s2k_rfc2440(void *arg)
-{
- char buf[29];
- char buf2[29];
- char *buf3 = NULL;
- int i;
-
- (void)arg;
- memset(buf, 0, sizeof(buf));
- memset(buf2, 0, sizeof(buf2));
- buf3 = tor_malloc(65536);
- memset(buf3, 0, 65536);
-
- secret_to_key_rfc2440(buf+9, 20, "", 0, buf);
- crypto_digest(buf2+9, buf3, 1024);
- tt_mem_op(buf,OP_EQ, buf2, 29);
-
- memcpy(buf,"vrbacrda",8);
- memcpy(buf2,"vrbacrda",8);
- buf[8] = 96;
- buf2[8] = 96;
- secret_to_key_rfc2440(buf+9, 20, "12345678", 8, buf);
- for (i = 0; i < 65536; i += 16) {
- memcpy(buf3+i, "vrbacrda12345678", 16);
- }
- crypto_digest(buf2+9, buf3, 65536);
- tt_mem_op(buf,OP_EQ, buf2, 29);
-
- done:
- tor_free(buf3);
-}
-
-static void
-run_s2k_tests(const unsigned flags, const unsigned type,
- int speclen, const int keylen, int legacy)
-{
- uint8_t buf[S2K_MAXLEN], buf2[S2K_MAXLEN], buf3[S2K_MAXLEN];
- int r;
- size_t sz;
- const char pw1[] = "You can't come in here unless you say swordfish!";
- const char pw2[] = "Now, I give you one more guess.";
-
- r = secret_to_key_new(buf, sizeof(buf), &sz,
- pw1, strlen(pw1), flags);
- tt_int_op(r, OP_EQ, S2K_OKAY);
- tt_int_op(buf[0], OP_EQ, type);
-
- tt_int_op(sz, OP_EQ, keylen + speclen);
-
- if (legacy) {
- memmove(buf, buf+1, sz-1);
- --sz;
- --speclen;
- }
-
- tt_int_op(S2K_OKAY, OP_EQ,
- secret_to_key_check(buf, sz, pw1, strlen(pw1)));
-
- tt_int_op(S2K_BAD_SECRET, OP_EQ,
- secret_to_key_check(buf, sz, pw2, strlen(pw2)));
-
- /* Move key to buf2, and clear it. */
- memset(buf3, 0, sizeof(buf3));
- memcpy(buf2, buf+speclen, keylen);
- memset(buf+speclen, 0, sz - speclen);
-
- /* Derivekey should produce the same results. */
- tt_int_op(S2K_OKAY, OP_EQ,
- secret_to_key_derivekey(buf3, keylen, buf, speclen, pw1, strlen(pw1)));
-
- tt_mem_op(buf2, OP_EQ, buf3, keylen);
-
- /* Derivekey with a longer output should fill the output. */
- memset(buf2, 0, sizeof(buf2));
- tt_int_op(S2K_OKAY, OP_EQ,
- secret_to_key_derivekey(buf2, sizeof(buf2), buf, speclen,
- pw1, strlen(pw1)));
-
- tt_mem_op(buf2, OP_NE, buf3, sizeof(buf2));
-
- memset(buf3, 0, sizeof(buf3));
- tt_int_op(S2K_OKAY, OP_EQ,
- secret_to_key_derivekey(buf3, sizeof(buf3), buf, speclen,
- pw1, strlen(pw1)));
- tt_mem_op(buf2, OP_EQ, buf3, sizeof(buf3));
- tt_assert(!tor_mem_is_zero((char*)buf2+keylen, sizeof(buf2)-keylen));
-
- done:
- ;
-}
-
-static void
-test_crypto_s2k_general(void *arg)
-{
- const char *which = arg;
-
- if (!strcmp(which, "scrypt")) {
- run_s2k_tests(0, 2, 19, 32, 0);
- } else if (!strcmp(which, "scrypt-low")) {
- run_s2k_tests(S2K_FLAG_LOW_MEM, 2, 19, 32, 0);
- } else if (!strcmp(which, "pbkdf2")) {
- run_s2k_tests(S2K_FLAG_USE_PBKDF2, 1, 18, 20, 0);
- } else if (!strcmp(which, "rfc2440")) {
- run_s2k_tests(S2K_FLAG_NO_SCRYPT, 0, 10, 20, 0);
- } else if (!strcmp(which, "rfc2440-legacy")) {
- run_s2k_tests(S2K_FLAG_NO_SCRYPT, 0, 10, 20, 1);
- } else {
- tt_fail();
- }
-}
-
-static void
-test_crypto_s2k_errors(void *arg)
-{
- uint8_t buf[S2K_MAXLEN], buf2[S2K_MAXLEN];
- size_t sz;
-
- (void)arg;
-
- /* Bogus specifiers: simple */
- tt_int_op(S2K_BAD_LEN, OP_EQ,
- secret_to_key_derivekey(buf, sizeof(buf),
- (const uint8_t*)"", 0, "ABC", 3));
- tt_int_op(S2K_BAD_ALGORITHM, OP_EQ,
- secret_to_key_derivekey(buf, sizeof(buf),
- (const uint8_t*)"\x10", 1, "ABC", 3));
- tt_int_op(S2K_BAD_LEN, OP_EQ,
- secret_to_key_derivekey(buf, sizeof(buf),
- (const uint8_t*)"\x01\x02", 2, "ABC", 3));
-
- tt_int_op(S2K_BAD_LEN, OP_EQ,
- secret_to_key_check((const uint8_t*)"", 0, "ABC", 3));
- tt_int_op(S2K_BAD_ALGORITHM, OP_EQ,
- secret_to_key_check((const uint8_t*)"\x10", 1, "ABC", 3));
- tt_int_op(S2K_BAD_LEN, OP_EQ,
- secret_to_key_check((const uint8_t*)"\x01\x02", 2, "ABC", 3));
-
- /* too long gets "BAD_LEN" too */
- memset(buf, 0, sizeof(buf));
- buf[0] = 2;
- tt_int_op(S2K_BAD_LEN, OP_EQ,
- secret_to_key_derivekey(buf2, sizeof(buf2),
- buf, sizeof(buf), "ABC", 3));
-
- /* Truncated output */
-#ifdef HAVE_LIBSCRYPT_H
- tt_int_op(S2K_TRUNCATED, OP_EQ, secret_to_key_new(buf, 50, &sz,
- "ABC", 3, 0));
- tt_int_op(S2K_TRUNCATED, OP_EQ, secret_to_key_new(buf, 50, &sz,
- "ABC", 3, S2K_FLAG_LOW_MEM));
-#endif
- tt_int_op(S2K_TRUNCATED, OP_EQ, secret_to_key_new(buf, 37, &sz,
- "ABC", 3, S2K_FLAG_USE_PBKDF2));
- tt_int_op(S2K_TRUNCATED, OP_EQ, secret_to_key_new(buf, 29, &sz,
- "ABC", 3, S2K_FLAG_NO_SCRYPT));
-
-#ifdef HAVE_LIBSCRYPT_H
- tt_int_op(S2K_TRUNCATED, OP_EQ, secret_to_key_make_specifier(buf, 18, 0));
- tt_int_op(S2K_TRUNCATED, OP_EQ, secret_to_key_make_specifier(buf, 18,
- S2K_FLAG_LOW_MEM));
-#endif
- tt_int_op(S2K_TRUNCATED, OP_EQ, secret_to_key_make_specifier(buf, 17,
- S2K_FLAG_USE_PBKDF2));
- tt_int_op(S2K_TRUNCATED, OP_EQ, secret_to_key_make_specifier(buf, 9,
- S2K_FLAG_NO_SCRYPT));
-
- /* Now try using type-specific bogus specifiers. */
-
- /* It's a bad pbkdf2 buffer if it has an iteration count that would overflow
- * int32_t. */
- memset(buf, 0, sizeof(buf));
- buf[0] = 1; /* pbkdf2 */
- buf[17] = 100; /* 1<<100 is much bigger than INT32_MAX */
- tt_int_op(S2K_BAD_PARAMS, OP_EQ,
- secret_to_key_derivekey(buf2, sizeof(buf2),
- buf, 18, "ABC", 3));
-
-#ifdef HAVE_LIBSCRYPT_H
- /* It's a bad scrypt buffer if N would overflow uint64 */
- memset(buf, 0, sizeof(buf));
- buf[0] = 2; /* scrypt */
- buf[17] = 100; /* 1<<100 is much bigger than UINT64_MAX */
- tt_int_op(S2K_BAD_PARAMS, OP_EQ,
- secret_to_key_derivekey(buf2, sizeof(buf2),
- buf, 19, "ABC", 3));
-#endif
-
- done:
- ;
-}
-
-static void
-test_crypto_scrypt_vectors(void *arg)
-{
- char *mem_op_hex_tmp = NULL;
- uint8_t spec[64], out[64];
-
- (void)arg;
-#ifndef HAVE_LIBSCRYPT_H
- if (1)
- tt_skip();
-#endif
-
- /* Test vectors from
- http://tools.ietf.org/html/draft-josefsson-scrypt-kdf-00 section 11.
-
- Note that the names of 'r' and 'N' are switched in that section. Or
- possibly in libscrypt.
- */
-
- base16_decode((char*)spec, sizeof(spec),
- "0400", 4);
- memset(out, 0x00, sizeof(out));
- tt_int_op(64, OP_EQ,
- secret_to_key_compute_key(out, 64, spec, 2, "", 0, 2));
- test_memeq_hex(out,
- "77d6576238657b203b19ca42c18a0497"
- "f16b4844e3074ae8dfdffa3fede21442"
- "fcd0069ded0948f8326a753a0fc81f17"
- "e8d3e0fb2e0d3628cf35e20c38d18906");
-
- base16_decode((char*)spec, sizeof(spec),
- "4e61436c" "0A34", 12);
- memset(out, 0x00, sizeof(out));
- tt_int_op(64, OP_EQ,
- secret_to_key_compute_key(out, 64, spec, 6, "password", 8, 2));
- test_memeq_hex(out,
- "fdbabe1c9d3472007856e7190d01e9fe"
- "7c6ad7cbc8237830e77376634b373162"
- "2eaf30d92e22a3886ff109279d9830da"
- "c727afb94a83ee6d8360cbdfa2cc0640");
-
- base16_decode((char*)spec, sizeof(spec),
- "536f6469756d43686c6f72696465" "0e30", 32);
- memset(out, 0x00, sizeof(out));
- tt_int_op(64, OP_EQ,
- secret_to_key_compute_key(out, 64, spec, 16,
- "pleaseletmein", 13, 2));
- test_memeq_hex(out,
- "7023bdcb3afd7348461c06cd81fd38eb"
- "fda8fbba904f8e3ea9b543f6545da1f2"
- "d5432955613f0fcf62d49705242a9af9"
- "e61e85dc0d651e40dfcf017b45575887");
-
- base16_decode((char*)spec, sizeof(spec),
- "536f6469756d43686c6f72696465" "1430", 32);
- memset(out, 0x00, sizeof(out));
- tt_int_op(64, OP_EQ,
- secret_to_key_compute_key(out, 64, spec, 16,
- "pleaseletmein", 13, 2));
- test_memeq_hex(out,
- "2101cb9b6a511aaeaddbbe09cf70f881"
- "ec568d574a2ffd4dabe5ee9820adaa47"
- "8e56fd8f4ba5d09ffa1c6d927c40f4c3"
- "37304049e8a952fbcbf45c6fa77a41a4");
-
- done:
- tor_free(mem_op_hex_tmp);
-}
-
-static void
-test_crypto_pbkdf2_vectors(void *arg)
-{
- char *mem_op_hex_tmp = NULL;
- uint8_t spec[64], out[64];
- (void)arg;
-
- /* Test vectors from RFC6070, section 2 */
- base16_decode((char*)spec, sizeof(spec),
- "73616c74" "00" , 10);
- memset(out, 0x00, sizeof(out));
- tt_int_op(20, OP_EQ,
- secret_to_key_compute_key(out, 20, spec, 5, "password", 8, 1));
- test_memeq_hex(out, "0c60c80f961f0e71f3a9b524af6012062fe037a6");
-
- base16_decode((char*)spec, sizeof(spec),
- "73616c74" "01" , 10);
- memset(out, 0x00, sizeof(out));
- tt_int_op(20, OP_EQ,
- secret_to_key_compute_key(out, 20, spec, 5, "password", 8, 1));
- test_memeq_hex(out, "ea6c014dc72d6f8ccd1ed92ace1d41f0d8de8957");
-
- base16_decode((char*)spec, sizeof(spec),
- "73616c74" "0C" , 10);
- memset(out, 0x00, sizeof(out));
- tt_int_op(20, OP_EQ,
- secret_to_key_compute_key(out, 20, spec, 5, "password", 8, 1));
- test_memeq_hex(out, "4b007901b765489abead49d926f721d065a429c1");
-
- base16_decode((char*)spec, sizeof(spec),
- "73616c74" "18" , 10);
- memset(out, 0x00, sizeof(out));
- tt_int_op(20, OP_EQ,
- secret_to_key_compute_key(out, 20, spec, 5, "password", 8, 1));
- test_memeq_hex(out, "eefe3d61cd4da4e4e9945b3d6ba2158c2634e984");
-
- base16_decode((char*)spec, sizeof(spec),
- "73616c7453414c5473616c7453414c5473616c745"
- "3414c5473616c7453414c5473616c74" "0C" , 74);
- memset(out, 0x00, sizeof(out));
- tt_int_op(25, OP_EQ,
- secret_to_key_compute_key(out, 25, spec, 37,
- "passwordPASSWORDpassword", 24, 1));
- test_memeq_hex(out, "3d2eec4fe41c849b80c8d83662c0e44a8b291a964cf2f07038");
-
- base16_decode((char*)spec, sizeof(spec),
- "7361006c74" "0c" , 12);
- memset(out, 0x00, sizeof(out));
- tt_int_op(16, OP_EQ,
- secret_to_key_compute_key(out, 16, spec, 6, "pass\0word", 9, 1));
- test_memeq_hex(out, "56fa6aa75548099dcc37d7f03425e0c3");
-
- done:
- tor_free(mem_op_hex_tmp);
-}
-
-static void
-test_crypto_pwbox(void *arg)
-{
- uint8_t *boxed=NULL, *decoded=NULL;
- size_t len, dlen;
- unsigned i;
- const char msg[] = "This bunny reminds you that you still have a "
- "salamander in your sylladex. She is holding the bunny Dave got you. "
- "It’s sort of uncanny how similar they are, aside from the knitted "
- "enhancements. Seriously, what are the odds?? So weird.";
- const char pw[] = "I'm a night owl and a wise bird too";
-
- const unsigned flags[] = { 0,
- S2K_FLAG_NO_SCRYPT,
- S2K_FLAG_LOW_MEM,
- S2K_FLAG_NO_SCRYPT|S2K_FLAG_LOW_MEM,
- S2K_FLAG_USE_PBKDF2 };
- (void)arg;
-
- for (i = 0; i < ARRAY_LENGTH(flags); ++i) {
- tt_int_op(0, OP_EQ, crypto_pwbox(&boxed, &len,
- (const uint8_t*)msg, strlen(msg),
- pw, strlen(pw), flags[i]));
- tt_assert(boxed);
- tt_assert(len > 128+32);
-
- tt_int_op(0, OP_EQ, crypto_unpwbox(&decoded, &dlen, boxed, len,
- pw, strlen(pw)));
-
- tt_assert(decoded);
- tt_uint_op(dlen, OP_EQ, strlen(msg));
- tt_mem_op(decoded, OP_EQ, msg, dlen);
-
- tor_free(decoded);
-
- tt_int_op(UNPWBOX_BAD_SECRET, OP_EQ, crypto_unpwbox(&decoded, &dlen,
- boxed, len,
- pw, strlen(pw)-1));
- boxed[len-1] ^= 1;
- tt_int_op(UNPWBOX_BAD_SECRET, OP_EQ, crypto_unpwbox(&decoded, &dlen,
- boxed, len,
- pw, strlen(pw)));
- boxed[0] = 255;
- tt_int_op(UNPWBOX_CORRUPTED, OP_EQ, crypto_unpwbox(&decoded, &dlen,
- boxed, len,
- pw, strlen(pw)));
-
- tor_free(boxed);
- }
-
- done:
- tor_free(boxed);
- tor_free(decoded);
-}
-
/** Test AES-CTR encryption and decryption with IV. */
static void
test_crypto_aes_iv(void *arg)
@@ -1988,23 +1612,6 @@ struct testcase_t crypto_tests[] = {
{ "pk_fingerprints", test_crypto_pk_fingerprints, TT_FORK, NULL, NULL },
CRYPTO_LEGACY(digests),
CRYPTO_LEGACY(dh),
- CRYPTO_LEGACY(s2k_rfc2440),
-#ifdef HAVE_LIBSCRYPT_H
- { "s2k_scrypt", test_crypto_s2k_general, 0, &passthrough_setup,
- (void*)"scrypt" },
- { "s2k_scrypt_low", test_crypto_s2k_general, 0, &passthrough_setup,
- (void*)"scrypt-low" },
-#endif
- { "s2k_pbkdf2", test_crypto_s2k_general, 0, &passthrough_setup,
- (void*)"pbkdf2" },
- { "s2k_rfc2440_general", test_crypto_s2k_general, 0, &passthrough_setup,
- (void*)"rfc2440" },
- { "s2k_rfc2440_legacy", test_crypto_s2k_general, 0, &passthrough_setup,
- (void*)"rfc2440-legacy" },
- { "s2k_errors", test_crypto_s2k_errors, 0, NULL, NULL },
- { "scrypt_vectors", test_crypto_scrypt_vectors, 0, NULL, NULL },
- { "pbkdf2_vectors", test_crypto_pbkdf2_vectors, 0, NULL, NULL },
- { "pwbox", test_crypto_pwbox, 0, NULL, NULL },
{ "aes_iv_AES", test_crypto_aes_iv, TT_FORK, &passthrough_setup,
(void*)"aes" },
{ "aes_iv_EVP", test_crypto_aes_iv, TT_FORK, &passthrough_setup,
diff --git a/src/test/test_crypto_slow.c b/src/test/test_crypto_slow.c
new file mode 100644
index 0000000..94fd69d
--- /dev/null
+++ b/src/test/test_crypto_slow.c
@@ -0,0 +1,410 @@
+/* Copyright (c) 2001-2004, Roger Dingledine.
+ * Copyright (c) 2004-2006, Roger Dingledine, Nick Mathewson.
+ * Copyright (c) 2007-2015, The Tor Project, Inc. */
+/* See LICENSE for licensing information */
+
+#include "orconfig.h"
+#define CRYPTO_S2K_PRIVATE
+#include "or.h"
+#include "test.h"
+#include "crypto_s2k.h"
+#include "crypto_pwbox.h"
+
+
+/** Run unit tests for our secret-to-key passphrase hashing functionality. */
+static void
+test_crypto_s2k_rfc2440(void *arg)
+{
+ char buf[29];
+ char buf2[29];
+ char *buf3 = NULL;
+ int i;
+
+ (void)arg;
+ memset(buf, 0, sizeof(buf));
+ memset(buf2, 0, sizeof(buf2));
+ buf3 = tor_malloc(65536);
+ memset(buf3, 0, 65536);
+
+ secret_to_key_rfc2440(buf+9, 20, "", 0, buf);
+ crypto_digest(buf2+9, buf3, 1024);
+ tt_mem_op(buf,OP_EQ, buf2, 29);
+
+ memcpy(buf,"vrbacrda",8);
+ memcpy(buf2,"vrbacrda",8);
+ buf[8] = 96;
+ buf2[8] = 96;
+ secret_to_key_rfc2440(buf+9, 20, "12345678", 8, buf);
+ for (i = 0; i < 65536; i += 16) {
+ memcpy(buf3+i, "vrbacrda12345678", 16);
+ }
+ crypto_digest(buf2+9, buf3, 65536);
+ tt_mem_op(buf,OP_EQ, buf2, 29);
+
+ done:
+ tor_free(buf3);
+}
+
+static void
+run_s2k_tests(const unsigned flags, const unsigned type,
+ int speclen, const int keylen, int legacy)
+{
+ uint8_t buf[S2K_MAXLEN], buf2[S2K_MAXLEN], buf3[S2K_MAXLEN];
+ int r;
+ size_t sz;
+ const char pw1[] = "You can't come in here unless you say swordfish!";
+ const char pw2[] = "Now, I give you one more guess.";
+
+ r = secret_to_key_new(buf, sizeof(buf), &sz,
+ pw1, strlen(pw1), flags);
+ tt_int_op(r, OP_EQ, S2K_OKAY);
+ tt_int_op(buf[0], OP_EQ, type);
+
+ tt_int_op(sz, OP_EQ, keylen + speclen);
+
+ if (legacy) {
+ memmove(buf, buf+1, sz-1);
+ --sz;
+ --speclen;
+ }
+
+ tt_int_op(S2K_OKAY, OP_EQ,
+ secret_to_key_check(buf, sz, pw1, strlen(pw1)));
+
+ tt_int_op(S2K_BAD_SECRET, OP_EQ,
+ secret_to_key_check(buf, sz, pw2, strlen(pw2)));
+
+ /* Move key to buf2, and clear it. */
+ memset(buf3, 0, sizeof(buf3));
+ memcpy(buf2, buf+speclen, keylen);
+ memset(buf+speclen, 0, sz - speclen);
+
+ /* Derivekey should produce the same results. */
+ tt_int_op(S2K_OKAY, OP_EQ,
+ secret_to_key_derivekey(buf3, keylen, buf, speclen, pw1, strlen(pw1)));
+
+ tt_mem_op(buf2, OP_EQ, buf3, keylen);
+
+ /* Derivekey with a longer output should fill the output. */
+ memset(buf2, 0, sizeof(buf2));
+ tt_int_op(S2K_OKAY, OP_EQ,
+ secret_to_key_derivekey(buf2, sizeof(buf2), buf, speclen,
+ pw1, strlen(pw1)));
+
+ tt_mem_op(buf2, OP_NE, buf3, sizeof(buf2));
+
+ memset(buf3, 0, sizeof(buf3));
+ tt_int_op(S2K_OKAY, OP_EQ,
+ secret_to_key_derivekey(buf3, sizeof(buf3), buf, speclen,
+ pw1, strlen(pw1)));
+ tt_mem_op(buf2, OP_EQ, buf3, sizeof(buf3));
+ tt_assert(!tor_mem_is_zero((char*)buf2+keylen, sizeof(buf2)-keylen));
+
+ done:
+ ;
+}
+
+static void
+test_crypto_s2k_general(void *arg)
+{
+ const char *which = arg;
+
+ if (!strcmp(which, "scrypt")) {
+ run_s2k_tests(0, 2, 19, 32, 0);
+ } else if (!strcmp(which, "scrypt-low")) {
+ run_s2k_tests(S2K_FLAG_LOW_MEM, 2, 19, 32, 0);
+ } else if (!strcmp(which, "pbkdf2")) {
+ run_s2k_tests(S2K_FLAG_USE_PBKDF2, 1, 18, 20, 0);
+ } else if (!strcmp(which, "rfc2440")) {
+ run_s2k_tests(S2K_FLAG_NO_SCRYPT, 0, 10, 20, 0);
+ } else if (!strcmp(which, "rfc2440-legacy")) {
+ run_s2k_tests(S2K_FLAG_NO_SCRYPT, 0, 10, 20, 1);
+ } else {
+ tt_fail();
+ }
+}
+
+static void
+test_crypto_s2k_errors(void *arg)
+{
+ uint8_t buf[S2K_MAXLEN], buf2[S2K_MAXLEN];
+ size_t sz;
+
+ (void)arg;
+
+ /* Bogus specifiers: simple */
+ tt_int_op(S2K_BAD_LEN, OP_EQ,
+ secret_to_key_derivekey(buf, sizeof(buf),
+ (const uint8_t*)"", 0, "ABC", 3));
+ tt_int_op(S2K_BAD_ALGORITHM, OP_EQ,
+ secret_to_key_derivekey(buf, sizeof(buf),
+ (const uint8_t*)"\x10", 1, "ABC", 3));
+ tt_int_op(S2K_BAD_LEN, OP_EQ,
+ secret_to_key_derivekey(buf, sizeof(buf),
+ (const uint8_t*)"\x01\x02", 2, "ABC", 3));
+
+ tt_int_op(S2K_BAD_LEN, OP_EQ,
+ secret_to_key_check((const uint8_t*)"", 0, "ABC", 3));
+ tt_int_op(S2K_BAD_ALGORITHM, OP_EQ,
+ secret_to_key_check((const uint8_t*)"\x10", 1, "ABC", 3));
+ tt_int_op(S2K_BAD_LEN, OP_EQ,
+ secret_to_key_check((const uint8_t*)"\x01\x02", 2, "ABC", 3));
+
+ /* too long gets "BAD_LEN" too */
+ memset(buf, 0, sizeof(buf));
+ buf[0] = 2;
+ tt_int_op(S2K_BAD_LEN, OP_EQ,
+ secret_to_key_derivekey(buf2, sizeof(buf2),
+ buf, sizeof(buf), "ABC", 3));
+
+ /* Truncated output */
+#ifdef HAVE_LIBSCRYPT_H
+ tt_int_op(S2K_TRUNCATED, OP_EQ, secret_to_key_new(buf, 50, &sz,
+ "ABC", 3, 0));
+ tt_int_op(S2K_TRUNCATED, OP_EQ, secret_to_key_new(buf, 50, &sz,
+ "ABC", 3, S2K_FLAG_LOW_MEM));
+#endif
+ tt_int_op(S2K_TRUNCATED, OP_EQ, secret_to_key_new(buf, 37, &sz,
+ "ABC", 3, S2K_FLAG_USE_PBKDF2));
+ tt_int_op(S2K_TRUNCATED, OP_EQ, secret_to_key_new(buf, 29, &sz,
+ "ABC", 3, S2K_FLAG_NO_SCRYPT));
+
+#ifdef HAVE_LIBSCRYPT_H
+ tt_int_op(S2K_TRUNCATED, OP_EQ, secret_to_key_make_specifier(buf, 18, 0));
+ tt_int_op(S2K_TRUNCATED, OP_EQ, secret_to_key_make_specifier(buf, 18,
+ S2K_FLAG_LOW_MEM));
+#endif
+ tt_int_op(S2K_TRUNCATED, OP_EQ, secret_to_key_make_specifier(buf, 17,
+ S2K_FLAG_USE_PBKDF2));
+ tt_int_op(S2K_TRUNCATED, OP_EQ, secret_to_key_make_specifier(buf, 9,
+ S2K_FLAG_NO_SCRYPT));
+
+ /* Now try using type-specific bogus specifiers. */
+
+ /* It's a bad pbkdf2 buffer if it has an iteration count that would overflow
+ * int32_t. */
+ memset(buf, 0, sizeof(buf));
+ buf[0] = 1; /* pbkdf2 */
+ buf[17] = 100; /* 1<<100 is much bigger than INT32_MAX */
+ tt_int_op(S2K_BAD_PARAMS, OP_EQ,
+ secret_to_key_derivekey(buf2, sizeof(buf2),
+ buf, 18, "ABC", 3));
+
+#ifdef HAVE_LIBSCRYPT_H
+ /* It's a bad scrypt buffer if N would overflow uint64 */
+ memset(buf, 0, sizeof(buf));
+ buf[0] = 2; /* scrypt */
+ buf[17] = 100; /* 1<<100 is much bigger than UINT64_MAX */
+ tt_int_op(S2K_BAD_PARAMS, OP_EQ,
+ secret_to_key_derivekey(buf2, sizeof(buf2),
+ buf, 19, "ABC", 3));
+#endif
+
+ done:
+ ;
+}
+
+static void
+test_crypto_scrypt_vectors(void *arg)
+{
+ char *mem_op_hex_tmp = NULL;
+ uint8_t spec[64], out[64];
+
+ (void)arg;
+#ifndef HAVE_LIBSCRYPT_H
+ if (1)
+ tt_skip();
+#endif
+
+ /* Test vectors from
+ http://tools.ietf.org/html/draft-josefsson-scrypt-kdf-00 section 11.
+
+ Note that the names of 'r' and 'N' are switched in that section. Or
+ possibly in libscrypt.
+ */
+
+ base16_decode((char*)spec, sizeof(spec),
+ "0400", 4);
+ memset(out, 0x00, sizeof(out));
+ tt_int_op(64, OP_EQ,
+ secret_to_key_compute_key(out, 64, spec, 2, "", 0, 2));
+ test_memeq_hex(out,
+ "77d6576238657b203b19ca42c18a0497"
+ "f16b4844e3074ae8dfdffa3fede21442"
+ "fcd0069ded0948f8326a753a0fc81f17"
+ "e8d3e0fb2e0d3628cf35e20c38d18906");
+
+ base16_decode((char*)spec, sizeof(spec),
+ "4e61436c" "0A34", 12);
+ memset(out, 0x00, sizeof(out));
+ tt_int_op(64, OP_EQ,
+ secret_to_key_compute_key(out, 64, spec, 6, "password", 8, 2));
+ test_memeq_hex(out,
+ "fdbabe1c9d3472007856e7190d01e9fe"
+ "7c6ad7cbc8237830e77376634b373162"
+ "2eaf30d92e22a3886ff109279d9830da"
+ "c727afb94a83ee6d8360cbdfa2cc0640");
+
+ base16_decode((char*)spec, sizeof(spec),
+ "536f6469756d43686c6f72696465" "0e30", 32);
+ memset(out, 0x00, sizeof(out));
+ tt_int_op(64, OP_EQ,
+ secret_to_key_compute_key(out, 64, spec, 16,
+ "pleaseletmein", 13, 2));
+ test_memeq_hex(out,
+ "7023bdcb3afd7348461c06cd81fd38eb"
+ "fda8fbba904f8e3ea9b543f6545da1f2"
+ "d5432955613f0fcf62d49705242a9af9"
+ "e61e85dc0d651e40dfcf017b45575887");
+
+ base16_decode((char*)spec, sizeof(spec),
+ "536f6469756d43686c6f72696465" "1430", 32);
+ memset(out, 0x00, sizeof(out));
+ tt_int_op(64, OP_EQ,
+ secret_to_key_compute_key(out, 64, spec, 16,
+ "pleaseletmein", 13, 2));
+ test_memeq_hex(out,
+ "2101cb9b6a511aaeaddbbe09cf70f881"
+ "ec568d574a2ffd4dabe5ee9820adaa47"
+ "8e56fd8f4ba5d09ffa1c6d927c40f4c3"
+ "37304049e8a952fbcbf45c6fa77a41a4");
+
+ done:
+ tor_free(mem_op_hex_tmp);
+}
+
+static void
+test_crypto_pbkdf2_vectors(void *arg)
+{
+ char *mem_op_hex_tmp = NULL;
+ uint8_t spec[64], out[64];
+ (void)arg;
+
+ /* Test vectors from RFC6070, section 2 */
+ base16_decode((char*)spec, sizeof(spec),
+ "73616c74" "00" , 10);
+ memset(out, 0x00, sizeof(out));
+ tt_int_op(20, OP_EQ,
+ secret_to_key_compute_key(out, 20, spec, 5, "password", 8, 1));
+ test_memeq_hex(out, "0c60c80f961f0e71f3a9b524af6012062fe037a6");
+
+ base16_decode((char*)spec, sizeof(spec),
+ "73616c74" "01" , 10);
+ memset(out, 0x00, sizeof(out));
+ tt_int_op(20, OP_EQ,
+ secret_to_key_compute_key(out, 20, spec, 5, "password", 8, 1));
+ test_memeq_hex(out, "ea6c014dc72d6f8ccd1ed92ace1d41f0d8de8957");
+
+ base16_decode((char*)spec, sizeof(spec),
+ "73616c74" "0C" , 10);
+ memset(out, 0x00, sizeof(out));
+ tt_int_op(20, OP_EQ,
+ secret_to_key_compute_key(out, 20, spec, 5, "password", 8, 1));
+ test_memeq_hex(out, "4b007901b765489abead49d926f721d065a429c1");
+
+ base16_decode((char*)spec, sizeof(spec),
+ "73616c74" "18" , 10);
+ memset(out, 0x00, sizeof(out));
+ tt_int_op(20, OP_EQ,
+ secret_to_key_compute_key(out, 20, spec, 5, "password", 8, 1));
+ test_memeq_hex(out, "eefe3d61cd4da4e4e9945b3d6ba2158c2634e984");
+
+ base16_decode((char*)spec, sizeof(spec),
+ "73616c7453414c5473616c7453414c5473616c745"
+ "3414c5473616c7453414c5473616c74" "0C" , 74);
+ memset(out, 0x00, sizeof(out));
+ tt_int_op(25, OP_EQ,
+ secret_to_key_compute_key(out, 25, spec, 37,
+ "passwordPASSWORDpassword", 24, 1));
+ test_memeq_hex(out, "3d2eec4fe41c849b80c8d83662c0e44a8b291a964cf2f07038");
+
+ base16_decode((char*)spec, sizeof(spec),
+ "7361006c74" "0c" , 12);
+ memset(out, 0x00, sizeof(out));
+ tt_int_op(16, OP_EQ,
+ secret_to_key_compute_key(out, 16, spec, 6, "pass\0word", 9, 1));
+ test_memeq_hex(out, "56fa6aa75548099dcc37d7f03425e0c3");
+
+ done:
+ tor_free(mem_op_hex_tmp);
+}
+
+static void
+test_crypto_pwbox(void *arg)
+{
+ uint8_t *boxed=NULL, *decoded=NULL;
+ size_t len, dlen;
+ unsigned i;
+ const char msg[] = "This bunny reminds you that you still have a "
+ "salamander in your sylladex. She is holding the bunny Dave got you. "
+ "It’s sort of uncanny how similar they are, aside from the knitted "
+ "enhancements. Seriously, what are the odds?? So weird.";
+ const char pw[] = "I'm a night owl and a wise bird too";
+
+ const unsigned flags[] = { 0,
+ S2K_FLAG_NO_SCRYPT,
+ S2K_FLAG_LOW_MEM,
+ S2K_FLAG_NO_SCRYPT|S2K_FLAG_LOW_MEM,
+ S2K_FLAG_USE_PBKDF2 };
+ (void)arg;
+
+ for (i = 0; i < ARRAY_LENGTH(flags); ++i) {
+ tt_int_op(0, OP_EQ, crypto_pwbox(&boxed, &len,
+ (const uint8_t*)msg, strlen(msg),
+ pw, strlen(pw), flags[i]));
+ tt_assert(boxed);
+ tt_assert(len > 128+32);
+
+ tt_int_op(0, OP_EQ, crypto_unpwbox(&decoded, &dlen, boxed, len,
+ pw, strlen(pw)));
+
+ tt_assert(decoded);
+ tt_uint_op(dlen, OP_EQ, strlen(msg));
+ tt_mem_op(decoded, OP_EQ, msg, dlen);
+
+ tor_free(decoded);
+
+ tt_int_op(UNPWBOX_BAD_SECRET, OP_EQ, crypto_unpwbox(&decoded, &dlen,
+ boxed, len,
+ pw, strlen(pw)-1));
+ boxed[len-1] ^= 1;
+ tt_int_op(UNPWBOX_BAD_SECRET, OP_EQ, crypto_unpwbox(&decoded, &dlen,
+ boxed, len,
+ pw, strlen(pw)));
+ boxed[0] = 255;
+ tt_int_op(UNPWBOX_CORRUPTED, OP_EQ, crypto_unpwbox(&decoded, &dlen,
+ boxed, len,
+ pw, strlen(pw)));
+
+ tor_free(boxed);
+ }
+
+ done:
+ tor_free(boxed);
+ tor_free(decoded);
+}
+
+#define CRYPTO_LEGACY(name) \
+ { #name, test_crypto_ ## name , 0, NULL, NULL }
+
+struct testcase_t slow_crypto_tests[] = {
+ CRYPTO_LEGACY(s2k_rfc2440),
+#ifdef HAVE_LIBSCRYPT_H
+ { "s2k_scrypt", test_crypto_s2k_general, 0, &passthrough_setup,
+ (void*)"scrypt" },
+ { "s2k_scrypt_low", test_crypto_s2k_general, 0, &passthrough_setup,
+ (void*)"scrypt-low" },
+#endif
+ { "s2k_pbkdf2", test_crypto_s2k_general, 0, &passthrough_setup,
+ (void*)"pbkdf2" },
+ { "s2k_rfc2440_general", test_crypto_s2k_general, 0, &passthrough_setup,
+ (void*)"rfc2440" },
+ { "s2k_rfc2440_legacy", test_crypto_s2k_general, 0, &passthrough_setup,
+ (void*)"rfc2440-legacy" },
+ { "s2k_errors", test_crypto_s2k_errors, 0, NULL, NULL },
+ { "scrypt_vectors", test_crypto_scrypt_vectors, 0, NULL, NULL },
+ { "pbkdf2_vectors", test_crypto_pbkdf2_vectors, 0, NULL, NULL },
+ { "pwbox", test_crypto_pwbox, 0, NULL, NULL },
+ END_OF_TESTCASES
+};
+
diff --git a/src/test/test_slow.c b/src/test/test_slow.c
new file mode 100644
index 0000000..32386b4
--- /dev/null
+++ b/src/test/test_slow.c
@@ -0,0 +1,29 @@
+/* Copyright (c) 2001-2004, Roger Dingledine.
+ * Copyright (c) 2004-2006, Roger Dingledine, Nick Mathewson.
+ * Copyright (c) 2007-2015, The Tor Project, Inc. */
+/* See LICENSE for licensing information */
+
+/**
+ * \file test_slow.c
+ * \brief Slower unit tests for many pieces of the lower level Tor modules.
+ **/
+
+#include "orconfig.h"
+
+#include <stdio.h>
+#ifdef HAVE_FCNTL_H
+#include <fcntl.h>
+#endif
+
+#include "or.h"
+#include "test.h"
+
+extern struct testcase_t slow_crypto_tests[];
+extern struct testcase_t slow_util_tests[];
+
+struct testgroup_t testgroups[] = {
+ { "slow/crypto/", slow_crypto_tests },
+ { "slow/util/", slow_util_tests },
+ END_OF_GROUPS
+};
+
diff --git a/src/test/test_util.c b/src/test/test_util.c
index b53c8fc..e5df5b4 100644
--- a/src/test/test_util.c
+++ b/src/test/test_util.c
@@ -3380,370 +3380,6 @@ test_util_fgets_eagain(void *ptr)
}
#endif
-#ifndef BUILDDIR
-#define BUILDDIR "."
-#endif
-
-#ifdef _WIN32
-#define notify_pending_waitpid_callbacks() STMT_NIL
-#define TEST_CHILD "test-child.exe"
-#define EOL "\r\n"
-#else
-#define TEST_CHILD (BUILDDIR "/src/test/test-child")
-#define EOL "\n"
-#endif
-
-#ifdef _WIN32
-/* I've assumed Windows doesn't have the gap between fork and exec
- * that causes the race condition on unix-like platforms */
-#define MATCH_PROCESS_STATUS(s1,s2) ((s1) == (s2))
-
-#else
-/* work around a race condition of the timing of SIGCHLD handler updates
- * to the process_handle's fields, and checks of those fields
- *
- * TODO: Once we can signal failure to exec, change PROCESS_STATUS_RUNNING to
- * PROCESS_STATUS_ERROR (and similarly with *_OR_NOTRUNNING) */
-#define PROCESS_STATUS_RUNNING_OR_NOTRUNNING (PROCESS_STATUS_RUNNING+1)
-#define IS_RUNNING_OR_NOTRUNNING(s) \
- ((s) == PROCESS_STATUS_RUNNING || (s) == PROCESS_STATUS_NOTRUNNING)
-/* well, this is ugly */
-#define MATCH_PROCESS_STATUS(s1,s2) \
- ( (s1) == (s2) \
- ||((s1) == PROCESS_STATUS_RUNNING_OR_NOTRUNNING \
- && IS_RUNNING_OR_NOTRUNNING(s2)) \
- ||((s2) == PROCESS_STATUS_RUNNING_OR_NOTRUNNING \
- && IS_RUNNING_OR_NOTRUNNING(s1)))
-
-#endif // _WIN32
-
-/** Helper function for testing tor_spawn_background */
-static void
-run_util_spawn_background(const char *argv[], const char *expected_out,
- const char *expected_err, int expected_exit,
- int expected_status)
-{
- int retval, exit_code;
- ssize_t pos;
- process_handle_t *process_handle=NULL;
- char stdout_buf[100], stderr_buf[100];
- int status;
-
- /* Start the program */
-#ifdef _WIN32
- status = tor_spawn_background(NULL, argv, NULL, &process_handle);
-#else
- status = tor_spawn_background(argv[0], argv, NULL, &process_handle);
-#endif
-
- notify_pending_waitpid_callbacks();
-
- /* the race condition doesn't affect status,
- * because status isn't updated by the SIGCHLD handler,
- * but we still need to handle PROCESS_STATUS_RUNNING_OR_NOTRUNNING */
- tt_assert(MATCH_PROCESS_STATUS(expected_status, status));
- if (status == PROCESS_STATUS_ERROR) {
- tt_ptr_op(process_handle, OP_EQ, NULL);
- return;
- }
-
- tt_assert(process_handle != NULL);
-
- /* When a spawned process forks, fails, then exits very quickly,
- * (this typically occurs when exec fails)
- * there is a race condition between the SIGCHLD handler
- * updating the process_handle's fields, and this test
- * checking the process status in those fields.
- * The SIGCHLD update can occur before or after the code below executes.
- * This causes intermittent failures in spawn_background_fail(),
- * typically when the machine is under load.
- * We use PROCESS_STATUS_RUNNING_OR_NOTRUNNING to avoid this issue. */
-
- /* the race condition affects the change in
- * process_handle->status from RUNNING to NOTRUNNING */
- tt_assert(MATCH_PROCESS_STATUS(expected_status, process_handle->status));
-
-#ifndef _WIN32
- notify_pending_waitpid_callbacks();
- /* the race condition affects the change in
- * process_handle->waitpid_cb to NULL,
- * so we skip the check if expected_status is ambiguous,
- * that is, PROCESS_STATUS_RUNNING_OR_NOTRUNNING */
- tt_assert(process_handle->waitpid_cb != NULL
- || expected_status == PROCESS_STATUS_RUNNING_OR_NOTRUNNING);
-#endif
-
-#ifdef _WIN32
- tt_assert(process_handle->stdout_pipe != INVALID_HANDLE_VALUE);
- tt_assert(process_handle->stderr_pipe != INVALID_HANDLE_VALUE);
-#else
- tt_assert(process_handle->stdout_pipe >= 0);
- tt_assert(process_handle->stderr_pipe >= 0);
-#endif
-
- /* Check stdout */
- pos = tor_read_all_from_process_stdout(process_handle, stdout_buf,
- sizeof(stdout_buf) - 1);
- tt_assert(pos >= 0);
- stdout_buf[pos] = '\0';
- tt_int_op(strlen(expected_out),OP_EQ, pos);
- tt_str_op(expected_out,OP_EQ, stdout_buf);
-
- notify_pending_waitpid_callbacks();
-
- /* Check it terminated correctly */
- retval = tor_get_exit_code(process_handle, 1, &exit_code);
- tt_int_op(PROCESS_EXIT_EXITED,OP_EQ, retval);
- tt_int_op(expected_exit,OP_EQ, exit_code);
- // TODO: Make test-child exit with something other than 0
-
-#ifndef _WIN32
- notify_pending_waitpid_callbacks();
- tt_ptr_op(process_handle->waitpid_cb, OP_EQ, NULL);
-#endif
-
- /* Check stderr */
- pos = tor_read_all_from_process_stderr(process_handle, stderr_buf,
- sizeof(stderr_buf) - 1);
- tt_assert(pos >= 0);
- stderr_buf[pos] = '\0';
- tt_str_op(expected_err,OP_EQ, stderr_buf);
- tt_int_op(strlen(expected_err),OP_EQ, pos);
-
- notify_pending_waitpid_callbacks();
-
- done:
- if (process_handle)
- tor_process_handle_destroy(process_handle, 1);
-}
-
-/** Check that we can launch a process and read the output */
-static void
-test_util_spawn_background_ok(void *ptr)
-{
- const char *argv[] = {TEST_CHILD, "--test", NULL};
- const char *expected_out = "OUT"EOL "--test"EOL "SLEEPING"EOL "DONE" EOL;
- const char *expected_err = "ERR"EOL;
-
- (void)ptr;
-
- run_util_spawn_background(argv, expected_out, expected_err, 0,
- PROCESS_STATUS_RUNNING);
-}
-
-/** Check that failing to find the executable works as expected */
-static void
-test_util_spawn_background_fail(void *ptr)
-{
- const char *argv[] = {BUILDDIR "/src/test/no-such-file", "--test", NULL};
- const char *expected_err = "";
- char expected_out[1024];
- char code[32];
-#ifdef _WIN32
- const int expected_status = PROCESS_STATUS_ERROR;
-#else
- /* TODO: Once we can signal failure to exec, set this to be
- * PROCESS_STATUS_RUNNING_OR_ERROR */
- const int expected_status = PROCESS_STATUS_RUNNING_OR_NOTRUNNING;
-#endif
-
- memset(expected_out, 0xf0, sizeof(expected_out));
- memset(code, 0xf0, sizeof(code));
-
- (void)ptr;
-
- tor_snprintf(code, sizeof(code), "%x/%x",
- 9 /* CHILD_STATE_FAILEXEC */ , ENOENT);
- tor_snprintf(expected_out, sizeof(expected_out),
- "ERR: Failed to spawn background process - code %s\n", code);
-
- run_util_spawn_background(argv, expected_out, expected_err, 255,
- expected_status);
-}
-
-/** Test that reading from a handle returns a partial read rather than
- * blocking */
-static void
-test_util_spawn_background_partial_read_impl(int exit_early)
-{
- const int expected_exit = 0;
- const int expected_status = PROCESS_STATUS_RUNNING;
-
- int retval, exit_code;
- ssize_t pos = -1;
- process_handle_t *process_handle=NULL;
- int status;
- char stdout_buf[100], stderr_buf[100];
-
- const char *argv[] = {TEST_CHILD, "--test", NULL};
- const char *expected_out[] = { "OUT" EOL "--test" EOL "SLEEPING" EOL,
- "DONE" EOL,
- NULL };
- const char *expected_err = "ERR" EOL;
-
-#ifndef _WIN32
- int eof = 0;
-#endif
- int expected_out_ctr;
-
- if (exit_early) {
- argv[1] = "--hang";
- expected_out[0] = "OUT"EOL "--hang"EOL "SLEEPING" EOL;
- }
-
- /* Start the program */
-#ifdef _WIN32
- status = tor_spawn_background(NULL, argv, NULL, &process_handle);
-#else
- status = tor_spawn_background(argv[0], argv, NULL, &process_handle);
-#endif
- tt_int_op(expected_status,OP_EQ, status);
- tt_assert(process_handle);
- tt_int_op(expected_status,OP_EQ, process_handle->status);
-
- /* Check stdout */
- for (expected_out_ctr = 0; expected_out[expected_out_ctr] != NULL;) {
-#ifdef _WIN32
- pos = tor_read_all_handle(process_handle->stdout_pipe, stdout_buf,
- sizeof(stdout_buf) - 1, NULL);
-#else
- /* Check that we didn't read the end of file last time */
- tt_assert(!eof);
- pos = tor_read_all_handle(process_handle->stdout_handle, stdout_buf,
- sizeof(stdout_buf) - 1, NULL, &eof);
-#endif
- log_info(LD_GENERAL, "tor_read_all_handle() returned %d", (int)pos);
-
- /* We would have blocked, keep on trying */
- if (0 == pos)
- continue;
-
- tt_assert(pos > 0);
- stdout_buf[pos] = '\0';
- tt_str_op(expected_out[expected_out_ctr],OP_EQ, stdout_buf);
- tt_int_op(strlen(expected_out[expected_out_ctr]),OP_EQ, pos);
- expected_out_ctr++;
- }
-
- if (exit_early) {
- tor_process_handle_destroy(process_handle, 1);
- process_handle = NULL;
- goto done;
- }
-
- /* The process should have exited without writing more */
-#ifdef _WIN32
- pos = tor_read_all_handle(process_handle->stdout_pipe, stdout_buf,
- sizeof(stdout_buf) - 1,
- process_handle);
- tt_int_op(0,OP_EQ, pos);
-#else
- if (!eof) {
- /* We should have got all the data, but maybe not the EOF flag */
- pos = tor_read_all_handle(process_handle->stdout_handle, stdout_buf,
- sizeof(stdout_buf) - 1,
- process_handle, &eof);
- tt_int_op(0,OP_EQ, pos);
- tt_assert(eof);
- }
- /* Otherwise, we got the EOF on the last read */
-#endif
-
- /* Check it terminated correctly */
- retval = tor_get_exit_code(process_handle, 1, &exit_code);
- tt_int_op(PROCESS_EXIT_EXITED,OP_EQ, retval);
- tt_int_op(expected_exit,OP_EQ, exit_code);
-
- // TODO: Make test-child exit with something other than 0
-
- /* Check stderr */
- pos = tor_read_all_from_process_stderr(process_handle, stderr_buf,
- sizeof(stderr_buf) - 1);
- tt_assert(pos >= 0);
- stderr_buf[pos] = '\0';
- tt_str_op(expected_err,OP_EQ, stderr_buf);
- tt_int_op(strlen(expected_err),OP_EQ, pos);
-
- done:
- tor_process_handle_destroy(process_handle, 1);
-}
-
-static void
-test_util_spawn_background_partial_read(void *arg)
-{
- (void)arg;
- test_util_spawn_background_partial_read_impl(0);
-}
-
-static void
-test_util_spawn_background_exit_early(void *arg)
-{
- (void)arg;
- test_util_spawn_background_partial_read_impl(1);
-}
-
-static void
-test_util_spawn_background_waitpid_notify(void *arg)
-{
- int retval, exit_code;
- process_handle_t *process_handle=NULL;
- int status;
- int ms_timer;
-
- const char *argv[] = {TEST_CHILD, "--fast", NULL};
-
- (void) arg;
-
-#ifdef _WIN32
- status = tor_spawn_background(NULL, argv, NULL, &process_handle);
-#else
- status = tor_spawn_background(argv[0], argv, NULL, &process_handle);
-#endif
-
- tt_int_op(status, OP_EQ, PROCESS_STATUS_RUNNING);
- tt_ptr_op(process_handle, OP_NE, NULL);
-
- /* We're not going to look at the stdout/stderr output this time. Instead,
- * we're testing whether notify_pending_waitpid_calbacks() can report the
- * process exit (on unix) and/or whether tor_get_exit_code() can notice it
- * (on windows) */
-
-#ifndef _WIN32
- ms_timer = 30*1000;
- tt_ptr_op(process_handle->waitpid_cb, OP_NE, NULL);
- while (process_handle->waitpid_cb && ms_timer > 0) {
- tor_sleep_msec(100);
- ms_timer -= 100;
- notify_pending_waitpid_callbacks();
- }
- tt_int_op(ms_timer, OP_GT, 0);
- tt_ptr_op(process_handle->waitpid_cb, OP_EQ, NULL);
-#endif
-
- ms_timer = 30*1000;
- while (((retval = tor_get_exit_code(process_handle, 0, &exit_code))
- == PROCESS_EXIT_RUNNING) && ms_timer > 0) {
- tor_sleep_msec(100);
- ms_timer -= 100;
- }
- tt_int_op(ms_timer, OP_GT, 0);
-
- tt_int_op(retval, OP_EQ, PROCESS_EXIT_EXITED);
-
- done:
- tor_process_handle_destroy(process_handle, 1);
-}
-
-#undef TEST_CHILD
-#undef EOL
-
-#undef MATCH_PROCESS_STATUS
-
-#ifndef _WIN32
-#undef PROCESS_STATUS_RUNNING_OR_NOTRUNNING
-#undef IS_RUNNING_OR_NOTRUNNING
-#endif
-
/**
* Test for format_hex_number_sigsafe()
*/
@@ -4796,11 +4432,6 @@ struct testcase_t util_tests[] = {
UTIL_TEST(exit_status, 0),
UTIL_TEST(fgets_eagain, 0),
#endif
- UTIL_TEST(spawn_background_ok, 0),
- UTIL_TEST(spawn_background_fail, 0),
- UTIL_TEST(spawn_background_partial_read, 0),
- UTIL_TEST(spawn_background_exit_early, 0),
- UTIL_TEST(spawn_background_waitpid_notify, 0),
UTIL_TEST(format_hex_number, 0),
UTIL_TEST(format_dec_number, 0),
UTIL_TEST(join_win_cmdline, 0),
diff --git a/src/test/test_util_slow.c b/src/test/test_util_slow.c
new file mode 100644
index 0000000..4adcbe1
--- /dev/null
+++ b/src/test/test_util_slow.c
@@ -0,0 +1,388 @@
+/* Copyright (c) 2001-2004, Roger Dingledine.
+ * Copyright (c) 2004-2006, Roger Dingledine, Nick Mathewson.
+ * Copyright (c) 2007-2015, The Tor Project, Inc. */
+/* See LICENSE for licensing information */
+
+#include "orconfig.h"
+#define UTIL_PRIVATE
+#include "util.h"
+#include "util_process.h"
+#include "crypto.h"
+#include "torlog.h"
+#include "test.h"
+
+#ifndef BUILDDIR
+#define BUILDDIR "."
+#endif
+
+#ifdef _WIN32
+#define notify_pending_waitpid_callbacks() STMT_NIL
+#define TEST_CHILD "test-child.exe"
+#define EOL "\r\n"
+#else
+#define TEST_CHILD (BUILDDIR "/src/test/test-child")
+#define EOL "\n"
+#endif
+
+#ifdef _WIN32
+/* I've assumed Windows doesn't have the gap between fork and exec
+ * that causes the race condition on unix-like platforms */
+#define MATCH_PROCESS_STATUS(s1,s2) ((s1) == (s2))
+
+#else
+/* work around a race condition of the timing of SIGCHLD handler updates
+ * to the process_handle's fields, and checks of those fields
+ *
+ * TODO: Once we can signal failure to exec, change PROCESS_STATUS_RUNNING to
+ * PROCESS_STATUS_ERROR (and similarly with *_OR_NOTRUNNING) */
+#define PROCESS_STATUS_RUNNING_OR_NOTRUNNING (PROCESS_STATUS_RUNNING+1)
+#define IS_RUNNING_OR_NOTRUNNING(s) \
+ ((s) == PROCESS_STATUS_RUNNING || (s) == PROCESS_STATUS_NOTRUNNING)
+/* well, this is ugly */
+#define MATCH_PROCESS_STATUS(s1,s2) \
+ ( (s1) == (s2) \
+ ||((s1) == PROCESS_STATUS_RUNNING_OR_NOTRUNNING \
+ && IS_RUNNING_OR_NOTRUNNING(s2)) \
+ ||((s2) == PROCESS_STATUS_RUNNING_OR_NOTRUNNING \
+ && IS_RUNNING_OR_NOTRUNNING(s1)))
+
+#endif // _WIN32
+
+/** Helper function for testing tor_spawn_background */
+static void
+run_util_spawn_background(const char *argv[], const char *expected_out,
+ const char *expected_err, int expected_exit,
+ int expected_status)
+{
+ int retval, exit_code;
+ ssize_t pos;
+ process_handle_t *process_handle=NULL;
+ char stdout_buf[100], stderr_buf[100];
+ int status;
+
+ /* Start the program */
+#ifdef _WIN32
+ status = tor_spawn_background(NULL, argv, NULL, &process_handle);
+#else
+ status = tor_spawn_background(argv[0], argv, NULL, &process_handle);
+#endif
+
+ notify_pending_waitpid_callbacks();
+
+ /* the race condition doesn't affect status,
+ * because status isn't updated by the SIGCHLD handler,
+ * but we still need to handle PROCESS_STATUS_RUNNING_OR_NOTRUNNING */
+ tt_assert(MATCH_PROCESS_STATUS(expected_status, status));
+ if (status == PROCESS_STATUS_ERROR) {
+ tt_ptr_op(process_handle, OP_EQ, NULL);
+ return;
+ }
+
+ tt_assert(process_handle != NULL);
+
+ /* When a spawned process forks, fails, then exits very quickly,
+ * (this typically occurs when exec fails)
+ * there is a race condition between the SIGCHLD handler
+ * updating the process_handle's fields, and this test
+ * checking the process status in those fields.
+ * The SIGCHLD update can occur before or after the code below executes.
+ * This causes intermittent failures in spawn_background_fail(),
+ * typically when the machine is under load.
+ * We use PROCESS_STATUS_RUNNING_OR_NOTRUNNING to avoid this issue. */
+
+ /* the race condition affects the change in
+ * process_handle->status from RUNNING to NOTRUNNING */
+ tt_assert(MATCH_PROCESS_STATUS(expected_status, process_handle->status));
+
+#ifndef _WIN32
+ notify_pending_waitpid_callbacks();
+ /* the race condition affects the change in
+ * process_handle->waitpid_cb to NULL,
+ * so we skip the check if expected_status is ambiguous,
+ * that is, PROCESS_STATUS_RUNNING_OR_NOTRUNNING */
+ tt_assert(process_handle->waitpid_cb != NULL
+ || expected_status == PROCESS_STATUS_RUNNING_OR_NOTRUNNING);
+#endif
+
+#ifdef _WIN32
+ tt_assert(process_handle->stdout_pipe != INVALID_HANDLE_VALUE);
+ tt_assert(process_handle->stderr_pipe != INVALID_HANDLE_VALUE);
+#else
+ tt_assert(process_handle->stdout_pipe >= 0);
+ tt_assert(process_handle->stderr_pipe >= 0);
+#endif
+
+ /* Check stdout */
+ pos = tor_read_all_from_process_stdout(process_handle, stdout_buf,
+ sizeof(stdout_buf) - 1);
+ tt_assert(pos >= 0);
+ stdout_buf[pos] = '\0';
+ tt_int_op(strlen(expected_out),OP_EQ, pos);
+ tt_str_op(expected_out,OP_EQ, stdout_buf);
+
+ notify_pending_waitpid_callbacks();
+
+ /* Check it terminated correctly */
+ retval = tor_get_exit_code(process_handle, 1, &exit_code);
+ tt_int_op(PROCESS_EXIT_EXITED,OP_EQ, retval);
+ tt_int_op(expected_exit,OP_EQ, exit_code);
+ // TODO: Make test-child exit with something other than 0
+
+#ifndef _WIN32
+ notify_pending_waitpid_callbacks();
+ tt_ptr_op(process_handle->waitpid_cb, OP_EQ, NULL);
+#endif
+
+ /* Check stderr */
+ pos = tor_read_all_from_process_stderr(process_handle, stderr_buf,
+ sizeof(stderr_buf) - 1);
+ tt_assert(pos >= 0);
+ stderr_buf[pos] = '\0';
+ tt_str_op(expected_err,OP_EQ, stderr_buf);
+ tt_int_op(strlen(expected_err),OP_EQ, pos);
+
+ notify_pending_waitpid_callbacks();
+
+ done:
+ if (process_handle)
+ tor_process_handle_destroy(process_handle, 1);
+}
+
+/** Check that we can launch a process and read the output */
+static void
+test_util_spawn_background_ok(void *ptr)
+{
+ const char *argv[] = {TEST_CHILD, "--test", NULL};
+ const char *expected_out = "OUT"EOL "--test"EOL "SLEEPING"EOL "DONE" EOL;
+ const char *expected_err = "ERR"EOL;
+
+ (void)ptr;
+
+ run_util_spawn_background(argv, expected_out, expected_err, 0,
+ PROCESS_STATUS_RUNNING);
+}
+
+/** Check that failing to find the executable works as expected */
+static void
+test_util_spawn_background_fail(void *ptr)
+{
+ const char *argv[] = {BUILDDIR "/src/test/no-such-file", "--test", NULL};
+ const char *expected_err = "";
+ char expected_out[1024];
+ char code[32];
+#ifdef _WIN32
+ const int expected_status = PROCESS_STATUS_ERROR;
+#else
+ /* TODO: Once we can signal failure to exec, set this to be
+ * PROCESS_STATUS_RUNNING_OR_ERROR */
+ const int expected_status = PROCESS_STATUS_RUNNING_OR_NOTRUNNING;
+#endif
+
+ memset(expected_out, 0xf0, sizeof(expected_out));
+ memset(code, 0xf0, sizeof(code));
+
+ (void)ptr;
+
+ tor_snprintf(code, sizeof(code), "%x/%x",
+ 9 /* CHILD_STATE_FAILEXEC */ , ENOENT);
+ tor_snprintf(expected_out, sizeof(expected_out),
+ "ERR: Failed to spawn background process - code %s\n", code);
+
+ run_util_spawn_background(argv, expected_out, expected_err, 255,
+ expected_status);
+}
+
+/** Test that reading from a handle returns a partial read rather than
+ * blocking */
+static void
+test_util_spawn_background_partial_read_impl(int exit_early)
+{
+ const int expected_exit = 0;
+ const int expected_status = PROCESS_STATUS_RUNNING;
+
+ int retval, exit_code;
+ ssize_t pos = -1;
+ process_handle_t *process_handle=NULL;
+ int status;
+ char stdout_buf[100], stderr_buf[100];
+
+ const char *argv[] = {TEST_CHILD, "--test", NULL};
+ const char *expected_out[] = { "OUT" EOL "--test" EOL "SLEEPING" EOL,
+ "DONE" EOL,
+ NULL };
+ const char *expected_err = "ERR" EOL;
+
+#ifndef _WIN32
+ int eof = 0;
+#endif
+ int expected_out_ctr;
+
+ if (exit_early) {
+ argv[1] = "--hang";
+ expected_out[0] = "OUT"EOL "--hang"EOL "SLEEPING" EOL;
+ }
+
+ /* Start the program */
+#ifdef _WIN32
+ status = tor_spawn_background(NULL, argv, NULL, &process_handle);
+#else
+ status = tor_spawn_background(argv[0], argv, NULL, &process_handle);
+#endif
+ tt_int_op(expected_status,OP_EQ, status);
+ tt_assert(process_handle);
+ tt_int_op(expected_status,OP_EQ, process_handle->status);
+
+ /* Check stdout */
+ for (expected_out_ctr = 0; expected_out[expected_out_ctr] != NULL;) {
+#ifdef _WIN32
+ pos = tor_read_all_handle(process_handle->stdout_pipe, stdout_buf,
+ sizeof(stdout_buf) - 1, NULL);
+#else
+ /* Check that we didn't read the end of file last time */
+ tt_assert(!eof);
+ pos = tor_read_all_handle(process_handle->stdout_handle, stdout_buf,
+ sizeof(stdout_buf) - 1, NULL, &eof);
+#endif
+ log_info(LD_GENERAL, "tor_read_all_handle() returned %d", (int)pos);
+
+ /* We would have blocked, keep on trying */
+ if (0 == pos)
+ continue;
+
+ tt_assert(pos > 0);
+ stdout_buf[pos] = '\0';
+ tt_str_op(expected_out[expected_out_ctr],OP_EQ, stdout_buf);
+ tt_int_op(strlen(expected_out[expected_out_ctr]),OP_EQ, pos);
+ expected_out_ctr++;
+ }
+
+ if (exit_early) {
+ tor_process_handle_destroy(process_handle, 1);
+ process_handle = NULL;
+ goto done;
+ }
+
+ /* The process should have exited without writing more */
+#ifdef _WIN32
+ pos = tor_read_all_handle(process_handle->stdout_pipe, stdout_buf,
+ sizeof(stdout_buf) - 1,
+ process_handle);
+ tt_int_op(0,OP_EQ, pos);
+#else
+ if (!eof) {
+ /* We should have got all the data, but maybe not the EOF flag */
+ pos = tor_read_all_handle(process_handle->stdout_handle, stdout_buf,
+ sizeof(stdout_buf) - 1,
+ process_handle, &eof);
+ tt_int_op(0,OP_EQ, pos);
+ tt_assert(eof);
+ }
+ /* Otherwise, we got the EOF on the last read */
+#endif
+
+ /* Check it terminated correctly */
+ retval = tor_get_exit_code(process_handle, 1, &exit_code);
+ tt_int_op(PROCESS_EXIT_EXITED,OP_EQ, retval);
+ tt_int_op(expected_exit,OP_EQ, exit_code);
+
+ // TODO: Make test-child exit with something other than 0
+
+ /* Check stderr */
+ pos = tor_read_all_from_process_stderr(process_handle, stderr_buf,
+ sizeof(stderr_buf) - 1);
+ tt_assert(pos >= 0);
+ stderr_buf[pos] = '\0';
+ tt_str_op(expected_err,OP_EQ, stderr_buf);
+ tt_int_op(strlen(expected_err),OP_EQ, pos);
+
+ done:
+ tor_process_handle_destroy(process_handle, 1);
+}
+
+static void
+test_util_spawn_background_partial_read(void *arg)
+{
+ (void)arg;
+ test_util_spawn_background_partial_read_impl(0);
+}
+
+static void
+test_util_spawn_background_exit_early(void *arg)
+{
+ (void)arg;
+ test_util_spawn_background_partial_read_impl(1);
+}
+
+static void
+test_util_spawn_background_waitpid_notify(void *arg)
+{
+ int retval, exit_code;
+ process_handle_t *process_handle=NULL;
+ int status;
+ int ms_timer;
+
+ const char *argv[] = {TEST_CHILD, "--fast", NULL};
+
+ (void) arg;
+
+#ifdef _WIN32
+ status = tor_spawn_background(NULL, argv, NULL, &process_handle);
+#else
+ status = tor_spawn_background(argv[0], argv, NULL, &process_handle);
+#endif
+
+ tt_int_op(status, OP_EQ, PROCESS_STATUS_RUNNING);
+ tt_ptr_op(process_handle, OP_NE, NULL);
+
+ /* We're not going to look at the stdout/stderr output this time. Instead,
+ * we're testing whether notify_pending_waitpid_calbacks() can report the
+ * process exit (on unix) and/or whether tor_get_exit_code() can notice it
+ * (on windows) */
+
+#ifndef _WIN32
+ ms_timer = 30*1000;
+ tt_ptr_op(process_handle->waitpid_cb, OP_NE, NULL);
+ while (process_handle->waitpid_cb && ms_timer > 0) {
+ tor_sleep_msec(100);
+ ms_timer -= 100;
+ notify_pending_waitpid_callbacks();
+ }
+ tt_int_op(ms_timer, OP_GT, 0);
+ tt_ptr_op(process_handle->waitpid_cb, OP_EQ, NULL);
+#endif
+
+ ms_timer = 30*1000;
+ while (((retval = tor_get_exit_code(process_handle, 0, &exit_code))
+ == PROCESS_EXIT_RUNNING) && ms_timer > 0) {
+ tor_sleep_msec(100);
+ ms_timer -= 100;
+ }
+ tt_int_op(ms_timer, OP_GT, 0);
+
+ tt_int_op(retval, OP_EQ, PROCESS_EXIT_EXITED);
+
+ done:
+ tor_process_handle_destroy(process_handle, 1);
+}
+
+#undef TEST_CHILD
+#undef EOL
+
+#undef MATCH_PROCESS_STATUS
+
+#ifndef _WIN32
+#undef PROCESS_STATUS_RUNNING_OR_NOTRUNNING
+#undef IS_RUNNING_OR_NOTRUNNING
+#endif
+
+#define UTIL_TEST(name, flags) \
+ { #name, test_util_ ## name, flags, NULL, NULL }
+
+struct testcase_t slow_util_tests[] = {
+ UTIL_TEST(spawn_background_ok, 0),
+ UTIL_TEST(spawn_background_fail, 0),
+ UTIL_TEST(spawn_background_partial_read, 0),
+ UTIL_TEST(spawn_background_exit_early, 0),
+ UTIL_TEST(spawn_background_waitpid_notify, 0),
+ END_OF_TESTCASES
+};
diff --git a/src/test/testing_common.c b/src/test/testing_common.c
new file mode 100644
index 0000000..d7d6dac
--- /dev/null
+++ b/src/test/testing_common.c
@@ -0,0 +1,298 @@
+/* Copyright (c) 2001-2004, Roger Dingledine.
+ * Copyright (c) 2004-2006, Roger Dingledine, Nick Mathewson.
+ * Copyright (c) 2007-2015, The Tor Project, Inc. */
+/* See LICENSE for licensing information */
+
+/* Ordinarily defined in tor_main.c; this bit is just here to provide one
+ * since we're not linking to tor_main.c */
+const char tor_git_revision[] = "";
+
+/**
+ * \file test_common.c
+ * \brief Common pieces to implement unit tests.
+ **/
+
+#include "orconfig.h"
+#include "or.h"
+#include "config.h"
+#include "rephist.h"
+#include "backtrace.h"
+#include "test.h"
+
+#include <stdio.h>
+#ifdef HAVE_FCNTL_H
+#include <fcntl.h>
+#endif
+
+#ifdef _WIN32
+/* For mkdir() */
+#include <direct.h>
+#else
+#include <dirent.h>
+#endif
+
+#include "or.h"
+
+#ifdef USE_DMALLOC
+#include <dmalloc.h>
+#include <openssl/crypto.h>
+#include "main.h"
+#endif
+
+/** Temporary directory (set up by setup_directory) under which we store all
+ * our files during testing. */
+static char temp_dir[256];
+#ifdef _WIN32
+#define pid_t int
+#endif
+static pid_t temp_dir_setup_in_pid = 0;
+
+/** Select and create the temporary directory we'll use to run our unit tests.
+ * Store it in <b>temp_dir</b>. Exit immediately if we can't create it.
+ * idempotent. */
+static void
+setup_directory(void)
+{
+ static int is_setup = 0;
+ int r;
+ char rnd[256], rnd32[256];
+ if (is_setup) return;
+
+/* Due to base32 limitation needs to be a multiple of 5. */
+#define RAND_PATH_BYTES 5
+ crypto_rand(rnd, RAND_PATH_BYTES);
+ base32_encode(rnd32, sizeof(rnd32), rnd, RAND_PATH_BYTES);
+
+#ifdef _WIN32
+ {
+ char buf[MAX_PATH];
+ const char *tmp = buf;
+ const char *extra_backslash = "";
+ /* If this fails, we're probably screwed anyway */
+ if (!GetTempPathA(sizeof(buf),buf))
+ tmp = "c:\\windows\\temp\\";
+ if (strcmpend(tmp, "\\")) {
+ /* According to MSDN, it should be impossible for GetTempPath to give us
+ * an answer that doesn't end with \. But let's make sure. */
+ extra_backslash = "\\";
+ }
+ tor_snprintf(temp_dir, sizeof(temp_dir),
+ "%s%stor_test_%d_%s", tmp, extra_backslash,
+ (int)getpid(), rnd32);
+ r = mkdir(temp_dir);
+ }
+#else
+ tor_snprintf(temp_dir, sizeof(temp_dir), "/tmp/tor_test_%d_%s",
+ (int) getpid(), rnd32);
+ r = mkdir(temp_dir, 0700);
+ if (!r) {
+ /* undo sticky bit so tests don't get confused. */
+ r = chown(temp_dir, getuid(), getgid());
+ }
+#endif
+ if (r) {
+ fprintf(stderr, "Can't create directory %s:", temp_dir);
+ perror("");
+ exit(1);
+ }
+ is_setup = 1;
+ temp_dir_setup_in_pid = getpid();
+}
+
+/** Return a filename relative to our testing temporary directory */
+const char *
+get_fname(const char *name)
+{
+ static char buf[1024];
+ setup_directory();
+ if (!name)
+ return temp_dir;
+ tor_snprintf(buf,sizeof(buf),"%s/%s",temp_dir,name);
+ return buf;
+}
+
+/* Remove a directory and all of its subdirectories */
+static void
+rm_rf(const char *dir)
+{
+ struct stat st;
+ smartlist_t *elements;
+
+ elements = tor_listdir(dir);
+ if (elements) {
+ SMARTLIST_FOREACH_BEGIN(elements, const char *, cp) {
+ char *tmp = NULL;
+ tor_asprintf(&tmp, "%s"PATH_SEPARATOR"%s", dir, cp);
+ if (0 == stat(tmp,&st) && (st.st_mode & S_IFDIR)) {
+ rm_rf(tmp);
+ } else {
+ if (unlink(tmp)) {
+ fprintf(stderr, "Error removing %s: %s\n", tmp, strerror(errno));
+ }
+ }
+ tor_free(tmp);
+ } SMARTLIST_FOREACH_END(cp);
+ SMARTLIST_FOREACH(elements, char *, cp, tor_free(cp));
+ smartlist_free(elements);
+ }
+ if (rmdir(dir))
+ fprintf(stderr, "Error removing directory %s: %s\n", dir, strerror(errno));
+}
+
+/** Remove all files stored under the temporary directory, and the directory
+ * itself. Called by atexit(). */
+static void
+remove_directory(void)
+{
+ if (getpid() != temp_dir_setup_in_pid) {
+ /* Only clean out the tempdir when the main process is exiting. */
+ return;
+ }
+
+ rm_rf(temp_dir);
+}
+
+/** Define this if unit tests spend too much time generating public keys*/
+#undef CACHE_GENERATED_KEYS
+
+static crypto_pk_t *pregen_keys[5] = {NULL, NULL, NULL, NULL, NULL};
+#define N_PREGEN_KEYS ARRAY_LENGTH(pregen_keys)
+
+/** Generate and return a new keypair for use in unit tests. If we're using
+ * the key cache optimization, we might reuse keys: we only guarantee that
+ * keys made with distinct values for <b>idx</b> are different. The value of
+ * <b>idx</b> must be at least 0, and less than N_PREGEN_KEYS. */
+crypto_pk_t *
+pk_generate(int idx)
+{
+#ifdef CACHE_GENERATED_KEYS
+ tor_assert(idx < N_PREGEN_KEYS);
+ if (! pregen_keys[idx]) {
+ pregen_keys[idx] = crypto_pk_new();
+ tor_assert(!crypto_pk_generate_key(pregen_keys[idx]));
+ }
+ return crypto_pk_dup_key(pregen_keys[idx]);
+#else
+ crypto_pk_t *result;
+ (void) idx;
+ result = crypto_pk_new();
+ tor_assert(!crypto_pk_generate_key(result));
+ return result;
+#endif
+}
+
+/** Free all storage used for the cached key optimization. */
+static void
+free_pregenerated_keys(void)
+{
+ unsigned idx;
+ for (idx = 0; idx < N_PREGEN_KEYS; ++idx) {
+ if (pregen_keys[idx]) {
+ crypto_pk_free(pregen_keys[idx]);
+ pregen_keys[idx] = NULL;
+ }
+ }
+}
+
+static void *
+passthrough_test_setup(const struct testcase_t *testcase)
+{
+ return testcase->setup_data;
+}
+static int
+passthrough_test_cleanup(const struct testcase_t *testcase, void *ptr)
+{
+ (void)testcase;
+ (void)ptr;
+ return 1;
+}
+
+const struct testcase_setup_t passthrough_setup = {
+ passthrough_test_setup, passthrough_test_cleanup
+};
+
+extern struct testgroup_t testgroups[];
+
+/** Main entry point for unit test code: parse the command line, and run
+ * some unit tests. */
+int
+main(int c, const char **v)
+{
+ or_options_t *options;
+ char *errmsg = NULL;
+ int i, i_out;
+ int loglevel = LOG_ERR;
+ int accel_crypto = 0;
+
+#ifdef USE_DMALLOC
+ {
+ int r = CRYPTO_set_mem_ex_functions(tor_malloc_, tor_realloc_, tor_free_);
+ tor_assert(r);
+ }
+#endif
+
+ update_approx_time(time(NULL));
+ options = options_new();
+ tor_threads_init();
+ init_logging(1);
+ configure_backtrace_handler(get_version());
+
+ for (i_out = i = 1; i < c; ++i) {
+ if (!strcmp(v[i], "--warn")) {
+ loglevel = LOG_WARN;
+ } else if (!strcmp(v[i], "--notice")) {
+ loglevel = LOG_NOTICE;
+ } else if (!strcmp(v[i], "--info")) {
+ loglevel = LOG_INFO;
+ } else if (!strcmp(v[i], "--debug")) {
+ loglevel = LOG_DEBUG;
+ } else if (!strcmp(v[i], "--accel")) {
+ accel_crypto = 1;
+ } else {
+ v[i_out++] = v[i];
+ }
+ }
+ c = i_out;
+
+ {
+ log_severity_list_t s;
+ memset(&s, 0, sizeof(s));
+ set_log_severity_config(loglevel, LOG_ERR, &s);
+ add_stream_log(&s, "", fileno(stdout));
+ }
+
+ options->command = CMD_RUN_UNITTESTS;
+ if (crypto_global_init(accel_crypto, NULL, NULL)) {
+ printf("Can't initialize crypto subsystem; exiting.\n");
+ return 1;
+ }
+ crypto_set_tls_dh_prime(NULL);
+ crypto_seed_rng(1);
+ rep_hist_init();
+ network_init();
+ setup_directory();
+ options_init(options);
+ options->DataDirectory = tor_strdup(temp_dir);
+ options->EntryStatistics = 1;
+ if (set_options(options, &errmsg) < 0) {
+ printf("Failed to set initial options: %s\n", errmsg);
+ tor_free(errmsg);
+ return 1;
+ }
+
+ atexit(remove_directory);
+
+ int have_failed = (tinytest_main(c, v, testgroups) != 0);
+
+ free_pregenerated_keys();
+#ifdef USE_DMALLOC
+ tor_free_all(0);
+ dmalloc_log_unfreed();
+#endif
+
+ if (have_failed)
+ return 1;
+ else
+ return 0;
+}
+
1
0
commit 034e2788f812852ed530b42291b3e07c7dc85d84
Author: Nick Mathewson <nickm(a)torproject.org>
Date: Fri Jan 23 11:18:28 2015 -0500
whitespace fixes
---
src/or/circuitbuild.h | 3 ++-
src/or/config.c | 1 -
src/or/cpuworker.c | 1 -
src/or/directory.c | 1 -
src/or/directory.h | 3 ++-
src/or/routerlist.c | 6 +++---
src/test/test_crypto_slow.c | 1 -
src/test/test_routerlist.c | 2 +-
src/test/test_util_slow.c | 1 +
9 files changed, 9 insertions(+), 10 deletions(-)
diff --git a/src/or/circuitbuild.h b/src/or/circuitbuild.h
index 7d49530..c72016d 100644
--- a/src/or/circuitbuild.h
+++ b/src/or/circuitbuild.h
@@ -22,7 +22,8 @@ origin_circuit_t *circuit_establish_circuit(uint8_t purpose,
extend_info_t *exit,
int flags);
int circuit_handle_first_hop(origin_circuit_t *circ);
-void circuit_n_chan_done(channel_t *chan, int status, int close_origin_circuits);
+void circuit_n_chan_done(channel_t *chan, int status,
+ int close_origin_circuits);
int inform_testing_reachability(void);
int circuit_timeout_want_to_count_circ(origin_circuit_t *circ);
int circuit_send_next_onion_skin(origin_circuit_t *circ);
diff --git a/src/or/config.c b/src/or/config.c
index 91fbe97..568baec 100644
--- a/src/or/config.c
+++ b/src/or/config.c
@@ -5758,7 +5758,6 @@ parse_port_config(smartlist_t *out,
return 0;
} /* end if (listenaddrs) */
-
/* No ListenAddress lines. If there's no FooPort, then maybe make a default
* one. */
if (! ports) {
diff --git a/src/or/cpuworker.c b/src/or/cpuworker.c
index 39d2079..0785c67 100644
--- a/src/or/cpuworker.c
+++ b/src/or/cpuworker.c
@@ -366,7 +366,6 @@ cpuworker_onion_handshake_replyfn(void *work_)
}
log_debug(LD_OR,"onionskin_answer succeeded. Yay.");
-
done_processing:
memwipe(&rpl, 0, sizeof(rpl));
memwipe(job, 0, sizeof(*job));
diff --git a/src/or/directory.c b/src/or/directory.c
index 348d971..d2b6b86 100644
--- a/src/or/directory.c
+++ b/src/or/directory.c
@@ -236,7 +236,6 @@ dir_fetch_type(int dir_purpose, int router_purpose, const char *resource)
return type;
}
-
/** Return true iff <b>identity_digest</b> is the digest of a router which
* says that it caches extrainfos. (If <b>is_authority</b> we always
* believe that to be true.) */
diff --git a/src/or/directory.h b/src/or/directory.h
index 51e6ed3..4899eb5 100644
--- a/src/or/directory.h
+++ b/src/or/directory.h
@@ -123,7 +123,8 @@ int download_status_get_n_failures(const download_status_t *dls);
/* Used only by directory.c and test_dir.c */
STATIC int parse_http_url(const char *headers, char **url);
-STATIC int purpose_needs_anonymity(uint8_t dir_purpose, uint8_t router_purpose);
+STATIC int purpose_needs_anonymity(uint8_t dir_purpose,
+ uint8_t router_purpose);
STATIC dirinfo_type_t dir_fetch_type(int dir_purpose, int router_purpose,
const char *resource);
#endif
diff --git a/src/or/routerlist.c b/src/or/routerlist.c
index dacf980..fe92ac0 100644
--- a/src/or/routerlist.c
+++ b/src/or/routerlist.c
@@ -1442,7 +1442,7 @@ router_pick_directory_server_impl(dirinfo_type_t type, int flags,
const networkstatus_t *consensus = networkstatus_get_latest_consensus();
const int requireother = ! (flags & PDS_ALLOW_SELF);
const int fascistfirewall = ! (flags & PDS_IGNORE_FASCISTFIREWALL);
- const int no_serverdesc_fetching = (flags & PDS_NO_EXISTING_SERVERDESC_FETCH);
+ const int no_serverdesc_fetching =(flags & PDS_NO_EXISTING_SERVERDESC_FETCH);
const int no_microdesc_fetching = (flags & PDS_NO_EXISTING_MICRODESC_FETCH);
const int for_guard = (flags & PDS_FOR_GUARD);
int try_excluding = 1, n_excluded = 0, n_busy = 0;
@@ -4265,7 +4265,8 @@ MOCK_IMPL(STATIC void, initiate_descriptor_downloads,
if (b64_256) {
digest256_to_base64(cp, smartlist_get(digests, lo));
} else {
- base16_encode(cp, enc_digest_len, smartlist_get(digests, lo), digest_len);
+ base16_encode(cp, enc_digest_len, smartlist_get(digests, lo),
+ digest_len);
}
smartlist_add(tmp, cp);
}
@@ -4372,7 +4373,6 @@ launch_descriptor_downloads(int purpose,
"tried downloading descriptors recently. Downloading.",
descname);
}
-
}
}
diff --git a/src/test/test_crypto_slow.c b/src/test/test_crypto_slow.c
index 94fd69d..a0f6cdc 100644
--- a/src/test/test_crypto_slow.c
+++ b/src/test/test_crypto_slow.c
@@ -10,7 +10,6 @@
#include "crypto_s2k.h"
#include "crypto_pwbox.h"
-
/** Run unit tests for our secret-to-key passphrase hashing functionality. */
static void
test_crypto_s2k_rfc2440(void *arg)
diff --git a/src/test/test_routerlist.c b/src/test/test_routerlist.c
index 390b691..381a592 100644
--- a/src/test/test_routerlist.c
+++ b/src/test/test_routerlist.c
@@ -7,7 +7,6 @@
#include "directory.h"
#include "test.h"
-
/* 4 digests + 3 sep + pre + post + NULL */
static char output[4*BASE64_DIGEST256_LEN+3+2+2+1];
@@ -101,3 +100,4 @@ struct testcase_t routerlist_tests[] = {
NODE(launch_descriptor_downloads, 0),
END_OF_TESTCASES
};
+
diff --git a/src/test/test_util_slow.c b/src/test/test_util_slow.c
index 4adcbe1..a597ef3 100644
--- a/src/test/test_util_slow.c
+++ b/src/test/test_util_slow.c
@@ -386,3 +386,4 @@ struct testcase_t slow_util_tests[] = {
UTIL_TEST(spawn_background_waitpid_notify, 0),
END_OF_TESTCASES
};
+
1
0

[tor/master] Refactor code that looks up addresses from interfaces
by nickm@torproject.org 23 Jan '15
by nickm@torproject.org 23 Jan '15
23 Jan '15
commit 3966145dff817adb67e5b46020632d55f19e289f
Author: rl1987 <rl1987(a)sdf.lonestar.org>
Date: Sat May 24 15:03:14 2014 +0300
Refactor code that looks up addresses from interfaces
Now the code has separate implementation and examination functions,
uses smartlists sanely, and has relatively decent test coverage.
---
changes/ticket12376_part2 | 11 ++
src/common/address.c | 227 +++++++++++++++-------
src/common/address.h | 53 +++++
src/test/include.am | 1 +
src/test/test.c | 2 +
src/test/test_address.c | 467 +++++++++++++++++++++++++++++++++++++++++++++
6 files changed, 697 insertions(+), 64 deletions(-)
diff --git a/changes/ticket12376_part2 b/changes/ticket12376_part2
new file mode 100644
index 0000000..13f9bb5
--- /dev/null
+++ b/changes/ticket12376_part2
@@ -0,0 +1,11 @@
+ o Major refactoring:
+ - Refactor the get_interface_addresses_raw() Doom-function into
+ multiple smaller and easier to understand subfunctions. Cover the
+ resulting subfunctions with unit-tests. Fixes a significant portion
+ of issue 12376.
+
+ o Minor bugfixes:
+ - Fix the ioctl()-based network interface lookup code so that it will
+ work on systems that have variable-length struct ifreq, for example
+ Mac OS X.
+
diff --git a/src/common/address.c b/src/common/address.c
index 2825b12..7b4584f 100644
--- a/src/common/address.c
+++ b/src/common/address.c
@@ -8,24 +8,26 @@
* \brief Functions to use and manipulate the tor_addr_t structure.
**/
-#include "orconfig.h"
-#include "compat.h"
-#include "util.h"
-#include "address.h"
-#include "torlog.h"
-#include "container.h"
-#include "sandbox.h"
+#define ADDRESS_PRIVATE
#ifdef _WIN32
-#include <process.h>
-#include <windows.h>
-#include <winsock2.h>
/* For access to structs needed by GetAdaptersAddresses */
#undef _WIN32_WINNT
#define _WIN32_WINNT 0x0501
+#include <process.h>
+#include <winsock2.h>
+#include <windows.h>
#include <iphlpapi.h>
#endif
+#include "orconfig.h"
+#include "compat.h"
+#include "util.h"
+#include "address.h"
+#include "torlog.h"
+#include "container.h"
+#include "sandbox.h"
+
#ifdef HAVE_SYS_TIME_H
#include <sys/time.h>
#endif
@@ -122,7 +124,7 @@ tor_addr_to_sockaddr(const tor_addr_t *a,
}
/** Set the tor_addr_t in <b>a</b> to contain the socket address contained in
- * <b>sa</b>. */
+ * <b>sa</b>. Return 0 on success and -1 on failure. */
int
tor_addr_from_sockaddr(tor_addr_t *a, const struct sockaddr *sa,
uint16_t *port_out)
@@ -1192,26 +1194,17 @@ typedef ULONG (WINAPI *GetAdaptersAddresses_fn_t)(
ULONG, ULONG, PVOID, PIP_ADAPTER_ADDRESSES, PULONG);
#endif
-/** Try to ask our network interfaces what addresses they are bound to.
- * Return a new smartlist of tor_addr_t on success, and NULL on failure.
- * (An empty smartlist indicates that we successfully learned that we have no
- * addresses.) Log failure messages at <b>severity</b>. */
-static smartlist_t *
-get_interface_addresses_raw(int severity)
+#ifdef HAVE_IFADDRS_TO_SMARTLIST
+/*
+ * Convert a linked list consisting of <b>ifaddrs</b> structures
+ * into smartlist of <b>tor_addr_t</b> structures.
+ */
+STATIC smartlist_t *
+ifaddrs_to_smartlist(const struct ifaddrs *ifa)
{
-#if defined(HAVE_GETIFADDRS)
- /* Most free Unixy systems provide getifaddrs, which gives us a linked list
- * of struct ifaddrs. */
- struct ifaddrs *ifa = NULL;
+ smartlist_t *result = smartlist_new();
const struct ifaddrs *i;
- smartlist_t *result;
- if (getifaddrs(&ifa) < 0) {
- log_fn(severity, LD_NET, "Unable to call getifaddrs(): %s",
- strerror(errno));
- return NULL;
- }
- result = smartlist_new();
for (i = ifa; i; i = i->ifa_next) {
tor_addr_t tmp;
if ((i->ifa_flags & (IFF_UP | IFF_RUNNING)) != (IFF_UP | IFF_RUNNING))
@@ -1226,9 +1219,72 @@ get_interface_addresses_raw(int severity)
smartlist_add(result, tor_memdup(&tmp, sizeof(tmp)));
}
+ return result;
+}
+
+/** Use getiffaddrs() function to get list of current machine
+ * network interface addresses. Represent the result by smartlist of
+ * <b>tor_addr_t</b> structures.
+ */
+STATIC smartlist_t *
+get_interface_addresses_ifaddrs(int severity)
+{
+
+ /* Most free Unixy systems provide getifaddrs, which gives us a linked list
+ * of struct ifaddrs. */
+ struct ifaddrs *ifa = NULL;
+ smartlist_t *result;
+ if (getifaddrs(&ifa) < 0) {
+ log_fn(severity, LD_NET, "Unable to call getifaddrs(): %s",
+ strerror(errno));
+ return NULL;
+ }
+
+ result = ifaddrs_to_smartlist(ifa);
+
freeifaddrs(ifa);
+
+ return result;
+}
+#endif
+
+#ifdef HAVE_IP_ADAPTER_TO_SMARTLIST
+
+/** Convert a Windows-specific <b>addresses</b> linked list into smartlist
+ * of <b>tor_addr_t</b> structures.
+ */
+
+STATIC smartlist_t *
+ip_adapter_addresses_to_smartlist(const IP_ADAPTER_ADDRESSES *addresses)
+{
+ smartlist_t *result = smartlist_new();
+ const IP_ADAPTER_ADDRESSES *address;
+
+ for (address = addresses; address; address = address->Next) {
+ const IP_ADAPTER_UNICAST_ADDRESS *a;
+ for (a = address->FirstUnicastAddress; a; a = a->Next) {
+ /* Yes, it's a linked list inside a linked list */
+ const struct sockaddr *sa = a->Address.lpSockaddr;
+ tor_addr_t tmp;
+ if (sa->sa_family != AF_INET && sa->sa_family != AF_INET6)
+ continue;
+ if (tor_addr_from_sockaddr(&tmp, sa, NULL) < 0)
+ continue;
+ smartlist_add(result, tor_memdup(&tmp, sizeof(tmp)));
+ }
+ }
+
return result;
-#elif defined(_WIN32)
+}
+
+/** Windows only: use GetAdaptersInfo() function to retrieve network interface
+ * addresses of current machine and return them to caller as smartlist of
+ * <b>tor_addr_t</b> structures.
+ */
+STATIC smartlist_t *
+get_interface_addresses_win32(int severity)
+{
+
/* Windows XP began to provide GetAdaptersAddresses. Windows 2000 had a
"GetAdaptersInfo", but that's deprecated; let's just try
GetAdaptersAddresses and fall back to connect+getsockname.
@@ -1237,7 +1293,7 @@ get_interface_addresses_raw(int severity)
smartlist_t *result = NULL;
GetAdaptersAddresses_fn_t fn;
ULONG size, res;
- IP_ADAPTER_ADDRESSES *addresses = NULL, *address;
+ IP_ADAPTER_ADDRESSES *addresses = NULL;
(void) severity;
@@ -1272,63 +1328,106 @@ get_interface_addresses_raw(int severity)
goto done;
}
- result = smartlist_new();
- for (address = addresses; address; address = address->Next) {
- IP_ADAPTER_UNICAST_ADDRESS *a;
- for (a = address->FirstUnicastAddress; a; a = a->Next) {
- /* Yes, it's a linked list inside a linked list */
- struct sockaddr *sa = a->Address.lpSockaddr;
- tor_addr_t tmp;
- if (sa->sa_family != AF_INET && sa->sa_family != AF_INET6)
- continue;
- if (tor_addr_from_sockaddr(&tmp, sa, NULL) < 0)
- continue;
- smartlist_add(result, tor_memdup(&tmp, sizeof(tmp)));
- }
- }
+ result = ip_adapter_addresses_to_smartlist(addresses);
done:
if (lib)
FreeLibrary(lib);
tor_free(addresses);
return result;
-#elif defined(SIOCGIFCONF) && defined(HAVE_IOCTL)
+}
+
+#endif
+
+#ifdef HAVE_IFCONF_TO_SMARTLIST
+
+/* This is defined on Mac OS X */
+#ifndef _SIZEOF_ADDR_IFREQ
+#define _SIZEOF_ADDR_IFREQ sizeof
+#endif
+
+/** Convert <b>*ifr</b>, an ifreq structure array of size <b>buflen</b>
+ * into smartlist of <b>tor_addr_t</b> structures.
+ */
+STATIC smartlist_t *
+ifreq_to_smartlist(const struct ifreq *ifr, size_t buflen)
+{
+ smartlist_t *result = smartlist_new();
+
+ struct ifreq *r = (struct ifreq *)ifr;
+
+ while ((char *)r < (char *)ifr+buflen) {
+ const struct sockaddr *sa = &r->ifr_addr;
+ tor_addr_t tmp;
+ int valid_sa_family = (sa->sa_family == AF_INET ||
+ sa->sa_family == AF_INET6);
+
+ int conversion_success = (tor_addr_from_sockaddr(&tmp, sa, NULL) == 0);
+
+ if (valid_sa_family && conversion_success)
+ smartlist_add(result, tor_memdup(&tmp, sizeof(tmp)));
+
+ r = (struct ifreq *)((char *)r + _SIZEOF_ADDR_IFREQ(*r));
+ }
+
+ return result;
+}
+
+/** Use ioctl(.,SIOCGIFCONF,.) to get a list of current machine
+ * network interface addresses. Represent the result by smartlist of
+ * <b>tor_addr_t</b> structures.
+ */
+STATIC smartlist_t *
+get_interface_addresses_ioctl(int severity)
+{
/* Some older unixy systems make us use ioctl(SIOCGIFCONF) */
struct ifconf ifc;
- int fd, i, sz, n;
+ int fd, sz;
+ void *databuf = NULL;
smartlist_t *result = NULL;
+
/* This interface, AFAICT, only supports AF_INET addresses */
fd = socket(AF_INET, SOCK_DGRAM, 0);
if (fd < 0) {
tor_log(severity, LD_NET, "socket failed: %s", strerror(errno));
goto done;
}
+
/* Guess how much space we need. */
- ifc.ifc_len = sz = 15*1024;
- ifc.ifc_ifcu.ifcu_req = tor_malloc(sz);
+ ifc.ifc_len = sz = 4096;
+ databuf = tor_malloc_zero(sz);
+ ifc.ifc_buf = databuf;
+
if (ioctl(fd, SIOCGIFCONF, &ifc) < 0) {
tor_log(severity, LD_NET, "ioctl failed: %s", strerror(errno));
close(fd);
goto done;
}
- close(fd);
- result = smartlist_new();
- if (ifc.ifc_len < sz)
- sz = ifc.ifc_len;
- n = sz / sizeof(struct ifreq);
- for (i = 0; i < n ; ++i) {
- struct ifreq *r = &ifc.ifc_ifcu.ifcu_req[i];
- struct sockaddr *sa = &r->ifr_addr;
- tor_addr_t tmp;
- if (sa->sa_family != AF_INET && sa->sa_family != AF_INET6)
- continue; /* should be impossible */
- if (tor_addr_from_sockaddr(&tmp, sa, NULL) < 0)
- continue;
- smartlist_add(result, tor_memdup(&tmp, sizeof(tmp)));
- }
+
+ result = ifreq_to_smartlist(databuf, ifc.ifc_len);
+
done:
- tor_free(ifc.ifc_ifcu.ifcu_req);
+ close(fd);
+ tor_free(databuf);
return result;
+}
+#endif
+
+/** Try to ask our network interfaces what addresses they are bound to.
+ * Return a new smartlist of tor_addr_t on success, and NULL on failure.
+ * (An empty smartlist indicates that we successfully learned that we have no
+ * addresses.) Log failure messages at <b>severity</b>. */
+STATIC smartlist_t *
+get_interface_addresses_raw(int severity)
+{
+#if defined(HAVE_IFADDRS_TO_SMARTLIST)
+ return get_interface_addresses_ifaddrs(severity);
+#endif
+#if defined(HAVE_IP_ADAPTER_TO_SMARTLIST)
+ return get_interface_addresses_win32(severity);
+#endif
+#if defined(HAVE_IFCONF_TO_SMARTLIST)
+ return get_interface_addresses_ioctl(severity);
#else
(void) severity;
return NULL;
diff --git a/src/common/address.h b/src/common/address.h
index 8dc63b7..934c3f5 100644
--- a/src/common/address.h
+++ b/src/common/address.h
@@ -11,10 +11,41 @@
#ifndef TOR_ADDRESS_H
#define TOR_ADDRESS_H
+//#include <sys/sockio.h>
#include "orconfig.h"
#include "torint.h"
#include "compat.h"
+#ifdef ADDRESS_PRIVATE
+
+#if defined(HAVE_SYS_IOCTL_H)
+#include <sys/ioctl.h>
+#endif
+
+#ifdef HAVE_GETIFADDRS
+#define HAVE_IFADDRS_TO_SMARTLIST
+#endif
+
+#ifdef _WIN32
+#define HAVE_IP_ADAPTER_TO_SMARTLIST
+#endif
+
+#if defined(SIOCGIFCONF) && defined(HAVE_IOCTL)
+#define HAVE_IFCONF_TO_SMARTLIST
+#endif
+
+#if defined(HAVE_NET_IF_H)
+#include <net/if.h> // for struct ifconf
+#endif
+
+#if defined(HAVE_IFADDRS_TO_SMARTLIST)
+#include <ifaddrs.h>
+#endif
+
+// TODO win32 specific includes
+#include "container.h"
+#endif // ADDRESS_PRIVATE
+
/** The number of bits from an address to consider while doing a masked
* comparison. */
typedef uint8_t maskbits_t;
@@ -229,5 +260,27 @@ int get_interface_address(int severity, uint32_t *addr);
tor_addr_port_t *tor_addr_port_new(const tor_addr_t *addr, uint16_t port);
+#ifdef ADDRESS_PRIVATE
+STATIC smartlist_t *get_interface_addresses_raw(int severity);
+
+#ifdef HAVE_IFADDRS_TO_SMARTLIST
+STATIC smartlist_t *ifaddrs_to_smartlist(const struct ifaddrs *ifa);
+STATIC smartlist_t *get_interface_addresses_ifaddrs(int severity);
+#endif
+
+#ifdef HAVE_IP_ADAPTER_TO_SMARTLIST
+STATIC smartlist_t *ip_adapter_addresses_to_smartlist(
+ const IP_ADAPTER_ADDRESSES *addresses);
+STATIC smartlist_t *get_interface_addresses_win32(int severity);
+#endif
+
+#ifdef HAVE_IFCONF_TO_SMARTLIST
+STATIC smartlist_t *ifreq_to_smartlist(const struct ifreq *ifr,
+ size_t buflen);
+STATIC smartlist_t *get_interface_addresses_ioctl(int severity);
+#endif
+
+#endif // ADDRESS_PRIVATE
+
#endif
diff --git a/src/test/include.am b/src/test/include.am
index fba439a..371f063 100644
--- a/src/test/include.am
+++ b/src/test/include.am
@@ -45,6 +45,7 @@ src_test_test_SOURCES = \
src/test/test_nodelist.c \
src/test/test_policy.c \
src/test/test_status.c \
+ src/test/test_address.c \
src/ext/tinytest.c
src_test_test_CFLAGS = $(AM_CFLAGS) $(TEST_CFLAGS)
diff --git a/src/test/test.c b/src/test/test.c
index c96b396..ed3013c 100644
--- a/src/test/test.c
+++ b/src/test/test.c
@@ -1287,6 +1287,7 @@ static struct testcase_t test_array[] = {
};
extern struct testcase_t addr_tests[];
+extern struct testcase_t address_tests[];
extern struct testcase_t buffer_tests[];
extern struct testcase_t crypto_tests[];
extern struct testcase_t container_tests[];
@@ -1319,6 +1320,7 @@ static struct testgroup_t testgroups[] = {
{ "buffer/", buffer_tests },
{ "socks/", socks_tests },
{ "addr/", addr_tests },
+ { "address/", address_tests },
{ "crypto/", crypto_tests },
{ "container/", container_tests },
{ "util/", util_tests },
diff --git a/src/test/test_address.c b/src/test/test_address.c
new file mode 100644
index 0000000..971618d
--- /dev/null
+++ b/src/test/test_address.c
@@ -0,0 +1,467 @@
+/* Copyright (c) 2014-2015, The Tor Project, Inc. */
+/* See LICENSE for licensing information */
+
+#define ADDRESS_PRIVATE
+
+#ifdef _WIN32
+#include <winsock2.h>
+/* For access to structs needed by GetAdaptersAddresses */
+#undef _WIN32_WINNT
+#define _WIN32_WINNT 0x0501
+#include <iphlpapi.h>
+#endif
+
+#ifdef HAVE_IFADDRS_TO_SMARTLIST
+#include <net/if.h>
+#include <ifaddrs.h>
+#endif
+
+#ifdef HAVE_IFCONF_TO_SMARTLIST
+#ifdef HAVE_SYS_IOCTL_H
+#include <sys/ioctl.h>
+#endif
+#include <net/if.h>
+#endif
+
+#include "or.h"
+#include "address.h"
+#include "test.h"
+
+/** Return 1 iff <b>sockaddr1</b> and <b>sockaddr2</b> represent
+ * the same IP address and port combination. Otherwise, return 0.
+ */
+static uint8_t
+sockaddr_in_are_equal(struct sockaddr_in *sockaddr1,
+ struct sockaddr_in *sockaddr2)
+{
+ return ((sockaddr1->sin_family == sockaddr2->sin_family) &&
+ (sockaddr1->sin_port == sockaddr2->sin_port) &&
+ (sockaddr1->sin_addr.s_addr == sockaddr2->sin_addr.s_addr));
+}
+
+/** Return 1 iff <b>sockaddr1</b> and <b>sockaddr2</b> represent
+ * the same IP address and port combination. Otherwise, return 0.
+ */
+static uint8_t
+sockaddr_in6_are_equal(struct sockaddr_in6 *sockaddr1,
+ struct sockaddr_in6 *sockaddr2)
+{
+ return ((sockaddr1->sin6_family == sockaddr2->sin6_family) &&
+ (sockaddr1->sin6_port == sockaddr2->sin6_port) &&
+ (tor_memeq(sockaddr1->sin6_addr.s6_addr,
+ sockaddr2->sin6_addr.s6_addr,16)));
+}
+
+/** Create a sockaddr_in structure from IP address string <b>ip_str</b>.
+ *
+ * If <b>out</b> is not NULL, write the result
+ * to the memory address in <b>out</b>. Otherwise, allocate the memory
+ * for result. On success, return pointer to result. Otherwise, return
+ * NULL.
+ */
+static struct sockaddr_in *
+sockaddr_in_from_string(const char *ip_str, struct sockaddr_in *out)
+{
+ // [FIXME: add some error checking?]
+ if (!out)
+ out = tor_malloc_zero(sizeof(struct sockaddr_in));
+
+ out->sin_family = AF_INET;
+ out->sin_port = 0;
+ tor_inet_pton(AF_INET,ip_str,&(out->sin_addr));
+
+ return out;
+}
+
+/** Return 1 iff <b>smartlist</b> contains a tor_addr_t structure
+ * that points to 127.0.0.1. Otherwise, return 0.
+ */
+static int
+smartlist_contains_localhost_tor_addr(smartlist_t *smartlist)
+{
+ int found_localhost = 0;
+
+ struct sockaddr_in *sockaddr_localhost;
+ struct sockaddr_storage *sockaddr_to_check;
+
+ sockaddr_localhost = sockaddr_in_from_string("127.0.0.1",NULL);
+
+ sockaddr_to_check = tor_malloc(sizeof(struct sockaddr_in));
+
+ SMARTLIST_FOREACH_BEGIN(smartlist, tor_addr_t *, tor_addr) {
+ tor_addr_to_sockaddr(tor_addr,0,(struct sockaddr *)sockaddr_to_check,
+ sizeof(struct sockaddr_in));
+
+ if (sockaddr_in_are_equal((struct sockaddr_in *)sockaddr_to_check,
+ sockaddr_localhost)) {
+ found_localhost = 1;
+ break;
+ }
+ } SMARTLIST_FOREACH_END(tor_addr);
+
+ tor_free(sockaddr_localhost);
+ tor_free(sockaddr_to_check);
+
+ return found_localhost;
+}
+
+#ifdef HAVE_IFADDRS_TO_SMARTLIST
+static void
+test_address_ifaddrs_to_smartlist(void *arg)
+{
+ struct ifaddrs *ifa = NULL;
+ struct ifaddrs *ifa_ipv4 = NULL;
+ struct ifaddrs *ifa_ipv6 = NULL;
+ struct sockaddr_in *ipv4_sockaddr_local = NULL;
+ struct sockaddr_in *netmask_slash8 = NULL;
+ struct sockaddr_in *ipv4_sockaddr_remote = NULL;
+ struct sockaddr_in6 *ipv6_sockaddr = NULL;
+ smartlist_t *smartlist = NULL;
+ tor_addr_t *tor_addr = NULL;
+ struct sockaddr *sockaddr_to_check = NULL;
+ socklen_t addr_len;
+
+ (void)arg;
+
+ netmask_slash8 = sockaddr_in_from_string("255.0.0.0",NULL);
+ ipv4_sockaddr_local = sockaddr_in_from_string("127.0.0.1",NULL);
+ ipv4_sockaddr_remote = sockaddr_in_from_string("128.52.160.20",NULL);
+
+ ipv6_sockaddr = tor_malloc(sizeof(struct sockaddr_in6));
+ ipv6_sockaddr->sin6_family = AF_INET6;
+ ipv6_sockaddr->sin6_port = 0;
+ inet_pton(AF_INET6, "2001:db8:8714:3a90::12",
+ &(ipv6_sockaddr->sin6_addr));
+
+ ifa = tor_malloc(sizeof(struct ifaddrs));
+ ifa_ipv4 = tor_malloc(sizeof(struct ifaddrs));
+ ifa_ipv6 = tor_malloc(sizeof(struct ifaddrs));
+
+ ifa->ifa_next = ifa_ipv4;
+ ifa->ifa_name = tor_strdup("eth0");
+ ifa->ifa_flags = IFF_UP | IFF_RUNNING;
+ ifa->ifa_addr = (struct sockaddr *)ipv4_sockaddr_local;
+ ifa->ifa_netmask = (struct sockaddr *)netmask_slash8;
+ ifa->ifa_dstaddr = NULL;
+ ifa->ifa_data = NULL;
+
+ ifa_ipv4->ifa_next = ifa_ipv6;
+ ifa_ipv4->ifa_name = tor_strdup("eth1");
+ ifa_ipv4->ifa_flags = IFF_UP | IFF_RUNNING;
+ ifa_ipv4->ifa_addr = (struct sockaddr *)ipv4_sockaddr_remote;
+ ifa_ipv4->ifa_netmask = (struct sockaddr *)netmask_slash8;
+ ifa_ipv4->ifa_dstaddr = NULL;
+ ifa_ipv4->ifa_data = NULL;
+
+ ifa_ipv6->ifa_next = NULL;
+ ifa_ipv6->ifa_name = tor_strdup("eth2");
+ ifa_ipv6->ifa_flags = IFF_UP | IFF_RUNNING;
+ ifa_ipv6->ifa_addr = (struct sockaddr *)ipv6_sockaddr;
+ ifa_ipv6->ifa_netmask = NULL;
+ ifa_ipv6->ifa_dstaddr = NULL;
+ ifa_ipv6->ifa_data = NULL;
+
+ smartlist = ifaddrs_to_smartlist(ifa);
+
+ tt_assert(smartlist);
+ tt_assert(smartlist_len(smartlist) == 3);
+
+ sockaddr_to_check = tor_malloc(sizeof(struct sockaddr_in6));
+
+ tor_addr = smartlist_get(smartlist,0);
+ addr_len =
+ tor_addr_to_sockaddr(tor_addr,0,sockaddr_to_check,
+ sizeof(struct sockaddr_in));
+
+ tt_int_op(addr_len,==,sizeof(struct sockaddr_in));
+ tt_assert(sockaddr_in_are_equal((struct sockaddr_in *)sockaddr_to_check,
+ ipv4_sockaddr_local));
+
+ tor_addr = smartlist_get(smartlist,1);
+ addr_len =
+ tor_addr_to_sockaddr(tor_addr,0,sockaddr_to_check,
+ sizeof(struct sockaddr_in));
+
+ tt_int_op(addr_len,==,sizeof(struct sockaddr_in));
+ tt_assert(sockaddr_in_are_equal((struct sockaddr_in *)sockaddr_to_check,
+ ipv4_sockaddr_remote));
+
+ tor_addr = smartlist_get(smartlist,2);
+ addr_len =
+ tor_addr_to_sockaddr(tor_addr,0,sockaddr_to_check,
+ sizeof(struct sockaddr_in6));
+
+ tt_int_op(addr_len,==,sizeof(struct sockaddr_in6));
+ tt_assert(sockaddr_in6_are_equal((struct sockaddr_in6*)sockaddr_to_check,
+ ipv6_sockaddr));
+
+ done:
+ tor_free(netmask_slash8);
+ tor_free(ipv4_sockaddr_local);
+ tor_free(ipv4_sockaddr_remote);
+ tor_free(ipv6_sockaddr);
+ tor_free(ifa);
+ tor_free(ifa_ipv4);
+ tor_free(ifa_ipv6);
+ tor_free(sockaddr_to_check);
+ SMARTLIST_FOREACH(smartlist, tor_addr_t *, t, tor_free(t));
+ smartlist_free(smartlist);
+
+ return;
+}
+
+static void
+test_address_get_if_addrs_ifaddrs(void *arg)
+{
+
+ smartlist_t *results = NULL;
+
+ (void)arg;
+
+ results = get_interface_addresses_ifaddrs(0);
+
+ tt_int_op(smartlist_len(results),>=,1);
+ tt_assert(smartlist_contains_localhost_tor_addr(results));
+
+ done:
+ SMARTLIST_FOREACH(results, tor_addr_t *, t, tor_free(t));
+ tor_free(results);
+ return;
+}
+
+#endif
+
+#ifdef HAVE_IP_ADAPTER_TO_SMARTLIST
+
+static void
+test_address_get_if_addrs_win32(void *arg)
+{
+
+ smartlist_t *results = NULL;
+
+ (void)arg;
+
+ results = get_interface_addresses_win32(0);
+
+ tt_int_op(smartlist_len(results),>=,1);
+ tt_assert(smartlist_contains_localhost_tor_addr(results));
+
+ done:
+ SMARTLIST_FOREACH(results, tor_addr_t *, t, tor_free(t));
+ tor_free(results);
+ return;
+}
+
+static void
+test_address_ip_adapter_addresses_to_smartlist(void *arg)
+{
+
+ IP_ADAPTER_ADDRESSES *addrs1;
+ IP_ADAPTER_ADDRESSES *addrs2;
+
+ IP_ADAPTER_UNICAST_ADDRESS *unicast11;
+ IP_ADAPTER_UNICAST_ADDRESS *unicast12;
+ IP_ADAPTER_UNICAST_ADDRESS *unicast21;
+
+ smartlist_t *result = NULL;
+
+ struct sockaddr_in *sockaddr_test1;
+ struct sockaddr_in *sockaddr_test2;
+ struct sockaddr_in *sockaddr_localhost;
+ struct sockaddr_in *sockaddr_to_check;
+
+ tor_addr_t *tor_addr;
+
+ (void)arg;
+ (void)sockaddr_in6_are_equal;
+
+ sockaddr_to_check = tor_malloc_zero(sizeof(struct sockaddr_in));
+
+ addrs1 =
+ tor_malloc_zero(sizeof(IP_ADAPTER_ADDRESSES));
+
+ addrs1->FirstUnicastAddress =
+ unicast11 = tor_malloc_zero(sizeof(IP_ADAPTER_UNICAST_ADDRESS));
+ sockaddr_test1 = sockaddr_in_from_string("86.59.30.40",NULL);
+ unicast11->Address.lpSockaddr = (LPSOCKADDR)sockaddr_test1;
+
+ unicast11->Next = unicast12 =
+ tor_malloc_zero(sizeof(IP_ADAPTER_UNICAST_ADDRESS));
+ sockaddr_test2 = sockaddr_in_from_string("93.95.227.222", NULL);
+ unicast12->Address.lpSockaddr = (LPSOCKADDR)sockaddr_test2;
+
+ addrs1->Next = addrs2 =
+ tor_malloc_zero(sizeof(IP_ADAPTER_ADDRESSES));
+
+ addrs2->FirstUnicastAddress =
+ unicast21 = tor_malloc_zero(sizeof(IP_ADAPTER_UNICAST_ADDRESS));
+ sockaddr_localhost = sockaddr_in_from_string("127.0.0.1", NULL);
+ unicast21->Address.lpSockaddr = (LPSOCKADDR)sockaddr_localhost;
+
+ result = ip_adapter_addresses_to_smartlist(addrs1);
+
+ tt_assert(result);
+ tt_assert(smartlist_len(result) == 3);
+
+ tor_addr = smartlist_get(result,0);
+
+ tor_addr_to_sockaddr(tor_addr,0,(struct sockaddr *)sockaddr_to_check,
+ sizeof(struct sockaddr_in));
+
+ tt_assert(sockaddr_in_are_equal(sockaddr_test1,sockaddr_to_check));
+
+ tor_addr = smartlist_get(result,1);
+
+ tor_addr_to_sockaddr(tor_addr,0,(struct sockaddr *)sockaddr_to_check,
+ sizeof(struct sockaddr_in));
+
+ tt_assert(sockaddr_in_are_equal(sockaddr_test2,sockaddr_to_check));
+
+ tor_addr = smartlist_get(result,2);
+
+ tor_addr_to_sockaddr(tor_addr,0,(struct sockaddr *)sockaddr_to_check,
+ sizeof(struct sockaddr_in));
+
+ tt_assert(sockaddr_in_are_equal(sockaddr_localhost,sockaddr_to_check));
+
+ done:
+ SMARTLIST_FOREACH(result, tor_addr_t *, t, tor_free(t));
+ smartlist_free(result);
+ tor_free(addrs1);
+ tor_free(addrs2);
+ tor_free(unicast11->Address.lpSockaddr);
+ tor_free(unicast11);
+ tor_free(unicast12->Address.lpSockaddr);
+ tor_free(unicast12);
+ tor_free(unicast21->Address.lpSockaddr);
+ tor_free(unicast21);
+ tor_free(sockaddr_to_check);
+ return;
+}
+#endif
+
+#ifdef HAVE_IFCONF_TO_SMARTLIST
+
+static void
+test_address_ifreq_to_smartlist(void *arg)
+{
+ smartlist_t *results = NULL;
+ tor_addr_t *tor_addr = NULL;
+ struct sockaddr_in *sockaddr = NULL;
+ struct sockaddr_in *sockaddr_eth1 = NULL;
+ struct sockaddr_in *sockaddr_to_check = NULL;
+
+ struct ifconf *ifc;
+ struct ifreq *ifr;
+ struct ifreq *ifr_next;
+
+ socklen_t addr_len;
+
+ (void)arg;
+
+ sockaddr_to_check = tor_malloc(sizeof(struct sockaddr_in));
+
+ ifr = tor_malloc(sizeof(struct ifreq));
+ memset(ifr,0,sizeof(struct ifreq));
+ strlcpy(ifr->ifr_name,"lo",3);
+ sockaddr = (struct sockaddr_in *) &(ifr->ifr_ifru.ifru_addr);
+ sockaddr_in_from_string("127.0.0.1",sockaddr);
+
+ ifc = tor_malloc(sizeof(struct ifconf));
+ memset(ifc,0,sizeof(struct ifconf));
+ ifc->ifc_len = sizeof(struct ifreq);
+ ifc->ifc_ifcu.ifcu_req = ifr;
+
+ results = ifreq_to_smartlist((struct ifreq *)ifc->ifc_buf,ifc->ifc_len);
+ tt_int_op(smartlist_len(results),==,1);
+
+ tor_addr = smartlist_get(results, 0);
+ addr_len =
+ tor_addr_to_sockaddr(tor_addr,0,(struct sockaddr *)sockaddr_to_check,
+ sizeof(struct sockaddr_in));
+
+ tt_int_op(addr_len,==,sizeof(struct sockaddr_in));
+ tt_assert(sockaddr_in_are_equal(sockaddr,sockaddr_to_check));
+
+ ifr = tor_realloc(ifr,2*sizeof(struct ifreq));
+ ifr_next = ifr+1;
+ strlcpy(ifr_next->ifr_name,"eth1",5);
+ ifc->ifc_len = 2*sizeof(struct ifreq);
+ ifc->ifc_ifcu.ifcu_req = ifr;
+ sockaddr = (struct sockaddr_in *) &(ifr->ifr_ifru.ifru_addr);
+
+ sockaddr_eth1 = (struct sockaddr_in *) &(ifr_next->ifr_ifru.ifru_addr);
+ sockaddr_in_from_string("192.168.10.55",sockaddr_eth1);
+
+ smartlist_free(results);
+
+ results = ifreq_to_smartlist((struct ifreq *)ifc->ifc_buf,ifc->ifc_len);
+ tt_int_op(smartlist_len(results),==,2);
+
+ tor_addr = smartlist_get(results, 0);
+ addr_len =
+ tor_addr_to_sockaddr(tor_addr,0,(struct sockaddr *)sockaddr_to_check,
+ sizeof(struct sockaddr_in));
+
+ tt_int_op(addr_len,==,sizeof(struct sockaddr_in));
+ tt_assert(sockaddr_in_are_equal(sockaddr,sockaddr_to_check));
+
+ tor_addr = smartlist_get(results, 1);
+ addr_len =
+ tor_addr_to_sockaddr(tor_addr,0,(struct sockaddr *)sockaddr_to_check,
+ sizeof(struct sockaddr_in));
+
+ tt_int_op(addr_len,==,sizeof(struct sockaddr_in));
+ tt_assert(sockaddr_in_are_equal(sockaddr_eth1,sockaddr_to_check));
+
+ done:
+ tor_free(sockaddr_to_check);
+ smartlist_free(results);
+ tor_free(tor_addr);
+ tor_free(ifc);
+ tor_free(ifr);
+ return;
+}
+
+static void
+test_address_get_if_addrs_ioctl(void *arg)
+{
+
+ smartlist_t *result = NULL;
+
+ (void)arg;
+
+ result = get_interface_addresses_ioctl(LOG_ERR);
+
+ tt_assert(result);
+ tt_int_op(smartlist_len(result),>=,1);
+
+ tt_assert(smartlist_contains_localhost_tor_addr(result));
+
+ done:
+ SMARTLIST_FOREACH(result, tor_addr_t *, t, tor_free(t));
+ smartlist_free(result);
+ return;
+}
+
+#endif
+
+#define ADDRESS_TEST(name, flags) \
+ { #name, test_address_ ## name, flags, NULL, NULL }
+
+struct testcase_t address_tests[] = {
+#ifdef HAVE_IFADDRS_TO_SMARTLIST
+ ADDRESS_TEST(get_if_addrs_ifaddrs, TT_FORK),
+ ADDRESS_TEST(ifaddrs_to_smartlist, 0),
+#endif
+#ifdef HAVE_IP_ADAPTER_TO_SMARTLIST
+ ADDRESS_TEST(get_if_addrs_win32, TT_FORK),
+ ADDRESS_TEST(ip_adapter_addresses_to_smartlist, 0),
+#endif
+#ifdef HAVE_IFCONF_TO_SMARTLIST
+ ADDRESS_TEST(get_if_addrs_ioctl, TT_FORK),
+ ADDRESS_TEST(ifreq_to_smartlist, 0),
+#endif
+ END_OF_TESTCASES
+};
+
1
0

23 Jan '15
commit 420037dcefade09f43e4a6e44282ed04f9f3ac52
Merge: 0b12143 3966145
Author: Nick Mathewson <nickm(a)torproject.org>
Date: Fri Jan 23 10:13:37 2015 -0500
Merge branch 'if_addr_refactoring_squashed'
Conflicts:
src/test/include.am
src/test/test.c
changes/ticket12376_part2 | 11 ++
src/common/address.c | 227 +++++++++++++++-------
src/common/address.h | 53 +++++
src/test/include.am | 1 +
src/test/test.c | 2 +
src/test/test_address.c | 467 +++++++++++++++++++++++++++++++++++++++++++++
6 files changed, 697 insertions(+), 64 deletions(-)
diff --cc src/common/address.c
index 1c3777f,7b4584f..3b4be1d
--- a/src/common/address.c
+++ b/src/common/address.c
@@@ -121,17 -123,8 +123,17 @@@ tor_addr_to_sockaddr(const tor_addr_t *
}
}
+/** Set address <b>a</b> to zero. This address belongs to
+ * the AF_UNIX family. */
+static void
+tor_addr_make_af_unix(tor_addr_t *a)
+{
+ memset(a, 0, sizeof(*a));
+ a->family = AF_UNIX;
+}
+
/** Set the tor_addr_t in <b>a</b> to contain the socket address contained in
- * <b>sa</b>. */
+ * <b>sa</b>. Return 0 on success and -1 on failure. */
int
tor_addr_from_sockaddr(tor_addr_t *a, const struct sockaddr *sa,
uint16_t *port_out)
diff --cc src/test/include.am
index f07c78b,371f063..d206033
--- a/src/test/include.am
+++ b/src/test/include.am
@@@ -17,17 -17,11 +17,18 @@@ src_test_AM_CPPFLAGS = -DSHARE_DATADIR=
src_test_test_SOURCES = \
src/test/test.c \
+ src/test/test_accounting.c \
src/test/test_addr.c \
++ src/test/test_address.c \
src/test/test_buffers.c \
src/test/test_cell_formats.c \
+ src/test/test_cell_queue.c \
+ src/test/test_channel.c \
+ src/test/test_channeltls.c \
+ src/test/test_checkdir.c \
src/test/test_circuitlist.c \
src/test/test_circuitmux.c \
+ src/test/test_config.c \
src/test/test_containers.c \
src/test/test_controller_events.c \
src/test/test_crypto.c \
diff --cc src/test/test.c
index debee0a,ed3013c..d752336
--- a/src/test/test.c
+++ b/src/test/test.c
@@@ -1294,86 -1286,65 +1294,88 @@@ static struct testcase_t test_array[]
END_OF_TESTCASES
};
+extern struct testcase_t accounting_tests[];
extern struct testcase_t addr_tests[];
+ extern struct testcase_t address_tests[];
extern struct testcase_t buffer_tests[];
-extern struct testcase_t crypto_tests[];
-extern struct testcase_t container_tests[];
-extern struct testcase_t util_tests[];
-extern struct testcase_t dir_tests[];
-extern struct testcase_t microdesc_tests[];
-extern struct testcase_t pt_tests[];
-extern struct testcase_t config_tests[];
-extern struct testcase_t introduce_tests[];
-extern struct testcase_t replaycache_tests[];
-extern struct testcase_t relaycell_tests[];
extern struct testcase_t cell_format_tests[];
+extern struct testcase_t cell_queue_tests[];
+extern struct testcase_t channel_tests[];
+extern struct testcase_t channeltls_tests[];
+extern struct testcase_t checkdir_tests[];
extern struct testcase_t circuitlist_tests[];
extern struct testcase_t circuitmux_tests[];
-extern struct testcase_t cell_queue_tests[];
-extern struct testcase_t options_tests[];
-extern struct testcase_t socks_tests[];
-extern struct testcase_t extorport_tests[];
+extern struct testcase_t config_tests[];
+extern struct testcase_t container_tests[];
extern struct testcase_t controller_event_tests[];
-extern struct testcase_t logging_tests[];
+extern struct testcase_t crypto_tests[];
+extern struct testcase_t dir_tests[];
+extern struct testcase_t entryconn_tests[];
+extern struct testcase_t entrynodes_tests[];
+extern struct testcase_t extorport_tests[];
extern struct testcase_t hs_tests[];
+extern struct testcase_t introduce_tests[];
+extern struct testcase_t logging_tests[];
+extern struct testcase_t microdesc_tests[];
extern struct testcase_t nodelist_tests[];
-extern struct testcase_t routerkeys_tests[];
extern struct testcase_t oom_tests[];
+extern struct testcase_t options_tests[];
extern struct testcase_t policy_tests[];
+extern struct testcase_t pt_tests[];
+extern struct testcase_t relay_tests[];
+extern struct testcase_t relaycell_tests[];
+extern struct testcase_t replaycache_tests[];
+extern struct testcase_t router_tests[];
+extern struct testcase_t routerkeys_tests[];
+extern struct testcase_t routerlist_tests[];
+extern struct testcase_t routerset_tests[];
+extern struct testcase_t scheduler_tests[];
+extern struct testcase_t socks_tests[];
extern struct testcase_t status_tests[];
+extern struct testcase_t thread_tests[];
+extern struct testcase_t util_tests[];
static struct testgroup_t testgroups[] = {
{ "", test_array },
- { "buffer/", buffer_tests },
- { "socks/", socks_tests },
+ { "accounting/", accounting_tests },
{ "addr/", addr_tests },
+ { "address/", address_tests },
- { "crypto/", crypto_tests },
- { "container/", container_tests },
- { "util/", util_tests },
- { "util/logging/", logging_tests },
+ { "buffer/", buffer_tests },
{ "cellfmt/", cell_format_tests },
{ "cellqueue/", cell_queue_tests },
- { "dir/", dir_tests },
- { "dir/md/", microdesc_tests },
- { "pt/", pt_tests },
- { "config/", config_tests },
- { "replaycache/", replaycache_tests },
- { "relaycell/", relaycell_tests },
- { "introduce/", introduce_tests },
+ { "channel/", channel_tests },
+ { "channeltls/", channeltls_tests },
+ { "checkdir/", checkdir_tests },
{ "circuitlist/", circuitlist_tests },
{ "circuitmux/", circuitmux_tests },
- { "options/", options_tests },
- { "extorport/", extorport_tests },
+ { "config/", config_tests },
+ { "container/", container_tests },
{ "control/", controller_event_tests },
+ { "crypto/", crypto_tests },
+ { "dir/", dir_tests },
+ { "dir/md/", microdesc_tests },
+ { "entryconn/", entryconn_tests },
+ { "entrynodes/", entrynodes_tests },
+ { "extorport/", extorport_tests },
{ "hs/", hs_tests },
+ { "introduce/", introduce_tests },
{ "nodelist/", nodelist_tests },
- { "routerkeys/", routerkeys_tests },
{ "oom/", oom_tests },
+ { "options/", options_tests },
{ "policy/" , policy_tests },
+ { "pt/", pt_tests },
+ { "relay/" , relay_tests },
+ { "relaycell/", relaycell_tests },
+ { "replaycache/", replaycache_tests },
+ { "routerkeys/", routerkeys_tests },
+ { "routerlist/", routerlist_tests },
+ { "routerset/" , routerset_tests },
+ { "scheduler/", scheduler_tests },
+ { "socks/", socks_tests },
{ "status/" , status_tests },
+ { "util/", util_tests },
+ { "util/logging/", logging_tests },
+ { "util/thread/", thread_tests },
END_OF_GROUPS
};
1
0