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"
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()
-
- })
-
- })
-}
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)
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)
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)
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)
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)
commit 50f2edc69685d81dc9a1578c1809242f491c4861
Author: emma peel <emma.peel(a)riseup.net>
Date: Wed May 12 13:16:11 2021 +0200
update tranlations branch content
---
.../community-resources/good-bad-isps/contents.lr | 5 +-
.../technical-considerations/contents.lr | 7 +-
.../bridge/centos-rhel-opensuse/contents.lr | 4 +-
.../bridge/debian-ubuntu/contents.lr | 2 +-
.../technical-setup/bridge/docker/contents.lr | 14 +++-
.../bridge/dragonflybsd/contents.lr | 2 +-
.../technical-setup/bridge/fedora/contents.lr | 2 +-
.../technical-setup/bridge/freebsd/contents.lr | 2 +-
.../technical-setup/bridge/netbsd/contents.lr | 2 +-
.../technical-setup/bridge/openbsd/contents.lr | 2 +-
.../bridge/post-install/contents.lr | 2 +-
.../technical-setup/guard/fedora/contents.lr | 12 ++-
.../technical-setup/guard/windows/contents.lr | 93 ++++++++++++++++++++++
content/user-research/guidelines/contents.lr | 30 +++++--
content/user-research/how-to-volunteer/contents.lr | 70 ++++++++++++++++
content/user-research/open/contents.lr | 21 +----
content/user-research/persona/contents.lr | 11 +--
content/user-research/reports/contents.lr | 36 +++++++++
18 files changed, 265 insertions(+), 52 deletions(-)
diff --git a/content/relay-operations/community-resources/good-bad-isps/contents.lr b/content/relay-operations/community-resources/good-bad-isps/contents.lr
index dc4bb3c..f5c4280 100644
--- a/content/relay-operations/community-resources/good-bad-isps/contents.lr
+++ b/content/relay-operations/community-resources/good-bad-isps/contents.lr
@@ -21,7 +21,7 @@ For network diversity and stronger anonymity, you should avoid providers and cou
* Hetzner Online GmbH (AS24940)
* DigitalOcean, LLC (AS14061)
-**Note**: This page is currently being revamped. If you would like to help out please see [#31063](https://trac.torproject.org/projects/tor/ticket/31063).
+**Note**: This page is currently being revamped. If you would like to help out please see [#72](https://gitlab.torproject.org/tpo/web/community/-/issues/72).
# Good Experiences
@@ -213,7 +213,7 @@ For network diversity and stronger anonymity, you should avoid providers and cou
| **Company/ISP** | **ASN** | **Bridges** | **Relay** | **Exit** | **Comments** | **Last Updated** |
|-------------------------|-------------|-----------------|--------------|-------------|---------------------|------------------------|
-| [Hitme.net.pl](http://hitme.net.pl/) | - | Yes | Yes | Yes | - | 12/06/2017 |
+| [Hitme.pl](http://hitme.pl/) | - | Yes | Yes | No | They block accounts if you receive an abuse report | 29/03/2021 |
| [Hostowisko.pl](http://www.hostowisko.pl/) | - | Yes | Yes | ? | - | 27/08/2013 |
| [Exone](http://www.exone.pl/) | - | Yes | Yes | ? | - | 28/08/2013 |
| [e24cloud](http://www.e24cloud.com/en) | - | Yes | Yes | ? | - | 01/10/2013 |
@@ -243,6 +243,7 @@ For network diversity and stronger anonymity, you should avoid providers and cou
| [PRQ](http://prq.se/?p=dedicated&intl=1) | - | Yes | Yes | Yes | - | - |
| [Portlane](http://www.portlane.com/) | - | Yes | Yes | Yes | Previously provided connectivity for ThePirateBay, OpenBitTorrent tracker et al. Handles abuse according to "Swedish praxis". | - |
| [Yourserver](https://www.yourserver.se/) | - | Yes | Yes | ? | Support team will allow relay/exit but TOR Traffic is throttled to 5Mbps speed. If your Exit relay receive too much complaints, they will ask to you to stop or otherwise they will suspend. | 2015/03/06 |
+| [Svea Hosting](https://svea.net/) | AS41634 | Yes | Yes | Yes | They run an exit node themselves and write on their dedicated server page "It is perfect for [...] TOR Exit Nodes" | 04/2021 |
### Switzerland
diff --git a/content/relay-operations/technical-considerations/contents.lr b/content/relay-operations/technical-considerations/contents.lr
index 33ae63e..83906f3 100644
--- a/content/relay-operations/technical-considerations/contents.lr
+++ b/content/relay-operations/technical-considerations/contents.lr
@@ -19,7 +19,7 @@ If you do not own physical hardware, you could run a relay on a rented dedicated
This can cost anywhere between $3.00/month and thousands per month, depending on your provider, hardware configuration, and bandwidth usage.
Many VPS providers will not allow you to run exit relays.
You must follow the VPS provider's terms of service, or risk having your account disabled.
-For more information on hosting providers and their policies on allowing Tor relays, please see this list maintained by the Tor community: [GoodBadISPs](/relay/community-resources/good-bad-isps).
+For more information on hosting providers and their policies on allowing Tor relays, please see this list maintained by the Tor community: [GoodBadISPs](../community-resources/good-bad-isps/).
## Questions to consider when choosing a host
@@ -27,7 +27,8 @@ For more information on hosting providers and their policies on allowing Tor rel
* Does the hoster provide IPv6 connectivity? It is recommended, but not required.
* What virtualization / hypervisor (if any) does the provider use? Anything but OpenVZ should be fine.
* Does the hoster start to throttle bandwidth after a certain amount of traffic?
-* How well connected is the autonomous system of the hoster? To answer this question you can use the AS rank of the autonomous systems if you want to compare: (a lower value is better) http://as-rank.caida.org/
+* How well connected is the autonomous system of the hoster?
+ To answer this question you can use the AS rank of the autonomous systems if you want to compare: (a lower value is better) <http://as-rank.caida.org/>
## If you plan to run exit relays
@@ -35,7 +36,7 @@ For more information on hosting providers and their policies on allowing Tor rel
* Does the hoster allow custom WHOIS records for your IP addresses? This helps reduce the amount of abuse sent to the hoster instead of you.
* Does the hoster allow you to set a custom DNS reverse entry? (DNS PTR record)
- You can usually ask these questions in a Pre-Sales ticket.
+You can usually ask these questions in a Pre-Sales ticket.
# AS/location diversity
diff --git a/content/relay-operations/technical-setup/bridge/centos-rhel-opensuse/contents.lr b/content/relay-operations/technical-setup/bridge/centos-rhel-opensuse/contents.lr
index 7701282..f31d12e 100644
--- a/content/relay-operations/technical-setup/bridge/centos-rhel-opensuse/contents.lr
+++ b/content/relay-operations/technical-setup/bridge/centos-rhel-opensuse/contents.lr
@@ -131,9 +131,7 @@ If your bridge is now running, check out the [post-install notes](https://commun
---
html: two-columns-page.html
---
-key:
-
-2
+key: 1
---
subtitle: How to deploy an obfs4 bridge on CentOS / RHEL / OpenSUSE
---
diff --git a/content/relay-operations/technical-setup/bridge/debian-ubuntu/contents.lr b/content/relay-operations/technical-setup/bridge/debian-ubuntu/contents.lr
index 4d25952..76926a9 100644
--- a/content/relay-operations/technical-setup/bridge/debian-ubuntu/contents.lr
+++ b/content/relay-operations/technical-setup/bridge/debian-ubuntu/contents.lr
@@ -86,7 +86,7 @@ If you are having trouble setting up your bridge, have a look at [our help secti
If your bridge is now running, check out the [post-install notes](https://community.torproject.org/relay/setup/bridge/post-install/).
---
-key: 1
+key: 2
---
html: two-columns-page.html
---
diff --git a/content/relay-operations/technical-setup/bridge/docker/contents.lr b/content/relay-operations/technical-setup/bridge/docker/contents.lr
index 00e26a1..85ffb24 100644
--- a/content/relay-operations/technical-setup/bridge/docker/contents.lr
+++ b/content/relay-operations/technical-setup/bridge/docker/contents.lr
@@ -9,7 +9,7 @@ body:
### 1. Deploy a container
We provide a docker-compose file that helps you deploy the container.
-First, [download docker-compose.yml](https://dip.torproject.org/torproject/anti-censorship/d…, and then write your bridge configuration to a new file, `.env`, which is in the same directory as `docker-compose.yml`. Here's a template:
+First, [download docker-compose.yml](https://gitlab.torproject.org/torproject/anti-censorshi…, and then write your bridge configuration to a new file, `.env`, which is in the same directory as `docker-compose.yml`. Here's a template:
```
# Your bridge's Tor port.
@@ -73,10 +73,20 @@ obfs4 1.2.3.4:1234 B0E566C9031657EA7ED3FC9D248E8AC4F37635A4 cert=OYWq67L7MDApdJC
Make sure to check out the [post-install notes](https://community.torproject.org/relay/setup/bridge/post-install/).
If you are having trouble setting up your bridge, have a look at [our help section](https://community.torproject.org/relay/getting-help/).
+### 4. Advanced usage
+
+You may set additional torrc variables in your `.env` file by setting `OBFS4_ENABLE_ADDITIONAL_VARIABLES` to 1 and prefixing the desired torrc options with `OBFS4V_`. For example, to set the `AddressDisableIPv6` option, include the following lines in your `.env`:
+
+```
+OBFS4_ENABLE_ADDITIONAL_VARIABLES=1
+OBFS4V_AddressDisableIPv6=1
+```
+
+You may [download our template .env](https://gitlab.torproject.org/torproject/anti-censorship/docker-obfs4-bridge/raw/master/.env) to get started.
---
html: two-columns-page.html
---
-key: 5
+key: 3
---
subtitle: How to deploy an obfs4 bridge using a docker container
---
diff --git a/content/relay-operations/technical-setup/bridge/dragonflybsd/contents.lr b/content/relay-operations/technical-setup/bridge/dragonflybsd/contents.lr
index 8a0c15e..1027a79 100644
--- a/content/relay-operations/technical-setup/bridge/dragonflybsd/contents.lr
+++ b/content/relay-operations/technical-setup/bridge/dragonflybsd/contents.lr
@@ -6,7 +6,7 @@ title: DragonflyBSD
---
html: two-columns-page.html
---
-key: 5
+key: 4
---
body:
diff --git a/content/relay-operations/technical-setup/bridge/fedora/contents.lr b/content/relay-operations/technical-setup/bridge/fedora/contents.lr
index 6708a92..095bac2 100644
--- a/content/relay-operations/technical-setup/bridge/fedora/contents.lr
+++ b/content/relay-operations/technical-setup/bridge/fedora/contents.lr
@@ -105,7 +105,7 @@ html: two-columns-page.html
---
key:
-2
+5
---
subtitle: How to deploy an obfs4 bridge on Fedora
---
diff --git a/content/relay-operations/technical-setup/bridge/freebsd/contents.lr b/content/relay-operations/technical-setup/bridge/freebsd/contents.lr
index 29baea0..5d182d8 100644
--- a/content/relay-operations/technical-setup/bridge/freebsd/contents.lr
+++ b/content/relay-operations/technical-setup/bridge/freebsd/contents.lr
@@ -6,7 +6,7 @@ title: FreeBSD
---
html: two-columns-page.html
---
-key: 3
+key: 6
---
body:
diff --git a/content/relay-operations/technical-setup/bridge/netbsd/contents.lr b/content/relay-operations/technical-setup/bridge/netbsd/contents.lr
index a9799cd..c681497 100644
--- a/content/relay-operations/technical-setup/bridge/netbsd/contents.lr
+++ b/content/relay-operations/technical-setup/bridge/netbsd/contents.lr
@@ -6,7 +6,7 @@ title: NetBSD
---
html: two-columns-page.html
---
-key: 6
+key: 7
---
body:
diff --git a/content/relay-operations/technical-setup/bridge/openbsd/contents.lr b/content/relay-operations/technical-setup/bridge/openbsd/contents.lr
index d5ef072..0a60051 100644
--- a/content/relay-operations/technical-setup/bridge/openbsd/contents.lr
+++ b/content/relay-operations/technical-setup/bridge/openbsd/contents.lr
@@ -6,7 +6,7 @@ color: primary
---
html: two-columns-page.html
---
-key: 4
+key: 8
---
body:
diff --git a/content/relay-operations/technical-setup/bridge/post-install/contents.lr b/content/relay-operations/technical-setup/bridge/post-install/contents.lr
index 4abc2ea..e0aea26 100644
--- a/content/relay-operations/technical-setup/bridge/post-install/contents.lr
+++ b/content/relay-operations/technical-setup/bridge/post-install/contents.lr
@@ -21,7 +21,7 @@ Finally, you can monitor your obfs4 bridge's usage on [Relay Search](https://met
---
html: two-columns-page.html
---
-key: 6
+key: 9
---
subtitle: How to find your bridge in Relay Search and connect manually
---
diff --git a/content/relay-operations/technical-setup/guard/fedora/contents.lr b/content/relay-operations/technical-setup/guard/fedora/contents.lr
index 7152ca7..795fe98 100644
--- a/content/relay-operations/technical-setup/guard/fedora/contents.lr
+++ b/content/relay-operations/technical-setup/guard/fedora/contents.lr
@@ -10,7 +10,7 @@ body:
One of the most important things to keeps your relay secure is to install security updates timely and ideally automatically so you can not forget about it. Follow the instructions to enable [automatic software updates](updates) for your operating system.
-# 2. # 3. Add the following to /etc/yum.repos.d/tor.repo and then install the tor package.
+# 2. Add the following to `/etc/yum.repos.d/tor.repo` and then install the tor package.
```
[tor]
@@ -22,7 +22,12 @@ gpgkey=https://rpm.torproject.org/fedora/public_gpg.key
cost=100
```
-# 3. Put the tor configuration file `/etc/tor/torrc` in place
+`sudo dnf install tor`
+
+
+# 3. Configuration File
+
+Put the configuration file `/etc/tor/torrc` in place:
```
#change the nickname "myNiceRelay" to a name that you like
@@ -42,7 +47,8 @@ systemctl start tor
# 5. Final notes
-If you are having trouble setting up your relay, have a look at our [help section](/relay/getting-help/). If your relay is now running, check out the [post-install](/relay/setup/post-install/) notes.
+If you are having trouble setting up your relay, have a look at our [help section](/relay/getting-help/).
+If your relay is now running, check out the [post-install](/relay/setup/post-install/) notes.
---
html: two-columns-page.html
---
diff --git a/content/relay-operations/technical-setup/guard/windows/contents.lr b/content/relay-operations/technical-setup/guard/windows/contents.lr
new file mode 100644
index 0000000..2dcd62d
--- /dev/null
+++ b/content/relay-operations/technical-setup/guard/windows/contents.lr
@@ -0,0 +1,93 @@
+_model: page
+---
+color: primary
+---
+title: Windows 10
+---
+html: two-columns-page.html
+---
+key: 8
+---
+section: Middle/Guard relay
+---
+section_id: relay-operations
+---
+subtitle: How to deploy a middle/Guard relay on Windows
+---
+body:
+
+**Note: You should only run a Windows relay if you can run it 24/7. If the operator is unable to guarantee that, a [Snowflake](https://snowflake.torproject.org/) is a better way to contribute resources.**
+
+Setting up a Windows system as a relay requires performing a few simple steps to set up a user account, download the expert bundle, implement a torrc configuration file and start up Tor from the command line.
+Below are detailed instructions on how to perform these steps - please ensure you follow them very carefully, and make any of the necessary modifications outlined along the way.
+
+# 1. Creating a user account for Tor
+First you will need to create a new account to allow Tor to run isolated from your personal configuration as well as have manageable system permissions.
+
+1. To begin, open your Control Panel and select 'Accounts'.
+2. On the left-side menu, select 'Family & other people'.
+3. Beside the 'Add another user to this PC' subheader, click the large `+` sign.
+4. A panel will now appear asking for the Windows account information. On the bottom, select the small text that states "I do not have this users sign-in information".
+5. On the next panel, select the similar text on the bottom stating "Set up user without using a Microsoft account".
+6. Enter a username for the user. Anything you like is fine, though within this guide the username `torrelay` will be used. Then enter a strong password and continue.
+
+# 2. Downloading and configuring the Windows Expert bundle
+
+## 2.1 Downloading
+
+The next step is to download and install Windows Expert bundle as well as set up your torrc file.
+
+1. Head over to [Download Tor Source code]( https://www.torproject.org/download/tor/) and scroll down to select 'Windows Expert Bundle'.
+2. Head to your `C:\Users\torrelay\` directory.
+3. Create a folder called `tor`.
+*(Optional. A custom path can be used, though you will have to make necessary modifications in the following steps.)
+
+## 2.2 Configuration
+
+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`.
+2. You will now need to create a torrc file to define the ruleset of your relay.
+3. The default directory path for this file is `C:\Users\torrelay\AppData\Roaming\tor\torrc`, though you can specify a custom location at commandline startup with the `-f` flag. (More below)
+4. Open up your newly created `torrc` file in your text editor and populate it with the following contents:
+
+```
+#Change the nickname "myNiceRelay" to a name that you like
+Nickname myNiceRelay
+ORPort 9001
+ExitRelay 0
+SocksPort 0
+#Paths assume you extracted to C:\Users\torrelay\tor - if you
+#extracted elsewhere or used a different username, adjust the
+#paths accordingly
+DataDirectory C:\Users\torrelay\tor\Data
+Log notice file C:\Users\torrelay\tor\log\notices.log
+GeoIPFile C:\Users\torrelay\tor\Data\Tor\geoip
+GeoIPv6File C:\Users\torrelay\tor\Data\Tor\geoip6
+#Put your email below - Note that it will be published on the metrics page
+ContactInfo tor-operator@your-emailaddress-domain
+```
+
+Make sure everything is filled in correctly, then save and exit.
+
+# 3. Starting up your relay
+
+There are two methods for starting up your relay for the first time depending on your preferences and needs.
+
+### 3.1 Method 1: User interface
+
+1. Navigate to the directory you extracted Tors files.
+2. Simply right-click on the `tor.exe` file and select 'Run as other user' from the drop-down menu, and enter the password for your Tor account when prompted.
+* **Note:** Be sure **not** to click the 'Run as administrator' button - this is dangerous!
+
+### 3.2 Method 2: Command line
+
+1. Open your command prompt. Navigate to `C:\Users\user\torrelay\tor\Tor` with the command `cd C:\Users\user\torrelay\tor\Tor`.
+2. Type `RUNAS /user:torrelay tor.exe` and press enter. If you have your `torrc` file somewhere other than the default location (Like the `home` folder), specify the path with the `-f` flag.
+* Example: `RUNAS /user:torrelay tor.exe -f C:\Users\user\torrelay\tor\Tor\torrc`
+3. You should now see Tor starting up in your terminal. Wait until its finished bootstrapping.
+4. After a short period it should publish its OrPort, and you will be successfully relaying traffic for the Tor Network.
+ * **Notice:** Depending on your systems settings, Tor may fail to start and produce an error indicating it is unable to create files. If this occurs, simply open the Windows Defender Security Center and select "App & browser control". Add the tor.exe file to the permissions list, then rerun `tor.exe` from the command line. Tor should now start up normally.
+
+## 4. Final notes
+
+If you are having trouble setting up your relay, have a look at our [help section](/relay/getting-help/).
+If your relay is now running, check out the [post-install](/relay/setup/post-install/) notes.
diff --git a/content/user-research/guidelines/contents.lr b/content/user-research/guidelines/contents.lr
index fb6c5f7..c78ca5e 100644
--- a/content/user-research/guidelines/contents.lr
+++ b/content/user-research/guidelines/contents.lr
@@ -8,7 +8,6 @@ title: User Research Guidelines
---
subtitle: We collect only necessary data to improve our services.
---
->>>>>>> parent of 1e624ba... update content status
key: 3
---
html: two-columns-page.html
@@ -36,18 +35,21 @@ You'd love to read about your experiences during the training, product testing,
* Scenario: describe the process of the test you ran.
* Demographics: While we are not interested in specific characteristics of our audience, or binary attributes, we must know the total reach of your Tor training. You should take [this material]() with you on the day of your research, distribute it among participants, and answer their questions about how to fill it in if they have any.
-* Interview Process: Thank the participant for their willingness to participate in this process and explain that we are testing the product, not them. The interview should not last longer than 20 minutes, you can record if you wish, but you can also take notes on the printed material you will carry with you (or on your computer). Thank the participant again and end the interview.
+* Interview Process: Thank the participant for their willingness to participate in this process and explain that we are testing the product, not them.
+The interview should not last longer than 20 minutes, you can record if you wish, but you can also take notes on the printed material you will carry with you (or on your computer).
+Thank the participant again and end the interview.
Send us the result - you don't have to write a report, we can do this data analysis with the material you collected.
-
## Coordinate with the trainer and the Tor UX team
You're not doing all this work alone - we will support you with meetings, guides, and mentorship if you want. You can join us at any time on our IRC channel #tor-ux and our [mailing list](https://lists.torproject.org/cgi-bin/mailman/listinfo/ux).
-You must be aligned about the agenda and time to run interviews (if that is the case) during the end of the training. **We strongly recommend that you go through the program of the exercise with the trainer**. Also, we want you two to coordinate feedback together — both for you and for your audience.
+You must be aligned about the agenda and time to run interviews (if that is the case) during the end of the training. **We strongly recommend that you go through the program of the exercise with the trainer**.
+Also, we want you two to coordinate feedback together - both for you and for your audience.
At the beginning of the training, be sure to let everyone know what is your role there and why you're taking notes on the practice.
## Get prepared!
+
Print and bring with you the material that you will need to run the research - that will probably be something like:
* Demographics
@@ -59,13 +61,25 @@ It is easier to have this material printed and in hand, but if you prefer, you c
Keep in mind that you might not have Internet access at the venue, so if you're going to install a Tor feature with someone during the interview, you may need to have it downloaded before the training.
## Report to Tor UX team
-Before ending the training, coordinate the feedback with the trainer. The two of you should work together to hand out post-its for the audience, you can give each participant post-it of a different color per question and ask them to fill it with what they think about: 1. the service they just learned; 2. Tor project; and 3. Tor in general. It can also be questions - keep in mind that any feedback is a good feedback.
-It is very important for us to hear back from you. We want to know how the training and the research was for you, how we can improve our support and also, if you want to keep running Tor User Research. We will ask you to fill a form at the end of the research, so we can get your address to send to you a researcher kit (t-shirt and stickers).
+Before ending the training, coordinate the feedback with the trainer.
+The two of you should work together to hand out post-its for the audience, you can give each participant post-it of a different color per question and ask them to fill it with what they think about: 1. the service they just learned; 2. Tor project; and 3. Tor in general.
+It can also be questions - keep in mind that any feedback is a good feedback.
+
+It is very important for us to hear back from you.
+We want to know how the training and the research was for you, how we can improve our support and also, if you want to keep running Tor User Research.
+We will ask you to fill a form at the end of the research, so we can get your address to send to you a researcher kit (t-shirt and stickers).
We hope to hear back from you very soon!
-We will send you our document on **how to report** to the UX team, so please [get in touch](https://lists.torproject.org/cgi-bin/mailman/listinfo/ux) with us to get it.
-If you think you won't have time to gather and report in this format, we would love to have another way to get the material you collected. You can take pictures or send your ´raw´ notes for us.
+Before your session, read and print this material on [User Research Reporting](https://gitlab.torproject.org/tpo/ux/research/-/blob/master/comm….
+If you don't think you'll have time to report in this format, we will happily accept your findings another way - for example, you can take pictures or send your 'raw' notes to us.
+
+### How to submit your findings
+
+1. Write your [report](https://gitlab.torproject.org/tpo/ux/research/-/blob/master/communi… (keep it simple).
+2. Upload it to our [Gitlab repository](https://gitlab.torproject.org/tpo/ux/research/-/blob/master/REA….
+3. Create issues in the [Research repository](https://gitlab.torproject.org/tpo/ux/research/-/blob/master/REA….
+4. UX team will discuss each issue and forward it to developers when necessary.
## Additional links
diff --git a/content/user-research/how-to-volunteer/contents.lr b/content/user-research/how-to-volunteer/contents.lr
new file mode 100644
index 0000000..754db35
--- /dev/null
+++ b/content/user-research/how-to-volunteer/contents.lr
@@ -0,0 +1,70 @@
+_model: page
+---
+title: How to Volunteer
+---
+body:
+
+## Where to start
+
+If this is your first time running a User Research session for the Tor Project, we recommend starting with one of these studies. Both can be conducted on a rolling basis and ran remotely.
+
+- [Usability Testing Tor Browser Desktop](https://gitlab.torproject.org/tpo/ux/research/-/blob/master/script…
+- [Discovery Bridges](https://gitlab.torproject.org/tpo/ux/research/-/blob/master/script…
+
+After choosing which study to run, open an issue in our [GitLab page](https://gitlab.torproject.org/tpo/ux/research).
+Add the title of your research, then select the Usability Testing template option and fill it in.
+Please remember to update the issue as your research evolves.
+
+Not all of the data collected in our research is disclosed to the public, but our general findings are.
+To protect our participants' privacy we take care to anonymize their responses and avoid recording our sessions.
+
+If you're already familiar with the Tor Project and user testing, have a look at our [current needs for user research](https://community.torproject.org/user-research/open/) and see which study better suits you.
+Remember to drop us an email telling us about your plans so we can follow and support your research.
+
+As a volunteer we also ask that you read and follow our [Code of Conduct](https://gitweb.torproject.org/community/policies.git/tree/code_of_…, as well our [Guidelines for Research](https://community.torproject.org/user-research/guidelines/).
+
+**Why do we run Demographics?**
+We don't collect personal data in our [Demographics](https://gitlab.torproject.org/tpo/ux/research/-/blob/master/s…, and all questions are optional.
+We believe it's important to collect basic demographics to help us understand if we are meeting our mission regarding diversity and inclusion.
+In addition, collecting these demographics is required for specific studies to support human rights.
+
+**We don't trick participants.** We don't use trick questions in our research.
+We expect participants to be honest with us, and we must be honest about our questions in return.
+As a transparent research space our surveys, studies, and reports are all public, and participants are free to view past studies prior to taking part - however they are not advised to do so.
+
+**We don't track participants.** We care about your privacy and security.
+If we invite you to participate in a study, we won't track you and any recordings will be erased after the report is complete.
+We advise volunteers not to record their sessions at all.
+
+**Open source for privacy.**
+We use free and open source software to analyze our data, and we recommend our volunteers do the same.
+We also ask anyone running research not use software hosted by third parties like cloud providers.
+
+**Decision-making process.** We don't have a single model for decision making.
+After conducting your research, it's normal to be excited to see your feedback implemented as soon as possible.
+However all feedback must be discussed internally across the different teams at the Tor Project first.
+This means that it's often necessary to run the same research more than once to validate your findings, and meet the expectations of the engineers, developers, designers, researchers and others at Tor.
+Please read our [Guidelines](https://community.torproject.org/user-research/guidelines/) to get to know this process more.
+
+## Checklist
+
+- Read the guidelines on [how to do user research with Tor](https://gitlab.torproject.org/tpo/ux/research/-/blob/master/README.md).
+- Read and follow our [Code of Conduct](https://gitweb.torproject.org/community/policies.git/tree/code_of_….
+- If you don't have one yet, [request a Gitlab account](https://support.torproject.org/misc/bug-or-feedback/).
+- Open an issue in the [UX Research Repository](https://gitlab.torproject.org/tpo/ux/research/-/issues).
+- Subscribe to the [UX mailing list](https://lists.torproject.org/cgi-bin/mailman/listinfo).
+- Learn more about our users by reading [Tor's user personas](https://community.torproject.org/user-research/persona).
+---
+color: primary
+---
+html: two-columns-page.html
+---
+image: eye
+---
+key: 5
+---
+section: user research
+---
+section_id: user research
+---
+subtitle: We care about privacy and security.
diff --git a/content/user-research/open/contents.lr b/content/user-research/open/contents.lr
index 813cde3..91d34df 100644
--- a/content/user-research/open/contents.lr
+++ b/content/user-research/open/contents.lr
@@ -18,7 +18,8 @@ html: two-columns-page.html
---
body:
-These are our current needs for testing Tor products, as well as methodologies and testing scripts. Before running Tor user research, be sure you read our [Guidelines to becoming a user researcher with Tor](https://community.torproject.org/user-research/guidelines).
+These are our current needs for testing Tor products, as well as methodologies and testing scripts.
+Before running Tor user research, be sure you read our [Guidelines to becoming a user researcher with Tor](https://community.torproject.org/user-research/guidelines).
### Tor Browser for Desktop
* [Tor Browser Usage](https://gitlab.torproject.org/tpo/ux/research/-/blob/master/scripts%…
@@ -33,21 +34,3 @@ These are our current needs for testing Tor products, as well as methodologies a
### Emma
* [Run Emma Network Test](https://gitlab.torproject.org/tpo/ux/research/-/blob/master/scripts%2…
-
-### Other Research
-* [Censored Continent: Understanding the use of tools during Internet censorship in Africa: Cameroon, Nigeria, Uganda and Zimbabwe as case studies.](https://research.torproject.org/techreports/icfp-censored-contine…
-
-
-## Past User Research
-We’re committed to open design, so you can see the user research we’ve conducted in the global-south. If you want to run user research with us, please [get in touch.](https://lists.torproject.org/cgi-bin/mailman/listinfo/ux)
-
-| Project | Methodology | Locations | Dates | Reporting |
-| -------- | ----------- | --------- | --------- | ----- |
-| Discovery: Get Bridges | User Discovery ([.md](https://gitlab.torproject.org/tpo/ux/research/-/blob/master/scripts%20and%20activities/2020/discovery-bridges.md)) | Online | Q420, Q121 | [.pdf](https://gitlab.torproject.org/tpo/ux/research/-/blob/master/reports/2021/User_Research_-_Bridges.pdf) |
-| Tor Users Demographics | Survey ([.md](https://gitlab.torproject.org/tpo/ux/research/-/blob/master/scripts%20and%20activities/2020/user_demographics-en.md)) | Online | 2020 | n/a |
-| User Research: Security Settings | Usability testing ([.pdf](https://gitlab.torproject.org/tpo/ux/research/-/blob/master/scripts%20and%20activities/2019/2.Tor_Browser_Desktop_-_Security_Settings.pdf)) | Multiple locations | 2019 | n/a |
-| Tor Launcher | Usability testing ([.pdf](https://gitlab.torproject.org/tpo/ux/research/-/blob/master/scripts%20and%20activities/2018/1.India_User_testing_Tor_Launcher_Test.pdf)) | Mumbai(IN) | Q118 | .pdf |
-| Onion Security Indicator | Usability testing ([.pdf](https://gitlab.torproject.org/tpo/ux/research/-/blob/master/scripts%20and%20activities/2018/2.User_testing_.onion_states_Test.pdf)) | Mumbai(IN), Kampala(UG), Valencia(ES), Mombasa(KE)| Q118, Q218 | [.pdf](https://gitlab.torproject.org/tpo/ux/research/-/blob/master/reports/2018/ur_kenya_2018_Feature_report__Onions_and_Circuit_Display.pdf) |
-| TB Circuit Display | Usability testing ([.pdf](https://gitlab.torproject.org/tpo/ux/research/-/blob/master/scripts%20and%20activities/2018/3.User_testing_circuit_display_Test.pdf)) | Kampala(UG), Nairobi(KE), Mombasa(KE) | Q118, Q218 | [.pdf](https://gitlab.torproject.org/tpo/ux/research/-/blob/master/reports/2018/ur_kenya_2018_Feature_report__Onions_and_Circuit_Display.pdf) |
-| Tor Browser for Desktop | User needs discovery ([.pdf](https://gitlab.torproject.org/tpo/ux/research/-/blob/master/scripts%20and%20activities/2018/4.00_user_needs_discovery.pdf)) | Bogotá(CL), Cali(CL), Valle del Cauca(CL), Kampala(UG), Hoima(UG), Nairobi(KE) | 2018 | [.pdf](https://gitlab.torproject.org/tpo/ux/research/-/blob/master/reports/2018/ur_colombia_2018_report_tbb-tba.pdf) |
-| Tor Browser for Android | User needs discovery ([.pdf](https://gitlab.torproject.org/tpo/ux/research/-/blob/master/scripts%20and%20activities/2018/4.00_user_needs_discovery.pdf)) | Bogotá(CL), Cali(CL), Valle del Cauca(CL), Kampala(UG), Hoima(UG), Nairobi(KE) | 2018 | [.pdf](https://gitlab.torproject.org/tpo/ux/research/-/blob/master/reports/2018/ur_colombia_2018_report_tbb-tba.pdf) |
diff --git a/content/user-research/persona/contents.lr b/content/user-research/persona/contents.lr
index 147cee9..33efd66 100644
--- a/content/user-research/persona/contents.lr
+++ b/content/user-research/persona/contents.lr
@@ -15,13 +15,14 @@ key: 4
html: two-columns-page.html
---
body:
+
Persona is a tool that represents the needs, thoughts, and goals of the target user. We created personas because they help us to drive human-centered design processes.
As part of our global south travels during 2018 and 2019, we got the lucky chance to meet a lot of different Tor users: from activists to journalists, all of them with different motivations, but demanding a usable private and secure tool to access the Internet.
With the Community Team, we have been working collecting and mapping real user stories and finding patterns across them. It is how our Personas emerged from our in field research.
### Tor Personas
-* [Jelani, the human rights defender](https://dip.torproject.org/torproject/ux/research/tree/master/per…
-* [Aleisha, the privacy looker](https://dip.torproject.org/torproject/ux/research/tree/master/perso…
-* [Fernanda, the feminist activist](https://dip.torproject.org/torproject/ux/research/tree/master/per…
-* [Fatima, the censored user](https://dip.torproject.org/torproject/ux/research/tree/master/persona…
-* [Alex, the fearless journalist](https://dip.torproject.org/torproject/ux/research/tree/master/p…
+* Jelani, the human rights defender: [View on Gitlab](https://gitlab.torproject.org/tpo/ux/research/-/blob/master/persona… · [Download PDF](https://gitlab.torproject.org/tpo/ux/research/-/raw/master/persona/jel…
+* Aleisha, the privacy looker: [View on Gitlab](https://gitlab.torproject.org/tpo/ux/research/-/blob/master/persona… · [Download PDF](https://gitlab.torproject.org/tpo/ux/research/-/raw/master/persona/ale…
+* Fernanda, the feminist activist: [View on Gitlab](https://gitlab.torproject.org/tpo/ux/research/-/blob/master/persona… · [Download PDF](https://gitlab.torproject.org/tpo/ux/research/-/raw/master/persona/fer…
+* Fatima, the censored user: [View on Gitlab](https://gitlab.torproject.org/tpo/ux/research/-/blob/master/persona… · [Download PDF](https://gitlab.torproject.org/tpo/ux/research/-/raw/master/persona/fat…
+* Alex, the fearless journalist: [View on Gitlab](https://gitlab.torproject.org/tpo/ux/research/-/blob/master/persona… · [Download PDF](https://gitlab.torproject.org/tpo/ux/research/-/raw/master/persona/ale…
diff --git a/content/user-research/reports/contents.lr b/content/user-research/reports/contents.lr
new file mode 100644
index 0000000..c03b651
--- /dev/null
+++ b/content/user-research/reports/contents.lr
@@ -0,0 +1,36 @@
+section: user research
+---
+section_id: user-research
+---
+color: primary
+---
+image: eye
+---
+_template: layout.html
+---
+title: Reports
+---
+subtitle: We are committed to open design, so you can see the user research we have conducted within our community.
+---
+key: 5
+---
+html: two-columns-page.html
+---
+body:
+
+We are committed to open design, so you can see the user research we have conducted in the global-south. If you want to run user research with us, please [get in touch.](https://lists.torproject.org/cgi-bin/mailman/listinfo/ux)
+
+
+| Project | Methodology | Locations | Dates | Reporting |
+| -------- | ----------- | --------- | --------- | ----- |
+| Discovery: Get Bridges | User Discovery ([.md](https://gitlab.torproject.org/tpo/ux/research/-/blob/master/scripts%20and%20activities/2020/discovery-bridges.md)) | Online | Q420, Q121 | [.pdf](https://gitlab.torproject.org/tpo/ux/research/-/blob/master/reports/2021/User_Research_-_Bridges.pdf) |
+| Tor Users Demographics | Survey ([.md](https://gitlab.torproject.org/tpo/ux/research/-/blob/master/scripts%20and%20activities/2020/user_demographics-en.md)) | Online | 2020 | n/a |
+| User Research: Security Settings | Usability testing ([.pdf](https://gitlab.torproject.org/tpo/ux/research/-/blob/master/scripts%20and%20activities/2019/2.Tor_Browser_Desktop_-_Security_Settings.pdf)) | Multiple locations | 2019 | n/a |
+| Tor Launcher | Usability testing ([.pdf](https://gitlab.torproject.org/tpo/ux/research/-/blob/master/scripts%20and%20activities/2018/1.India_User_testing_Tor_Launcher_Test.pdf)) | Mumbai(IN) | Q118 | .pdf |
+| Onion Security Indicator | Usability testing ([.pdf](https://gitlab.torproject.org/tpo/ux/research/-/blob/master/scripts%20and%20activities/2018/2.User_testing_.onion_states_Test.pdf)) | Mumbai(IN), Kampala(UG), Valencia(ES), Mombasa(KE)| Q118, Q218 | [.pdf](https://gitlab.torproject.org/tpo/ux/research/-/blob/master/reports/2018/ur_kenya_2018_Feature_report__Onions_and_Circuit_Display.pdf) |
+| TB Circuit Display | Usability testing ([.pdf](https://gitlab.torproject.org/tpo/ux/research/-/blob/master/scripts%20and%20activities/2018/3.User_testing_circuit_display_Test.pdf)) | Kampala(UG), Nairobi(KE), Mombasa(KE) | Q118, Q218 | [.pdf](https://gitlab.torproject.org/tpo/ux/research/-/blob/master/reports/2018/ur_kenya_2018_Feature_report__Onions_and_Circuit_Display.pdf) |
+| Tor Browser for Desktop | User needs discovery ([.pdf](https://gitlab.torproject.org/tpo/ux/research/-/blob/master/scripts%20and%20activities/2018/4.00_user_needs_discovery.pdf)) | Bogotá(CL), Cali(CL), Valle del Cauca(CL), Kampala(UG), Hoima(UG), Nairobi(KE) | 2018 | [.pdf](https://gitlab.torproject.org/tpo/ux/research/-/blob/master/reports/2018/ur_colombia_2018_report_tbb-tba.pdf) |
+| Tor Browser for Android | User needs discovery ([.pdf](https://gitlab.torproject.org/tpo/ux/research/-/blob/master/scripts%20and%20activities/2018/4.00_user_needs_discovery.pdf)) | Bogotá(CL), Cali(CL), Valle del Cauca(CL), Kampala(UG), Hoima(UG), Nairobi(KE) | 2018 | [.pdf](https://gitlab.torproject.org/tpo/ux/research/-/blob/master/reports/2018/ur_colombia_2018_report_tbb-tba.pdf) |
+
+### Community Research
+* [Censored Continent - Understanding the use of tools during Internet censorship in Africa](https://research.torproject.org/techreports/icfp-censored-continent…: Cameroon, Nigeria, Uganda and Zimbabwe as case studies.