tor-commits
Threads by month
- ----- 2026 -----
- January
- ----- 2025 -----
- December
- November
- October
- September
- August
- July
- June
- 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
May 2021
- 20 participants
- 1973 discussions
[translation/tbmanual-contentspot] https://gitweb.torproject.org/translation.git/commit/?h=tbmanual-contentspot
by translation@torproject.org 12 May '21
by translation@torproject.org 12 May '21
12 May '21
commit 5acfa1cfa3e04e8e2bb48016302214ec3303029d
Author: Translation commit bot <translation(a)torproject.org>
Date: Wed May 12 13:17:02 2021 +0000
https://gitweb.torproject.org/translation.git/commit/?h=tbmanual-contentspot
---
contents+pl.po | 52 +++++++++++++++++++++++++++++++++++++++++++++++++++-
1 file changed, 51 insertions(+), 1 deletion(-)
diff --git a/contents+pl.po b/contents+pl.po
index 01d1ca92e1..945b018026 100644
--- a/contents+pl.po
+++ b/contents+pl.po
@@ -675,6 +675,8 @@ msgid ""
"<img class=\"col-md-6\" src=\"../../static/images/configure.png\" "
"alt=\"Click 'configure' to adjust network settings.\">"
msgstr ""
+"<img class=\"col-md-6\" src=\"../../static/images/configure.png\" "
+"alt=\"Kliknij 'konfiguruj' aby dostosować ustawienia sieci.\"/>"
#: https//tb-manual.torproject.org/running-tor-browser/
#: (content/running-tor-browser/contents+en.lrtopic.body)
@@ -691,6 +693,8 @@ msgid ""
"<img class=\"col-md-6\" src=\"../../static/images/proxy_question.png\" "
"alt=\"Select options for censored connection or proxy use.\">"
msgstr ""
+"<img class=\"col-md-6\" src=\"../../static/images/proxy_question.png\" "
+"alt=\"Wybierz opcję dla cenzurowanych połączeń lub użycia proxy.\"/>"
#: https//tb-manual.torproject.org/running-tor-browser/
#: (content/running-tor-browser/contents+en.lrtopic.body)
@@ -705,6 +709,8 @@ msgid ""
"<img class=\"col-md-6\" src=\"../../static/images/pluggable-transport.png\" "
"alt=\"Configure Tor bridge options\">"
msgstr ""
+"<img class=\"col-md-6\" src=\"../../static/images/pluggable-transport.png\" "
+"alt=\"Konfiguruj opcję mostu Tor\"/>"
#: https//tb-manual.torproject.org/running-tor-browser/
#: (content/running-tor-browser/contents+en.lrtopic.body)
@@ -737,6 +743,8 @@ msgid ""
"This will display the [Circumvention](../circumvention) section to configure"
" a pluggable transport."
msgstr ""
+"Wyświetli się sekcja [Omijania Blokad](../circumvention) pozwalająca na "
+"konfigurację transportu wtykowego."
#: https//tb-manual.torproject.org/running-tor-browser/
#: (content/running-tor-browser/contents+en.lrtopic.body)
@@ -744,6 +752,8 @@ msgid ""
"<img class=\"col-md-6\" src=\"../../static/images/proxy.png\" "
"alt=\"Configure proxy options\">"
msgstr ""
+"<img class=\"col-md-6\" src=\"../../static/images/proxy.png\" "
+"alt=\"Konfiguruj ustawienia proxy\"/>"
#: https//tb-manual.torproject.org/running-tor-browser/
#: (content/running-tor-browser/contents+en.lrtopic.body)
@@ -946,6 +956,8 @@ msgid ""
"Or, if you have Tor Browser running, click on \"Preferences\" in the "
"hamburger menu and then on \"Tor\" in the sidebar."
msgstr ""
+"Lub, jeśli masz już włączoną Przeglądarkę Tor, kliknij „Preferencje\" w "
+"hamburger menu (menu główne), a następnie „Tor\" w panelu bocznym."
#: https//tb-manual.torproject.org/circumvention/
#: (content/circumvention/contents+en.lrtopic.body)
@@ -1112,6 +1124,9 @@ msgid ""
"src=\"../../static/images/request-a-bridge.png\" alt=\"Request a bridge from"
" torproject.org\">"
msgstr ""
+"<img class=\"col-md-6\" align=\"right\" hspace=\"5\" "
+"src=\"../../static/images/request-a-bridge.png\" alt=\"Żądaj mostu od "
+"torproject.org\"/>"
#: https//tb-manual.torproject.org/bridges/
#: (content/bridges/contents+en.lrtopic.body)
@@ -1174,6 +1189,9 @@ msgid ""
"src=\"../../static/images/tor-launcher-custom-bridges.png\" alt=\"Enter "
"custom bridge addresses\">"
msgstr ""
+"<img class=\"col-md-6\" align=\"right\" hspace=\"5\" "
+"src=\"../../static/images/tor-launcher-custom-bridges.png\" alt=\"Wprowadź "
+"własny adres mostu\"/>"
#: https//tb-manual.torproject.org/bridges/
#: (content/bridges/contents+en.lrtopic.body)
@@ -1301,6 +1319,9 @@ msgid ""
"src=\"../../static/images/circuit_full.png\" alt=\"Display circuit diagram "
"under the site information menu\">"
msgstr ""
+"<img class=\"col-md-6\" align=\"right\" hspace=\"5\" "
+"src=\"../../static/images/circuit_full.png\" alt=\"Wyświetl diagram obwodu "
+"pod menu informacji o stronie\"/>"
#: https//tb-manual.torproject.org/managing-identities/
#: (content/managing-identities/contents+en.lrtopic.body)
@@ -1416,6 +1437,9 @@ msgid ""
"src=\"../../static/images/new_identity.png\" alt=\"New Identity and New Tor "
"Circuit options under main menu\">"
msgstr ""
+"<img style=\"max-width:100%\" class=\"col-md-6\" "
+"src=\"../../static/images/new_identity.png\" alt=\"opcje Nowa Tożsamość i "
+"Nowy Obwód Tor pod głównym menu\"/>"
#: https//tb-manual.torproject.org/managing-identities/
#: (content/managing-identities/contents+en.lrtopic.body)
@@ -1634,6 +1658,8 @@ msgid ""
"<img style=\"max-width:100%\" class=\"col-md-6\" src=\"../../static/images"
"/onion-location.png\" alt=\"Onion-Location\">"
msgstr ""
+"<img style=\"max-width:100%\" class=\"col-md-6\" src=\"../../static/images"
+"/onion-location.png\" alt=\"Onion-Location\">"
#: https//tb-manual.torproject.org/onion-services/
#: (content/onion-services/contents+en.lrtopic.body)
@@ -1718,6 +1744,8 @@ msgid ""
"<img style=\"max-width:100%\" class=\"col-md-6\" src=\"../../static/images"
"/client-auth.png\" alt=\"Client Authorization\">"
msgstr ""
+"<img style=\"max-width:100%\" class=\"col-md-6\" src=\"../../static/images"
+"/client-auth.png\" alt=\"Uwierzytelnianie Klienta\"/>"
#: https//tb-manual.torproject.org/onion-services/
#: (content/onion-services/contents+en.lrtopic.body)
@@ -2021,6 +2049,9 @@ msgid ""
"/security-settings-anim.gif\" alt=\"Click on 'Advanced Security Settings' "
"under the shield menu.\">"
msgstr ""
+"<img style=\"max-width:100%\" class=\"col-lg-6\" src=\"../../static/images"
+"/security-settings-anim.gif\" alt=\"Kliknij na 'Zaawansowane Ustawienia "
+"Bezpieczeństwa' pod menu tarczy\"/>"
#: https//tb-manual.torproject.org/security-slider~Redirect links from orphan
#: page to update page/ (content/security-slider~Redirect
@@ -2066,6 +2097,9 @@ msgid ""
"/security-settings-safest.png\" alt=\"Security Level is currently set to "
"Standard.\">"
msgstr ""
+"<img style=\"max-width:100%\" class=\"col-lg-6\" src=\"../../static/images"
+"/security-settings-safest.png\" alt=\"Poziom Bezpieczeństwa jest aktualnie "
+"ustawiony na Standardowy\"/>"
#: https//tb-manual.torproject.org/security-slider~Redirect links from orphan
#: page to update page/ (content/security-slider~Redirect
@@ -2211,6 +2245,8 @@ msgid ""
"<img width=\"400\" src=\"../../static/images/update1.png\" alt=\"Select "
"'Restart to update Tor Browser' under the main menu\"/>"
msgstr ""
+"<img width=\"400\" src=\"../../static/images/update1.png\" alt=\"Wybierz "
+"'Zrestartuj aby zaktualizować Przeglądarkę Tor' pod głównym menu\"/>"
#: https//tb-manual.torproject.org/updating/
#: (content/updating/contents+en.lrtopic.body)
@@ -2228,6 +2264,8 @@ msgid ""
"<img width=\"500\" src=\"../../static/images/update4.png\" alt=\"Update "
"progress bar\"/>"
msgstr ""
+"<img width=\"500\" src=\"../../static/images/update4.png\" alt=\"Zaktualizuj"
+" pasek postępu\"/>"
#: https//tb-manual.torproject.org/updating/
#: (content/updating/contents+en.lrtopic.body)
@@ -2299,6 +2337,8 @@ msgid ""
"<img class=\"col-md-6\" src=\"../../static/images/connect.png\" alt=\"Click "
"'Connect' to connect to Tor.\">"
msgstr ""
+"<img class=\"col-md-6\" src=\"../../static/images/connect.png\" "
+"alt=\"Kliknij 'Połącz' aby połączyć się z Torem.\"/>"
#: https//tb-manual.torproject.org/troubleshooting/
#: (content/troubleshooting/contents+en.lrtopic.body)
@@ -2497,6 +2537,8 @@ msgstr ""
msgid ""
"Read the [Circumvention](/circumvention) section for possible solutions."
msgstr ""
+"Przeczytaj sekcję [Omijania Blokad](/circumvention) w poszukiwaniu możliwych"
+" rozwiązań."
#: https//tb-manual.torproject.org/troubleshooting/
#: (content/troubleshooting/contents+en.lrtopic.body)
@@ -3266,11 +3308,13 @@ msgid ""
"You will then be taken to the [Circumvention](../circumvention) screen to "
"configure a pluggable transport."
msgstr ""
+"Następnie zostaniesz przeniesiony na ekran [Omijania "
+"Blokad](../circumvention) w celu skonfigurowania transportu wtykowego."
#: https//tb-manual.torproject.org/mobile-tor/
#: (content/mobile-tor/contents+en.lrtopic.body)
msgid "### CIRCUMVENTION"
-msgstr ""
+msgstr "### OMIJANIE BLOKAD"
#: https//tb-manual.torproject.org/mobile-tor/
#: (content/mobile-tor/contents+en.lrtopic.body)
@@ -3567,6 +3611,9 @@ msgid ""
"/android-update-f-droid.png\" alt=\"Updating Tor Browser for Android on "
"F-Droid\">"
msgstr ""
+"<img style=\"max-width:300px\" class=\"col-md-6\" src=\"../../static/images"
+"/android-update-f-droid.png\" alt=\"Aktualizacja Przeglądarki Tor dla "
+"systemów Android przez F-Droid\"/>"
#: https//tb-manual.torproject.org/mobile-tor/
#: (content/mobile-tor/contents+en.lrtopic.body)
@@ -3691,6 +3738,9 @@ msgid ""
"/android-uninstall-f-droid.png\" alt=\"Uninstalling Tor Browser for Android "
"on F-Droid\">"
msgstr ""
+"<img style=\"max-width:300px\" class=\"col-md-6\" src=\"../../static/images"
+"/android-uninstall-f-droid.png\" alt=\"Odinstalowywanie Przeglądarki Tor dla"
+" systemów Android przez F-Droid\"/>"
#: https//tb-manual.torproject.org/mobile-tor/
#: (content/mobile-tor/contents+en.lrtopic.body)
1
0
[translation/communitytpo-contentspot] https://gitweb.torproject.org/translation.git/commit/?h=communitytpo-contentspot
by translation@torproject.org 12 May '21
by translation@torproject.org 12 May '21
12 May '21
commit 58aaf946a53b07c358b7597e39e1b0528adafb5b
Author: Translation commit bot <translation(a)torproject.org>
Date: Wed May 12 13:15:12 2021 +0000
https://gitweb.torproject.org/translation.git/commit/?h=communitytpo-conten…
---
contents+es.po | 37 ++++++++++++++++++++++++++++++++-----
1 file changed, 32 insertions(+), 5 deletions(-)
diff --git a/contents+es.po b/contents+es.po
index 6f779e5528..7d636551f3 100644
--- a/contents+es.po
+++ b/contents+es.po
@@ -19088,7 +19088,7 @@ msgid ""
"Two files will be placed there; one called `Tor`, and the other `Data`."
msgstr ""
"1. Descomprime el paquete Experto dentro de tu directorio Tor recientemente "
-"creado. Dos archivos estarán ubicados allí; uno llamado `Tor` y el otro "
+"creado. Dos carpetas estarán ubicadas allí; uno llamada `Tor` y la otra "
"`Data`."
#: https//community.torproject.org/relay/setup/guard/windows/
@@ -19251,7 +19251,7 @@ msgstr "### 3.1 Método 1: Interfaz de usuario"
#: https//community.torproject.org/relay/setup/guard/windows/
#: (content/relay-operations/technical-setup/guard/windows/contents+en.lrpage.body)
msgid "1. Navigate to the directory you extracted Tors files."
-msgstr ""
+msgstr "1. Navega hacia el directorio donde extrajiste los archivos de Tor."
#: https//community.torproject.org/relay/setup/guard/windows/
#: (content/relay-operations/technical-setup/guard/windows/contents+en.lrpage.body)
@@ -19260,6 +19260,9 @@ msgid ""
"from the drop-down menu, and enter the password for your Tor account when "
"prompted."
msgstr ""
+"2. Simplemente haz clic derecho sobre el archivo `tor.exe` y selecciona "
+"'Ejecutar como otro usuario' desde el menú desplegable, e ingresa la "
+"contraseña para tu cuenta Tor cuando se te solicite."
#: https//community.torproject.org/relay/setup/guard/windows/
#: (content/relay-operations/technical-setup/guard/windows/contents+en.lrpage.body)
@@ -19267,11 +19270,13 @@ msgid ""
"* **Note:** Be sure **not** to click the 'Run as administrator' button - "
"this is dangerous!"
msgstr ""
+"* **Nota:** Asegúrate de **no** hacer clic en el botón 'Ejecutar como "
+"administrador' - ¡esto es peligroso!"
#: https//community.torproject.org/relay/setup/guard/windows/
#: (content/relay-operations/technical-setup/guard/windows/contents+en.lrpage.body)
msgid "### 3.2 Method 2: Command line"
-msgstr ""
+msgstr "### 3.2 Método 2: Línea de comando"
#: https//community.torproject.org/relay/setup/guard/windows/
#: (content/relay-operations/technical-setup/guard/windows/contents+en.lrpage.body)
@@ -19280,6 +19285,9 @@ msgid ""
"`C:\\Users\\user\\torrelay\\tor\\Tor` with the command `cd "
"C:\\Users\\user\\torrelay\\tor\\Tor`."
msgstr ""
+"1. Abre tu línea de comando. Navega hacia "
+"`C:\\Users\\user\\torrelay\\tor\\Tor` con el comando `cd "
+"C:\\Users\\user\\torrelay\\tor\\Tor`."
#: https//community.torproject.org/relay/setup/guard/windows/
#: (content/relay-operations/technical-setup/guard/windows/contents+en.lrpage.body)
@@ -19288,6 +19296,9 @@ msgid ""
"`torrc` file somewhere other than the default location (Like the `home` "
"folder), specify the path with the `-f` flag."
msgstr ""
+"2. Tipea `RUNAS /user:torrelay tor.exe` y presiona Entrada. Si tienes tu "
+"archivo `torrc` en otro lugar que la ubicación predeterminada (Como la "
+"carpeta `home`), especifica la ruta con el modificador `-f`."
#: https//community.torproject.org/relay/setup/guard/windows/
#: (content/relay-operations/technical-setup/guard/windows/contents+en.lrpage.body)
@@ -19295,6 +19306,8 @@ msgid ""
"* Example: `RUNAS /user:torrelay tor.exe -f "
"C:\\Users\\user\\torrelay\\tor\\Tor\\torrc`"
msgstr ""
+"* Ejemplo: `RUNAS /user:torrelay tor.exe -f "
+"C:\\Users\\user\\torrelay\\tor\\Tor\\torrc`"
#: https//community.torproject.org/relay/setup/guard/windows/
#: (content/relay-operations/technical-setup/guard/windows/contents+en.lrpage.body)
@@ -19302,6 +19315,8 @@ msgid ""
"3. You should now see Tor starting up in your terminal. Wait until its "
"finished bootstrapping."
msgstr ""
+"3. Debieras ver a Tor iniciándose en tu terminal. Espera hasta que finalice "
+"su ciclo de inicio."
#: https//community.torproject.org/relay/setup/guard/windows/
#: (content/relay-operations/technical-setup/guard/windows/contents+en.lrpage.body)
@@ -19309,6 +19324,8 @@ msgid ""
"4. After a short period it should publish its OrPort, and you will be "
"successfully relaying traffic for the Tor Network."
msgstr ""
+"4. Luego de un corto intervalo debiera publicar su OrPort, y estarás "
+"repitiendo tráfico exitosamente para la red Tor."
#: https//community.torproject.org/relay/setup/guard/windows/
#: (content/relay-operations/technical-setup/guard/windows/contents+en.lrpage.body)
@@ -19319,11 +19336,17 @@ msgid ""
"control\". Add the tor.exe file to the permissions list, then rerun "
"`tor.exe` from the command line. Tor should now start up normally."
msgstr ""
+"* **Advertencia:** Dependiendo de los ajustes de tu sistema, Tor pudiera "
+"fallar al inicio y producir un error indicando que no es capaz de crear "
+"archivos. Si esto ocurre, simplemente abre el Centro de Seguridad Windows "
+"Defender y selecciona \"Control de aplicaciones y navegador\". Agrega el "
+"archivo tor.exe a la lista de permisos, luego vuelve a ejecutar `tor.exe` "
+"desde la línea de comando. Ahora Tor debiera arrancar normalmente."
#: https//community.torproject.org/relay/setup/guard/windows/
#: (content/relay-operations/technical-setup/guard/windows/contents+en.lrpage.body)
msgid "## 4. Final notes"
-msgstr ""
+msgstr "# 4. Notas Finales"
#: https//community.torproject.org/relay/setup/guard/windows/
#: (content/relay-operations/technical-setup/guard/windows/contents+en.lrpage.body)
@@ -19654,6 +19677,8 @@ msgid ""
"# 2. Add the following to `/etc/yum.repos.d/tor.repo` and then install the "
"tor package."
msgstr ""
+"# 2. Agrega lo siguiente a `/etc/yum.repos.d/tor.repo`, e instala luego el "
+"paquete tor."
#: https//community.torproject.org/relay/setup/guard/fedora/
#: (content/relay-operations/technical-setup/guard/fedora/contents+en.lrpage.body)
@@ -21267,6 +21292,8 @@ msgid ""
"The best resource of all is the active community of relay operators on tor-"
"relays mailing list and on IRC"
msgstr ""
+"El mejor recurso de todos es la comunidad activa de operadores de "
+"repetidores en la lista de correo tor-relays y en el IRC"
#: templates/relay-operations.html:24
msgid "#tor-relays"
@@ -21274,7 +21301,7 @@ msgstr "#tor-relays"
#: templates/relay-operations.html:24
msgid "in irc.oftc.net."
-msgstr ""
+msgstr "en irc.oftc.net."
#: templates/relay-operations.html:26
msgid "Relay Operators mailing list"
1
0
[snowflake/main] Implement snowflake client lib as PTv2.1 Go API
by cohosh@torproject.org 12 May '21
by cohosh@torproject.org 12 May '21
12 May '21
commit e87b9175dd7559fccd665cd7eb4b6edecc231950
Author: Cecylia Bocovich <cohosh(a)torproject.org>
Date: Sat Mar 20 12:36:33 2021 -0400
Implement snowflake client lib as PTv2.1 Go API
This implements a pluggable transports v2.1 compatible Go API in the
Snowflake client library, and refactors how the main Snowflake program
calls it. The Go API implements the two required client side functions:
a constructor that returns a Transport, and a Dial function for the
Transport that returns a net.Conn. See the PT specification for more
information:
https://github.com/Pluggable-Transports/Pluggable-Transports-spec/blob/mast…
---
client/client_test.go | 59 ---------------
client/lib/lib_test.go | 55 ++++++++++----
client/lib/snowflake.go | 198 +++++++++++++++++++++++++++++++++---------------
client/snowflake.go | 106 ++++++++------------------
4 files changed, 211 insertions(+), 207 deletions(-)
diff --git a/client/client_test.go b/client/client_test.go
deleted file mode 100644
index 84e9cc1..0000000
--- a/client/client_test.go
+++ /dev/null
@@ -1,59 +0,0 @@
-package main
-
-import (
- "testing"
-
- . "github.com/smartystreets/goconvey/convey"
-)
-
-func TestICEServerParser(t *testing.T) {
- Convey("Test parsing of ICE servers", t, func() {
- for _, test := range []struct {
- input string
- urls [][]string
- length int
- }{
- {
- "",
- nil,
- 0,
- },
- {
- " ",
- nil,
- 0,
- },
- {
- "stun:stun.l.google.com:19302",
- [][]string{[]string{"stun:stun.l.google.com:19302"}},
- 1,
- },
- {
- "stun:stun.l.google.com:19302,stun.ekiga.net",
- [][]string{[]string{"stun:stun.l.google.com:19302"}, []string{"stun.ekiga.net"}},
- 2,
- },
- {
- "stun:stun.l.google.com:19302, stun.ekiga.net",
- [][]string{[]string{"stun:stun.l.google.com:19302"}, []string{"stun.ekiga.net"}},
- 2,
- },
- } {
- servers := parseIceServers(test.input)
-
- if test.urls == nil {
- So(servers, ShouldBeNil)
- } else {
- So(servers, ShouldNotBeNil)
- }
-
- So(len(servers), ShouldEqual, test.length)
-
- for _, server := range servers {
- So(test.urls, ShouldContain, server.URLs)
- }
-
- }
-
- })
-}
diff --git a/client/lib/lib_test.go b/client/lib/lib_test.go
index 5537a52..6140e0b 100644
--- a/client/lib/lib_test.go
+++ b/client/lib/lib_test.go
@@ -156,19 +156,6 @@ func TestSnowflakeClient(t *testing.T) {
})
- Convey("Snowflake", t, func() {
-
- SkipConvey("Handler Grants correctly", func() {
- socks := &FakeSocksConn{}
- broker := &BrokerChannel{Host: "test"}
- d := NewWebRTCDialer(broker, nil, 1)
-
- So(socks.rejected, ShouldEqual, false)
- Handler(socks, d)
- So(socks.rejected, ShouldEqual, true)
- })
- })
-
Convey("Dialers", t, func() {
Convey("Can construct WebRTCDialer.", func() {
broker := &BrokerChannel{Host: "test"}
@@ -267,3 +254,45 @@ func TestSnowflakeClient(t *testing.T) {
})
}
+
+func TestICEServerParser(t *testing.T) {
+ Convey("Test parsing of ICE servers", t, func() {
+ for _, test := range []struct {
+ input []string
+ urls [][]string
+ length int
+ }{
+ {
+ []string{"stun:stun.l.google.com:19302"},
+ [][]string{[]string{"stun:stun.l.google.com:19302"}},
+ 1,
+ },
+ {
+ []string{"stun:stun.l.google.com:19302", "stun.ekiga.net"},
+ [][]string{[]string{"stun:stun.l.google.com:19302"}, []string{"stun.ekiga.net"}},
+ 2,
+ },
+ {
+ []string{"stun:stun.l.google.com:19302", "stun.ekiga.net"},
+ [][]string{[]string{"stun:stun.l.google.com:19302"}, []string{"stun.ekiga.net"}},
+ 2,
+ },
+ } {
+ servers := parseIceServers(test.input)
+
+ if test.urls == nil {
+ So(servers, ShouldBeNil)
+ } else {
+ So(servers, ShouldNotBeNil)
+ }
+
+ So(len(servers), ShouldEqual, test.length)
+
+ for _, server := range servers {
+ So(test.urls, ShouldContain, server.URLs)
+ }
+
+ }
+
+ })
+}
diff --git a/client/lib/snowflake.go b/client/lib/snowflake.go
index 2ed51a1..6e87b81 100644
--- a/client/lib/snowflake.go
+++ b/client/lib/snowflake.go
@@ -3,12 +3,15 @@ package lib
import (
"context"
"errors"
- "io"
"log"
+ "math/rand"
"net"
+ "strings"
"time"
+ "git.torproject.org/pluggable-transports/snowflake.git/common/nat"
"git.torproject.org/pluggable-transports/snowflake.git/common/turbotunnel"
+ "github.com/pion/webrtc/v3"
"github.com/xtaci/kcp-go/v5"
"github.com/xtaci/smux"
)
@@ -25,6 +28,138 @@ type dummyAddr struct{}
func (addr dummyAddr) Network() string { return "dummy" }
func (addr dummyAddr) String() string { return "dummy" }
+// Transport is a structure with methods that conform to the Go PT v2.1 API
+// https://github.com/Pluggable-Transports/Pluggable-Transports-spec/blob/mast…
+type Transport struct {
+ dialer *WebRTCDialer
+}
+
+// Create a new Snowflake transport client that can spawn multiple Snowflake connections.
+// brokerURL and frontDomain are the urls for the broker host and domain fronting host
+// iceAddresses are the STUN/TURN urls needed for WebRTC negotiation
+// keepLocalAddresses is a flag to enable sending local network addresses (for testing purposes)
+// max is the maximum number of snowflakes the client should gather for each SOCKS connection
+func NewSnowflakeClient(brokerURL, frontDomain string, iceAddresses []string, keepLocalAddresses bool, max int) (*Transport, error) {
+
+ log.Println("\n\n\n --- Starting Snowflake Client ---")
+
+ iceServers := parseIceServers(iceAddresses)
+ // chooses a random subset of servers from inputs
+ rand.Seed(time.Now().UnixNano())
+ rand.Shuffle(len(iceServers), func(i, j int) {
+ iceServers[i], iceServers[j] = iceServers[j], iceServers[i]
+ })
+ if len(iceServers) > 2 {
+ iceServers = iceServers[:(len(iceServers)+1)/2]
+ }
+ log.Printf("Using ICE servers:")
+ for _, server := range iceServers {
+ log.Printf("url: %v", strings.Join(server.URLs, " "))
+ }
+
+ // Use potentially domain-fronting broker to rendezvous.
+ broker, err := NewBrokerChannel(
+ brokerURL, frontDomain, CreateBrokerTransport(),
+ keepLocalAddresses)
+ if err != nil {
+ return nil, err
+ }
+ go updateNATType(iceServers, broker)
+
+ transport := &Transport{dialer: NewWebRTCDialer(broker, iceServers, max)}
+
+ return transport, nil
+}
+
+// Create a new Snowflake connection. Starts the collection of snowflakes and returns a
+// smux Stream.
+func (t *Transport) Dial() (net.Conn, error) {
+ // Prepare to collect remote WebRTC peers.
+ snowflakes, err := NewPeers(t.dialer)
+ if err != nil {
+ return nil, err
+ }
+
+ // Use a real logger to periodically output how much traffic is happening.
+ snowflakes.BytesLogger = NewBytesSyncLogger()
+
+ log.Printf("---- SnowflakeConn: begin collecting snowflakes ---")
+ go connectLoop(snowflakes)
+
+ // Create a new smux session
+ log.Printf("---- SnowflakeConn: starting a new session ---")
+ pconn, sess, err := newSession(snowflakes)
+ if err != nil {
+ return nil, err
+ }
+
+ // On the smux session we overlay a stream.
+ stream, err := sess.OpenStream()
+ if err != nil {
+ return nil, err
+ }
+
+ // Begin exchanging data.
+ log.Printf("---- SnowflakeConn: begin stream %v ---", stream.ID())
+ return &SnowflakeConn{Stream: stream, sess: sess, pconn: pconn, snowflakes: snowflakes}, nil
+}
+
+type SnowflakeConn struct {
+ *smux.Stream
+ sess *smux.Session
+ pconn net.PacketConn
+ snowflakes *Peers
+}
+
+func (conn *SnowflakeConn) Close() error {
+ log.Printf("---- SnowflakeConn: closed stream %v ---", conn.ID())
+ conn.Stream.Close()
+ log.Printf("---- SnowflakeConn: end collecting snowflakes ---")
+ conn.snowflakes.End()
+ conn.pconn.Close()
+ log.Printf("---- SnowflakeConn: discarding finished session ---")
+ conn.sess.Close()
+ return nil //TODO: return errors if any of the above do
+}
+
+// loop through all provided STUN servers until we exhaust the list or find
+// one that is compatable with RFC 5780
+func updateNATType(servers []webrtc.ICEServer, broker *BrokerChannel) {
+
+ var restrictedNAT bool
+ var err error
+ for _, server := range servers {
+ addr := strings.TrimPrefix(server.URLs[0], "stun:")
+ restrictedNAT, err = nat.CheckIfRestrictedNAT(addr)
+ if err == nil {
+ if restrictedNAT {
+ broker.SetNATType(nat.NATRestricted)
+ } else {
+ broker.SetNATType(nat.NATUnrestricted)
+ }
+ break
+ }
+ }
+ if err != nil {
+ broker.SetNATType(nat.NATUnknown)
+ }
+}
+
+// Returns a slice of webrtc.ICEServer given a slice of addresses
+func parseIceServers(addresses []string) []webrtc.ICEServer {
+ var servers []webrtc.ICEServer
+ if len(addresses) == 0 {
+ return nil
+ }
+ for _, url := range addresses {
+ url = strings.TrimSpace(url)
+ servers = append(servers, webrtc.ICEServer{
+ URLs: []string{url},
+ })
+ }
+ return servers
+}
+
// newSession returns a new smux.Session and the net.PacketConn it is running
// over. The net.PacketConn successively connects through Snowflake proxies
// pulled from snowflakes.
@@ -94,47 +229,6 @@ func newSession(snowflakes SnowflakeCollector) (net.PacketConn, *smux.Session, e
return pconn, sess, err
}
-// Given an accepted SOCKS connection, establish a WebRTC connection to the
-// remote peer and exchange traffic.
-func Handler(socks net.Conn, tongue Tongue) error {
- // Prepare to collect remote WebRTC peers.
- snowflakes, err := NewPeers(tongue)
- if err != nil {
- return err
- }
-
- // Use a real logger to periodically output how much traffic is happening.
- snowflakes.BytesLogger = NewBytesSyncLogger()
-
- log.Printf("---- Handler: begin collecting snowflakes ---")
- go connectLoop(snowflakes)
-
- // Create a new smux session
- log.Printf("---- Handler: starting a new session ---")
- pconn, sess, err := newSession(snowflakes)
- if err != nil {
- return err
- }
-
- // On the smux session we overlay a stream.
- stream, err := sess.OpenStream()
- if err != nil {
- return err
- }
- defer stream.Close()
-
- // Begin exchanging data.
- log.Printf("---- Handler: begin stream %v ---", stream.ID())
- copyLoop(socks, stream)
- log.Printf("---- Handler: closed stream %v ---", stream.ID())
- snowflakes.End()
- log.Printf("---- Handler: end collecting snowflakes ---")
- pconn.Close()
- sess.Close()
- log.Printf("---- Handler: discarding finished session ---")
- return nil
-}
-
// Maintain |SnowflakeCapacity| number of available WebRTC connections, to
// transfer to the Tor SOCKS handler when needed.
func connectLoop(snowflakes SnowflakeCollector) {
@@ -153,23 +247,3 @@ func connectLoop(snowflakes SnowflakeCollector) {
}
}
}
-
-// Exchanges bytes between two ReadWriters.
-// (In this case, between a SOCKS connection and smux stream.)
-func copyLoop(socks, stream io.ReadWriter) {
- done := make(chan struct{}, 2)
- go func() {
- if _, err := io.Copy(socks, stream); err != nil {
- log.Printf("copying WebRTC to SOCKS resulted in error: %v", err)
- }
- done <- struct{}{}
- }()
- go func() {
- if _, err := io.Copy(stream, socks); err != nil {
- log.Printf("copying SOCKS to stream resulted in error: %v", err)
- }
- done <- struct{}{}
- }()
- <-done
- log.Println("copy loop ended")
-}
diff --git a/client/snowflake.go b/client/snowflake.go
index d79de97..f19afcf 100644
--- a/client/snowflake.go
+++ b/client/snowflake.go
@@ -6,7 +6,6 @@ import (
"io"
"io/ioutil"
"log"
- "math/rand"
"net"
"os"
"os/signal"
@@ -14,21 +13,38 @@ import (
"strings"
"sync"
"syscall"
- "time"
pt "git.torproject.org/pluggable-transports/goptlib.git"
sf "git.torproject.org/pluggable-transports/snowflake.git/client/lib"
- "git.torproject.org/pluggable-transports/snowflake.git/common/nat"
"git.torproject.org/pluggable-transports/snowflake.git/common/safelog"
- "github.com/pion/webrtc/v3"
)
const (
DefaultSnowflakeCapacity = 1
)
-// Accept local SOCKS connections and pass them to the handler.
-func socksAcceptLoop(ln *pt.SocksListener, tongue sf.Tongue, shutdown chan struct{}, wg *sync.WaitGroup) {
+// Exchanges bytes between two ReadWriters.
+// (In this case, between a SOCKS connection and a snowflake transport conn)
+func copyLoop(socks, sfconn io.ReadWriter) {
+ done := make(chan struct{}, 2)
+ go func() {
+ if _, err := io.Copy(socks, sfconn); err != nil {
+ log.Printf("copying Snowflake to SOCKS resulted in error: %v", err)
+ }
+ done <- struct{}{}
+ }()
+ go func() {
+ if _, err := io.Copy(sfconn, socks); err != nil {
+ log.Printf("copying SOCKS to Snowflake resulted in error: %v", err)
+ }
+ done <- struct{}{}
+ }()
+ <-done
+ log.Println("copy loop ended")
+}
+
+// Accept local SOCKS connections and connect to a Snowflake connection
+func socksAcceptLoop(ln *pt.SocksListener, transport *sf.Transport, shutdown chan struct{}, wg *sync.WaitGroup) {
defer ln.Close()
for {
conn, err := ln.AcceptSocks()
@@ -53,10 +69,14 @@ func socksAcceptLoop(ln *pt.SocksListener, tongue sf.Tongue, shutdown chan struc
handler := make(chan struct{})
go func() {
- err = sf.Handler(conn, tongue)
+ // pass an empty address because the broker chooses the bridge
+ sconn, err := transport.Dial()
if err != nil {
- log.Printf("handler error: %s", err)
+ log.Printf("dial error: %s", err)
}
+ // copy between the created Snowflake conn and the SOCKS conn
+ copyLoop(conn, sconn)
+ sconn.Close()
close(handler)
return
@@ -72,23 +92,6 @@ func socksAcceptLoop(ln *pt.SocksListener, tongue sf.Tongue, shutdown chan struc
}
}
-// s is a comma-separated list of ICE server URLs.
-func parseIceServers(s string) []webrtc.ICEServer {
- var servers []webrtc.ICEServer
- s = strings.TrimSpace(s)
- if len(s) == 0 {
- return nil
- }
- urls := strings.Split(s, ",")
- for _, url := range urls {
- url = strings.TrimSpace(url)
- servers = append(servers, webrtc.ICEServer{
- URLs: []string{url},
- })
- }
- return servers
-}
-
func main() {
iceServersCommas := flag.String("ice", "", "comma-separated list of ICE servers")
brokerURL := flag.String("url", "", "URL of signaling broker")
@@ -137,33 +140,13 @@ func main() {
log.SetOutput(&safelog.LogScrubber{Output: logOutput})
}
- log.Println("\n\n\n --- Starting Snowflake Client ---")
-
- iceServers := parseIceServers(*iceServersCommas)
- // chooses a random subset of servers from inputs
- rand.Seed(time.Now().UnixNano())
- rand.Shuffle(len(iceServers), func(i, j int) {
- iceServers[i], iceServers[j] = iceServers[j], iceServers[i]
- })
- if len(iceServers) > 2 {
- iceServers = iceServers[:(len(iceServers)+1)/2]
- }
- log.Printf("Using ICE servers:")
- for _, server := range iceServers {
- log.Printf("url: %v", strings.Join(server.URLs, " "))
- }
+ iceAddresses := strings.Split(strings.TrimSpace(*iceServersCommas), ",")
- // Use potentially domain-fronting broker to rendezvous.
- broker, err := sf.NewBrokerChannel(
- *brokerURL, *frontDomain, sf.CreateBrokerTransport(),
- *keepLocalAddresses || *oldKeepLocalAddresses)
+ transport, err := sf.NewSnowflakeClient(*brokerURL, *frontDomain, iceAddresses,
+ *keepLocalAddresses || *oldKeepLocalAddresses, *max)
if err != nil {
- log.Fatalf("parsing broker URL: %v", err)
+ log.Fatal("Failed to start snowflake transport: ", err)
}
- go updateNATType(iceServers, broker)
-
- // Create a new WebRTCDialer to use as the |Tongue| to catch snowflakes
- dialer := sf.NewWebRTCDialer(broker, iceServers, *max)
// Begin goptlib client process.
ptInfo, err := pt.ClientSetup(nil)
@@ -187,7 +170,7 @@ func main() {
break
}
log.Printf("Started SOCKS listener at %v.", ln.Addr())
- go socksAcceptLoop(ln, dialer, shutdown, &wg)
+ go socksAcceptLoop(ln, transport, shutdown, &wg)
pt.Cmethod(methodName, ln.Version(), ln.Addr())
listeners = append(listeners, ln)
default:
@@ -223,26 +206,3 @@ func main() {
wg.Wait()
log.Println("snowflake is done.")
}
-
-// loop through all provided STUN servers until we exhaust the list or find
-// one that is compatable with RFC 5780
-func updateNATType(servers []webrtc.ICEServer, broker *sf.BrokerChannel) {
-
- var restrictedNAT bool
- var err error
- for _, server := range servers {
- addr := strings.TrimPrefix(server.URLs[0], "stun:")
- restrictedNAT, err = nat.CheckIfRestrictedNAT(addr)
- if err == nil {
- if restrictedNAT {
- broker.SetNATType(nat.NATRestricted)
- } else {
- broker.SetNATType(nat.NATUnrestricted)
- }
- break
- }
- }
- if err != nil {
- broker.SetNATType(nat.NATUnknown)
- }
-}
1
0
12 May '21
commit 11f0846264d4033e7a7dc7824febb6ad7140762f
Author: Cecylia Bocovich <cohosh(a)torproject.org>
Date: Sat Mar 20 18:24:00 2021 -0400
Implement server as a v2.1 PT Go API
---
server/lib/http.go | 211 +++++++++++++++++
server/lib/server_test.go | 55 +++++
server/lib/snowflake.go | 242 ++++++++++++++++++++
server/{ => lib}/turbotunnel.go | 2 +-
server/{ => lib}/turbotunnel_test.go | 2 +-
server/server.go | 426 ++++-------------------------------
server/server_test.go | 153 -------------
7 files changed, 551 insertions(+), 540 deletions(-)
diff --git a/server/lib/http.go b/server/lib/http.go
new file mode 100644
index 0000000..b1c453c
--- /dev/null
+++ b/server/lib/http.go
@@ -0,0 +1,211 @@
+package lib
+
+import (
+ "bufio"
+ "bytes"
+ "fmt"
+ "io"
+ "log"
+ "net"
+ "net/http"
+ "time"
+
+ "git.torproject.org/pluggable-transports/snowflake.git/common/encapsulation"
+ "git.torproject.org/pluggable-transports/snowflake.git/common/turbotunnel"
+ "git.torproject.org/pluggable-transports/snowflake.git/common/websocketconn"
+ "github.com/gorilla/websocket"
+)
+
+const requestTimeout = 10 * time.Second
+
+// How long to remember outgoing packets for a client, when we don't currently
+// have an active WebSocket connection corresponding to that client. Because a
+// client session may span multiple WebSocket connections, we keep packets we
+// aren't able to send immediately in memory, for a little while but not
+// indefinitely.
+const clientMapTimeout = 1 * time.Minute
+
+// How big to make the map of ClientIDs to IP addresses. The map is used in
+// turbotunnelMode to store a reasonable IP address for a client session that
+// may outlive any single WebSocket connection.
+const clientIDAddrMapCapacity = 1024
+
+// How long to wait for ListenAndServe or ListenAndServeTLS to return an error
+// before deciding that it's not going to return.
+const listenAndServeErrorTimeout = 100 * time.Millisecond
+
+var upgrader = websocket.Upgrader{
+ CheckOrigin: func(r *http.Request) bool { return true },
+}
+
+// clientIDAddrMap stores short-term mappings from ClientIDs to IP addresses.
+// When we call pt.DialOr, tor wants us to provide a USERADDR string that
+// represents the remote IP address of the client (for metrics purposes, etc.).
+// This data structure bridges the gap between ServeHTTP, which knows about IP
+// addresses, and handleStream, which is what calls pt.DialOr. The common piece
+// of information linking both ends of the chain is the ClientID, which is
+// attached to the WebSocket connection and every session.
+var clientIDAddrMap = newClientIDMap(clientIDAddrMapCapacity)
+
+// overrideReadConn is a net.Conn with an overridden Read method. Compare to
+// recordingConn at
+// https://dave.cheney.net/2015/05/22/struct-composition-with-go.
+type overrideReadConn struct {
+ net.Conn
+ io.Reader
+}
+
+func (conn *overrideReadConn) Read(p []byte) (int, error) {
+ return conn.Reader.Read(p)
+}
+
+type HTTPHandler struct {
+ // pconn is the adapter layer between stream-oriented WebSocket
+ // connections and the packet-oriented KCP layer.
+ pconn *turbotunnel.QueuePacketConn
+ ln *SnowflakeListener
+}
+
+func (handler *HTTPHandler) ServeHTTP(w http.ResponseWriter, r *http.Request) {
+ ws, err := upgrader.Upgrade(w, r, nil)
+ if err != nil {
+ log.Println(err)
+ return
+ }
+
+ conn := websocketconn.New(ws)
+ defer conn.Close()
+
+ // Pass the address of client as the remote address of incoming connection
+ clientIPParam := r.URL.Query().Get("client_ip")
+ addr := clientAddr(clientIPParam)
+
+ var token [len(turbotunnel.Token)]byte
+ _, err = io.ReadFull(conn, token[:])
+ if err != nil {
+ // Don't bother logging EOF: that happens with an unused
+ // connection, which clients make frequently as they maintain a
+ // pool of proxies.
+ if err != io.EOF {
+ log.Printf("reading token: %v", err)
+ }
+ return
+ }
+
+ switch {
+ case bytes.Equal(token[:], turbotunnel.Token[:]):
+ err = turbotunnelMode(conn, addr, handler.pconn)
+ default:
+ // We didn't find a matching token, which means that we are
+ // dealing with a client that doesn't know about such things.
+ // "Unread" the token by constructing a new Reader and pass it
+ // to the old one-session-per-WebSocket mode.
+ conn2 := &overrideReadConn{Conn: conn, Reader: io.MultiReader(bytes.NewReader(token[:]), conn)}
+ err = oneshotMode(conn2, addr, handler.ln)
+ }
+ if err != nil {
+ log.Println(err)
+ return
+ }
+}
+
+// oneshotMode handles clients that did not send turbotunnel.Token at the start
+// of their stream. These clients use the WebSocket as a raw pipe, and expect
+// their session to begin and end when this single WebSocket does.
+func oneshotMode(conn net.Conn, addr net.Addr, ln *SnowflakeListener) error {
+ return ln.QueueConn(&SnowflakeClientConn{Conn: conn, address: addr})
+}
+
+// turbotunnelMode handles clients that sent turbotunnel.Token at the start of
+// their stream. These clients expect to send and receive encapsulated packets,
+// with a long-lived session identified by ClientID.
+func turbotunnelMode(conn net.Conn, addr net.Addr, pconn *turbotunnel.QueuePacketConn) error {
+ // Read the ClientID prefix. Every packet encapsulated in this WebSocket
+ // connection pertains to the same ClientID.
+ var clientID turbotunnel.ClientID
+ _, err := io.ReadFull(conn, clientID[:])
+ if err != nil {
+ return fmt.Errorf("reading ClientID: %v", err)
+ }
+
+ // Store a a short-term mapping from the ClientID to the client IP
+ // address attached to this WebSocket connection. tor will want us to
+ // provide a client IP address when we call pt.DialOr. But a KCP session
+ // does not necessarily correspond to any single IP address--it's
+ // composed of packets that are carried in possibly multiple WebSocket
+ // streams. We apply the heuristic that the IP address of the most
+ // recent WebSocket connection that has had to do with a session, at the
+ // time the session is established, is the IP address that should be
+ // credited for the entire KCP session.
+ clientIDAddrMap.Set(clientID, addr.String())
+
+ errCh := make(chan error)
+
+ // The remainder of the WebSocket stream consists of encapsulated
+ // packets. We read them one by one and feed them into the
+ // QueuePacketConn on which kcp.ServeConn was set up, which eventually
+ // leads to KCP-level sessions in the acceptSessions function.
+ go func() {
+ for {
+ p, err := encapsulation.ReadData(conn)
+ if err != nil {
+ errCh <- err
+ break
+ }
+ pconn.QueueIncoming(p, clientID)
+ }
+ }()
+
+ // At the same time, grab packets addressed to this ClientID and
+ // encapsulate them into the downstream.
+ go func() {
+ // Buffer encapsulation.WriteData operations to keep length
+ // prefixes in the same send as the data that follows.
+ bw := bufio.NewWriter(conn)
+ for p := range pconn.OutgoingQueue(clientID) {
+ _, err := encapsulation.WriteData(bw, p)
+ if err == nil {
+ err = bw.Flush()
+ }
+ if err != nil {
+ errCh <- err
+ break
+ }
+ }
+ }()
+
+ // Wait until one of the above loops terminates. The closing of the
+ // WebSocket connection will terminate the other one.
+ <-errCh
+
+ return nil
+}
+
+type ClientMapAddr string
+
+func (addr ClientMapAddr) Network() string {
+ return "snowflake"
+}
+
+func (addr ClientMapAddr) String() string {
+ return string(addr)
+}
+
+// Return a client address
+func clientAddr(clientIPParam string) net.Addr {
+ if clientIPParam == "" {
+ return ClientMapAddr("")
+ }
+ // Check if client addr is a valid IP
+ clientIP := net.ParseIP(clientIPParam)
+ if clientIP == nil {
+ return ClientMapAddr("")
+ }
+ // Check if client addr is 0.0.0.0 or [::]. Some proxies erroneously
+ // report an address of 0.0.0.0: https://bugs.torproject.org/33157.
+ if clientIP.IsUnspecified() {
+ return ClientMapAddr("")
+ }
+ // Add a stub port number. USERADDR requires a port number.
+ return ClientMapAddr((&net.TCPAddr{IP: clientIP, Port: 1, Zone: ""}).String())
+}
diff --git a/server/lib/server_test.go b/server/lib/server_test.go
new file mode 100644
index 0000000..65d31d1
--- /dev/null
+++ b/server/lib/server_test.go
@@ -0,0 +1,55 @@
+package lib
+
+import (
+ "net"
+ "strconv"
+ "testing"
+
+ . "github.com/smartystreets/goconvey/convey"
+)
+
+func TestClientAddr(t *testing.T) {
+ Convey("Testing clientAddr", t, func() {
+ // good tests
+ for _, test := range []struct {
+ input string
+ expected net.IP
+ }{
+ {"1.2.3.4", net.ParseIP("1.2.3.4")},
+ {"1:2::3:4", net.ParseIP("1:2::3:4")},
+ } {
+ useraddr := clientAddr(test.input).String()
+ host, port, err := net.SplitHostPort(useraddr)
+ if err != nil {
+ t.Errorf("clientAddr(%q) → SplitHostPort error %v", test.input, err)
+ continue
+ }
+ if !test.expected.Equal(net.ParseIP(host)) {
+ t.Errorf("clientAddr(%q) → host %q, not %v", test.input, host, test.expected)
+ }
+ portNo, err := strconv.Atoi(port)
+ if err != nil {
+ t.Errorf("clientAddr(%q) → port %q", test.input, port)
+ continue
+ }
+ if portNo == 0 {
+ t.Errorf("clientAddr(%q) → port %d", test.input, portNo)
+ }
+ }
+
+ // bad tests
+ for _, input := range []string{
+ "",
+ "abc",
+ "1.2.3.4.5",
+ "[12::34]",
+ "0.0.0.0",
+ "[::]",
+ } {
+ useraddr := clientAddr(input).String()
+ if useraddr != "" {
+ t.Errorf("clientAddr(%q) → %q, not %q", input, useraddr, "")
+ }
+ }
+ })
+}
diff --git a/server/lib/snowflake.go b/server/lib/snowflake.go
new file mode 100644
index 0000000..319acd8
--- /dev/null
+++ b/server/lib/snowflake.go
@@ -0,0 +1,242 @@
+package lib
+
+import (
+ "crypto/tls"
+ "fmt"
+ "io"
+ "log"
+ "net"
+ "net/http"
+ "sync"
+ "time"
+
+ "git.torproject.org/pluggable-transports/snowflake.git/common/turbotunnel"
+ "github.com/xtaci/kcp-go/v5"
+ "github.com/xtaci/smux"
+ "golang.org/x/net/http2"
+)
+
+// Transport is a structure with methods that conform to the Go PT v2.1 API
+// https://github.com/Pluggable-Transports/Pluggable-Transports-spec/blob/mast…
+type Transport struct {
+ getCertificate func(*tls.ClientHelloInfo) (*tls.Certificate, error)
+}
+
+func NewSnowflakeServer(getCertificate func(*tls.ClientHelloInfo) (*tls.Certificate, error)) *Transport {
+
+ return &Transport{getCertificate: getCertificate}
+}
+
+func (t *Transport) Listen(addr net.Addr) (*SnowflakeListener, error) {
+ listener := &SnowflakeListener{addr: addr, queue: make(chan net.Conn, 65534)}
+
+ handler := HTTPHandler{
+ // pconn is shared among all connections to this server. It
+ // overlays packet-based client sessions on top of ephemeral
+ // WebSocket connections.
+ pconn: turbotunnel.NewQueuePacketConn(addr, clientMapTimeout),
+ }
+ server := &http.Server{
+ Addr: addr.String(),
+ Handler: &handler,
+ ReadTimeout: requestTimeout,
+ }
+ // We need to override server.TLSConfig.GetCertificate--but first
+ // server.TLSConfig needs to be non-nil. If we just create our own new
+ // &tls.Config, it will lack the default settings that the net/http
+ // package sets up for things like HTTP/2. Therefore we first call
+ // http2.ConfigureServer for its side effect of initializing
+ // server.TLSConfig properly. An alternative would be to make a dummy
+ // net.Listener, call Serve on it, and let it return.
+ // https://github.com/golang/go/issues/16588#issuecomment-237386446
+ err := http2.ConfigureServer(server, nil)
+ if err != nil {
+ return nil, err
+ }
+ server.TLSConfig.GetCertificate = t.getCertificate
+
+ // Another unfortunate effect of the inseparable net/http ListenAndServe
+ // is that we can't check for Listen errors like "permission denied" and
+ // "address already in use" without potentially entering the infinite
+ // loop of Serve. The hack we apply here is to wait a short time,
+ // listenAndServeErrorTimeout, to see if an error is returned (because
+ // it's better if the error message goes to the tor log through
+ // SMETHOD-ERROR than if it only goes to the snowflake log).
+ errChan := make(chan error)
+ go func() {
+ if t.getCertificate == nil {
+ // TLS is disabled
+ log.Printf("listening with plain HTTP on %s", addr)
+ err := server.ListenAndServe()
+ if err != nil {
+ log.Printf("error in ListenAndServe: %s", err)
+ }
+ errChan <- err
+ } else {
+ log.Printf("listening with HTTPS on %s", addr)
+ err := server.ListenAndServeTLS("", "")
+ if err != nil {
+ log.Printf("error in ListenAndServeTLS: %s", err)
+ }
+ errChan <- err
+ }
+ }()
+
+ select {
+ case err = <-errChan:
+ break
+ case <-time.After(listenAndServeErrorTimeout):
+ break
+ }
+
+ listener.server = server
+
+ // Start a KCP engine, set up to read and write its packets over the
+ // WebSocket connections that arrive at the web server.
+ // handler.ServeHTTP is responsible for encapsulation/decapsulation of
+ // packets on behalf of KCP. KCP takes those packets and turns them into
+ // sessions which appear in the acceptSessions function.
+ ln, err := kcp.ServeConn(nil, 0, 0, handler.pconn)
+ if err != nil {
+ server.Close()
+ return nil, err
+ }
+ go func() {
+ defer ln.Close()
+ err := listener.acceptSessions(ln)
+ if err != nil {
+ log.Printf("acceptSessions: %v", err)
+ }
+ }()
+
+ listener.ln = ln
+
+ return listener, nil
+
+}
+
+type SnowflakeListener struct {
+ addr net.Addr
+ queue chan net.Conn
+ server *http.Server
+ ln *kcp.Listener
+ closed chan struct{}
+ closeOnce sync.Once
+}
+
+// Allows the caller to accept incoming Snowflake connections
+// We accept connections from a queue to accommodate both incoming
+// smux Streams and legacy non-turbotunnel connections
+func (l *SnowflakeListener) Accept() (net.Conn, error) {
+ select {
+ case <-l.closed:
+ //channel has been closed, no longer accepting connections
+ return nil, io.ErrClosedPipe
+ case conn := <-l.queue:
+ return conn, nil
+ }
+}
+
+func (l *SnowflakeListener) Addr() net.Addr {
+ return l.addr
+}
+
+func (l *SnowflakeListener) Close() error {
+ // Close our HTTP server and our KCP listener
+ l.closeOnce.Do(func() {
+ close(l.closed)
+ l.server.Close()
+ l.ln.Close()
+ })
+ return nil
+}
+
+// acceptStreams layers an smux.Session on the KCP connection and awaits streams
+// on it. Passes each stream to our SnowflakeListener accept queue.
+func (l *SnowflakeListener) acceptStreams(conn *kcp.UDPSession) error {
+ // Look up the IP address associated with this KCP session, via the
+ // ClientID that is returned by the session's RemoteAddr method.
+ addr, ok := clientIDAddrMap.Get(conn.RemoteAddr().(turbotunnel.ClientID))
+ if !ok {
+ // This means that the map is tending to run over capacity, not
+ // just that there was not client_ip on the incoming connection.
+ // We store "" in the map in the absence of client_ip. This log
+ // message means you should increase clientIDAddrMapCapacity.
+ log.Printf("no address in clientID-to-IP map (capacity %d)", clientIDAddrMapCapacity)
+ }
+
+ smuxConfig := smux.DefaultConfig()
+ smuxConfig.Version = 2
+ smuxConfig.KeepAliveTimeout = 10 * time.Minute
+ sess, err := smux.Server(conn, smuxConfig)
+ if err != nil {
+ return err
+ }
+
+ for {
+ stream, err := sess.AcceptStream()
+ if err != nil {
+ if err, ok := err.(net.Error); ok && err.Temporary() {
+ continue
+ }
+ return err
+ }
+ l.QueueConn(&SnowflakeClientConn{Conn: stream, address: clientAddr(addr)})
+ }
+}
+
+// acceptSessions listens for incoming KCP connections and passes them to
+// acceptStreams. It is handler.ServeHTTP that provides the network interface
+// that drives this function.
+func (l *SnowflakeListener) acceptSessions(ln *kcp.Listener) error {
+ for {
+ conn, err := ln.AcceptKCP()
+ if err != nil {
+ if err, ok := err.(net.Error); ok && err.Temporary() {
+ continue
+ }
+ return err
+ }
+ // Permit coalescing the payloads of consecutive sends.
+ conn.SetStreamMode(true)
+ // Set the maximum send and receive window sizes to a high number
+ // Removes KCP bottlenecks: https://gitlab.torproject.org/tpo/anti-censorship/pluggable-transports/snow…
+ conn.SetWindowSize(65535, 65535)
+ // Disable the dynamic congestion window (limit only by the
+ // maximum of local and remote static windows).
+ conn.SetNoDelay(
+ 0, // default nodelay
+ 0, // default interval
+ 0, // default resend
+ 1, // nc=1 => congestion window off
+ )
+ go func() {
+ defer conn.Close()
+ err := l.acceptStreams(conn)
+ if err != nil && err != io.ErrClosedPipe {
+ log.Printf("acceptStreams: %v", err)
+ }
+ }()
+ }
+}
+
+func (l *SnowflakeListener) QueueConn(conn net.Conn) error {
+ select {
+ case <-l.closed:
+ return fmt.Errorf("accepted connection on closed listener")
+ case l.queue <- conn:
+ return nil
+ }
+}
+
+// A wrapper for the underlying oneshot or turbotunnel conn
+// because we need to reference our mapping to determine the client
+// address
+type SnowflakeClientConn struct {
+ net.Conn
+ address net.Addr
+}
+
+func (conn *SnowflakeClientConn) RemoteAddr() net.Addr {
+ return conn.address
+}
diff --git a/server/turbotunnel.go b/server/lib/turbotunnel.go
similarity index 99%
rename from server/turbotunnel.go
rename to server/lib/turbotunnel.go
index 1d00897..bb16fa3 100644
--- a/server/turbotunnel.go
+++ b/server/lib/turbotunnel.go
@@ -1,4 +1,4 @@
-package main
+package lib
import (
"sync"
diff --git a/server/turbotunnel_test.go b/server/lib/turbotunnel_test.go
similarity index 99%
rename from server/turbotunnel_test.go
rename to server/lib/turbotunnel_test.go
index c4bf02b..ba4cf60 100644
--- a/server/turbotunnel_test.go
+++ b/server/lib/turbotunnel_test.go
@@ -1,4 +1,4 @@
-package main
+package lib
import (
"encoding/binary"
diff --git a/server/server.go b/server/server.go
index 620cd50..b61d5b4 100644
--- a/server/server.go
+++ b/server/server.go
@@ -3,9 +3,6 @@
package main
import (
- "bufio"
- "bytes"
- "crypto/tls"
"flag"
"fmt"
"io"
@@ -19,38 +16,15 @@ import (
"strings"
"sync"
"syscall"
- "time"
- pt "git.torproject.org/pluggable-transports/goptlib.git"
- "git.torproject.org/pluggable-transports/snowflake.git/common/encapsulation"
"git.torproject.org/pluggable-transports/snowflake.git/common/safelog"
- "git.torproject.org/pluggable-transports/snowflake.git/common/turbotunnel"
- "git.torproject.org/pluggable-transports/snowflake.git/common/websocketconn"
- "github.com/gorilla/websocket"
- "github.com/xtaci/kcp-go/v5"
- "github.com/xtaci/smux"
"golang.org/x/crypto/acme/autocert"
- "golang.org/x/net/http2"
+
+ pt "git.torproject.org/pluggable-transports/goptlib.git"
+ sf "git.torproject.org/pluggable-transports/snowflake.git/server/lib"
)
const ptMethodName = "snowflake"
-const requestTimeout = 10 * time.Second
-
-// How long to remember outgoing packets for a client, when we don't currently
-// have an active WebSocket connection corresponding to that client. Because a
-// client session may span multiple WebSocket connections, we keep packets we
-// aren't able to send immediately in memory, for a little while but not
-// indefinitely.
-const clientMapTimeout = 1 * time.Minute
-
-// How big to make the map of ClientIDs to IP addresses. The map is used in
-// turbotunnelMode to store a reasonable IP address for a client session that
-// may outlive any single WebSocket connection.
-const clientIDAddrMapCapacity = 1024
-
-// How long to wait for ListenAndServe or ListenAndServeTLS to return an error
-// before deciding that it's not going to return.
-const listenAndServeErrorTimeout = 100 * time.Millisecond
var ptInfo pt.ServerInfo
@@ -92,366 +66,30 @@ func proxy(local *net.TCPConn, conn net.Conn) {
wg.Wait()
}
-// Return an address string suitable to pass into pt.DialOr.
-func clientAddr(clientIPParam string) string {
- if clientIPParam == "" {
- return ""
- }
- // Check if client addr is a valid IP
- clientIP := net.ParseIP(clientIPParam)
- if clientIP == nil {
- return ""
- }
- // Check if client addr is 0.0.0.0 or [::]. Some proxies erroneously
- // report an address of 0.0.0.0: https://bugs.torproject.org/33157.
- if clientIP.IsUnspecified() {
- return ""
- }
- // Add a dummy port number. USERADDR requires a port number.
- return (&net.TCPAddr{IP: clientIP, Port: 1, Zone: ""}).String()
-}
-
-var upgrader = websocket.Upgrader{
- CheckOrigin: func(r *http.Request) bool { return true },
-}
-
-// clientIDAddrMap stores short-term mappings from ClientIDs to IP addresses.
-// When we call pt.DialOr, tor wants us to provide a USERADDR string that
-// represents the remote IP address of the client (for metrics purposes, etc.).
-// This data structure bridges the gap between ServeHTTP, which knows about IP
-// addresses, and handleStream, which is what calls pt.DialOr. The common piece
-// of information linking both ends of the chain is the ClientID, which is
-// attached to the WebSocket connection and every session.
-var clientIDAddrMap = newClientIDMap(clientIDAddrMapCapacity)
-
-// overrideReadConn is a net.Conn with an overridden Read method. Compare to
-// recordingConn at
-// https://dave.cheney.net/2015/05/22/struct-composition-with-go.
-type overrideReadConn struct {
- net.Conn
- io.Reader
-}
-
-func (conn *overrideReadConn) Read(p []byte) (int, error) {
- return conn.Reader.Read(p)
-}
-
-type HTTPHandler struct {
- // pconn is the adapter layer between stream-oriented WebSocket
- // connections and the packet-oriented KCP layer.
- pconn *turbotunnel.QueuePacketConn
-}
-
-func (handler *HTTPHandler) ServeHTTP(w http.ResponseWriter, r *http.Request) {
- ws, err := upgrader.Upgrade(w, r, nil)
- if err != nil {
- log.Println(err)
- return
- }
-
- conn := websocketconn.New(ws)
- defer conn.Close()
-
- // Pass the address of client as the remote address of incoming connection
- clientIPParam := r.URL.Query().Get("client_ip")
- addr := clientAddr(clientIPParam)
-
- var token [len(turbotunnel.Token)]byte
- _, err = io.ReadFull(conn, token[:])
- if err != nil {
- // Don't bother logging EOF: that happens with an unused
- // connection, which clients make frequently as they maintain a
- // pool of proxies.
- if err != io.EOF {
- log.Printf("reading token: %v", err)
- }
- return
- }
-
- switch {
- case bytes.Equal(token[:], turbotunnel.Token[:]):
- err = turbotunnelMode(conn, addr, handler.pconn)
- default:
- // We didn't find a matching token, which means that we are
- // dealing with a client that doesn't know about such things.
- // "Unread" the token by constructing a new Reader and pass it
- // to the old one-session-per-WebSocket mode.
- conn2 := &overrideReadConn{Conn: conn, Reader: io.MultiReader(bytes.NewReader(token[:]), conn)}
- err = oneshotMode(conn2, addr)
- }
- if err != nil {
- log.Println(err)
- return
- }
-}
-
-// oneshotMode handles clients that did not send turbotunnel.Token at the start
-// of their stream. These clients use the WebSocket as a raw pipe, and expect
-// their session to begin and end when this single WebSocket does.
-func oneshotMode(conn net.Conn, addr string) error {
- statsChannel <- addr != ""
- or, err := pt.DialOr(&ptInfo, addr, ptMethodName)
- if err != nil {
- return fmt.Errorf("failed to connect to ORPort: %s", err)
- }
- defer or.Close()
-
- proxy(or, conn)
-
- return nil
-}
-
-// turbotunnelMode handles clients that sent turbotunnel.Token at the start of
-// their stream. These clients expect to send and receive encapsulated packets,
-// with a long-lived session identified by ClientID.
-func turbotunnelMode(conn net.Conn, addr string, pconn *turbotunnel.QueuePacketConn) error {
- // Read the ClientID prefix. Every packet encapsulated in this WebSocket
- // connection pertains to the same ClientID.
- var clientID turbotunnel.ClientID
- _, err := io.ReadFull(conn, clientID[:])
- if err != nil {
- return fmt.Errorf("reading ClientID: %v", err)
- }
-
- // Store a a short-term mapping from the ClientID to the client IP
- // address attached to this WebSocket connection. tor will want us to
- // provide a client IP address when we call pt.DialOr. But a KCP session
- // does not necessarily correspond to any single IP address--it's
- // composed of packets that are carried in possibly multiple WebSocket
- // streams. We apply the heuristic that the IP address of the most
- // recent WebSocket connection that has had to do with a session, at the
- // time the session is established, is the IP address that should be
- // credited for the entire KCP session.
- clientIDAddrMap.Set(clientID, addr)
-
- errCh := make(chan error)
-
- // The remainder of the WebSocket stream consists of encapsulated
- // packets. We read them one by one and feed them into the
- // QueuePacketConn on which kcp.ServeConn was set up, which eventually
- // leads to KCP-level sessions in the acceptSessions function.
- go func() {
- for {
- p, err := encapsulation.ReadData(conn)
- if err != nil {
- errCh <- err
- break
- }
- pconn.QueueIncoming(p, clientID)
- }
- }()
-
- // At the same time, grab packets addressed to this ClientID and
- // encapsulate them into the downstream.
- go func() {
- // Buffer encapsulation.WriteData operations to keep length
- // prefixes in the same send as the data that follows.
- bw := bufio.NewWriter(conn)
- for p := range pconn.OutgoingQueue(clientID) {
- _, err := encapsulation.WriteData(bw, p)
- if err == nil {
- err = bw.Flush()
- }
- if err != nil {
- errCh <- err
- break
- }
- }
- }()
-
- // Wait until one of the above loops terminates. The closing of the
- // WebSocket connection will terminate the other one.
- <-errCh
-
- return nil
-}
-
-// handleStream bidirectionally connects a client stream with the ORPort.
-func handleStream(stream net.Conn, addr string) error {
- statsChannel <- addr != ""
- or, err := pt.DialOr(&ptInfo, addr, ptMethodName)
- if err != nil {
- return fmt.Errorf("connecting to ORPort: %v", err)
- }
- defer or.Close()
-
- proxy(or, stream)
-
- return nil
-}
-
-// acceptStreams layers an smux.Session on the KCP connection and awaits streams
-// on it. Passes each stream to handleStream.
-func acceptStreams(conn *kcp.UDPSession) error {
- // Look up the IP address associated with this KCP session, via the
- // ClientID that is returned by the session's RemoteAddr method.
- addr, ok := clientIDAddrMap.Get(conn.RemoteAddr().(turbotunnel.ClientID))
- if !ok {
- // This means that the map is tending to run over capacity, not
- // just that there was not client_ip on the incoming connection.
- // We store "" in the map in the absence of client_ip. This log
- // message means you should increase clientIDAddrMapCapacity.
- log.Printf("no address in clientID-to-IP map (capacity %d)", clientIDAddrMapCapacity)
- }
-
- smuxConfig := smux.DefaultConfig()
- smuxConfig.Version = 2
- smuxConfig.KeepAliveTimeout = 10 * time.Minute
- sess, err := smux.Server(conn, smuxConfig)
- if err != nil {
- return err
- }
-
+func acceptLoop(ln net.Listener) {
for {
- stream, err := sess.AcceptStream()
+ conn, err := ln.Accept()
if err != nil {
if err, ok := err.(net.Error); ok && err.Temporary() {
continue
}
- return err
+ log.Printf("Snowflake accept error: %s", err)
+ break
}
- go func() {
- defer stream.Close()
- err := handleStream(stream, addr)
- if err != nil {
- log.Printf("handleStream: %v", err)
- }
- }()
- }
-}
+ defer conn.Close()
-// acceptSessions listens for incoming KCP connections and passes them to
-// acceptStreams. It is handler.ServeHTTP that provides the network interface
-// that drives this function.
-func acceptSessions(ln *kcp.Listener) error {
- for {
- conn, err := ln.AcceptKCP()
+ addr := conn.RemoteAddr().String()
+ statsChannel <- addr != ""
+ or, err := pt.DialOr(&ptInfo, addr, ptMethodName)
if err != nil {
- if err, ok := err.(net.Error); ok && err.Temporary() {
- continue
- }
- return err
+ log.Printf("failed to connect to ORPort: %s", err)
+ continue
}
- // Permit coalescing the payloads of consecutive sends.
- conn.SetStreamMode(true)
- // Set the maximum send and receive window sizes to a high number
- // Removes KCP bottlenecks: https://gitlab.torproject.org/tpo/anti-censorship/pluggable-transports/snow…
- conn.SetWindowSize(65535, 65535)
- // Disable the dynamic congestion window (limit only by the
- // maximum of local and remote static windows).
- conn.SetNoDelay(
- 0, // default nodelay
- 0, // default interval
- 0, // default resend
- 1, // nc=1 => congestion window off
- )
- go func() {
- defer conn.Close()
- err := acceptStreams(conn)
- if err != nil && err != io.ErrClosedPipe {
- log.Printf("acceptStreams: %v", err)
- }
- }()
+ defer or.Close()
+ go proxy(or, conn)
}
}
-func initServer(addr *net.TCPAddr,
- getCertificate func(*tls.ClientHelloInfo) (*tls.Certificate, error),
- listenAndServe func(*http.Server, chan<- error)) (*http.Server, error) {
- // We're not capable of listening on port 0 (i.e., an ephemeral port
- // unknown in advance). The reason is that while the net/http package
- // exposes ListenAndServe and ListenAndServeTLS, those functions never
- // return, so there's no opportunity to find out what the port number
- // is, in between the Listen and Serve steps.
- // https://groups.google.com/d/msg/Golang-nuts/3F1VRCCENp8/3hcayZiwYM8J
- if addr.Port == 0 {
- return nil, fmt.Errorf("cannot listen on port %d; configure a port using ServerTransportListenAddr", addr.Port)
- }
-
- handler := HTTPHandler{
- // pconn is shared among all connections to this server. It
- // overlays packet-based client sessions on top of ephemeral
- // WebSocket connections.
- pconn: turbotunnel.NewQueuePacketConn(addr, clientMapTimeout),
- }
- server := &http.Server{
- Addr: addr.String(),
- Handler: &handler,
- ReadTimeout: requestTimeout,
- }
- // We need to override server.TLSConfig.GetCertificate--but first
- // server.TLSConfig needs to be non-nil. If we just create our own new
- // &tls.Config, it will lack the default settings that the net/http
- // package sets up for things like HTTP/2. Therefore we first call
- // http2.ConfigureServer for its side effect of initializing
- // server.TLSConfig properly. An alternative would be to make a dummy
- // net.Listener, call Serve on it, and let it return.
- // https://github.com/golang/go/issues/16588#issuecomment-237386446
- err := http2.ConfigureServer(server, nil)
- if err != nil {
- return server, err
- }
- server.TLSConfig.GetCertificate = getCertificate
-
- // Another unfortunate effect of the inseparable net/http ListenAndServe
- // is that we can't check for Listen errors like "permission denied" and
- // "address already in use" without potentially entering the infinite
- // loop of Serve. The hack we apply here is to wait a short time,
- // listenAndServeErrorTimeout, to see if an error is returned (because
- // it's better if the error message goes to the tor log through
- // SMETHOD-ERROR than if it only goes to the snowflake log).
- errChan := make(chan error)
- go listenAndServe(server, errChan)
- select {
- case err = <-errChan:
- break
- case <-time.After(listenAndServeErrorTimeout):
- break
- }
-
- // Start a KCP engine, set up to read and write its packets over the
- // WebSocket connections that arrive at the web server.
- // handler.ServeHTTP is responsible for encapsulation/decapsulation of
- // packets on behalf of KCP. KCP takes those packets and turns them into
- // sessions which appear in the acceptSessions function.
- ln, err := kcp.ServeConn(nil, 0, 0, handler.pconn)
- if err != nil {
- server.Close()
- return server, err
- }
- go func() {
- defer ln.Close()
- err := acceptSessions(ln)
- if err != nil {
- log.Printf("acceptSessions: %v", err)
- }
- }()
-
- return server, err
-}
-
-func startServer(addr *net.TCPAddr) (*http.Server, error) {
- return initServer(addr, nil, func(server *http.Server, errChan chan<- error) {
- log.Printf("listening with plain HTTP on %s", addr)
- err := server.ListenAndServe()
- if err != nil {
- log.Printf("error in ListenAndServe: %s", err)
- }
- errChan <- err
- })
-}
-
-func startServerTLS(addr *net.TCPAddr, getCertificate func(*tls.ClientHelloInfo) (*tls.Certificate, error)) (*http.Server, error) {
- return initServer(addr, getCertificate, func(server *http.Server, errChan chan<- error) {
- log.Printf("listening with HTTPS on %s", addr)
- err := server.ListenAndServeTLS("", "")
- if err != nil {
- log.Printf("error in ListenAndServeTLS: %s", err)
- }
- errChan <- err
- })
-}
-
func getCertificateCacheDir() (string, error) {
stateDir, err := pt.MakeStateDir()
if err != nil {
@@ -535,7 +173,7 @@ func main() {
// https://github.com/ietf-wg-acme/acme/blob/master/draft-ietf-acme-acme.md#ht…
needHTTP01Listener := !disableTLS
- servers := make([]*http.Server, 0)
+ listeners := make([]net.Listener, 0)
for _, bindaddr := range ptInfo.Bindaddrs {
if bindaddr.MethodName != ptMethodName {
pt.SmethodError(bindaddr.MethodName, "no such method")
@@ -560,29 +198,47 @@ func main() {
go func() {
log.Fatal(server.Serve(lnHTTP01))
}()
- servers = append(servers, server)
+ listeners = append(listeners, lnHTTP01)
needHTTP01Listener = false
}
- var server *http.Server
+ // We're not capable of listening on port 0 (i.e., an ephemeral port
+ // unknown in advance). The reason is that while the net/http package
+ // exposes ListenAndServe and ListenAndServeTLS, those functions never
+ // return, so there's no opportunity to find out what the port number
+ // is, in between the Listen and Serve steps.
+ // https://groups.google.com/d/msg/Golang-nuts/3F1VRCCENp8/3hcayZiwYM8J
+ if bindaddr.Addr.Port == 0 {
+ err := fmt.Errorf(
+ "cannot listen on port %d; configure a port using ServerTransportListenAddr",
+ bindaddr.Addr.Port)
+ log.Printf("error opening listener: %s", err)
+ pt.SmethodError(bindaddr.MethodName, err.Error())
+ continue
+ }
+
+ var transport *sf.Transport
args := pt.Args{}
if disableTLS {
args.Add("tls", "no")
- server, err = startServer(bindaddr.Addr)
+ transport = sf.NewSnowflakeServer(nil)
} else {
args.Add("tls", "yes")
for _, hostname := range acmeHostnames {
args.Add("hostname", hostname)
}
- server, err = startServerTLS(bindaddr.Addr, certManager.GetCertificate)
+ transport = sf.NewSnowflakeServer(certManager.GetCertificate)
}
+ ln, err := transport.Listen(bindaddr.Addr)
if err != nil {
log.Printf("error opening listener: %s", err)
pt.SmethodError(bindaddr.MethodName, err.Error())
continue
}
+ defer ln.Close()
+ go acceptLoop(ln)
pt.SmethodArgs(bindaddr.MethodName, bindaddr.Addr, args)
- servers = append(servers, server)
+ listeners = append(listeners, ln)
}
pt.SmethodsDone()
@@ -606,7 +262,7 @@ func main() {
// Signal received, shut down.
log.Printf("caught signal %q, exiting", sig)
- for _, server := range servers {
- server.Close()
+ for _, ln := range listeners {
+ ln.Close()
}
}
diff --git a/server/server_test.go b/server/server_test.go
deleted file mode 100644
index ba00d16..0000000
--- a/server/server_test.go
+++ /dev/null
@@ -1,153 +0,0 @@
-package main
-
-import (
- "net"
- "net/http"
- "strconv"
- "testing"
-
- "git.torproject.org/pluggable-transports/snowflake.git/common/websocketconn"
- "github.com/gorilla/websocket"
- . "github.com/smartystreets/goconvey/convey"
-)
-
-func TestClientAddr(t *testing.T) {
- Convey("Testing clientAddr", t, func() {
- // good tests
- for _, test := range []struct {
- input string
- expected net.IP
- }{
- {"1.2.3.4", net.ParseIP("1.2.3.4")},
- {"1:2::3:4", net.ParseIP("1:2::3:4")},
- } {
- useraddr := clientAddr(test.input)
- host, port, err := net.SplitHostPort(useraddr)
- if err != nil {
- t.Errorf("clientAddr(%q) → SplitHostPort error %v", test.input, err)
- continue
- }
- if !test.expected.Equal(net.ParseIP(host)) {
- t.Errorf("clientAddr(%q) → host %q, not %v", test.input, host, test.expected)
- }
- portNo, err := strconv.Atoi(port)
- if err != nil {
- t.Errorf("clientAddr(%q) → port %q", test.input, port)
- continue
- }
- if portNo == 0 {
- t.Errorf("clientAddr(%q) → port %d", test.input, portNo)
- }
- }
-
- // bad tests
- for _, input := range []string{
- "",
- "abc",
- "1.2.3.4.5",
- "[12::34]",
- "0.0.0.0",
- "[::]",
- } {
- useraddr := clientAddr(input)
- if useraddr != "" {
- t.Errorf("clientAddr(%q) → %q, not %q", input, useraddr, "")
- }
- }
- })
-}
-
-type StubHandler struct{}
-
-func (handler *StubHandler) ServeHTTP(w http.ResponseWriter, r *http.Request) {
- ws, _ := upgrader.Upgrade(w, r, nil)
-
- conn := websocketconn.New(ws)
- defer conn.Close()
-
- //dial stub OR
- or, _ := net.DialTCP("tcp", nil, &net.TCPAddr{IP: net.ParseIP("localhost"), Port: 8889})
-
- proxy(or, conn)
-}
-
-func Test(t *testing.T) {
- Convey("Websocket server", t, func() {
- //Set up the snowflake web server
- ipStr, portStr, _ := net.SplitHostPort(":8888")
- port, _ := strconv.ParseUint(portStr, 10, 16)
- addr := &net.TCPAddr{IP: net.ParseIP(ipStr), Port: int(port)}
- Convey("We don't listen on port 0", func() {
- addr = &net.TCPAddr{IP: net.ParseIP(ipStr), Port: 0}
- server, err := initServer(addr, nil,
- func(server *http.Server, errChan chan<- error) {
- return
- })
- So(err, ShouldNotBeNil)
- So(server, ShouldBeNil)
- })
-
- Convey("Plain HTTP server accepts connections", func(c C) {
- server, err := startServer(addr)
- So(err, ShouldBeNil)
-
- ws, _, err := websocket.DefaultDialer.Dial("ws://localhost:8888", nil)
- wsConn := websocketconn.New(ws)
- So(err, ShouldEqual, nil)
- So(wsConn, ShouldNotEqual, nil)
-
- server.Close()
- wsConn.Close()
-
- })
- Convey("Handler proxies data", func(c C) {
-
- laddr := &net.TCPAddr{IP: net.ParseIP("localhost"), Port: 8889}
-
- go func() {
-
- //stub OR
- listener, err := net.ListenTCP("tcp", laddr)
- c.So(err, ShouldBeNil)
- conn, err := listener.Accept()
- c.So(err, ShouldBeNil)
-
- b := make([]byte, 5)
- n, err := conn.Read(b)
- c.So(err, ShouldBeNil)
- c.So(n, ShouldEqual, 5)
- c.So(b, ShouldResemble, []byte("Hello"))
-
- n, err = conn.Write([]byte("world!"))
- c.So(n, ShouldEqual, 6)
- c.So(err, ShouldBeNil)
- }()
-
- //overwite handler
- server, err := initServer(addr, nil,
- func(server *http.Server, errChan chan<- error) {
- server.ListenAndServe()
- })
- So(err, ShouldBeNil)
-
- var handler StubHandler
- server.Handler = &handler
-
- ws, _, err := websocket.DefaultDialer.Dial("ws://localhost:8888", nil)
- So(err, ShouldEqual, nil)
- wsConn := websocketconn.New(ws)
- So(wsConn, ShouldNotEqual, nil)
-
- wsConn.Write([]byte("Hello"))
- b := make([]byte, 6)
- n, err := wsConn.Read(b)
- So(n, ShouldEqual, 6)
- So(b, ShouldResemble, []byte("world!"))
-
- wsConn.Close()
- server.Close()
-
- })
-
- })
-}
1
0
[translation/tbmanual-contentspot] https://gitweb.torproject.org/translation.git/commit/?h=tbmanual-contentspot
by translation@torproject.org 12 May '21
by translation@torproject.org 12 May '21
12 May '21
commit 1882524d24122f5871d1343858a1122464453b6b
Author: Translation commit bot <translation(a)torproject.org>
Date: Wed May 12 12:47:10 2021 +0000
https://gitweb.torproject.org/translation.git/commit/?h=tbmanual-contentspot
---
contents+pl.po | 67 +++++++++++++++++++++++++++++++++++++++++++++++++++++++---
1 file changed, 64 insertions(+), 3 deletions(-)
diff --git a/contents+pl.po b/contents+pl.po
index c6451c2913..01d1ca92e1 100644
--- a/contents+pl.po
+++ b/contents+pl.po
@@ -566,6 +566,8 @@ msgid ""
"If you choose the latter click on \"Run\" after launching the start-tor-"
"browser.desktop file."
msgstr ""
+"Jeśli wybierzesz to ostatnie, kliknij na \"Uruchom\" po uruchomieniu pliku "
+"start-tor-browser.desktop."
#: https//tb-manual.torproject.org/installation/
#: (content/installation/contents+en.lrtopic.body)
@@ -629,6 +631,8 @@ msgid ""
"<img class=\"col-md-6\" src=\"../../static/images/connect.png\" alt=\"Click "
"'connect' to connect to Tor.\">"
msgstr ""
+"<img class=\"col-md-6\" src=\"../../static/images/connect.png\" "
+"alt=\"Naciśnij 'połącz' aby połączyć się z Torem.\"/>"
#: https//tb-manual.torproject.org/running-tor-browser/
#: (content/running-tor-browser/contents+en.lrtopic.body)
@@ -3458,6 +3462,8 @@ msgid ""
"[Security settings](../security-settings/) disable certain web features that"
" can be used to compromise your security and anonymity."
msgstr ""
+"[Ustawienia bezpieczeństwa](../security-settings/) wyłączają niektóre "
+"funkcje internetowe, które mogą naruszyć Twoje bezpieczeństwo i anonimowość."
#: https//tb-manual.torproject.org/mobile-tor/
#: (content/mobile-tor/contents+en.lrtopic.body)
@@ -3465,16 +3471,18 @@ msgid ""
"Tor Browser for Android provides the same three security levels that are "
"available on desktop."
msgstr ""
+"Przeglądarka Tor dla systemów Android zapewnia te same trzy poziomy "
+"bezpieczeństwa dostępne dla komputerów. "
#: https//tb-manual.torproject.org/mobile-tor/
#: (content/mobile-tor/contents+en.lrtopic.body)
msgid "You can modify the security level by following given steps:"
-msgstr ""
+msgstr "Możesz zmienić poziom bezpieczeństwa podążając za tymi instrukcjami:"
#: https//tb-manual.torproject.org/mobile-tor/
#: (content/mobile-tor/contents+en.lrtopic.body)
msgid "* Tap on a button of 3 vertical dots in URL bar."
-msgstr ""
+msgstr "* Naciśnij na przycisk 3 pionowych kropek na pasku adresu URL."
#: https//tb-manual.torproject.org/mobile-tor/
#: (content/mobile-tor/contents+en.lrtopic.body)
@@ -3485,6 +3493,8 @@ msgstr "* Zjedź na dół i kliknij w \"Ustawienia Bezpieczeństwa\"."
#: (content/mobile-tor/contents+en.lrtopic.body)
msgid "* You can now select an option i.e. Standard, Safer or Safest."
msgstr ""
+"* Możesz teraz wybrać opcje: Standardowe, Bezpieczniejsze, "
+"Najbezpieczniejsze."
#: https//tb-manual.torproject.org/mobile-tor/
#: (content/mobile-tor/contents+en.lrtopic.body)
@@ -3508,6 +3518,8 @@ msgid ""
"This method assumes that you have either Google Play or F-Droid installed on"
" your mobile device."
msgstr ""
+"Ta metoda zakłada, że na urządzeniu mobilnym jest zainstalowany Google "
+"Play lub F-Droid."
#: https//tb-manual.torproject.org/mobile-tor/
#: (content/mobile-tor/contents+en.lrtopic.body)
@@ -3531,6 +3543,8 @@ msgid ""
"Tap on the hamburger menu next to the search bar and navigate to \"My apps &"
" games\" > \"Updates\"."
msgstr ""
+"Naciśnij na menu hamburger (menu główne) obok paska wyszukiwania adresu URL "
+"i przejdź do \"Moje aplikacje i gry\" > \"Aktualizacje\"."
#: https//tb-manual.torproject.org/mobile-tor/
#: (content/mobile-tor/contents+en.lrtopic.body)
@@ -3538,6 +3552,8 @@ msgid ""
"If you find Tor Browser on the list of apps which need updating, select it "
"and tap the \"Update\" button."
msgstr ""
+"Jeśli znajdziesz Przeglądarkę Tor na liście aplikacji, które wymagają "
+"aktualizacji, wybierz ją i naciśnij przycisk \"Zaktualizuj\"."
#: https//tb-manual.torproject.org/mobile-tor/
#: (content/mobile-tor/contents+en.lrtopic.body)
@@ -3556,6 +3572,7 @@ msgstr ""
#: (content/mobile-tor/contents+en.lrtopic.body)
msgid "Tap on \"Settings\", then go to \"Manage installed apps\"."
msgstr ""
+"Naciśnij „Ustawienia”, a następnie „Zarządzaj zainstalowanymi aplikacjami”."
#: https//tb-manual.torproject.org/mobile-tor/
#: (content/mobile-tor/contents+en.lrtopic.body)
@@ -3563,6 +3580,8 @@ msgid ""
"On the next screen, select Tor Browser and finally tap on the \"Update\" "
"button."
msgstr ""
+"Na następnym ekranie wybierz Tor Browser i na koniec naciśnij przycisk "
+"„Aktualizuj”."
#: https//tb-manual.torproject.org/mobile-tor/
#: (content/mobile-tor/contents+en.lrtopic.body)
@@ -3618,6 +3637,9 @@ msgid ""
"select Tor Browser and tap on the \"Uninstall\" button. Afterwards, download"
" the latest Tor Browser release and install it."
msgstr ""
+"W zależności od marki urządzenia mobilnego przejdź do Ustawień aplikacji, a "
+"następnie wybierz Tor Browser i naciśnij przycisk „Odinstaluj”. Następnie "
+"pobierz najnowszą wersję przeglądarki Tor Browser i zainstaluj ją."
#: https//tb-manual.torproject.org/mobile-tor/
#: (content/mobile-tor/contents+en.lrtopic.body)
@@ -3630,6 +3652,8 @@ msgid ""
"Tor Browser for Android can be uninstalled directly from F-Droid, Google "
"Play or from your mobile device's app settings."
msgstr ""
+"Przeglądarkę Tor Browser dla systemu Android można odinstalować bezpośrednio"
+" z F-Droid, Google Play lub z ustawień aplikacji urządzenia mobilnego."
#: https//tb-manual.torproject.org/mobile-tor/
#: (content/mobile-tor/contents+en.lrtopic.body)
@@ -3648,6 +3672,8 @@ msgid ""
"Tap on the hamburger menu next to the search bar and navigate to \"My apps &"
" games\" > \"Installed\"."
msgstr ""
+"Naciśnij na menu \"hamburger\" (menu główne) obok paska wyszukiwania adresu "
+"URL i przejdź do \"Moje aplikacje i gry\" > \"Zainstalowane\"."
#: https//tb-manual.torproject.org/mobile-tor/
#: (content/mobile-tor/contents+en.lrtopic.body)
@@ -3672,6 +3698,8 @@ msgid ""
"On the next screen, select Tor Browser and finally tap on the \"Uninstall\" "
"button."
msgstr ""
+"Na następnym ekranie wybierz Przeglądarkę Tor i naciśnij przycisk "
+"„Odinstaluj”."
#: https//tb-manual.torproject.org/mobile-tor/
#: (content/mobile-tor/contents+en.lrtopic.body)
@@ -3695,6 +3723,9 @@ msgid ""
"Depending on your mobile device's brand, navigate to Settings > Apps, then "
"select Tor Browser and tap on the \"Uninstall\" button."
msgstr ""
+"W zależności od marki urządzenia mobilnego przejdź do Ustawienia > "
+"Aplikacje, a następnie wybierz Przeglądarkę Tor i naciśnij przycisk "
+"„Odinstaluj”."
#: https//tb-manual.torproject.org/mobile-tor/
#: (content/mobile-tor/contents+en.lrtopic.body)
@@ -3711,6 +3742,8 @@ msgid ""
"* You can't see your Tor circuit. "
"[#25764](https://gitlab.torproject.org/tpo/applications/torbutton/-/issues/25764)"
msgstr ""
+"* Nie widzisz swojego obwodu Tor. "
+"[#25764](https://gitlab.torproject.org/tpo/applications/torbutton/-/issues/25764)"
#: https//tb-manual.torproject.org/mobile-tor/
#: (content/mobile-tor/contents+en.lrtopic.body)
@@ -3719,6 +3752,10 @@ msgid ""
"[#31814](https://gitlab.torproject.org/tpo/applications/tor-"
"browser/-/issues/31814)"
msgstr ""
+"* Przeglądarka Tor dla systemów Android nie może nawiązać połączenia, gdy "
+"została przeniesiona na kartę SD. "
+"[#31814](https://gitlab.torproject.org/tpo/applications/tor-"
+"browser/-/issues/31814)"
#: https//tb-manual.torproject.org/mobile-tor/
#: (content/mobile-tor/contents+en.lrtopic.body)
@@ -3727,6 +3764,9 @@ msgid ""
"[#27987](https://gitlab.torproject.org/tpo/applications/tor-"
"browser/-/issues/27987)"
msgstr ""
+"* Nie możesz robić zrzutów ekranu podczas używania Przeglądarki Tor dla "
+"systemów Android. [#27987](https://gitlab.torproject.org/tpo/applications"
+"/tor-browser/-/issues/27987)"
#: https//tb-manual.torproject.org/mobile-tor/
#: (content/mobile-tor/contents+en.lrtopic.body)
@@ -3735,6 +3775,9 @@ msgid ""
"[#40283](https://gitlab.torproject.org/tpo/applications/tor-"
"browser/-/issues/40283)"
msgstr ""
+"* Nie możesz przesyłać plików przez Przeglądarkę Tor dla systemów Android. "
+"[#40283](https://gitlab.torproject.org/tpo/applications/tor-"
+"browser/-/issues/40283)"
#: https//tb-manual.torproject.org/mobile-tor/
#: (content/mobile-tor/contents+en.lrtopic.body)
@@ -3764,6 +3807,11 @@ msgid ""
"browsers, and Orfox was crucial for helping people circumvent censorship and"
" access blocked sites and critical resources."
msgstr ""
+"Przez okres 3 lat, Orfox nieprzerwanie się doskonalił i został popularnym "
+"wyborem dla ludzi, którzy chcą przeglądać internet zachowując więcej "
+"prywatności, niż przy użyciu standardowych przeglądarek, Orfox był kluczowy "
+"w pomocy w obejściu cenzury, dostępu do blokowanych witryn oraz krytycznych "
+"zasobów. "
#: https//tb-manual.torproject.org/mobile-tor/
#: (content/mobile-tor/contents+en.lrtopic.body)
@@ -3772,6 +3820,9 @@ msgid ""
"tor-browser-android) after the official Tor Browser for Android was "
"released."
msgstr ""
+"W 2019 [Orfox został wygaszony](https://blog.torproject.org/orfox-paved-way-"
+"tor-browser-android) po oficjalnym wydaniu Przeglądarki Tor dla systemów "
+"Android."
#: https//tb-manual.torproject.org/mobile-tor/
#: (content/mobile-tor/contents+en.lrtopic.body)
@@ -3789,7 +3840,7 @@ msgstr ""
#: https//tb-manual.torproject.org/mobile-tor/
#: (content/mobile-tor/contents+en.lrtopic.body)
msgid "Orbot uses Tor to encrypt your Internet traffic."
-msgstr ""
+msgstr "Orbot używa Tora do szyfrowania twojego ruchu sieciowego."
#: https//tb-manual.torproject.org/mobile-tor/
#: (content/mobile-tor/contents+en.lrtopic.body)
@@ -3797,6 +3848,8 @@ msgid ""
"Then you can use it with other apps installed on your mobile device to "
"circumvent censorship and protect against surveillance."
msgstr ""
+"Możesz go używać razem z innymi aplikacjami zainstalowanymi na twoim "
+"urządzeniu mobilnym, aby obejść cenzurę i chronić się przed inwigilacją."
#: https//tb-manual.torproject.org/mobile-tor/
#: (content/mobile-tor/contents+en.lrtopic.body)
@@ -3814,6 +3867,10 @@ msgid ""
"portal](https://support.torproject.org/tormobile/tormobile-6/) to know if "
"you need both Tor Browser for Android and Orbot or either one."
msgstr ""
+"Sprawdź [nasz Portal "
+"Pomocy](https://support.torproject.org/tormobile/tormobile-6/), aby "
+"dowiedzieć się czy potrzebujesz zarówno Przeglądarki Tor dla systemów "
+"Android i Orbot, czy tylko jednego z nich."
#: https//tb-manual.torproject.org/mobile-tor/
#: (content/mobile-tor/contents+en.lrtopic.body)
@@ -3877,6 +3934,10 @@ msgid ""
"Phones but in case of the newer Microsoft-branded/promoted phones, same "
"steps on [Tor Browser on Android](#tor-browser-for-android) can be followed."
msgstr ""
+"Nie ma aktualnie wspieranej metody używania Tora na starszych telefonach z "
+"systemem Windows, ale w przypadku nowszych telefonów spod marki Microsfot "
+"lub przez nich promowanych, można wykonać te same kroki co dla [Przeglądarki"
+" Tor dla systemów Android](#tor-browser-for-android)."
#: https//tb-manual.torproject.org/make-tor-portable/
#: (content/make-tor-portable/contents+en.lrtopic.title)
1
0
[translation/communitytpo-contentspot] https://gitweb.torproject.org/translation.git/commit/?h=communitytpo-contentspot
by translation@torproject.org 12 May '21
by translation@torproject.org 12 May '21
12 May '21
commit c49aa8e5cc98779405702b999525ee3e0ff40fbc
Author: Translation commit bot <translation(a)torproject.org>
Date: Wed May 12 12:45:15 2021 +0000
https://gitweb.torproject.org/translation.git/commit/?h=communitytpo-conten…
---
contents+es.po | 47 +++++++++++++++++++++++++++++++++++++----------
1 file changed, 37 insertions(+), 10 deletions(-)
diff --git a/contents+es.po b/contents+es.po
index ccab8bedcc..6f779e5528 100644
--- a/contents+es.po
+++ b/contents+es.po
@@ -19023,16 +19023,19 @@ msgid ""
"this guide the username `torrelay` will be used. Then enter a strong "
"password and continue."
msgstr ""
+"6. Ingresa un nombre de usuario. Cualquiera que te guste está bien, aunque "
+"dentro de esta guía será usado `torrelay`. Luego entra una contraseña fuerte"
+" y continúa."
#: https//community.torproject.org/relay/setup/guard/windows/
#: (content/relay-operations/technical-setup/guard/windows/contents+en.lrpage.body)
msgid "# 2. Downloading and configuring the Windows Expert bundle"
-msgstr ""
+msgstr "# 2. Descargando y configurando el paquete Experto de Windows"
#: https//community.torproject.org/relay/setup/guard/windows/
#: (content/relay-operations/technical-setup/guard/windows/contents+en.lrpage.body)
msgid "## 2.1 Downloading"
-msgstr ""
+msgstr "## 2.1 Descargando"
#: https//community.torproject.org/relay/setup/guard/windows/
#: (content/relay-operations/technical-setup/guard/windows/contents+en.lrpage.body)
@@ -19040,6 +19043,8 @@ msgid ""
"The next step is to download and install Windows Expert bundle as well as "
"set up your torrc file."
msgstr ""
+"El siguiente paso es descargar e instalar el paquete Experto de Windows, "
+"como así también configurar tu archivo torrc."
#: https//community.torproject.org/relay/setup/guard/windows/
#: (content/relay-operations/technical-setup/guard/windows/contents+en.lrpage.body)
@@ -19048,16 +19053,19 @@ msgid ""
"https://www.torproject.org/download/tor/) and scroll down to select 'Windows"
" Expert Bundle'."
msgstr ""
+"1. Vé hacia [Descargar código fuente de Tor]( "
+"https://www.torproject.org/download/tor/) y desliza hacia abajo para "
+"seleccionar 'Paquete Experto de Windows'."
#: https//community.torproject.org/relay/setup/guard/windows/
#: (content/relay-operations/technical-setup/guard/windows/contents+en.lrpage.body)
msgid "2. Head to your `C:\\Users\\torrelay\\` directory."
-msgstr ""
+msgstr "2. Vé hacia tu directorio `C:\\Users\\torrelay\\`."
#: https//community.torproject.org/relay/setup/guard/windows/
#: (content/relay-operations/technical-setup/guard/windows/contents+en.lrpage.body)
msgid "3. Create a folder called `tor`."
-msgstr ""
+msgstr "3. Crea una carpeta llamada `tor`."
#: https//community.torproject.org/relay/setup/guard/windows/
#: (content/relay-operations/technical-setup/guard/windows/contents+en.lrpage.body)
@@ -19065,11 +19073,13 @@ msgid ""
"*(Optional. A custom path can be used, though you will have to make "
"necessary modifications in the following steps.)"
msgstr ""
+"*(Opcional. Puede ser usada una ruta personalizada, aunque tendrás que hacer"
+" las modificaciones necesarias en los siguientes pasos.)"
#: https//community.torproject.org/relay/setup/guard/windows/
#: (content/relay-operations/technical-setup/guard/windows/contents+en.lrpage.body)
msgid "## 2.2 Configuration"
-msgstr ""
+msgstr "## 2.2 Configuración"
#: https//community.torproject.org/relay/setup/guard/windows/
#: (content/relay-operations/technical-setup/guard/windows/contents+en.lrpage.body)
@@ -19077,6 +19087,9 @@ msgid ""
"1. Unpack the zipped Expert bundle into your newly created Tor directory. "
"Two files will be placed there; one called `Tor`, and the other `Data`."
msgstr ""
+"1. Descomprime el paquete Experto dentro de tu directorio Tor recientemente "
+"creado. Dos archivos estarán ubicados allí; uno llamado `Tor` y el otro "
+"`Data`."
#: https//community.torproject.org/relay/setup/guard/windows/
#: (content/relay-operations/technical-setup/guard/windows/contents+en.lrpage.body)
@@ -19084,6 +19097,8 @@ msgid ""
"2. You will now need to create a torrc file to define the ruleset of your "
"relay."
msgstr ""
+"2. Ahora necesitarás crear un archivo torrc para definir el conjunto de "
+"reglas de tu repetidor."
#: https//community.torproject.org/relay/setup/guard/windows/
#: (content/relay-operations/technical-setup/guard/windows/contents+en.lrpage.body)
@@ -19092,6 +19107,10 @@ msgid ""
"`C:\\Users\\torrelay\\AppData\\Roaming\\tor\\torrc`, though you can specify "
"a custom location at commandline startup with the `-f` flag. (More below)"
msgstr ""
+"3. La ruta de directorios predeterminada para este archivo es "
+"`C:\\Users\\torrelay\\AppData\\Roaming\\tor\\torrc`, aunque puedes "
+"especificar una ubicación personalizada al iniciar la línea de comando con "
+"el modificador `-f`. (Más acerca de esto abajo)"
#: https//community.torproject.org/relay/setup/guard/windows/
#: (content/relay-operations/technical-setup/guard/windows/contents+en.lrpage.body)
@@ -19099,11 +19118,13 @@ msgid ""
"4. Open up your newly created `torrc` file in your text editor and populate "
"it with the following contents:"
msgstr ""
+"4. Abre tu archivo `torrc` recientemente creado en tu editor de texto y "
+"llénalo con los siguientes contenidos:"
#: https//community.torproject.org/relay/setup/guard/windows/
#: (content/relay-operations/technical-setup/guard/windows/contents+en.lrpage.body)
msgid "#Change the nickname \"myNiceRelay\" to a name that you like"
-msgstr ""
+msgstr "#Cambia el sobrenombre \"myNiceRelay\" a uno que te guste"
#: https//community.torproject.org/relay/setup/guard/windows/
#: (content/relay-operations/technical-setup/guard/windows/contents+en.lrpage.body)
@@ -19148,17 +19169,18 @@ msgstr "SocksPort 0"
#: https//community.torproject.org/relay/setup/guard/windows/
#: (content/relay-operations/technical-setup/guard/windows/contents+en.lrpage.body)
msgid "#Paths assume you extracted to C:\\Users\\torrelay\\tor - if you"
-msgstr ""
+msgstr "#La ruta asume que extrajiste a C:\\Users\\torrelay\\tor - si lo"
#: https//community.torproject.org/relay/setup/guard/windows/
#: (content/relay-operations/technical-setup/guard/windows/contents+en.lrpage.body)
msgid "#extracted elsewhere or used a different username, adjust the"
msgstr ""
+"#hiciste en otro lado o usaste un nombre de usuario diferente, ajusta la"
#: https//community.torproject.org/relay/setup/guard/windows/
#: (content/relay-operations/technical-setup/guard/windows/contents+en.lrpage.body)
msgid "#paths accordingly"
-msgstr ""
+msgstr "#ruta correspondientemente"
#: https//community.torproject.org/relay/setup/guard/windows/
#: (content/relay-operations/technical-setup/guard/windows/contents+en.lrpage.body)
@@ -19185,6 +19207,8 @@ msgstr "GeoIPv6File C:\\Users\\torrelay\\tor\\Data\\Tor\\geoip6"
msgid ""
"#Put your email below - Note that it will be published on the metrics page"
msgstr ""
+"#Pon tu correo electrónico debajo - Ten en cuenta que será publicado en la "
+"página de mediciones"
#: https//community.torproject.org/relay/setup/guard/windows/
#: (content/relay-operations/technical-setup/guard/windows/contents+en.lrpage.body)
@@ -19203,11 +19227,12 @@ msgstr "ContactInfo tor-operator@your-emailaddress-domain"
#: (content/relay-operations/technical-setup/guard/windows/contents+en.lrpage.body)
msgid "Make sure everything is filled in correctly, then save and exit."
msgstr ""
+"Asegúrate de que todo esté completado correctamente, luego guarda y sal."
#: https//community.torproject.org/relay/setup/guard/windows/
#: (content/relay-operations/technical-setup/guard/windows/contents+en.lrpage.body)
msgid "# 3. Starting up your relay"
-msgstr ""
+msgstr "# 3. Iniciando tu repetidor"
#: https//community.torproject.org/relay/setup/guard/windows/
#: (content/relay-operations/technical-setup/guard/windows/contents+en.lrpage.body)
@@ -19215,11 +19240,13 @@ msgid ""
"There are two methods for starting up your relay for the first time "
"depending on your preferences and needs."
msgstr ""
+"Hay dos métodos para iniciar tu repetidor por primera vez, dependiendo de "
+"tus preferencias y necesidades."
#: https//community.torproject.org/relay/setup/guard/windows/
#: (content/relay-operations/technical-setup/guard/windows/contents+en.lrpage.body)
msgid "### 3.1 Method 1: User interface"
-msgstr ""
+msgstr "### 3.1 Método 1: Interfaz de usuario"
#: https//community.torproject.org/relay/setup/guard/windows/
#: (content/relay-operations/technical-setup/guard/windows/contents+en.lrpage.body)
1
0
[translation/tbmanual-contentspot] https://gitweb.torproject.org/translation.git/commit/?h=tbmanual-contentspot
by translation@torproject.org 12 May '21
by translation@torproject.org 12 May '21
12 May '21
commit 80fee5016d6ada287f55c93258b868024c2e6bf5
Author: Translation commit bot <translation(a)torproject.org>
Date: Wed May 12 12:16:54 2021 +0000
https://gitweb.torproject.org/translation.git/commit/?h=tbmanual-contentspot
---
contents+pl.po | 38 ++++++++++++++++++++++++++++++++++++--
1 file changed, 36 insertions(+), 2 deletions(-)
diff --git a/contents+pl.po b/contents+pl.po
index a3c14b661f..c6451c2913 100644
--- a/contents+pl.po
+++ b/contents+pl.po
@@ -3001,6 +3001,10 @@ msgid ""
"tracking across websites, defending against surveillance, resisting browser "
"fingerprinting, and circumventing censorship."
msgstr ""
+"Niektóre z głównych funkcji Przeglądarki Tor dla systemu Android to: "
+"zmniejszenie śledzenia pomiędzy witrynami, obrona przed inwigilacją, "
+"odporność na identyfikacje \"odcisku palca\" przeglądarki, oraz omijanie "
+"cenzury."
#: https//tb-manual.torproject.org/mobile-tor/
#: (content/mobile-tor/contents+en.lrtopic.body)
@@ -3030,6 +3034,8 @@ msgid ""
"Tor Browser for Android is available on Play Store, F-Droid and the Tor "
"Project website."
msgstr ""
+"Przeglądarka Tor dla systemu Android jest dostępna w Play Store, F-Droid i "
+"na stronie Tor Project."
#: https//tb-manual.torproject.org/mobile-tor/
#: (content/mobile-tor/contents+en.lrtopic.body)
@@ -3081,6 +3087,8 @@ msgid ""
"1. Install the F-Droid app on your Android device from [the F-Droid "
"website.](https://f-droid.org/)"
msgstr ""
+"1. Zainstaluj aplikację F-Droid na urządzeniu z systemem Android ze [strony "
+"F-droid.](https://f-droid.org/)"
#: https//tb-manual.torproject.org/mobile-tor/
#: (content/mobile-tor/contents+en.lrtopic.body)
@@ -3167,6 +3175,9 @@ msgid ""
"connect directly to the Tor network, or to configure Tor Browser for your "
"connection with the settings icon."
msgstr ""
+"Kiedy uruchomisz Przeglądarkę Tor po raz pierwszy, zobacysz opcję połączenia"
+" bezpośrednio z siecią Tor, lub konfiguracji Przeglądarki Tor dla Twojego "
+"połączenia z ikoną ustawień."
#: https//tb-manual.torproject.org/mobile-tor/
#: (content/mobile-tor/contents+en.lrtopic.body)
@@ -3188,6 +3199,8 @@ msgid ""
"Once tapped, changing sentences will appear at the bottom of the screen, "
"indicating Tor’s connection progress."
msgstr ""
+"Po naciśnięciu, zmieniające się zdania pojawią się na dole ekranu, "
+"oznaczając postęp łączenia z siecią Tor."
#: https//tb-manual.torproject.org/mobile-tor/
#: (content/mobile-tor/contents+en.lrtopic.body)
@@ -3196,6 +3209,9 @@ msgid ""
" at a certain point, see the [Troubleshooting](../troubleshooting) page for "
"help solving the problem."
msgstr ""
+"Jeśli masz stosunkowo szybkie połączenie, ale wydaje Ci się, że pasek się "
+"zatrzymał, zobacz stronę [Rozwiązywanie problemów](../troubleshooting), aby "
+"uzyskać pomoc w rozwiązaniu problemu."
#: https//tb-manual.torproject.org/mobile-tor/
#: (content/mobile-tor/contents+en.lrtopic.body)
@@ -3217,6 +3233,8 @@ msgid ""
"If you know that your connection is censored, you should select the settings"
" icon."
msgstr ""
+"Jeśli wiesz, że twoje połączenie jest cenzurowane, powinieneś wybrać ikonę "
+"ustawień."
#: https//tb-manual.torproject.org/mobile-tor/
#: (content/mobile-tor/contents+en.lrtopic.body)
@@ -3224,6 +3242,8 @@ msgid ""
"The first screen will tell you about the status of the Tor Network and "
"provide you the option to configure a Bridge ('Config Bridge')."
msgstr ""
+"Pierwszy ekran powie Ci o statusie Sieci Tor, oraz pozwoli na konfigurację "
+"Mostu ('Konfiguruj Most')."
#: https//tb-manual.torproject.org/mobile-tor/
#: (content/mobile-tor/contents+en.lrtopic.body)
@@ -3232,6 +3252,9 @@ msgid ""
"connect to the Tor network and no other solutions have worked, tap on "
"'Config Bridge'."
msgstr ""
+"Jeśli wiesz, że twoje połączenie jest cenzurowane, lub próba połączenia z "
+"siecią Tor zakończyła się niepowodzeniem, i żadne inne rozwiązanie nie "
+"zadziałało, kliknij 'Konfiguruj Most'."
#: https//tb-manual.torproject.org/mobile-tor/
#: (content/mobile-tor/contents+en.lrtopic.body)
@@ -3271,6 +3294,8 @@ msgid ""
"To use a pluggable transport, tap on the settings icon when starting Tor "
"Browser for the first time."
msgstr ""
+"Aby skorzystać z transportu wtykowego, naciśnij ikonę ustawień podczas "
+"uruchamiania Przeglądarki Tor po raz pierwszy."
#: https//tb-manual.torproject.org/mobile-tor/
#: (content/mobile-tor/contents+en.lrtopic.body)
@@ -3278,6 +3303,8 @@ msgid ""
"The first screen tells you about the status of the Tor network. Tap on "
"'Config Bridge' to configure a bridge."
msgstr ""
+"Pierwszy ekran powie Ci o statusie sieci Tor. Naciśnij 'Konfiguruj Most' aby"
+" skonfigurować most."
#: https//tb-manual.torproject.org/mobile-tor/
#: (content/mobile-tor/contents+en.lrtopic.body)
@@ -3304,6 +3331,8 @@ msgid ""
"With the \"Use a Bridge\" option, you will have two options: \"obfs4\" and "
"\"meek-azure\"."
msgstr ""
+"Dzięki opcji „Wybierz most” będziesz mieć dwie opcje: „obfs4” i „meek-"
+"azure”."
#: https//tb-manual.torproject.org/mobile-tor/
#: (content/mobile-tor/contents+en.lrtopic.body)
@@ -3333,6 +3362,8 @@ msgid ""
"If you choose the \"Provide a Bridge I know\" option, then you have to enter"
" a [bridge address](../bridges/)."
msgstr ""
+"Jeśli wybierzesz opcję \"Podaj most, który znam\", musisz wprowadzić [adres "
+"mostu](../bridges/)."
#: https//tb-manual.torproject.org/mobile-tor/
#: (content/mobile-tor/contents+en.lrtopic.body)
@@ -3387,7 +3418,7 @@ msgstr ""
#: https//tb-manual.torproject.org/mobile-tor/
#: (content/mobile-tor/contents+en.lrtopic.body)
msgid "Tapping on this button will provide you with a new identity."
-msgstr ""
+msgstr "Naciśnięcie tego przycisku da Ci nową tożsamość."
#: https//tb-manual.torproject.org/mobile-tor/
#: (content/mobile-tor/contents+en.lrtopic.body)
@@ -3396,11 +3427,14 @@ msgid ""
"Browser for Android does not prevent your subsequent browser activity from "
"being linkable to what you were doing before."
msgstr ""
+"W przeciwieństwie do Przeglądarki Tor dla Komputerów, przycisk \"NOWA "
+"TOŻSAMOŚĆ\" w Przeglądarce Tor dla systemów Android nie zapobiega możliwości"
+" powiązania dalszej aktywności, z tym, co robiłeś wcześniej."
#: https//tb-manual.torproject.org/mobile-tor/
#: (content/mobile-tor/contents+en.lrtopic.body)
msgid "Selecting it will only change your Tor circuit."
-msgstr ""
+msgstr "Opcja ta jedynie zmieni twój obwód Tor."
#: https//tb-manual.torproject.org/mobile-tor/
#: (content/mobile-tor/contents+en.lrtopic.body)
1
0
[translation/communitytpo-contentspot] https://gitweb.torproject.org/translation.git/commit/?h=communitytpo-contentspot
by translation@torproject.org 12 May '21
by translation@torproject.org 12 May '21
12 May '21
commit c722424c23f70f202290d035f0c57d0590cc6391
Author: Translation commit bot <translation(a)torproject.org>
Date: Wed May 12 12:15:13 2021 +0000
https://gitweb.torproject.org/translation.git/commit/?h=communitytpo-conten…
---
contents+es.po | 23 ++++++++++++++++++++---
1 file changed, 20 insertions(+), 3 deletions(-)
diff --git a/contents+es.po b/contents+es.po
index 3c041d99a2..ccab8bedcc 100644
--- a/contents+es.po
+++ b/contents+es.po
@@ -18945,6 +18945,10 @@ msgid ""
"steps to set up a user account, download the expert bundle, implement a "
"torrc configuration file and start up Tor from the command line."
msgstr ""
+"Configurar un sistema Windows como repetidor requiere efectuar unos pocos "
+"simples pasos para establecer una cuenta de usuario, descargar el paquete "
+"experto, implementar un archivo torrc de configuración e iniciar Tor desde "
+"la línea de comando."
#: https//community.torproject.org/relay/setup/guard/windows/
#: (content/relay-operations/technical-setup/guard/windows/contents+en.lrpage.body)
@@ -18953,11 +18957,14 @@ msgid ""
"ensure you follow them very carefully, and make any of the necessary "
"modifications outlined along the way."
msgstr ""
+"Abajo hay instrucciones detalladas sobre como efectuar estos pasos - por "
+"favor asegúrate de seguirlos muy cuidadosamente, y haz cualquiera de las "
+"modificaciones necesarias sugeridas a medida que los sigues."
#: https//community.torproject.org/relay/setup/guard/windows/
#: (content/relay-operations/technical-setup/guard/windows/contents+en.lrpage.body)
msgid "# 1. Creating a user account for Tor"
-msgstr ""
+msgstr "# 1. Creando una cuenta de usuario para Tor"
#: https//community.torproject.org/relay/setup/guard/windows/
#: (content/relay-operations/technical-setup/guard/windows/contents+en.lrpage.body)
@@ -18966,16 +18973,19 @@ msgid ""
"from your personal configuration as well as have manageable system "
"permissions."
msgstr ""
+"Primero necesitarás crear una nueva cuenta para permitirle a Tor ejecutarse "
+"aislado de tu configuración personal, como así también tener permisos de "
+"sistema manejables."
#: https//community.torproject.org/relay/setup/guard/windows/
#: (content/relay-operations/technical-setup/guard/windows/contents+en.lrpage.body)
msgid "1. To begin, open your Control Panel and select 'Accounts'."
-msgstr ""
+msgstr "1. Para empezar, abre tu Panel de Control y selecciona 'Cuentas'."
#: https//community.torproject.org/relay/setup/guard/windows/
#: (content/relay-operations/technical-setup/guard/windows/contents+en.lrpage.body)
msgid "2. On the left-side menu, select 'Family & other people'."
-msgstr ""
+msgstr "2. En el menú de la izquierda, selecciona 'Familia y otras personas'."
#: https//community.torproject.org/relay/setup/guard/windows/
#: (content/relay-operations/technical-setup/guard/windows/contents+en.lrpage.body)
@@ -18983,6 +18993,8 @@ msgid ""
"3. Beside the 'Add another user to this PC' subheader, click the large `+` "
"sign."
msgstr ""
+"3. Al lado del subtítulo 'Agrega otro usuario a esta PC', haz clic en el "
+"signo `+`."
#: https//community.torproject.org/relay/setup/guard/windows/
#: (content/relay-operations/technical-setup/guard/windows/contents+en.lrpage.body)
@@ -18991,6 +19003,9 @@ msgid ""
"the bottom, select the small text that states \"I do not have this users "
"sign-in information\"."
msgstr ""
+"4. Aparecerá un panel solicitando la información de la cuenta de Windows. En"
+" el fondo, selecciona el pequeño texto que afirma \"No tengo la información "
+"de inicio de sesión de este usuario\"."
#: https//community.torproject.org/relay/setup/guard/windows/
#: (content/relay-operations/technical-setup/guard/windows/contents+en.lrpage.body)
@@ -18998,6 +19013,8 @@ msgid ""
"5. On the next panel, select the similar text on the bottom stating \"Set up"
" user without using a Microsoft account\"."
msgstr ""
+"5. En el siguiente panel, selecciona el texto similar en el fondo que afirma"
+" \"Configurar usuario sin usar una cuenta Microsoft\"."
#: https//community.torproject.org/relay/setup/guard/windows/
#: (content/relay-operations/technical-setup/guard/windows/contents+en.lrpage.body)
1
0
[translation/support-portal] https://gitweb.torproject.org/translation.git/commit/?h=support-portal
by translation@torproject.org 12 May '21
by translation@torproject.org 12 May '21
12 May '21
commit 6a629b710ede7b544333a848f9e6fc4ed48e474f
Author: Translation commit bot <translation(a)torproject.org>
Date: Wed May 12 11:47:43 2021 +0000
https://gitweb.torproject.org/translation.git/commit/?h=support-portal
---
contents+pl.po | 9 +++++++--
1 file changed, 7 insertions(+), 2 deletions(-)
diff --git a/contents+pl.po b/contents+pl.po
index bc38bd41d7..b83dafad16 100644
--- a/contents+pl.po
+++ b/contents+pl.po
@@ -1918,6 +1918,8 @@ msgid ""
"At the bottom of the page, next to the \"View the Tor logs\" text, click the"
" button \"View Logs...\"."
msgstr ""
+"Na dole strony, obok tekstu \"Zobacz dziennik zdarzeń Tor\" naciśnij "
+"przycisk \"Wyświetl dziennik...\""
#: https//support.torproject.org/glossary/tor-log/
#: (content/glossary/tor-log/contents+en.lrword.definition)
@@ -4287,13 +4289,16 @@ msgid ""
"navigate to the Tor Browser directory and launch the Tor Browser from the "
"command line by running:"
msgstr ""
+"Alternatywnie dla systemów GNU/Linux, można przeglądać dziennik zdarzeń w "
+"terminalu, przejdź do folderu Przeglądarki Tor i uruchom Przeglądarkę Tor z "
+"linii poleceń wpisując: "
#: https//support.torproject.org/tbb/tbb-21/
#: (content/tbb/tbb-21/contents+en.lrquestion.description)
#: https//support.torproject.org/connecting/connecting-2/
#: (content/connecting/connecting-2/contents+en.lrquestion.description)
msgid "`./start-tor-browser.desktop --verbose`"
-msgstr ""
+msgstr "`./start-tor-browser.desktop --verbose`"
#: https//support.torproject.org/tbb/tbb-21/
#: (content/tbb/tbb-21/contents+en.lrquestion.description)
@@ -4307,7 +4312,7 @@ msgstr ""
#: https//support.torproject.org/connecting/connecting-2/
#: (content/connecting/connecting-2/contents+en.lrquestion.description)
msgid "`./start-tor-browser.desktop --log [file]`"
-msgstr ""
+msgstr "`./start-tor-browser.desktop --log [file]`"
#: https//support.torproject.org/tbb/tbb-22/
#: (content/tbb/tbb-22/contents+en.lrquestion.title)
1
0
[translation/tbmanual-contentspot] https://gitweb.torproject.org/translation.git/commit/?h=tbmanual-contentspot
by translation@torproject.org 12 May '21
by translation@torproject.org 12 May '21
12 May '21
commit f6bb48df1e67beab46834a3405605471877111c9
Author: Translation commit bot <translation(a)torproject.org>
Date: Wed May 12 11:46:52 2021 +0000
https://gitweb.torproject.org/translation.git/commit/?h=tbmanual-contentspot
---
contents+pl.po | 59 +++++++++++++++++++++++++++++++++++++++++++++++++---------
1 file changed, 50 insertions(+), 9 deletions(-)
diff --git a/contents+pl.po b/contents+pl.po
index 228fb66b77..a3c14b661f 100644
--- a/contents+pl.po
+++ b/contents+pl.po
@@ -2434,6 +2434,8 @@ msgid ""
"At the bottom of the page, next to the \"View the Tor logs\" text, click the"
" button \"View Logs...\"."
msgstr ""
+"Na dole strony, obok tekstu \"Zobacz dziennik zdarzeń Tor\" naciśnij "
+"przycisk \"Wyświetl dziennik...\""
#: https//tb-manual.torproject.org/troubleshooting/
#: (content/troubleshooting/contents+en.lrtopic.body)
@@ -2442,21 +2444,26 @@ msgid ""
"navigate to the Tor Browser directory and launch the Tor Browser from the "
"command line by running:"
msgstr ""
+"Alternatywnie dla systemów GNU/Linux, można przeglądać dziennik zdarzeń w "
+"terminalu, przejdź do folderu Przeglądarki Tor i uruchom Przeglądarkę Tor z "
+"linii poleceń wpisując: "
#: https//tb-manual.torproject.org/troubleshooting/
#: (content/troubleshooting/contents+en.lrtopic.body)
msgid "`./start-tor-browser.desktop --verbose`"
-msgstr ""
+msgstr "`./start-tor-browser.desktop --verbose`"
#: https//tb-manual.torproject.org/troubleshooting/
#: (content/troubleshooting/contents+en.lrtopic.body)
msgid "Or to save the logs to a file (default: tor-browser.log):"
msgstr ""
+"Lub w celu zapisania dziennika zdarzeń do pliku (domyślnie: tor-"
+"browser.log):"
#: https//tb-manual.torproject.org/troubleshooting/
#: (content/troubleshooting/contents+en.lrtopic.body)
msgid "`./start-tor-browser.desktop --log [file]`"
-msgstr ""
+msgstr "`./start-tor-browser.desktop --log [file]`"
#: https//tb-manual.torproject.org/troubleshooting/
#: (content/troubleshooting/contents+en.lrtopic.body)
@@ -2464,6 +2471,8 @@ msgid ""
"More information on this can be found on the [Support "
"Portal](https://support.torproject.org/connecting/connecting-2/)."
msgstr ""
+"Więcej informacji na ten temat znajduje się na [Portalu "
+"Pomocy](https://support.torproject.org/connecting/connecting-2/)."
#: https//tb-manual.torproject.org/troubleshooting/
#: (content/troubleshooting/contents+en.lrtopic.body)
@@ -2476,6 +2485,8 @@ msgid ""
"If you still can’t connect, your Internet Service Provider might be "
"censoring connections to the Tor network."
msgstr ""
+"Jeśli nadal nie możesz się połączyć, twój Dostawca Usług Internetowych może "
+"cenzurować połączenia z siecią Tor."
#: https//tb-manual.torproject.org/troubleshooting/
#: (content/troubleshooting/contents+en.lrtopic.body)
@@ -2496,6 +2507,8 @@ msgid ""
"Tor Browser is under constant development, and some issues are known about "
"but not yet fixed."
msgstr ""
+"Przeglądarka Tor jest pod stałym rozwojem, niektóre problemy są znane, lecz "
+"jeszcze nie są rozwiązane."
#: https//tb-manual.torproject.org/troubleshooting/
#: (content/troubleshooting/contents+en.lrtopic.body)
@@ -2503,6 +2516,8 @@ msgid ""
"Please check the [Known Issues](/known-issues) page to see if the problem "
"you are experiencing is already listed there."
msgstr ""
+"Sprawdź [Znane Problemy](/known-issues) aby zobaczyć czy Twój problem już "
+"się tam znajduje."
#: https//tb-manual.torproject.org/plugins/
#: (content/plugins/contents+en.lrtopic.title)
@@ -2796,6 +2811,8 @@ msgstr ""
msgid ""
"* Antivirus or malware protection blocking users from accessing Tor Browser."
msgstr ""
+"* Program antywirusowy lub ochrona przed szkodliwym oprogramowaniem blokuje "
+"użytkowników przed dostępem do Przeglądarki Tor."
#: https//tb-manual.torproject.org/known-issues/
#: (content/known-issues/contents+en.lrtopic.body)
@@ -2804,6 +2821,10 @@ msgid ""
"vulnerabilities](https://support.torproject.org/tbb/antivirus-false-"
"positive/)."
msgstr ""
+"Czasami pojawiają się wraz z [fałszywie pozytywnymi powiadomieniami o "
+"niebezpiecznym oprogramowaniu lub/i zagrożeniami "
+"bezpieczeństwa](https://support.torproject.org/tbb/antivirus-false-"
+"positive/)."
#: https//tb-manual.torproject.org/known-issues/
#: (content/known-issues/contents+en.lrtopic.body)
@@ -2811,6 +2832,8 @@ msgid ""
"You can read more about this on our [Support "
"Portal](https://support.torproject.org/tbb/tbb-10/)."
msgstr ""
+"Możesz przeczytać o tym więcej na naszym [Portalu "
+"Pomocy](https://support.torproject.org/tbb/tbb-10/)."
#: https//tb-manual.torproject.org/known-issues/
#: (content/known-issues/contents+en.lrtopic.body)
@@ -2818,6 +2841,8 @@ msgid ""
"The following antivirus and firewall software have been known to interfere "
"with Tor and may need to be temporarily disabled:"
msgstr ""
+"Poniższe programy antywirusowe oraz oprogramowanie firewall ingeruje z Torem"
+" i może wymagać czasowego wyłączenia:"
#: https//tb-manual.torproject.org/known-issues/
#: (content/known-issues/contents+en.lrtopic.body)
@@ -2842,12 +2867,12 @@ msgstr "* Microsoft Security Essentials"
#: https//tb-manual.torproject.org/known-issues/
#: (content/known-issues/contents+en.lrtopic.body)
msgid "* Avast Antivirus"
-msgstr ""
+msgstr "* Antywirus Avast"
#: https//tb-manual.torproject.org/known-issues/
#: (content/known-issues/contents+en.lrtopic.body)
msgid "* VPNs also tend to interfere with Tor and need to be disabled."
-msgstr ""
+msgstr "* VPN również czasami mogą ingerować w Tora i muszą zostać wyłączone."
#: https//tb-manual.torproject.org/known-issues/
#: (content/known-issues/contents+en.lrtopic.body)
@@ -2856,6 +2881,9 @@ msgid ""
"advanced user who knows how to configure both in a way that doesn't "
"compromise your privacy."
msgstr ""
+"Nie zalecamy używania VPN wraz z Torem, jeśli nie jesteś zaawansowanym "
+"użytkownikiem, który wie jak skonfigurować oba programy, tak aby nie "
+"naruszyć swojej prywatności."
#: https//tb-manual.torproject.org/known-issues/
#: (content/known-issues/contents+en.lrtopic.body)
@@ -2863,16 +2891,18 @@ msgid ""
"You can find more detailed information about Tor + VPN at our "
"[wiki](https://gitlab.torproject.org/legacy/trac/-/wikis/doc/TorPlusVPN)."
msgstr ""
+"Możesz znaleźć bardziej szczegółowe informacje o Tor + VPN na naszej "
+"[wiki](https://gitlab.torproject.org/legacy/trac/-/wikis/doc/TorPlusVPN)."
#: https//tb-manual.torproject.org/known-issues/
#: (content/known-issues/contents+en.lrtopic.body)
msgid "* Videos that require Adobe Flash are unavailable."
-msgstr ""
+msgstr "* Filmy wymagające Adobe Flash są niedostępne."
#: https//tb-manual.torproject.org/known-issues/
#: (content/known-issues/contents+en.lrtopic.body)
msgid "Flash is disabled for security reasons."
-msgstr ""
+msgstr "Flash jest wyłączony ze względu na bezpieczeństwo."
#: https//tb-manual.torproject.org/known-issues/
#: (content/known-issues/contents+en.lrtopic.body)
@@ -2883,11 +2913,12 @@ msgstr "* Tor nie może użyć mostka, jeśli ustawiony jest serwer proxy."
#: (content/known-issues/contents+en.lrtopic.body)
msgid "* The Tor Browser package is dated January 1, 2000 00:00:00 UTC."
msgstr ""
+"* Paczka Przeglądarki Tor jest datowana na 1 Stycznia, 2000 00:00:00 UTC."
#: https//tb-manual.torproject.org/known-issues/
#: (content/known-issues/contents+en.lrtopic.body)
msgid "This is to ensure that each software build is exactly reproducible."
-msgstr ""
+msgstr "Zapewnia to dokładne odtworzenie każdej budowy programu."
#: https//tb-manual.torproject.org/known-issues/
#: (content/known-issues/contents+en.lrtopic.body)
@@ -2895,6 +2926,8 @@ msgid ""
"* Issues with making Tor Browser as your [default "
"browser](https://support.torproject.org/tbb/tbb-32/)."
msgstr ""
+"* Problemy z ustawieniem Przeglądarki Tor jako twojej [podstawowej "
+"przeglądarki](https://support.torproject.org/tbb/tbb-32/)."
#: https//tb-manual.torproject.org/known-issues/
#: (content/known-issues/contents+en.lrtopic.body)
@@ -2902,11 +2935,14 @@ msgid ""
"* If Tor Browser was working before and is not working now (especially after"
" a re-install or an update), your system may have been hibernating."
msgstr ""
+"* Jeśli Przeglądarka Tor wcześniej działała poprawnie, a teraz nie "
+"(zwłaszcza po ponownej instalacji lub aktualizacji), twój system mógł być w "
+"stanie hibernacji."
#: https//tb-manual.torproject.org/known-issues/
#: (content/known-issues/contents+en.lrtopic.body)
msgid "A reboot of your system, in that case, will solve the issue."
-msgstr ""
+msgstr "Restart systemu rozwiąże ten problem."
#: https//tb-manual.torproject.org/known-issues/
#: (content/known-issues/contents+en.lrtopic.body)
@@ -2914,6 +2950,9 @@ msgid ""
"* Tor won't start on Windows when the [folder path contains non-ascii "
"characters](https://gitlab.torproject.org/tpo/core/tor/-/issues/10416)."
msgstr ""
+"* Przeglądarka Tor nie uruchamia się na platformie Windows gdy [ścieżka "
+"folderu zawiera znaki inne niż "
+"ascii](https://gitlab.torproject.org/tpo/core/tor/-/issues/10416)."
#: https//tb-manual.torproject.org/known-issues/
#: (content/known-issues/contents+en.lrtopic.body)
@@ -2921,11 +2960,13 @@ msgid ""
"* BitTorrent [is not anonymous over Tor](https://blog.torproject.org"
"/bittorrent-over-tor-isnt-good-idea)."
msgstr ""
+"* BitTorrent [nie jest anonimowy w sieci Tor](https://blog.torproject.org"
+"/bittorrent-over-tor-isnt-good-idea)."
#: https//tb-manual.torproject.org/mobile-tor/
#: (content/mobile-tor/contents+en.lrtopic.title)
msgid "MOBILE TOR"
-msgstr ""
+msgstr "TOR NA URZĄDZENIU MOBILNYM"
#: https//tb-manual.torproject.org/mobile-tor/
#: (content/mobile-tor/contents+en.lrtopic.description)
1
0