[tor-commits] [translation/tor-messenger-otrproperties] Update translations for tor-messenger-otrproperties

2018-02-07 Thread translation
commit 9fa2105d2c273abb65eb056e8e07bb293a42f35f
Author: Translation commit bot 
Date:   Thu Feb 8 05:19:41 2018 +

Update translations for tor-messenger-otrproperties
---
 pt_BR/otr.properties | 22 +++---
 1 file changed, 11 insertions(+), 11 deletions(-)

diff --git a/pt_BR/otr.properties b/pt_BR/otr.properties
index 42a8ac3f6..938bfb233 100644
--- a/pt_BR/otr.properties
+++ b/pt_BR/otr.properties
@@ -3,29 +3,29 @@ msgevent.encryption_required_part2=Tentado iniciar uma 
conversa privada. A sua m
 msgevent.encryption_error=Ocorreu um erro ao criptografar a mensagem. Esta 
não foi enviada.
 msgevent.connection_ended=%S já finalizou a conexão privada com você. A sua 
mensagem não foi enviada. Você pode fechar sua conversa privada ou 
reiniciá-la.
 msgevent.setup_error=Ocorreu um erro ao estabelecer uma conversa privada com 

-msgevent.msg_reflected=Você está recebendo as suas próprias mensagens OTR. 
Ou bem você está tentando conversar consigo mesma, ou bem alguém está 
reenviando-lhe as suas mensagens.
+msgevent.msg_reflected=Você está recebendo suas próprias mensagens OTR. Ou 
você está tentando conversar consigo mesma/o, ou alguém está lhe reenviando 
suas mensagens.
 msgevent.msg_resent=A última mensagem para %S foi reenviada.
 msgevent.rcvdmsg_not_private=A mensagem criptografada, recebida de %S, é 
ilegível, pois você a sua comunicação não é privada nesse momento. 
 msgevent.rcvdmsg_unreadable=Nós recebemos uma mensagem criptografada 
ilegível de %S.
 msgevent.rcvdmsg_malformed=Nós recebemos uma mensagem de %S com dados 
malformados.
 msgevent.log_heartbeat_rcvd=Pulso recebido de %S.
 msgevent.log_heartbeat_sent=Pulso enviado para %S.
-msgevent.rcvdmsg_general_err=Ocorreu um erro OTR.
-msgevent.rcvdmsg_unecrypted=A seguinte mensage, recebida de %S, não está 
criptografada: %S
+msgevent.rcvdmsg_general_err=Ocorreu um erro no OTR.
+msgevent.rcvdmsg_unecrypted=A seguinte mensagem recebida de %S não foi 
criptografada: %S
 msgevent.rcvdmsg_unrecognized=Recebemos uma mensagem OTR não-reconhecida de 
%S. 
 msgevent.rcvdmsg_for_other_instance=%S enviou uma mensagem destinada a uma 
sessão diferente. Se você estiver logado várias vezes, outra sessão pode 
ter recebido a mensagem.
 context.gone_secure_private=A conversa privada com %S iniciou.
-context.gone_secure_unverified=A conversa privada com %S iniciou. Porém, a 
identidade dessa pessoa não foi verificada.
+context.gone_secure_unverified=A conversa privada com %S iniciou. Porém a 
identidade dessa pessoa não foi verificada.
 context.still_secure=Atualizada com sucesso a conversa privada com %S.
 error.enc=Ocorreu um erro ao criptografar a mensagem.
 error.not_priv=Você enviou dados criptografados para %S, que não esperava 
por isso.
 error.unreadable=Você transmitiu uma mensagem criptografada ilegível.
-error.malformed=Você transmitiu uma mensagem de dados malformado.
+error.malformed=Você transmitiu uma mensagem de dados malformada.
 resent=[reenviar]
 tlv.disconnected=%S terminou a conversa privada com você. Você deve fazer o 
mesmo.
-query.msg=%S solicitou uma conversa privada sem gravação. No entanto, você 
não tem um plugin para suportar isso. Veja http://otr.cypherpunks.ca/ para 
mais informações.
-trust.unused=Não utilizad
-trust.not_private=Não Privado
-trust.unverified=Não verificado
-trust.private=Privado
-trust.finished=Terminado
+query.msg=%S solicitou uma conversa privada OTR. No entanto, você não tem um 
plugin para suportar isso. Veja http://otr.cypherpunks.ca/ para mais 
informações.
+trust.unused=Não Utilizada
+trust.not_private=Não Privada
+trust.unverified=Não Verificada
+trust.private=Privada
+trust.finished=Terminada

___
tor-commits mailing list
tor-commits@lists.torproject.org
https://lists.torproject.org/cgi-bin/mailman/listinfo/tor-commits


[tor-commits] [translation/tor-messenger-otrproperties_completed] Update translations for tor-messenger-otrproperties_completed

2018-02-07 Thread translation
commit c9845b4f976c05487a4b947587350100d6854c93
Author: Translation commit bot 
Date:   Thu Feb 8 05:19:47 2018 +

Update translations for tor-messenger-otrproperties_completed
---
 pt_BR/otr.properties | 22 +++---
 1 file changed, 11 insertions(+), 11 deletions(-)

diff --git a/pt_BR/otr.properties b/pt_BR/otr.properties
index 42a8ac3f6..938bfb233 100644
--- a/pt_BR/otr.properties
+++ b/pt_BR/otr.properties
@@ -3,29 +3,29 @@ msgevent.encryption_required_part2=Tentado iniciar uma 
conversa privada. A sua m
 msgevent.encryption_error=Ocorreu um erro ao criptografar a mensagem. Esta 
não foi enviada.
 msgevent.connection_ended=%S já finalizou a conexão privada com você. A sua 
mensagem não foi enviada. Você pode fechar sua conversa privada ou 
reiniciá-la.
 msgevent.setup_error=Ocorreu um erro ao estabelecer uma conversa privada com 

-msgevent.msg_reflected=Você está recebendo as suas próprias mensagens OTR. 
Ou bem você está tentando conversar consigo mesma, ou bem alguém está 
reenviando-lhe as suas mensagens.
+msgevent.msg_reflected=Você está recebendo suas próprias mensagens OTR. Ou 
você está tentando conversar consigo mesma/o, ou alguém está lhe reenviando 
suas mensagens.
 msgevent.msg_resent=A última mensagem para %S foi reenviada.
 msgevent.rcvdmsg_not_private=A mensagem criptografada, recebida de %S, é 
ilegível, pois você a sua comunicação não é privada nesse momento. 
 msgevent.rcvdmsg_unreadable=Nós recebemos uma mensagem criptografada 
ilegível de %S.
 msgevent.rcvdmsg_malformed=Nós recebemos uma mensagem de %S com dados 
malformados.
 msgevent.log_heartbeat_rcvd=Pulso recebido de %S.
 msgevent.log_heartbeat_sent=Pulso enviado para %S.
-msgevent.rcvdmsg_general_err=Ocorreu um erro OTR.
-msgevent.rcvdmsg_unecrypted=A seguinte mensage, recebida de %S, não está 
criptografada: %S
+msgevent.rcvdmsg_general_err=Ocorreu um erro no OTR.
+msgevent.rcvdmsg_unecrypted=A seguinte mensagem recebida de %S não foi 
criptografada: %S
 msgevent.rcvdmsg_unrecognized=Recebemos uma mensagem OTR não-reconhecida de 
%S. 
 msgevent.rcvdmsg_for_other_instance=%S enviou uma mensagem destinada a uma 
sessão diferente. Se você estiver logado várias vezes, outra sessão pode 
ter recebido a mensagem.
 context.gone_secure_private=A conversa privada com %S iniciou.
-context.gone_secure_unverified=A conversa privada com %S iniciou. Porém, a 
identidade dessa pessoa não foi verificada.
+context.gone_secure_unverified=A conversa privada com %S iniciou. Porém a 
identidade dessa pessoa não foi verificada.
 context.still_secure=Atualizada com sucesso a conversa privada com %S.
 error.enc=Ocorreu um erro ao criptografar a mensagem.
 error.not_priv=Você enviou dados criptografados para %S, que não esperava 
por isso.
 error.unreadable=Você transmitiu uma mensagem criptografada ilegível.
-error.malformed=Você transmitiu uma mensagem de dados malformado.
+error.malformed=Você transmitiu uma mensagem de dados malformada.
 resent=[reenviar]
 tlv.disconnected=%S terminou a conversa privada com você. Você deve fazer o 
mesmo.
-query.msg=%S solicitou uma conversa privada sem gravação. No entanto, você 
não tem um plugin para suportar isso. Veja http://otr.cypherpunks.ca/ para 
mais informações.
-trust.unused=Não utilizad
-trust.not_private=Não Privado
-trust.unverified=Não verificado
-trust.private=Privado
-trust.finished=Terminado
+query.msg=%S solicitou uma conversa privada OTR. No entanto, você não tem um 
plugin para suportar isso. Veja http://otr.cypherpunks.ca/ para mais 
informações.
+trust.unused=Não Utilizada
+trust.not_private=Não Privada
+trust.unverified=Não Verificada
+trust.private=Privada
+trust.finished=Terminada

___
tor-commits mailing list
tor-commits@lists.torproject.org
https://lists.torproject.org/cgi-bin/mailman/listinfo/tor-commits


[tor-commits] [translation/tor-messenger-otrproperties_completed] Update translations for tor-messenger-otrproperties_completed

2018-02-07 Thread translation
commit ca04f3f66d94f7774fdcc12ff5537ebf6509c0cb
Author: Translation commit bot 
Date:   Thu Feb 8 04:49:50 2018 +

Update translations for tor-messenger-otrproperties_completed
---
 pt_BR/otr.properties | 2 +-
 1 file changed, 1 insertion(+), 1 deletion(-)

diff --git a/pt_BR/otr.properties b/pt_BR/otr.properties
index bb9d037bb..42a8ac3f6 100644
--- a/pt_BR/otr.properties
+++ b/pt_BR/otr.properties
@@ -1,7 +1,7 @@
 msgevent.encryption_required_part1=Você tentou enviar uma mensagem 
não-criptografada para %S. Em regra, mensagens não-criptografadas são 
interditas.
 msgevent.encryption_required_part2=Tentado iniciar uma conversa privada. A sua 
mensagem será retransmitida quando a conversa privada começar.
 msgevent.encryption_error=Ocorreu um erro ao criptografar a mensagem. Esta 
não foi enviada.
-msgevent.connection_ended=%S finalizou a conexão privada com você. A sua 
mensagem não foi enviada. Você pode fechar a conversa privada ou reiniciá-la.
+msgevent.connection_ended=%S já finalizou a conexão privada com você. A sua 
mensagem não foi enviada. Você pode fechar sua conversa privada ou 
reiniciá-la.
 msgevent.setup_error=Ocorreu um erro ao estabelecer uma conversa privada com 

 msgevent.msg_reflected=Você está recebendo as suas próprias mensagens OTR. 
Ou bem você está tentando conversar consigo mesma, ou bem alguém está 
reenviando-lhe as suas mensagens.
 msgevent.msg_resent=A última mensagem para %S foi reenviada.

___
tor-commits mailing list
tor-commits@lists.torproject.org
https://lists.torproject.org/cgi-bin/mailman/listinfo/tor-commits


[tor-commits] [translation/tor-messenger-otrproperties] Update translations for tor-messenger-otrproperties

2018-02-07 Thread translation
commit 78c0b3a9b926ddf38afdd08a7d294a1024f470fc
Author: Translation commit bot 
Date:   Thu Feb 8 04:49:44 2018 +

Update translations for tor-messenger-otrproperties
---
 pt_BR/otr.properties | 2 +-
 1 file changed, 1 insertion(+), 1 deletion(-)

diff --git a/pt_BR/otr.properties b/pt_BR/otr.properties
index bb9d037bb..42a8ac3f6 100644
--- a/pt_BR/otr.properties
+++ b/pt_BR/otr.properties
@@ -1,7 +1,7 @@
 msgevent.encryption_required_part1=Você tentou enviar uma mensagem 
não-criptografada para %S. Em regra, mensagens não-criptografadas são 
interditas.
 msgevent.encryption_required_part2=Tentado iniciar uma conversa privada. A sua 
mensagem será retransmitida quando a conversa privada começar.
 msgevent.encryption_error=Ocorreu um erro ao criptografar a mensagem. Esta 
não foi enviada.
-msgevent.connection_ended=%S finalizou a conexão privada com você. A sua 
mensagem não foi enviada. Você pode fechar a conversa privada ou reiniciá-la.
+msgevent.connection_ended=%S já finalizou a conexão privada com você. A sua 
mensagem não foi enviada. Você pode fechar sua conversa privada ou 
reiniciá-la.
 msgevent.setup_error=Ocorreu um erro ao estabelecer uma conversa privada com 

 msgevent.msg_reflected=Você está recebendo as suas próprias mensagens OTR. 
Ou bem você está tentando conversar consigo mesma, ou bem alguém está 
reenviando-lhe as suas mensagens.
 msgevent.msg_resent=A última mensagem para %S foi reenviada.

___
tor-commits mailing list
tor-commits@lists.torproject.org
https://lists.torproject.org/cgi-bin/mailman/listinfo/tor-commits


[tor-commits] [translation/tor-messenger-authdtd_completed] Update translations for tor-messenger-authdtd_completed

2018-02-07 Thread translation
commit d68696d4de06bcb75ed1ba1425344af23f533c6e
Author: Translation commit bot 
Date:   Thu Feb 8 04:49:21 2018 +

Update translations for tor-messenger-authdtd_completed
---
 pt_BR/auth.dtd | 12 ++--
 1 file changed, 6 insertions(+), 6 deletions(-)

diff --git a/pt_BR/auth.dtd b/pt_BR/auth.dtd
index fbf4948ef..9ef9ad456 100644
--- a/pt_BR/auth.dtd
+++ b/pt_BR/auth.dtd
@@ -7,15 +7,15 @@
 
 
 
-
+
 
 
-
+
 
-
-
-
+
+
+
 
-
+
 
 
\ No newline at end of file

___
tor-commits mailing list
tor-commits@lists.torproject.org
https://lists.torproject.org/cgi-bin/mailman/listinfo/tor-commits


[tor-commits] [translation/tor-messenger-authdtd] Update translations for tor-messenger-authdtd

2018-02-07 Thread translation
commit 01592401fcbc59e1c935d10c2273bdb0d092e2b4
Author: Translation commit bot 
Date:   Thu Feb 8 04:49:16 2018 +

Update translations for tor-messenger-authdtd
---
 pt_BR/auth.dtd | 12 ++--
 1 file changed, 6 insertions(+), 6 deletions(-)

diff --git a/pt_BR/auth.dtd b/pt_BR/auth.dtd
index fbf4948ef..9ef9ad456 100644
--- a/pt_BR/auth.dtd
+++ b/pt_BR/auth.dtd
@@ -7,15 +7,15 @@
 
 
 
-
+
 
 
-
+
 
-
-
-
+
+
+
 
-
+
 
 
\ No newline at end of file

___
tor-commits mailing list
tor-commits@lists.torproject.org
https://lists.torproject.org/cgi-bin/mailman/listinfo/tor-commits


[tor-commits] [translation/tor-messenger-authdtd_completed] Update translations for tor-messenger-authdtd_completed

2018-02-07 Thread translation
commit f99b091180b2526849848ce1550bb28bb050feee
Author: Translation commit bot 
Date:   Thu Feb 8 04:19:26 2018 +

Update translations for tor-messenger-authdtd_completed
---
 pt_BR/auth.dtd | 2 +-
 1 file changed, 1 insertion(+), 1 deletion(-)

diff --git a/pt_BR/auth.dtd b/pt_BR/auth.dtd
index 7018f946b..fbf4948ef 100644
--- a/pt_BR/auth.dtd
+++ b/pt_BR/auth.dtd
@@ -4,7 +4,7 @@
 
 
 
-
+
 
 
 

___
tor-commits mailing list
tor-commits@lists.torproject.org
https://lists.torproject.org/cgi-bin/mailman/listinfo/tor-commits


[tor-commits] [translation/tor-messenger-authdtd] Update translations for tor-messenger-authdtd

2018-02-07 Thread translation
commit 9bb47ee55704f92c8a6aa2c69ef7e6fda764a6e6
Author: Translation commit bot 
Date:   Thu Feb 8 04:19:20 2018 +

Update translations for tor-messenger-authdtd
---
 pt_BR/auth.dtd | 2 +-
 1 file changed, 1 insertion(+), 1 deletion(-)

diff --git a/pt_BR/auth.dtd b/pt_BR/auth.dtd
index 7018f946b..fbf4948ef 100644
--- a/pt_BR/auth.dtd
+++ b/pt_BR/auth.dtd
@@ -4,7 +4,7 @@
 
 
 
-
+
 
 
 

___
tor-commits mailing list
tor-commits@lists.torproject.org
https://lists.torproject.org/cgi-bin/mailman/listinfo/tor-commits


[tor-commits] [translation/tor_animation_completed] Update translations for tor_animation_completed

2018-02-07 Thread translation
commit 1d111ba13d5f5757ff90fcb5ba99d323e30daf14
Author: Translation commit bot 
Date:   Thu Feb 8 04:18:30 2018 +

Update translations for tor_animation_completed
---
 pt_BR.srt | 10 +-
 1 file changed, 5 insertions(+), 5 deletions(-)

diff --git a/pt_BR.srt b/pt_BR.srt
index 68baade20..79fdb6228 100644
--- a/pt_BR.srt
+++ b/pt_BR.srt
@@ -79,8 +79,8 @@ Tor também protege nossos dados
 
 18
 00:00:58,400 --> 00:01:01,900
-contra espionagem individual  feita por corporações  e governos
-e vigilância em massa.
+contra a espionagem de corporações e governos, direcionada
+ou em massa.
 
 19
 00:01:02,880 --> 00:01:07,340
@@ -109,7 +109,7 @@ mais forte ela fica
 
 24
 00:01:23,140 --> 00:01:27,800
-pois é mais fácil se esconder em uma multidão
+já que é mais fácil se esconder em uma multidão
 de pessoas que parecem idênticas.
 
 25
@@ -124,8 +124,8 @@ se o censor sabe o que você faz
 
 27
 00:01:36,540 --> 00:01:39,440
-Os anúncios de publicidade não  acompanharão você
-em todos os lugares durante meses,
+As publicidades não vão te seguir
+por toda a parte durante meses,
 
 28
 00:01:39,640 --> 00:01:41,300

___
tor-commits mailing list
tor-commits@lists.torproject.org
https://lists.torproject.org/cgi-bin/mailman/listinfo/tor-commits


[tor-commits] [translation/tor_animation] Update translations for tor_animation

2018-02-07 Thread translation
commit 71636f83a2775f24784b8dbb68da7b8351bd1cab
Author: Translation commit bot 
Date:   Thu Feb 8 04:18:24 2018 +

Update translations for tor_animation
---
 pt_BR.srt | 10 +-
 1 file changed, 5 insertions(+), 5 deletions(-)

diff --git a/pt_BR.srt b/pt_BR.srt
index 68baade20..79fdb6228 100644
--- a/pt_BR.srt
+++ b/pt_BR.srt
@@ -79,8 +79,8 @@ Tor também protege nossos dados
 
 18
 00:00:58,400 --> 00:01:01,900
-contra espionagem individual  feita por corporações  e governos
-e vigilância em massa.
+contra a espionagem de corporações e governos, direcionada
+ou em massa.
 
 19
 00:01:02,880 --> 00:01:07,340
@@ -109,7 +109,7 @@ mais forte ela fica
 
 24
 00:01:23,140 --> 00:01:27,800
-pois é mais fácil se esconder em uma multidão
+já que é mais fácil se esconder em uma multidão
 de pessoas que parecem idênticas.
 
 25
@@ -124,8 +124,8 @@ se o censor sabe o que você faz
 
 27
 00:01:36,540 --> 00:01:39,440
-Os anúncios de publicidade não  acompanharão você
-em todos os lugares durante meses,
+As publicidades não vão te seguir
+por toda a parte durante meses,
 
 28
 00:01:39,640 --> 00:01:41,300

___
tor-commits mailing list
tor-commits@lists.torproject.org
https://lists.torproject.org/cgi-bin/mailman/listinfo/tor-commits


[tor-commits] [translation/tor_animation] Update translations for tor_animation

2018-02-07 Thread translation
commit 0e987528fc0ae1caeab73f89499edc8985a2fe43
Author: Translation commit bot 
Date:   Thu Feb 8 03:48:28 2018 +

Update translations for tor_animation
---
 pt_BR.srt | 2 +-
 1 file changed, 1 insertion(+), 1 deletion(-)

diff --git a/pt_BR.srt b/pt_BR.srt
index d58d43c45..68baade20 100644
--- a/pt_BR.srt
+++ b/pt_BR.srt
@@ -46,7 +46,7 @@ compartilhar com pessoas desconhecidas,
 
 11
 00:00:31,700 --> 00:00:34,000
-que poderiam facilmente usar essas informações
+que poderiam facilmente usar esses dados
 pra se aproveitar de você.
 
 12

___
tor-commits mailing list
tor-commits@lists.torproject.org
https://lists.torproject.org/cgi-bin/mailman/listinfo/tor-commits


[tor-commits] [translation/tor_animation_completed] Update translations for tor_animation_completed

2018-02-07 Thread translation
commit 686d35a0ae5c131e72866e159cdb8cebd72e6364
Author: Translation commit bot 
Date:   Thu Feb 8 03:48:33 2018 +

Update translations for tor_animation_completed
---
 pt_BR.srt | 2 +-
 1 file changed, 1 insertion(+), 1 deletion(-)

diff --git a/pt_BR.srt b/pt_BR.srt
index d58d43c45..68baade20 100644
--- a/pt_BR.srt
+++ b/pt_BR.srt
@@ -46,7 +46,7 @@ compartilhar com pessoas desconhecidas,
 
 11
 00:00:31,700 --> 00:00:34,000
-que poderiam facilmente usar essas informações
+que poderiam facilmente usar esses dados
 pra se aproveitar de você.
 
 12

___
tor-commits mailing list
tor-commits@lists.torproject.org
https://lists.torproject.org/cgi-bin/mailman/listinfo/tor-commits


[tor-commits] [translation/tor_animation] Update translations for tor_animation

2018-02-07 Thread translation
commit 92fd5d69fff6478706b4d0712398105b6eae7403
Author: Translation commit bot 
Date:   Thu Feb 8 03:18:35 2018 +

Update translations for tor_animation
---
 pt_BR.srt | 4 ++--
 1 file changed, 2 insertions(+), 2 deletions(-)

diff --git a/pt_BR.srt b/pt_BR.srt
index b424708f6..d58d43c45 100644
--- a/pt_BR.srt
+++ b/pt_BR.srt
@@ -46,8 +46,8 @@ compartilhar com pessoas desconhecidas,
 
 11
 00:00:31,700 --> 00:00:34,000
-que poderiam usar essa informações
-para fins alheios à sua vontade.
+que poderiam facilmente usar essas informações
+pra se aproveitar de você.
 
 12
 00:00:34,500 --> 00:00:37,000

___
tor-commits mailing list
tor-commits@lists.torproject.org
https://lists.torproject.org/cgi-bin/mailman/listinfo/tor-commits


[tor-commits] [translation/tor_animation_completed] Update translations for tor_animation_completed

2018-02-07 Thread translation
commit eaf90fa025252a16a16aee18282a95d50c7626e7
Author: Translation commit bot 
Date:   Thu Feb 8 03:18:41 2018 +

Update translations for tor_animation_completed
---
 pt_BR.srt | 4 ++--
 1 file changed, 2 insertions(+), 2 deletions(-)

diff --git a/pt_BR.srt b/pt_BR.srt
index b424708f6..d58d43c45 100644
--- a/pt_BR.srt
+++ b/pt_BR.srt
@@ -46,8 +46,8 @@ compartilhar com pessoas desconhecidas,
 
 11
 00:00:31,700 --> 00:00:34,000
-que poderiam usar essa informações
-para fins alheios à sua vontade.
+que poderiam facilmente usar essas informações
+pra se aproveitar de você.
 
 12
 00:00:34,500 --> 00:00:37,000

___
tor-commits mailing list
tor-commits@lists.torproject.org
https://lists.torproject.org/cgi-bin/mailman/listinfo/tor-commits


[tor-commits] [stem/master] Validate address before connecting

2018-02-07 Thread atagar
commit 801ceb20f5cb113253d88956fac9a9501ce2521e
Author: Damian Johnson 
Date:   Wed Feb 7 12:27:43 2018 -0800

Validate address before connecting

Oops, the Address constructor indeed validates addresses *but* it was called
after we established a socket. As such our integ tests failed with...

  ==
  ERROR: test_invalid_arguments
  --
  Traceback (most recent call last):
File 
"/srv/jenkins-workspace/workspace/stem-tor-ci/test/integ/client/connection.py", 
line 20, in test_invalid_arguments
  self.assertRaisesRegexp(ValueError, "'nope' isn't an IPv4 or IPv6 
address", Relay.connect, 'nope', 80)
File 
"/srv/jenkins-workspace/workspace/stem-tor-ci/stem/util/test_tools.py", line 
278, in assertRaisesRegexp
  return super(original_type, self).assertRaisesRegexp(exc_type, 
exc_msg, func, *args, **kwargs)
File "/usr/lib/python2.7/unittest/case.py", line 993, in 
assertRaisesRegexp
  callable_obj(*args, **kwargs)
File 
"/srv/jenkins-workspace/workspace/stem-tor-ci/stem/client/__init__.py", line 
80, in connect
  conn = stem.socket.RelaySocket(address, port)
File "/srv/jenkins-workspace/workspace/stem-tor-ci/stem/socket.py", 
line 378, in __init__
  self.connect()
File "/srv/jenkins-workspace/workspace/stem-tor-ci/stem/socket.py", 
line 177, in connect
  self._socket = self._make_socket()
File "/srv/jenkins-workspace/workspace/stem-tor-ci/stem/socket.py", 
line 418, in _make_socket
  raise stem.SocketError(exc)
  SocketError: [Errno -2] Name or service not known

  --
---
 stem/client/__init__.py | 4 +++-
 1 file changed, 3 insertions(+), 1 deletion(-)

diff --git a/stem/client/__init__.py b/stem/client/__init__.py
index 2b853baa..340082c7 100644
--- a/stem/client/__init__.py
+++ b/stem/client/__init__.py
@@ -71,6 +71,8 @@ class Relay(object):
   * :class:`stem.SocketError` if we're unable to establish a connection
 """
 
+relay_addr = Address(address)
+
 if not stem.util.connection.is_valid_port(port):
   raise ValueError("'%s' isn't a valid port" % port)
 elif not link_protocols:
@@ -108,7 +110,7 @@ class Relay(object):
 # where it would help.
 
 link_protocol = max(common_protocols)
-conn.send(stem.client.cell.NetinfoCell(Address(address), 
[]).pack(link_protocol))
+conn.send(stem.client.cell.NetinfoCell(relay_addr, []).pack(link_protocol))
 
 return Relay(conn, link_protocol)
 

___
tor-commits mailing list
tor-commits@lists.torproject.org
https://lists.torproject.org/cgi-bin/mailman/listinfo/tor-commits


[tor-commits] [translation/tor-launcher-properties] Update translations for tor-launcher-properties

2018-02-07 Thread translation
commit 3232e9a6e3254fd6dde16a1fde01ccfd50dfb02c
Author: Translation commit bot 
Date:   Wed Feb 7 20:16:35 2018 +

Update translations for tor-launcher-properties
---
 ti/torlauncher.properties | 2 +-
 1 file changed, 1 insertion(+), 1 deletion(-)

diff --git a/ti/torlauncher.properties b/ti/torlauncher.properties
index f8b9e8562..a947a63b9 100644
--- a/ti/torlauncher.properties
+++ b/ti/torlauncher.properties
@@ -33,7 +33,7 @@ torlauncher.bridge_suffix.meek-azure=(works in China)
 
 torlauncher.connect=Connect
 torlauncher.restart_tor=Restart Tor
-torlauncher.quit=Quit
+torlauncher.quit=ኣቋርጽ
 torlauncher.quit_win=ውጻእ
 torlauncher.done=Done
 

___
tor-commits mailing list
tor-commits@lists.torproject.org
https://lists.torproject.org/cgi-bin/mailman/listinfo/tor-commits


[tor-commits] [stem/master] Drop todo note about recognized field

2018-02-07 Thread atagar
commit a50a07da4bccad91e4883c174cd4bfa00a6f49a8
Author: Damian Johnson 
Date:   Wed Feb 7 10:21:25 2018 -0800

Drop todo note about recognized field

Sent a little patch to clarify this field...

  https://trac.torproject.org/projects/tor/ticket/25171
---
 stem/client/cell.py | 9 +
 1 file changed, 1 insertion(+), 8 deletions(-)

diff --git a/stem/client/cell.py b/stem/client/cell.py
index 4ac8d40e..13f14f3c 100644
--- a/stem/client/cell.py
+++ b/stem/client/cell.py
@@ -292,18 +292,11 @@ class RelayCell(CircuitCell):
   :var stem.client.RelayCommand command: command to be issued
   :var int command_int: integer value of our command
   :var bytes data: payload of the cell
-  :var int recognized: zero if endpoint is this hop, non-zero otherwise
+  :var int recognized: zero if cell is decrypted, non-zero otherwise
   :var int digest: running digest held with the relay
   :var int stream_id: specific stream this concerns
   """
 
-  # TODO: Relay cells also have a 'recognized' field but from the spec I really
-  # haven't a clue what the heck it is. The spec makes multiple mentions to
-  # "when the 'recognized' field of a RELAY cell is zero" but no mention to if
-  # it's non-zero or what the field actually is. :/
-  #
-  # For now just leaving it out. I'll file a ticket to ask about it later.
-
   NAME = 'RELAY'
   VALUE = 3
   IS_FIXED_SIZE = True



___
tor-commits mailing list
tor-commits@lists.torproject.org
https://lists.torproject.org/cgi-bin/mailman/listinfo/tor-commits


[tor-commits] [stem/master] Only validate RELAY cells when unencrypted

2018-02-07 Thread atagar
commit 0d0a018d721db77015453d284bb348e7db72cb84
Author: Damian Johnson 
Date:   Wed Feb 7 10:35:59 2018 -0800

Only validate RELAY cells when unencrypted

When the cell is encrypted these fields are obviously essentially noise. In
practice this seems to be causing inconsistent failures roughly 1/10 of the
time...

  Traceback (most recent call last):
File "client-or-stream-raw.py", line 30, in 
  reply = circ.send('RELAY_BEGIN_DIR', stream_id = 1)
File "/home/atagar/Desktop/tor/endosome/stem/client/__init__.py", line 
246, in send
  reply = next(stem.client.cell.Cell.unpack(self.relay._orport.recv(), 
self.relay.link_protocol))
File "/home/atagar/Desktop/tor/endosome/stem/client/cell.py", line 135, 
in unpack
  cell, content = Cell.pop(content, link_protocol)
File "/home/atagar/Desktop/tor/endosome/stem/client/cell.py", line 166, 
in pop
  return cls._unpack(payload, circ_id, link_protocol), content
File "/home/atagar/Desktop/tor/endosome/stem/client/cell.py", line 349, 
in _unpack
  return RelayCell(circ_id, command, data, digest, stream_id, 
recognized)
File "/home/atagar/Desktop/tor/endosome/stem/client/cell.py", line 327, 
in __init__
  raise ValueError('%s relay cells concern the circuit itself and 
cannot have a stream id' % self.command)
  ValueError: RELAY_TRUNCATE relay cells concern the circuit itself and 
cannot have a stream id
---
 stem/client/__init__.py | 4 +---
 stem/client/cell.py | 9 +
 2 files changed, 6 insertions(+), 7 deletions(-)

diff --git a/stem/client/__init__.py b/stem/client/__init__.py
index f4fc718b..2b853baa 100644
--- a/stem/client/__init__.py
+++ b/stem/client/__init__.py
@@ -218,7 +218,7 @@ class Circuit(object):
 self.forward_key = Cipher(algorithms.AES(kdf.forward_key), ctr, 
default_backend()).encryptor()
 self.backward_key = Cipher(algorithms.AES(kdf.backward_key), ctr, 
default_backend()).decryptor()
 
-  def send(self, command, data, stream_id = 0):
+  def send(self, command, data = '', stream_id = 0):
 """
 Sends a message over the circuit.
 
@@ -227,8 +227,6 @@ class Circuit(object):
 :param int stream_id: specific stream this concerns
 """
 
-# TODO: move RelayCommand to this base module?
-
 with self.relay._orport_lock:
   orig_digest = self.forward_digest.copy()
   orig_key = copy.copy(self.forward_key)
diff --git a/stem/client/cell.py b/stem/client/cell.py
index 13f14f3c..c5f8f20b 100644
--- a/stem/client/cell.py
+++ b/stem/client/cell.py
@@ -321,10 +321,11 @@ class RelayCell(CircuitCell):
 self.digest = digest
 self.stream_id = stream_id
 
-if not stream_id and self.command in STREAM_ID_REQUIRED:
-  raise ValueError('%s relay cells require a stream id' % self.command)
-elif stream_id and self.command in STREAM_ID_DISALLOWED:
-  raise ValueError('%s relay cells concern the circuit itself and cannot 
have a stream id' % self.command)
+if digest == 0:
+  if not stream_id and self.command in STREAM_ID_REQUIRED:
+raise ValueError('%s relay cells require a stream id' % self.command)
+  elif stream_id and self.command in STREAM_ID_DISALLOWED:
+raise ValueError('%s relay cells concern the circuit itself and cannot 
have a stream id' % self.command)
 
   def pack(self, link_protocol):
 payload = io.BytesIO()



___
tor-commits mailing list
tor-commits@lists.torproject.org
https://lists.torproject.org/cgi-bin/mailman/listinfo/tor-commits


[tor-commits] [stem/master] Defer address validity check to Address constructor

2018-02-07 Thread atagar
commit c1dc2ec4998d7816161beaa53ff19a2ca8a2564b
Author: Damian Johnson 
Date:   Tue Feb 6 10:35:46 2018 -0800

Defer address validity check to Address constructor

There's no need to do upfront validation of our address since the Address
constructor already does this.
---
 stem/client/__init__.py | 12 ++--
 stem/client/cell.py |  2 --
 stem/client/datatype.py |  2 +-
 test/unit/client/address.py |  2 +-
 4 files changed, 4 insertions(+), 14 deletions(-)

diff --git a/stem/client/__init__.py b/stem/client/__init__.py
index 3f8507e5..b743a0eb 100644
--- a/stem/client/__init__.py
+++ b/stem/client/__init__.py
@@ -34,7 +34,7 @@ import stem.client.cell
 import stem.socket
 import stem.util.connection
 
-from stem.client.datatype import ZERO, AddrType, Address, KDF, split
+from stem.client.datatype import ZERO, Address, KDF, split
 
 __all__ = [
   'cell',
@@ -71,13 +71,6 @@ class Relay(object):
   * :class:`stem.SocketError` if we're unable to establish a connection
 """
 
-if stem.util.connection.is_valid_ipv4_address(address):
-  addr_type = AddrType.IPv4
-elif stem.util.connection.is_valid_ipv6_address(address):
-  addr_type = AddrType.IPv6
-else:
-  raise ValueError("'%s' isn't an IPv4 or IPv6 address" % address)
-
 if not stem.util.connection.is_valid_port(port):
   raise ValueError("'%s' isn't a valid port" % port)
 elif not link_protocols:
@@ -111,10 +104,9 @@ class Relay(object):
   raise stem.SocketError('Unable to find a common link protocol. We 
support %s but %s:%i supports %s.' % (', '.join(link_protocols), address, port, 
', '.join(versions_reply.versions)))
 
 # TODO: we should fill in our address, right?
-# TODO: what happens if we skip the NETINFO?
 
 link_protocol = max(common_protocols)
-conn.send(stem.client.cell.NetinfoCell(Address(address, addr_type), 
[]).pack(link_protocol))
+conn.send(stem.client.cell.NetinfoCell(Address(address), 
[]).pack(link_protocol))
 
 return Relay(conn, link_protocol)
 
diff --git a/stem/client/cell.py b/stem/client/cell.py
index 041e1c39..4ac8d40e 100644
--- a/stem/client/cell.py
+++ b/stem/client/cell.py
@@ -346,8 +346,6 @@ class RelayCell(CircuitCell):
 
   @classmethod
   def _unpack(cls, content, circ_id, link_protocol):
-orig_content = content
-
 command, content = Size.CHAR.pop(content)
 recognized, content = Size.SHORT.pop(content)  # 'recognized' field
 stream_id, content = Size.SHORT.pop(content)
diff --git a/stem/client/datatype.py b/stem/client/datatype.py
index 8b4c8e64..352a643e 100644
--- a/stem/client/datatype.py
+++ b/stem/client/datatype.py
@@ -347,7 +347,7 @@ class Address(Field):
   elif stem.util.connection.is_valid_ipv6_address(value):
 addr_type = AddrType.IPv6
   else:
-raise ValueError('Address type is required unless an IPv4 or IPv6 
address')
+raise ValueError("'%s' isn't an IPv4 or IPv6 address" % value)
 
 self.type, self.type_int = AddrType.get(addr_type)
 
diff --git a/test/unit/client/address.py b/test/unit/client/address.py
index f3da4971..09fcee95 100644
--- a/test/unit/client/address.py
+++ b/test/unit/client/address.py
@@ -44,7 +44,7 @@ class TestAddress(unittest.TestCase):
 
 self.assertRaisesRegexp(ValueError, re.escape("Packed IPv4 addresses 
should be four bytes, but was: '\\x7f\\x00'"), Address, '\x7f\x00', 4)
 self.assertRaisesRegexp(ValueError, re.escape("Packed IPv6 addresses 
should be sixteen bytes, but was: '\\x7f\\x00'"), Address, '\x7f\x00', 6)
-self.assertRaisesRegexp(ValueError, re.escape('Address type is required 
unless an IPv4 or IPv6 address'), Address, 'nope')
+self.assertRaisesRegexp(ValueError, re.escape("'nope' isn't an IPv4 or 
IPv6 address"), Address, 'nope')
 
   def test_unknown_type(self):
 addr = Address('hello', 12)



___
tor-commits mailing list
tor-commits@lists.torproject.org
https://lists.torproject.org/cgi-bin/mailman/listinfo/tor-commits


[tor-commits] [stem/master] Omit our address from NETINFO

2018-02-07 Thread atagar
commit cfadcde5a08af28e2e39eb467c0ba81aace662ef
Author: Damian Johnson 
Date:   Tue Feb 6 11:41:02 2018 -0800

Omit our address from NETINFO

We already weren't providing it so this just adjusts the comment talking 
about
why. There's a few issues...

1. Getting our address with python is clunky. Simplest approach is...

   socket.gethostbyname(socket.gethostname())

   ... but I suspect what we really want is our external address, which I'm
   unsure how best to get.

2. We don't have a usecase at present where it helps. Tor is quite happy to 
not
   receive one, and seems if I provide junk data it's happy to accept that 
too.

For now just opting to exclude it until we have a concrete use case, which 
in
turn will inform if the internal address is acceptable or we must resolve
something else.
---
 stem/client/__init__.py | 4 +++-
 1 file changed, 3 insertions(+), 1 deletion(-)

diff --git a/stem/client/__init__.py b/stem/client/__init__.py
index b743a0eb..f4fc718b 100644
--- a/stem/client/__init__.py
+++ b/stem/client/__init__.py
@@ -103,7 +103,9 @@ class Relay(object):
   conn.close()
   raise stem.SocketError('Unable to find a common link protocol. We 
support %s but %s:%i supports %s.' % (', '.join(link_protocols), address, port, 
', '.join(versions_reply.versions)))
 
-# TODO: we should fill in our address, right?
+# Establishing connections requires sending a NETINFO, but including our
+# address is optional. We can revisit including it when we have a usecase
+# where it would help.
 
 link_protocol = max(common_protocols)
 conn.send(stem.client.cell.NetinfoCell(Address(address), 
[]).pack(link_protocol))



___
tor-commits mailing list
tor-commits@lists.torproject.org
https://lists.torproject.org/cgi-bin/mailman/listinfo/tor-commits


[tor-commits] [stem/master] Building blocks for basic circuit requests

2018-02-07 Thread atagar
commit 79520a8290578d5fd96eaf06c8080f91ace0bddf
Merge: 76e8eb5f 0d0a018d
Author: Damian Johnson 
Date:   Wed Feb 7 11:21:03 2018 -0800

Building blocks for basic circuit requests

Low-level building blocks for circuit requests. This is *not* the API
we'll vend to end users (it's much too raw), but we now have everything
from Endosome [1] we need to download descriptors...

  import stem.client

  with stem.client.Relay.connect('127.0.0.1', 12345, [3]) as relay:
circ = relay.create_circuit()
circ.send('RELAY_BEGIN_DIR', stream_id = 1)
desc = circ.send('RELAY_DATA', 'GET /tor/server/authority 
HTTP/1.0\r\n\r\n', stream_id = 1).data
circ.close()

print(desc)

When run this prints our own descriptor...

  % python demo.py
  HTTP/1.0 200 OK
  Date: Wed, 07 Feb 2018 18:42:41 GMT
  Content-Type: text/plain
  Content-Encoding: identity
  Expires: Fri, 09 Feb 2018 18:42:41 GMT

  router Unnamed 97.113.177.53 12345 0 23456
  identity-ed25519
  -BEGIN ED25519 CERT-
  AQQABm/qAazUltT1iUUbIMw8VNNhGb50FDHKJz6S94FLQNxL0LObAQAgBAAapbO9
  iLFD0l9SEiEMFQWIT2VnbLyCZKvbrxTs5ULC1l1hQPoui6Y/lEd3yjrQhIs/vl6R
  1S6FbwSFDmiXOzq47mFrse4C71ht3TpLOD0F3wiyjWtsqU1k7iPmmpejUgs=
  -END ED25519 CERT-
  master-key-ed25519 GqWzvYixQ9JfUhIhDBUFiE

Next steps are to...

  a. Support ORPort downloads in 'stem.descriptor.remote'.
  b. Add more integration tests.
  c. Give more thought to the API we'd like to vend.
  d. Brainstorm a GSoC project idea that expands these capabilities.

However, first there's some other projects (in particular v3 hidden 
services)
that need my time.

[1] https://github.com/teor2345/endosome

 stem/__init__.py |   1 +
 stem/client/__init__.py  | 440 +++
 stem/client/cell.py  | 419 ++
 stem/client/datatype.py  | 482 +++
 stem/control.py  |   9 +-
 stem/socket.py   |   1 +
 test/integ/__init__.py   |   1 +
 test/integ/client/__init__.py|   7 +
 test/integ/client/connection.py  |  66 ++
 test/integ/control/controller.py |   4 +-
 test/runner.py   |   4 +-
 test/settings.cfg|   4 +-
 test/unit/client/__init__.py |   1 +
 test/unit/client/address.py  |  27 ++-
 test/unit/client/cell.py | 146 +---
 test/unit/client/certificate.py  |   2 +-
 test/unit/client/kdf.py  |  27 +++
 test/unit/client/size.py |   2 +-
 18 files changed, 1178 insertions(+), 465 deletions(-)

___
tor-commits mailing list
tor-commits@lists.torproject.org
https://lists.torproject.org/cgi-bin/mailman/listinfo/tor-commits


[tor-commits] [stem/master] Make Relay iterable to get circuits

2018-02-07 Thread atagar
commit 94cd4204b86a21f21f73c28f40073841269f6503
Author: Damian Johnson 
Date:   Tue Feb 6 10:26:30 2018 -0800

Make Relay iterable to get circuits

Thought is: iterate over relays to get circuits, and iterate over
circuits to get streams.
---
 stem/client/__init__.py | 5 +
 1 file changed, 5 insertions(+)

diff --git a/stem/client/__init__.py b/stem/client/__init__.py
index 5a9d09e6..3f8507e5 100644
--- a/stem/client/__init__.py
+++ b/stem/client/__init__.py
@@ -183,6 +183,11 @@ class Relay(object):
 
   return circ
 
+  def __iter__(self):
+with self._orport_lock:
+  for circ in self._circuits.values():
+yield circ
+
   def __enter__(self):
 return self
 



___
tor-commits mailing list
tor-commits@lists.torproject.org
https://lists.torproject.org/cgi-bin/mailman/listinfo/tor-commits


[tor-commits] [stem/master] Initial Circuit.send() method

2018-02-07 Thread atagar
commit b6ec30d450e929976acf3fce9378f0c3a777d938
Author: Damian Johnson 
Date:   Mon Feb 5 11:24:34 2018 -0800

Initial Circuit.send() method

Quite a few things I dislike about this, but it works! Next up: testing and
refinement...
---
 stem/client/__init__.py | 37 -
 stem/client/cell.py | 17 +++--
 2 files changed, 51 insertions(+), 3 deletions(-)

diff --git a/stem/client/__init__.py b/stem/client/__init__.py
index fdb436b6..4f9ed17c 100644
--- a/stem/client/__init__.py
+++ b/stem/client/__init__.py
@@ -19,6 +19,7 @@ a wrapper for :class:`~stem.socket.RelaySocket`, much the 
same way as
 +- close - shuts down our connection
 """
 
+import copy
 import hashlib
 
 import stem
@@ -26,7 +27,7 @@ import stem.client.cell
 import stem.socket
 import stem.util.connection
 
-from stem.client.datatype import ZERO, AddrType, Address, KDF
+from stem.client.datatype import ZERO, AddrType, Address, KDF, split
 
 __all__ = [
   'cell',
@@ -207,3 +208,37 @@ class Circuit(object):
 self.backward_digest = hashlib.sha1(kdf.backward_digest)
 self.forward_key = Cipher(algorithms.AES(kdf.forward_key), ctr, 
default_backend()).encryptor()
 self.backward_key = Cipher(algorithms.AES(kdf.backward_key), ctr, 
default_backend()).decryptor()
+
+  def send(self, command, data, stream_id = 0):
+"""
+Sends a message over the circuit.
+
+:param stem.client.RelayCommand command: command to be issued
+:param bytes data: message payload
+:param int stream_id: specific stream this concerns
+"""
+
+# TODO: move RelayCommand to this base module?
+# TODO: add lock
+
+orig_digest = self.forward_digest.copy()
+orig_key = copy.copy(self.forward_key)
+
+try:
+  cell = stem.client.cell.RelayCell(self.id, command, data, 0, stream_id)
+  payload_without_digest = cell.pack(self.relay.link_protocol)[3:]
+  self.forward_digest.update(payload_without_digest)
+
+  cell = stem.client.cell.RelayCell(self.id, command, data, 
self.forward_digest, stream_id)
+  header, payload = split(cell.pack(self.relay.link_protocol), 3)
+  encrypted_payload = header + self.forward_key.update(payload)
+
+  self.relay._orport.send(encrypted_payload)
+except:
+  self.forward_digest = orig_digest
+  self.forward_key = orig_key
+  raise
+
+  def close(self):
+
self.relay._orport.send(stem.client.cell.DestroyCell(self.id).pack(self.relay.link_protocol))
+del self.relay._circuits[self.id]
diff --git a/stem/client/cell.py b/stem/client/cell.py
index 17f27202..c4a19940 100644
--- a/stem/client/cell.py
+++ b/stem/client/cell.py
@@ -307,7 +307,7 @@ class RelayCell(CircuitCell):
   VALUE = 3
   IS_FIXED_SIZE = True
 
-  def __init__(self, circ_id, command, data, digest = 0, stream_id = 0):
+  def __init__(self, circ_id, command, data, digest = 0, stream_id = 0, 
raw_content = None):
 if 'hashlib.HASH' in str(type(digest)):
   # Unfortunately hashlib generates from a dynamic private class so
   # isinstance() isn't such a great option.
@@ -325,6 +325,7 @@ class RelayCell(CircuitCell):
 self.data = data
 self.digest = digest
 self.stream_id = stream_id
+self._raw_content = raw_content
 
 if not stream_id and self.command in STREAM_ID_REQUIRED:
   raise ValueError('%s relay cells require a stream id' % self.command)
@@ -342,8 +343,20 @@ class RelayCell(CircuitCell):
 
 return RelayCell._pack(link_protocol, payload.getvalue(), self.circ_id)
 
+  def decrypt(self, circ):
+# TODO: clearly funky, just a spot to start...
+
+if not self._raw_content:
+  raise ValueError('Only received cells can be decrypted')
+
+decrypted = circ.backward_key.update(self._raw_content)
+return RelayCell._unpack(decrypted, self.circ_id, 3)
+
+
   @classmethod
   def _unpack(cls, content, circ_id, link_protocol):
+orig_content = content
+
 command, content = Size.CHAR.pop(content)
 _, content = Size.SHORT.pop(content)  # 'recognized' field
 stream_id, content = Size.SHORT.pop(content)
@@ -351,7 +364,7 @@ class RelayCell(CircuitCell):
 data_len, content = Size.SHORT.pop(content)
 data, content = split(content, data_len)
 
-return RelayCell(circ_id, command, data, digest, stream_id)
+return RelayCell(circ_id, command, data, digest, stream_id, orig_content)
 
   def __hash__(self):
 return _hash_attr(self, 'command_int', 'stream_id', 'digest', 'data')



___
tor-commits mailing list
tor-commits@lists.torproject.org
https://lists.torproject.org/cgi-bin/mailman/listinfo/tor-commits


[tor-commits] [stem/master] Accept string and hash digests

2018-02-07 Thread atagar
commit bdc96f01bf91c3f7758e12a58e5e388b88734ad9
Author: Damian Johnson 
Date:   Mon Feb 5 10:14:14 2018 -0800

Accept string and hash digests

The RELAY cells actually work from a truncated digest. Only the two ends 
know
the full sha1 digest for the message series that has been sent. Adjusting 
the
RelayCell so it takes all three forms that the digest comes in.
---
 stem/client/cell.py  | 12 
 test/unit/client/cell.py |  8 
 2 files changed, 20 insertions(+)

diff --git a/stem/client/cell.py b/stem/client/cell.py
index ed8932c4..17f27202 100644
--- a/stem/client/cell.py
+++ b/stem/client/cell.py
@@ -308,6 +308,18 @@ class RelayCell(CircuitCell):
   IS_FIXED_SIZE = True
 
   def __init__(self, circ_id, command, data, digest = 0, stream_id = 0):
+if 'hashlib.HASH' in str(type(digest)):
+  # Unfortunately hashlib generates from a dynamic private class so
+  # isinstance() isn't such a great option.
+
+  digest = Size.LONG.unpack(digest.digest()[:4])
+elif isinstance(digest, str):
+  digest = Size.LONG.unpack(digest[:4])
+elif isinstance(digest, int):
+  pass
+else:
+  raise ValueError('RELAY cell digest must be a hash, string, or int but 
was a %s' % type(digest).__name__)
+
 super(RelayCell, self).__init__(circ_id)
 self.command, self.command_int = RelayCommand.get(command)
 self.data = data
diff --git a/test/unit/client/cell.py b/test/unit/client/cell.py
index f53355dd..19744c6d 100644
--- a/test/unit/client/cell.py
+++ b/test/unit/client/cell.py
@@ -3,6 +3,7 @@ Unit tests for the stem.client.cell.
 """
 
 import datetime
+import hashlib
 import os
 import unittest
 
@@ -153,6 +154,13 @@ class TestCell(unittest.TestCase):
   self.assertEqual(digest, cell.digest)
   self.assertEqual(stream_id, cell.stream_id)
 
+digest = hashlib.sha1('hi')
+self.assertEqual(3257622417, RelayCell(5, 'RELAY_BEGIN_DIR', '', digest, 
564346860).digest)
+self.assertEqual(3257622417, RelayCell(5, 'RELAY_BEGIN_DIR', '', 
digest.digest(), 564346860).digest)
+self.assertEqual(3257622417, RelayCell(5, 'RELAY_BEGIN_DIR', '', 
3257622417, 564346860).digest)
+self.assertRaisesRegexp(ValueError, 'RELAY cell digest must be a hash, 
string, or int but was a list', RelayCell, 5, 'RELAY_BEGIN_DIR', '', [], 
564346860)
+self.assertRaisesRegexp(ValueError, "Invalid enumeration 
'NO_SUCH_COMMAND', options are RELAY_BEGIN, RELAY_DATA", RelayCell, 5, 
'NO_SUCH_COMMAND', '', 5, 564346860)
+
   def test_destroy_cell(self):
 for cell_bytes, (circ_id, reason, reason_int) in DESTROY_CELLS.items():
   self.assertEqual(cell_bytes, DestroyCell(circ_id, reason).pack(5))



___
tor-commits mailing list
tor-commits@lists.torproject.org
https://lists.torproject.org/cgi-bin/mailman/listinfo/tor-commits


[tor-commits] [stem/master] Move Relay class into stem.client

2018-02-07 Thread atagar
commit 9b3a868a80e91527d9cdf276b3e27eef1bf34b02
Author: Damian Johnson 
Date:   Sun Feb 4 13:09:28 2018 -0800

Move Relay class into stem.client

On reflection I'd really prefer to keep all these modules colocated in this
module, much as stem.descriptor covers all things descriptor related.
---
 stem/__init__.py|   1 -
 stem/client/__init__.py | 594 ++--
 stem/client/cell.py |  36 ++-
 stem/client/datatype.py | 533 +++
 stem/relay.py   | 137 -
 test/integ/client/__init__.py   |   2 +-
 test/integ/client/connection.py |   2 +-
 test/settings.cfg   |   2 +-
 test/unit/client/address.py |   2 +-
 test/unit/client/cell.py|   2 +-
 test/unit/client/certificate.py |   2 +-
 test/unit/client/kdf.py |   6 +-
 test/unit/client/size.py|   2 +-
 13 files changed, 660 insertions(+), 661 deletions(-)

diff --git a/stem/__init__.py b/stem/__init__.py
index 2d2e1c6d..83a48903 100644
--- a/stem/__init__.py
+++ b/stem/__init__.py
@@ -494,7 +494,6 @@ __all__ = [
   'exit_policy',
   'prereq',
   'process',
-  'relay',
   'socket',
   'version',
   'ControllerError',
diff --git a/stem/client/__init__.py b/stem/client/__init__.py
index 9f4217c5..85473685 100644
--- a/stem/client/__init__.py
+++ b/stem/client/__init__.py
@@ -2,556 +2,142 @@
 # See LICENSE for licensing information
 
 """
-Support for `Tor's ORPort protocol
-`_.
-
-**This module only consists of low level components, and is not intended for
-users.** See our :class:`~stem.relay.Relay` the API you probably want.
+Interaction with a Tor relay's ORPort. :class:`~stem.client.Relay` is
+a wrapper for :class:`~stem.socket.RelaySocket`, much the same way as
+:class:`~stem.control.Controller` provides higher level functions for
+:class:`~stem.socket.ControlSocket`.
 
 .. versionadded:: 1.7.0
 
 ::
 
-  split - splits bytes into substrings
-
-  Field - Packable and unpackable datatype.
-|- Size - Field of a static size.
-|- Address - Relay address.
-|- Certificate - Relay certificate.
+  Relay - Connection with a tor relay's ORPort.
+| +- connect - Establishes a connection with a relay.
 |
-|- pack - encodes content
-|- unpack - decodes content
-+- pop - decodes content with remainder
-
-  KDF - KDF-TOR derivatived attributes
-+- from_value - parses key material
-
-.. data:: AddrType (enum)
-
-  Form an address takes.
-
-  = ===
-  AddressType   Description
-  = ===
-  **HOSTNAME**  relay hostname
-  **IPv4**  IPv4 address
-  **IPv6**  IPv6 address
-  **ERROR_TRANSIENT**   temporarily error retrieving address
-  **ERROR_PERMANENT**   permanent error retrieving address
-  **UNKNOWN**   unrecognized address type
-  = ===
-
-.. data:: RelayCommand (enum)
-
-  Command concerning streams and circuits we've established with a relay.
-  Commands have two characteristics...
-
-  * **forward/backward**: **forward** commands are issued from the orgin,
-whereas **backward** come from the relay
-
-  * **stream/circuit**: **steam** commands concern an individual steam, whereas
-**circuit** concern the entire circuit we've established with a relay
-
-  = ===
-  RelayCommand  Description
-  = ===
-  **BEGIN** begin a stream (**forward**, **stream**)
-  **DATA**  transmit data (**forward/backward**, **stream**)
-  **END**   end a stream (**forward/backward**, **stream**)
-  **CONNECTED** BEGIN reply (**backward**, **stream**)
-  **SENDME**ready to accept more cells (**forward/backward**, 
**stream/circuit**)
-  **EXTEND**extend the circuit through another relay (**forward**, 
**circuit**)
-  **EXTENDED**  EXTEND reply (**backward**, **circuit**)
-  **TRUNCATE**  remove last circuit hop (**forward**, **circuit**)
-  **TRUNCATED** TRUNCATE reply (**backward**, **circuit**)
-  **DROP**  ignorable no-op (**forward/backward**, **circuit**)
-  **RESOLVE**   request DNS resolution (**forward**, **stream**)
-  **RESOLVED**  RESOLVE reply (**backward**, **stream**)
-  **BEGIN_DIR** request descriptor (**forward**, **steam**)
-  **EXTEND2**   ntor EXTEND request (**forward**, **circuit**)
-  **EXTENDED2** EXTEND2 reply (**backward**, **circuit**)
-  **UNKNOWN**   unrecognized command
-  = ===
-
-.. data:: CertType (enum)
-
-  Relay certificate type.
-
-  = ===
-  CertType  Description
-  = ===
-  **LINK**  link key certificate 

[tor-commits] [stem/master] Make Relay thread safe

2018-02-07 Thread atagar
commit 331127483838c416b279d30cf041deb678984ab2
Author: Damian Johnson 
Date:   Tue Feb 6 09:53:08 2018 -0800

Make Relay thread safe
---
 stem/client/__init__.py | 91 +++--
 1 file changed, 51 insertions(+), 40 deletions(-)

diff --git a/stem/client/__init__.py b/stem/client/__init__.py
index 8d34b626..5a9d09e6 100644
--- a/stem/client/__init__.py
+++ b/stem/client/__init__.py
@@ -16,11 +16,18 @@ a wrapper for :class:`~stem.socket.RelaySocket`, much the 
same way as
 |
 |- is_alive - reports if our connection is open or closed
 |- connection_time - time when we last connected or disconnected
-+- close - shuts down our connection
+|- close - shuts down our connection
+|
++- create_circuit - establishes a new circuit
+
+  Circuit - Circuit we've established through a relay.
+|- send - sends a message through this circuit
++- close - closes this circuit
 """
 
 import copy
 import hashlib
+import threading
 
 import stem
 import stem.client.cell
@@ -47,6 +54,7 @@ class Relay(object):
   def __init__(self, orport, link_protocol):
 self.link_protocol = link_protocol
 self._orport = orport
+self._orport_lock = threading.RLock()
 self._circuits = {}
 
   @staticmethod
@@ -138,40 +146,42 @@ class Relay(object):
 :func:`~stem.socket.BaseSocket.close` method.
 """
 
-return self._orport.close()
+with self._orport_lock:
+  return self._orport.close()
 
   def create_circuit(self):
 """
 Establishes a new circuit.
 """
 
-# Find an unused circuit id. Since we're initiating the circuit we pick any
-# value from a range that's determined by our link protocol.
+with self._orport_lock:
+  # Find an unused circuit id. Since we're initiating the circuit we pick 
any
+  # value from a range that's determined by our link protocol.
 
-circ_id = 0x8000 if self.link_protocol > 3 else 0x01
+  circ_id = 0x8000 if self.link_protocol > 3 else 0x01
 
-while circ_id in self._circuits:
-  circ_id += 1
+  while circ_id in self._circuits:
+circ_id += 1
 
-create_fast_cell = stem.client.cell.CreateFastCell(circ_id)
-self._orport.send(create_fast_cell.pack(self.link_protocol))
+  create_fast_cell = stem.client.cell.CreateFastCell(circ_id)
+  self._orport.send(create_fast_cell.pack(self.link_protocol))
 
-response = stem.client.cell.Cell.unpack(self._orport.recv(), 
self.link_protocol)
-created_fast_cells = filter(lambda cell: isinstance(cell, 
stem.client.cell.CreatedFastCell), response)
+  response = stem.client.cell.Cell.unpack(self._orport.recv(), 
self.link_protocol)
+  created_fast_cells = filter(lambda cell: isinstance(cell, 
stem.client.cell.CreatedFastCell), response)
 
-if not created_fast_cells:
-  raise ValueError('We should get a CREATED_FAST response from a 
CREATE_FAST request')
+  if not created_fast_cells:
+raise ValueError('We should get a CREATED_FAST response from a 
CREATE_FAST request')
 
-created_fast_cell = created_fast_cells[0]
-kdf = KDF.from_value(create_fast_cell.key_material + 
created_fast_cell.key_material)
+  created_fast_cell = created_fast_cells[0]
+  kdf = KDF.from_value(create_fast_cell.key_material + 
created_fast_cell.key_material)
 
-if created_fast_cell.derivative_key != kdf.key_hash:
-  raise ValueError('Remote failed to prove that it knows our shared key')
+  if created_fast_cell.derivative_key != kdf.key_hash:
+raise ValueError('Remote failed to prove that it knows our shared key')
 
-circ = Circuit(self, circ_id, kdf)
-self._circuits[circ.id] = circ
+  circ = Circuit(self, circ_id, kdf)
+  self._circuits[circ.id] = circ
 
-return circ
+  return circ
 
   def __enter__(self):
 return self
@@ -219,30 +229,31 @@ class Circuit(object):
 """
 
 # TODO: move RelayCommand to this base module?
-# TODO: add lock
 
-orig_digest = self.forward_digest.copy()
-orig_key = copy.copy(self.forward_key)
+with self.relay._orport_lock:
+  orig_digest = self.forward_digest.copy()
+  orig_key = copy.copy(self.forward_key)
 
-try:
-  cell = stem.client.cell.RelayCell(self.id, command, data, 0, stream_id)
-  payload_without_digest = cell.pack(self.relay.link_protocol)[3:]
-  self.forward_digest.update(payload_without_digest)
+  try:
+cell = stem.client.cell.RelayCell(self.id, command, data, 0, stream_id)
+payload_without_digest = cell.pack(self.relay.link_protocol)[3:]
+self.forward_digest.update(payload_without_digest)
 
-  cell = stem.client.cell.RelayCell(self.id, command, data, 
self.forward_digest, stream_id)
-  header, payload = split(cell.pack(self.relay.link_protocol), 3)
-  encrypted_payload = header + self.forward_key.update(payload)
+cell = stem.client.cell.RelayCell(self.id, command, data, 

[tor-commits] [stem/master] Rename Cell.unpack to Cell.pop

2018-02-07 Thread atagar
commit 28467fc87102069fabb1b5b496725f9e9855256e
Author: Damian Johnson 
Date:   Sun Jan 28 12:48:46 2018 -0800

Rename Cell.unpack to Cell.pop

Usually when we unpack cells we'll want to process everything from a 
response.
As such having Cell.unpack provide a generator, and renaming our previous
function that unpacked a single cell to Cell.pop.
---
 stem/client/cell.py  | 30 +-
 test/unit/client/cell.py | 42 +-
 2 files changed, 46 insertions(+), 26 deletions(-)

diff --git a/stem/client/cell.py b/stem/client/cell.py
index e2e589f5..59fbc14c 100644
--- a/stem/client/cell.py
+++ b/stem/client/cell.py
@@ -32,8 +32,9 @@ Messages communicated over a Tor relay's ORPort.
 |- AuthenticateCell - Client authentication.  (section 4.5)
 |- AuthorizeCell - Client authorization.  (not yet used)
 |
-|- pack - Provides encoded bytes for this cell class.
-+- unpack - Decodes bytes for this cell class.
+|- pack - encodes cell into bytes
+|- unpack - decodes series of cells
++- pop - decodes cell with remainder
 """
 
 import datetime
@@ -95,9 +96,31 @@ class Cell(object):
 
 raise ValueError("'%s' isn't a valid cell value" % value)
 
+  def pack(self, link_version):
+raise NotImplementedError('Unpacking not yet implemented for %s cells' % 
type(self).NAME)
+
   @staticmethod
   def unpack(content, link_version):
 """
+Unpacks all cells from a response.
+
+:param bytes content: payload to decode
+:param int link_version: link protocol version
+
+:returns: :class:`~stem.client.cell.Cell` generator
+
+:raises:
+  * ValueError if content is malformed
+  * NotImplementedError if unable to unpack any of the cell types
+"""
+
+while content:
+  cell, content = Cell.pop(content, link_version)
+  yield cell
+
+  @staticmethod
+  def pop(content, link_version):
+"""
 Unpacks the first cell.
 
 :param bytes content: payload to decode
@@ -125,9 +148,6 @@ class Cell(object):
 payload, content = split(content, payload_len)
 return cls._unpack(payload, circ_id, link_version), content
 
-  def pack(self, link_version):
-raise NotImplementedError('Unpacking not yet implemented for %s cells' % 
type(self).NAME)
-
   @classmethod
   def _pack(cls, link_version, payload, circ_id = 0):
 """
diff --git a/test/unit/client/cell.py b/test/unit/client/cell.py
index ba28238e..1fde76cf 100644
--- a/test/unit/client/cell.py
+++ b/test/unit/client/cell.py
@@ -99,7 +99,7 @@ class TestCell(unittest.TestCase):
 self.assertRaises(ValueError, Cell.by_value, None)
 
   def test_unpack_not_implemented(self):
-self.assertRaisesRegexp(NotImplementedError, 'Unpacking not yet 
implemented for AUTHORIZE cells', Cell.unpack, 
'\x00\x00\x84\x00\x06\x00\x01\x00\x02\x00\x03', 2)
+self.assertRaisesRegexp(NotImplementedError, 'Unpacking not yet 
implemented for AUTHORIZE cells', Cell.pop, 
'\x00\x00\x84\x00\x06\x00\x01\x00\x02\x00\x03', 2)
 
   def test_unpack_for_new_link(self):
 expected_certs = (
@@ -112,10 +112,10 @@ class TestCell(unittest.TestCase):
 
 content = test_data('new_link_cells')
 
-version_cell, content = Cell.unpack(content, 2)
+version_cell, content = Cell.pop(content, 2)
 self.assertEqual(VersionsCell([3, 4, 5]), version_cell)
 
-certs_cell, content = Cell.unpack(content, 2)
+certs_cell, content = Cell.pop(content, 2)
 self.assertEqual(CertsCell, type(certs_cell))
 self.assertEqual(len(expected_certs), len(certs_cell.certificates))
 
@@ -124,10 +124,10 @@ class TestCell(unittest.TestCase):
   self.assertEqual(cert_type_int, certs_cell.certificates[i].type_int)
   self.assertTrue(certs_cell.certificates[i].value.startswith(cert_prefix))
 
-auth_challenge_cell, content = Cell.unpack(content, 2)
+auth_challenge_cell, content = Cell.pop(content, 2)
 self.assertEqual(AuthChallengeCell([1, 3], 
'\x89Y\t\x99\xb2\x1e\xd9*V\xb6\x1bn\n\x05\xd8/\xe3QH\x85\x13Z\x17\xfc\x1c\x00{\xa9\xae\x83^K'),
 auth_challenge_cell)
 
-netinfo_cell, content = Cell.unpack(content, 2)
+netinfo_cell, content = Cell.pop(content, 2)
 self.assertEqual(NetinfoCell, type(netinfo_cell))
 self.assertEqual(datetime.datetime(2018, 1, 14, 1, 46, 56), 
netinfo_cell.timestamp)
 self.assertEqual(Address('127.0.0.1'), netinfo_cell.receiver_address)
@@ -138,14 +138,14 @@ class TestCell(unittest.TestCase):
   def test_padding_cell(self):
 for cell_bytes, payload in PADDING_CELLS.items():
   self.assertEqual(cell_bytes, PaddingCell(payload).pack(2))
-  self.assertEqual(payload, Cell.unpack(cell_bytes, 2)[0].payload)
+  self.assertEqual(payload, Cell.pop(cell_bytes, 2)[0].payload)
 
   def test_relay_cell(self):
 for cell_bytes, (command, command_int, circ_id, stream_id, data, digest) 
in RELAY_CELLS.items():
   self.assertEqual(cell_bytes, 

[tor-commits] [stem/master] Move circuit construction into the Relay class

2018-02-07 Thread atagar
commit 2ca71ddb1d91154b7dd4a9c8e0c9e3bac06be204
Author: Damian Johnson 
Date:   Sun Feb 4 14:49:30 2018 -0800

Move circuit construction into the Relay class

Preferably I'd like to keep all socket activity within the Relay class. We
might need to bend this in practice but lets first give it a try.
---
 stem/client/__init__.py |  68 +++-
 stem/client/cell.py | 100 +++-
 stem/client/datatype.py |  51 
 3 files changed, 114 insertions(+), 105 deletions(-)

diff --git a/stem/client/__init__.py b/stem/client/__init__.py
index 85473685..fdb436b6 100644
--- a/stem/client/__init__.py
+++ b/stem/client/__init__.py
@@ -19,12 +19,14 @@ a wrapper for :class:`~stem.socket.RelaySocket`, much the 
same way as
 +- close - shuts down our connection
 """
 
+import hashlib
+
 import stem
 import stem.client.cell
 import stem.socket
 import stem.util.connection
 
-from stem.client.datatype import AddrType, Address
+from stem.client.datatype import ZERO, AddrType, Address, KDF
 
 __all__ = [
   'cell',
@@ -44,6 +46,7 @@ class Relay(object):
   def __init__(self, orport, link_protocol):
 self.link_protocol = link_protocol
 self._orport = orport
+self._circuits = {}
 
   @staticmethod
   def connect(address, port, link_protocols = DEFAULT_LINK_PROTOCOLS):
@@ -136,8 +139,71 @@ class Relay(object):
 
 return self._orport.close()
 
+  def create_circuit(self):
+"""
+Establishes a new circuit.
+"""
+
+# Find an unused circuit id. Since we're initiating the circuit we pick any
+# value from a range that's determined by our link protocol.
+
+circ_id = 0x8000 if self.link_protocol > 3 else 0x01
+
+while circ_id in self._circuits:
+  circ_id += 1
+
+create_fast_cell = stem.client.cell.CreateFastCell(circ_id)
+self._orport.send(create_fast_cell.pack(self.link_protocol))
+
+response = stem.client.cell.Cell.unpack(self._orport.recv(), 
self.link_protocol)
+created_fast_cells = filter(lambda cell: isinstance(cell, 
stem.client.cell.CreatedFastCell), response)
+
+if not created_fast_cells:
+  raise ValueError('We should get a CREATED_FAST response from a 
CREATE_FAST request')
+
+created_fast_cell = created_fast_cells[0]
+kdf = KDF.from_value(create_fast_cell.key_material + 
created_fast_cell.key_material)
+
+if created_fast_cell.derivative_key != kdf.key_hash:
+  raise ValueError('Remote failed to prove that it knows our shared key')
+
+circ = Circuit(self, circ_id, kdf)
+self._circuits[circ.id] = circ
+
+return circ
+
   def __enter__(self):
 return self
 
   def __exit__(self, exit_type, value, traceback):
 self.close()
+
+
+class Circuit(object):
+  """
+  Circuit through which requests can be made of a `Tor relay's ORPort
+  `_.
+
+  :var stem.client.Relay relay: relay through which this circuit has been 
established
+  :var int id: circuit id
+  :var hashlib.sha1 forward_digest: digest for forward integrity check
+  :var hashlib.sha1 backward_digest: digest for backward integrity check
+  :var bytes forward_key: forward encryption key
+  :var bytes backward_key: backward encryption key
+  """
+
+  def __init__(self, relay, circ_id, kdf):
+if not stem.prereq.is_crypto_available():
+  raise ImportError('Circuit construction requires the cryptography 
module')
+
+from cryptography.hazmat.primitives.ciphers import Cipher, algorithms, 
modes
+from cryptography.hazmat.backends import default_backend
+
+ctr = modes.CTR(ZERO * (algorithms.AES.block_size / 8))
+
+self.relay = relay
+self.id = circ_id
+self.forward_digest = hashlib.sha1(kdf.forward_digest)
+self.backward_digest = hashlib.sha1(kdf.backward_digest)
+self.forward_key = Cipher(algorithms.AES(kdf.forward_key), ctr, 
default_backend()).encryptor()
+self.backward_key = Cipher(algorithms.AES(kdf.backward_key), ctr, 
default_backend()).decryptor()
diff --git a/stem/client/cell.py b/stem/client/cell.py
index a018b2a3..ed8932c4 100644
--- a/stem/client/cell.py
+++ b/stem/client/cell.py
@@ -113,16 +113,16 @@ class Cell(object):
 
 raise ValueError("'%s' isn't a valid cell value" % value)
 
-  def pack(self, link_version):
+  def pack(self, link_protocol):
 raise NotImplementedError('Unpacking not yet implemented for %s cells' % 
type(self).NAME)
 
   @staticmethod
-  def unpack(content, link_version):
+  def unpack(content, link_protocol):
 """
 Unpacks all cells from a response.
 
 :param bytes content: payload to decode
-:param int link_version: link protocol version
+:param int link_protocol: link protocol version
 
 :returns: :class:`~stem.client.cell.Cell` generator
 
@@ -132,16 +132,16 @@ class Cell(object):
 """
 
 while content:
-  cell, content = Cell.pop(content, link_version)
+ 

[tor-commits] [stem/master] Initial Relay class

2018-02-07 Thread atagar
commit db52d5fcf38127c107399065768e710b297378c8
Author: Damian Johnson 
Date:   Sat Feb 3 14:03:00 2018 -0800

Initial Relay class

Clearly from all the todos just a start.
---
 stem/__init__.py|  2 ++
 stem/client/__init__.py |  9 ---
 stem/control.py |  2 +-
 stem/relay.py   | 71 +
 4 files changed, 79 insertions(+), 5 deletions(-)

diff --git a/stem/__init__.py b/stem/__init__.py
index 2741cee7..2d2e1c6d 100644
--- a/stem/__init__.py
+++ b/stem/__init__.py
@@ -485,6 +485,7 @@ __url__ = 'https://stem.torproject.org/'
 __license__ = 'LGPLv3'
 
 __all__ = [
+  'client',
   'descriptor',
   'response',
   'util',
@@ -493,6 +494,7 @@ __all__ = [
   'exit_policy',
   'prereq',
   'process',
+  'relay',
   'socket',
   'version',
   'ControllerError',
diff --git a/stem/client/__init__.py b/stem/client/__init__.py
index cbeed403..9f4217c5 100644
--- a/stem/client/__init__.py
+++ b/stem/client/__init__.py
@@ -2,10 +2,11 @@
 # See LICENSE for licensing information
 
 """
-Interaction with a Tor relay's ORPort. :class:`~stem.client.Relay` is
-a wrapper for :class:`~stem.socket.RelaySocket`, much the same way as
-:class:`~stem.control.Controller` provides higher level functions for
-:class:`~stem.socket.ControlSocket`.
+Support for `Tor's ORPort protocol
+`_.
+
+**This module only consists of low level components, and is not intended for
+users.** See our :class:`~stem.relay.Relay` the API you probably want.
 
 .. versionadded:: 1.7.0
 
diff --git a/stem/control.py b/stem/control.py
index 94ad5eaf..123e3b20 100644
--- a/stem/control.py
+++ b/stem/control.py
@@ -989,7 +989,7 @@ class BaseController(object):
 
 class Controller(BaseController):
   """
-  Communicates with a control socket. This is built on top of the
+  Connection with Tor's control socket. This is built on top of the
   BaseController and provides a more user friendly API for library users.
   """
 
diff --git a/stem/relay.py b/stem/relay.py
new file mode 100644
index ..7d1e8282
--- /dev/null
+++ b/stem/relay.py
@@ -0,0 +1,71 @@
+# Copyright 2018, Damian Johnson and The Tor Project
+# See LICENSE for licensing information
+
+"""
+Interaction with a Tor relay's ORPort. :class:`~stem.relay.Relay` is
+a wrapper for :class:`~stem.socket.RelaySocket`, much the same way as
+:class:`~stem.control.Controller` provides higher level functions for
+:class:`~stem.socket.ControlSocket`.
+
+.. versionadded:: 1.7.0
+
+::
+
+  Relay - Connection with a tor relay's ORPort.
+| +- connect - Establishes a connection with a relay.
+"""
+
+import stem.client
+import stem.client.cell
+import stem.socket
+import stem.util.connection
+
+DEFAULT_LINK_VERSIONS = (3, 4, 5)
+
+
+class Relay(object):
+  """
+  Connection with a Tor relay's ORPort.
+  """
+
+  def __init__(self, orport):
+self._orport = orport
+
+  @staticmethod
+  def connect(address, port, link_versions = DEFAULT_LINK_VERSIONS):
+"""
+Establishes a connection with the given ORPort.
+
+:param str address: ip address of the relay
+:param int port: ORPort of the relay
+:param tuple link_versions: acceptable link protocol versions
+
+:raises:
+  * **ValueError** if address or port are invalid
+  * :class:`stem.SocketError` if we're unable to establish a connection
+"""
+
+if stem.util.connection.is_valid_ipv4_address(address):
+  addr_type = stem.client.AddrType.IPv4
+elif stem.util.connection.is_valid_ipv6_address(address):
+  addr_type = stem.client.AddrType.IPv6
+else:
+  raise ValueError("'%s' isn't an IPv4 or IPv6 address" % address)
+
+if not stem.util.connection.is_port(port):
+  raise ValueError("'%s' isn't a valid port" % port)
+
+conn = stem.socket.RelaySocket(address, port)
+conn.send(stem.client.cell.VersionsCell(link_versions).pack())
+versions_reply = stem.client.cell.Cell.pop(conn.recv(), 2)[0]
+
+# TODO: determine the highest common link versions
+# TODO: we should fill in our address, right?
+# TODO: what happens if we skip the NETINFO?
+
+link_version = 3
+conn.send(stem.client.cell.NetinfoCell(stem.client.Address(address, 
addr_type), []).pack(link_version))
+
+# TODO: what if no link protocol versions are acceptable?
+
+return Relay(conn)



___
tor-commits mailing list
tor-commits@lists.torproject.org
https://lists.torproject.org/cgi-bin/mailman/listinfo/tor-commits


[tor-commits] [stem/master] Make address type optional for IPv4 and IPv6

2018-02-07 Thread atagar
commit 7ff9addebe19ae911c30e90296af16838c4896e5
Author: Damian Johnson 
Date:   Sat Jan 27 21:55:31 2018 -0800

Make address type optional for IPv4 and IPv6

Vast majority of time we create addresses they're IPv4 or IPv6. If provided 
a
plaintext address is provided then drop a need for it.
---
 stem/client/__init__.py | 12 ++--
 test/unit/client/address.py | 18 --
 test/unit/client/cell.py|  8 
 3 files changed, 26 insertions(+), 12 deletions(-)

diff --git a/stem/client/__init__.py b/stem/client/__init__.py
index 58c439e6..fb0f899d 100644
--- a/stem/client/__init__.py
+++ b/stem/client/__init__.py
@@ -355,7 +355,15 @@ class Address(Field):
   :var bytes value_bin: encoded address value
   """
 
-  def __init__(self, addr_type, value):
+  def __init__(self, value, addr_type = None):
+if addr_type is None:
+  if stem.util.connection.is_valid_ipv4_address(value):
+addr_type = AddrType.IPv4
+  elif stem.util.connection.is_valid_ipv6_address(value):
+addr_type = AddrType.IPv6
+  else:
+raise ValueError('Address type is required unless an IPv4 or IPv6 
address')
+
 self.type, self.type_int = AddrType.get(addr_type)
 
 if self.type == AddrType.IPv4:
@@ -408,7 +416,7 @@ class Address(Field):
 
 addr_value, content = split(content, addr_length)
 
-return Address(addr_type, addr_value), content
+return Address(addr_value, addr_type), content
 
   def __hash__(self):
 return _hash_attr(self, 'type_int', 'value_bin')
diff --git a/test/unit/client/address.py b/test/unit/client/address.py
index f5dc4a00..c92f7722 100644
--- a/test/unit/client/address.py
+++ b/test/unit/client/address.py
@@ -31,17 +31,23 @@ class TestAddress(unittest.TestCase):
 )
 
 for (addr_type, addr_value), expected in test_data:
-  addr = Address(addr_type, addr_value)
+  addr = Address(addr_value, addr_type)
   self.assertEqual(expected.type, addr.type)
   self.assertEqual(expected.type_int, addr.type_int)
   self.assertEqual(expected.value, addr.value)
   self.assertEqual(expected.value_bin, addr.value_bin)
 
-self.assertRaisesRegexp(ValueError, re.escape("Packed IPv4 addresses 
should be four bytes, but was: '\\x7f\\x00'"), Address, 4, '\x7f\x00')
-self.assertRaisesRegexp(ValueError, re.escape("Packed IPv6 addresses 
should be sixteen bytes, but was: '\\x7f\\x00'"), Address, 6, '\x7f\x00')
+# when an IPv4 or IPv6 address the type is optional
+
+self.assertEqual(AddrType.IPv4, Address('127.0.0.1').type)
+self.assertEqual(AddrType.IPv6, Address('2001:0DB8:AC10:FE01::').type)
+
+self.assertRaisesRegexp(ValueError, re.escape("Packed IPv4 addresses 
should be four bytes, but was: '\\x7f\\x00'"), Address, '\x7f\x00', 4)
+self.assertRaisesRegexp(ValueError, re.escape("Packed IPv6 addresses 
should be sixteen bytes, but was: '\\x7f\\x00'"), Address, '\x7f\x00', 6)
+self.assertRaisesRegexp(ValueError, re.escape('Address type is required 
unless an IPv4 or IPv6 address'), Address, 'nope')
 
   def test_unknown_type(self):
-addr = Address(12, 'hello')
+addr = Address('hello', 12)
 self.assertEqual(AddrType.UNKNOWN, addr.type)
 self.assertEqual(12, addr.type_int)
 self.assertEqual(None, addr.value)
@@ -49,8 +55,8 @@ class TestAddress(unittest.TestCase):
 
   def test_packing(self):
 test_data = {
-  '\x04\x04\x7f\x00\x00\x01': Address(AddrType.IPv4, '127.0.0.1'),
-  '\x06\x10 \x01\r\xb8\x00\x00\x00\x00\x00\x00\xff\x00\x00B\x83)': 
Address(AddrType.IPv6, '2001:0db8::::ff00:0042:8329'),
+  '\x04\x04\x7f\x00\x00\x01': Address('127.0.0.1'),
+  '\x06\x10 \x01\r\xb8\x00\x00\x00\x00\x00\x00\xff\x00\x00B\x83)': 
Address('2001:0db8::::ff00:0042:8329'),
 }
 
 for cell_bytes, address in test_data.items():
diff --git a/test/unit/client/cell.py b/test/unit/client/cell.py
index ffead90f..ba28238e 100644
--- a/test/unit/client/cell.py
+++ b/test/unit/client/cell.py
@@ -6,7 +6,7 @@ import datetime
 import os
 import unittest
 
-from stem.client import ZERO, AddrType, CertType, CloseReason, Address, 
Certificate
+from stem.client import ZERO, CertType, CloseReason, Address, Certificate
 from test.unit.client import test_data
 
 from stem.client.cell import (
@@ -56,7 +56,7 @@ VERSIONS_CELLS = {
 }
 
 NETINFO_CELLS = {
-  '\x00\x00\x08ZZ\xb6\x90\x04\x04\x7f\x00\x00\x01\x01\x04\x04aq\x0f\x02' + 
ZERO * (FIXED_PAYLOAD_LEN - 17): (datetime.datetime(2018, 1, 14, 1, 46, 56), 
Address(AddrType.IPv4, '127.0.0.1'), [Address(AddrType.IPv4, '97.113.15.2')]),
+  '\x00\x00\x08ZZ\xb6\x90\x04\x04\x7f\x00\x00\x01\x01\x04\x04aq\x0f\x02' + 
ZERO * (FIXED_PAYLOAD_LEN - 17): (datetime.datetime(2018, 1, 14, 1, 46, 56), 
Address('127.0.0.1'), [Address('97.113.15.2')]),
 }
 
 VPADDING_CELLS = {
@@ -130,8 +130,8 @@ class TestCell(unittest.TestCase):
 netinfo_cell, content = Cell.unpack(content, 2)
 

[tor-commits] [stem/master] Test RelayCell class

2018-02-07 Thread atagar
commit 2e6d441b9d0cbccb64414bd2762ac096a2253aef
Author: Damian Johnson 
Date:   Thu Jan 25 10:43:02 2018 -0800

Test RelayCell class

Found the unencrypted RELAY cell data in endosome so adding a couple tests 
that
we match it.
---
 stem/client/__init__.py  |  4 ++--
 stem/client/cell.py  |  3 +--
 test/unit/client/cell.py | 37 -
 3 files changed, 31 insertions(+), 13 deletions(-)

diff --git a/stem/client/__init__.py b/stem/client/__init__.py
index 0c900fb7..58c439e6 100644
--- a/stem/client/__init__.py
+++ b/stem/client/__init__.py
@@ -141,8 +141,8 @@ class _IntegerEnum(stem.util.enum.Enum):
   else:
 raise ValueError('IntegerEnums can only be constructed with two or 
three value tuples: %s' % repr(entry))
 
-  self._enum_to_int[enum] = int_val
-  self._int_to_enum[int_val] = enum
+  self._enum_to_int[str_val] = int_val
+  self._int_to_enum[int_val] = str_val
   parent_args.append((enum, str_val))
 
 parent_args.append(('UNKNOWN', 'UNKNOWN'))
diff --git a/stem/client/cell.py b/stem/client/cell.py
index e6f08b0b..a0737765 100644
--- a/stem/client/cell.py
+++ b/stem/client/cell.py
@@ -298,7 +298,6 @@ class RelayCell(CircuitCell):
 :param int link_version: link protocol version
 :param int circ_id: circuit id
 :param stem.client.RelayCommand command: reason the circuit is being closed
-:param int command_int: integer value of our command
 :param bytes data: payload of the cell
 :param int digest: running digest held with the relay
 :param int stream_id: specific stream this concerns
@@ -309,7 +308,7 @@ class RelayCell(CircuitCell):
 cell = RelayCell(circ_id, command, data, digest, stream_id)
 
 payload = io.BytesIO()
-payload.write(Size.CHAR.pack(cell.command))
+payload.write(Size.CHAR.pack(cell.command_int))
 payload.write(Size.SHORT.pack(0))  # 'recognized' field
 payload.write(Size.SHORT.pack(cell.stream_id))
 payload.write(Size.LONG.pack(cell.digest))
diff --git a/test/unit/client/cell.py b/test/unit/client/cell.py
index 5b8db2bb..e2a85b6f 100644
--- a/test/unit/client/cell.py
+++ b/test/unit/client/cell.py
@@ -13,6 +13,7 @@ from stem.client.cell import (
   FIXED_PAYLOAD_LEN,
   Cell,
   PaddingCell,
+  RelayCell,
   DestroyCell,
   CreateFastCell,
   CreatedFastCell,
@@ -30,6 +31,11 @@ PADDING_CELLS = {
   '\x00\x00\x00' + RANDOM_PAYLOAD: RANDOM_PAYLOAD,
 }
 
+RELAY_CELLS = {
+  '\x00\x01\x03\r\x00\x00\x00\x01!\xa3?\xec' + ZERO * 500: ('RELAY_BEGIN_DIR', 
13, 1, 1, '', 564346860),
+  '\x00\x01\x03\x02\x00\x00\x00\x01\x15:m\xe0\x00 /tor/server/authority 
HTTP/1.0\r\n\r\n' + ZERO * 460: ('RELAY_DATA', 2, 1, 1, 'GET 
/tor/server/authority HTTP/1.0\r\n\r\n', 356150752),
+}
+
 DESTROY_CELLS = {
   '\x80\x00\x00\x00\x04\x00' + ZERO * 508: (2147483648, CloseReason.NONE, 0),
   '\x80\x00\x00\x00\x04\x03' + ZERO * 508: (2147483648, CloseReason.REQUESTED, 
3),
@@ -129,12 +135,25 @@ class TestCell(unittest.TestCase):
 
 self.assertEqual('', content)  # check that we've consumed all of the bytes
 
-  def test_padding_packing(self):
+  def test_padding_cell(self):
 for cell_bytes, payload in PADDING_CELLS.items():
   self.assertEqual(cell_bytes, PaddingCell.pack(2, payload))
   self.assertEqual(payload, Cell.unpack(cell_bytes, 2)[0].payload)
 
-  def test_destroy_packing(self):
+  def test_relay_cell(self):
+for cell_bytes, (command, command_int, circ_id, stream_id, data, digest) 
in RELAY_CELLS.items():
+  self.assertEqual(cell_bytes, RelayCell.pack(2, circ_id, command, data, 
digest, stream_id))
+  self.assertEqual(cell_bytes, RelayCell.pack(2, circ_id, command_int, 
data, digest, stream_id))
+
+  cell = Cell.unpack(cell_bytes, 2)[0]
+  self.assertEqual(circ_id, cell.circ_id)
+  self.assertEqual(command, cell.command)
+  self.assertEqual(command_int, cell.command_int)
+  self.assertEqual(data, cell.data)
+  self.assertEqual(digest, cell.digest)
+  self.assertEqual(stream_id, cell.stream_id)
+
+  def test_destroy_cell(self):
 for cell_bytes, (circ_id, reason, reason_int) in DESTROY_CELLS.items():
   self.assertEqual(cell_bytes, DestroyCell.pack(5, circ_id, reason))
   self.assertEqual(cell_bytes, DestroyCell.pack(5, circ_id, reason_int))
@@ -146,7 +165,7 @@ class TestCell(unittest.TestCase):
 
 self.assertRaisesRegexp(ValueError, 'Circuit closure reason should be a 
single byte, but was 2', Cell.unpack, '\x80\x00\x00\x00\x04\x01\x01' + ZERO * 
507, 5)
 
-  def test_create_fast(self):
+  def test_create_fast_cell(self):
 for cell_bytes, (circ_id, key_material) in CREATE_FAST_CELLS.items():
   self.assertEqual(cell_bytes, CreateFastCell.pack(5, circ_id, 
key_material))
 
@@ -156,7 +175,7 @@ class TestCell(unittest.TestCase):
 
 self.assertRaisesRegexp(ValueError, 'Key material should be 20 bytes, but 
was 3', CreateFastCell.pack, 2, 5, 'boo')
 
-  def 

[tor-commits] [stem/master] Add basic socket functions to Relay class

2018-02-07 Thread atagar
commit ad47e6f72cad9ceb61e7ff1dfdc4d8e7755aa0a8
Author: Damian Johnson 
Date:   Sun Feb 4 12:31:07 2018 -0800

Add basic socket functions to Relay class

Like the BaseController, callers will want basic socket passthroughs. Adding
is_alive(), connection_time(), close(), and context management.
---
 stem/control.py |  7 +++
 stem/relay.py   | 40 
 stem/socket.py  |  1 +
 test/integ/client/connection.py | 17 +
 4 files changed, 61 insertions(+), 4 deletions(-)

diff --git a/stem/control.py b/stem/control.py
index 123e3b20..b78707c1 100644
--- a/stem/control.py
+++ b/stem/control.py
@@ -153,8 +153,7 @@ If you're fine with allowing your script to raise 
exceptions then this can be mo
 |- get_socket - provides the socket used for control communication
 |- get_latest_heartbeat - timestamp for when we last heard from tor
 |- add_status_listener - notifies a callback of changes in our status
-|- remove_status_listener - prevents further notification of status changes
-+- __enter__ / __exit__ - manages socket connection
++- remove_status_listener - prevents further notification of status changes
 
 .. data:: State (enum)
 
@@ -674,7 +673,7 @@ class BaseController(object):
   def is_alive(self):
 """
 Checks if our socket is currently connected. This is a pass-through for our
-socket's :func:`~stem.socket.ControlSocket.is_alive` method.
+socket's :func:`~stem.socket.BaseSocket.is_alive` method.
 
 :returns: **bool** that's **True** if our socket is connected and 
**False** otherwise
 """
@@ -729,7 +728,7 @@ class BaseController(object):
   def close(self):
 """
 Closes our socket connection. This is a pass-through for our socket's
-:func:`~stem.socket.ControlSocket.close` method.
+:func:`~stem.socket.BaseSocket.close` method.
 """
 
 self._socket.close()
diff --git a/stem/relay.py b/stem/relay.py
index 20341721..14b7833f 100644
--- a/stem/relay.py
+++ b/stem/relay.py
@@ -13,6 +13,10 @@ a wrapper for :class:`~stem.socket.RelaySocket`, much the 
same way as
 
   Relay - Connection with a tor relay's ORPort.
 | +- connect - Establishes a connection with a relay.
+|
+|- is_alive - reports if our connection is open or closed
+|- connection_time - time when we last connected or disconnected
++- close - shuts down our connection
 """
 
 import stem
@@ -95,3 +99,39 @@ class Relay(object):
 conn.send(stem.client.cell.NetinfoCell(stem.client.Address(address, 
addr_type), []).pack(link_protocol))
 
 return Relay(conn, link_protocol)
+
+  def is_alive(self):
+"""
+Checks if our socket is currently connected. This is a pass-through for our
+socket's :func:`~stem.socket.BaseSocket.is_alive` method.
+
+:returns: **bool** that's **True** if our socket is connected and 
**False** otherwise
+"""
+
+return self._orport.is_alive()
+
+  def connection_time(self):
+"""
+Provides the unix timestamp for when our socket was either connected or
+disconnected. That is to say, the time we connected if we're currently
+connected and the time we disconnected if we're not connected.
+
+:returns: **float** for when we last connected or disconnected, zero if
+  we've never connected
+"""
+
+return self._orport.connection_time()
+
+  def close(self):
+"""
+Closes our socket connection. This is a pass-through for our socket's
+:func:`~stem.socket.BaseSocket.close` method.
+"""
+
+return self._orport.close()
+
+  def __enter__(self):
+return self
+
+  def __exit__(self, exit_type, value, traceback):
+self.close()
diff --git a/stem/socket.py b/stem/socket.py
index 7a2ec9de..bde68cc9 100644
--- a/stem/socket.py
+++ b/stem/socket.py
@@ -60,6 +60,7 @@ Tor...
 |
 |- is_alive - reports if the socket is known to be closed
 |- is_localhost - returns if the socket is for the local system or not
+|- connection_time - timestamp when socket last connected or disconnected
 |- connect - connects a new socket
 |- close - shuts down the socket
 +- __enter__ / __exit__ - manages socket connection
diff --git a/test/integ/client/connection.py b/test/integ/client/connection.py
index bb6ae762..f5399a71 100644
--- a/test/integ/client/connection.py
+++ b/test/integ/client/connection.py
@@ -2,6 +2,7 @@
 Integration tests for establishing a connection with tor's ORPort.
 """
 
+import time
 import unittest
 
 import stem
@@ -40,6 +41,22 @@ class TestConnection(unittest.TestCase):
 for link_protocol in (1, 2, 6, 20):
   self.assertRaisesRegexp(stem.SocketError, 'Unable to establish a common 
link protocol with 127.0.0.1:1113', Relay.connect, '127.0.0.1', 
test.runner.ORPORT, [link_protocol])
 
+  def test_connection_time(self):
+"""
+Checks duration we've been connected.
+"""
+
+before = time.time()

[tor-commits] [stem/master] Move cell decryption into circuit

2018-02-07 Thread atagar
commit 981760fd7996c849945a1b41e6c304d191267d26
Author: Damian Johnson 
Date:   Mon Feb 5 18:37:00 2018 -0800

Move cell decryption into circuit
---
 stem/client/__init__.py |  4 
 stem/client/cell.py | 21 ++---
 2 files changed, 10 insertions(+), 15 deletions(-)

diff --git a/stem/client/__init__.py b/stem/client/__init__.py
index 4f9ed17c..8d34b626 100644
--- a/stem/client/__init__.py
+++ b/stem/client/__init__.py
@@ -234,6 +234,10 @@ class Circuit(object):
   encrypted_payload = header + self.forward_key.update(payload)
 
   self.relay._orport.send(encrypted_payload)
+  reply = next(stem.client.cell.Cell.unpack(self.relay._orport.recv(), 
self.relay.link_protocol))
+
+  decrypted = self.backward_key.update(reply.pack(3)[3:])
+  return stem.client.cell.RelayCell._unpack(decrypted, self.id, 3)
 except:
   self.forward_digest = orig_digest
   self.forward_key = orig_key
diff --git a/stem/client/cell.py b/stem/client/cell.py
index c4a19940..041e1c39 100644
--- a/stem/client/cell.py
+++ b/stem/client/cell.py
@@ -292,6 +292,7 @@ class RelayCell(CircuitCell):
   :var stem.client.RelayCommand command: command to be issued
   :var int command_int: integer value of our command
   :var bytes data: payload of the cell
+  :var int recognized: zero if endpoint is this hop, non-zero otherwise
   :var int digest: running digest held with the relay
   :var int stream_id: specific stream this concerns
   """
@@ -307,7 +308,7 @@ class RelayCell(CircuitCell):
   VALUE = 3
   IS_FIXED_SIZE = True
 
-  def __init__(self, circ_id, command, data, digest = 0, stream_id = 0, 
raw_content = None):
+  def __init__(self, circ_id, command, data, digest = 0, stream_id = 0, 
recognized = 0):
 if 'hashlib.HASH' in str(type(digest)):
   # Unfortunately hashlib generates from a dynamic private class so
   # isinstance() isn't such a great option.
@@ -323,9 +324,9 @@ class RelayCell(CircuitCell):
 super(RelayCell, self).__init__(circ_id)
 self.command, self.command_int = RelayCommand.get(command)
 self.data = data
+self.recognized = recognized
 self.digest = digest
 self.stream_id = stream_id
-self._raw_content = raw_content
 
 if not stream_id and self.command in STREAM_ID_REQUIRED:
   raise ValueError('%s relay cells require a stream id' % self.command)
@@ -335,7 +336,7 @@ class RelayCell(CircuitCell):
   def pack(self, link_protocol):
 payload = io.BytesIO()
 payload.write(Size.CHAR.pack(self.command_int))
-payload.write(Size.SHORT.pack(0))  # 'recognized' field
+payload.write(Size.SHORT.pack(self.recognized))
 payload.write(Size.SHORT.pack(self.stream_id))
 payload.write(Size.LONG.pack(self.digest))
 payload.write(Size.SHORT.pack(len(self.data)))
@@ -343,28 +344,18 @@ class RelayCell(CircuitCell):
 
 return RelayCell._pack(link_protocol, payload.getvalue(), self.circ_id)
 
-  def decrypt(self, circ):
-# TODO: clearly funky, just a spot to start...
-
-if not self._raw_content:
-  raise ValueError('Only received cells can be decrypted')
-
-decrypted = circ.backward_key.update(self._raw_content)
-return RelayCell._unpack(decrypted, self.circ_id, 3)
-
-
   @classmethod
   def _unpack(cls, content, circ_id, link_protocol):
 orig_content = content
 
 command, content = Size.CHAR.pop(content)
-_, content = Size.SHORT.pop(content)  # 'recognized' field
+recognized, content = Size.SHORT.pop(content)  # 'recognized' field
 stream_id, content = Size.SHORT.pop(content)
 digest, content = Size.LONG.pop(content)
 data_len, content = Size.SHORT.pop(content)
 data, content = split(content, data_len)
 
-return RelayCell(circ_id, command, data, digest, stream_id, orig_content)
+return RelayCell(circ_id, command, data, digest, stream_id, recognized)
 
   def __hash__(self):
 return _hash_attr(self, 'command_int', 'stream_id', 'digest', 'data')



___
tor-commits mailing list
tor-commits@lists.torproject.org
https://lists.torproject.org/cgi-bin/mailman/listinfo/tor-commits


[tor-commits] [stem/master] Replace pack function with a method

2018-02-07 Thread atagar
commit f42ec9286f6dbb50fa164873424a23e067dcf7fd
Author: Damian Johnson 
Date:   Sat Jan 27 17:07:08 2018 -0800

Replace pack function with a method

One sucky thing about python: no method overriding. We can have an instance
method or class method called pack, but not both.

Trivial to get around by renaming one of them but on relfection I suspect an
instance method is where we'll want to go in the long run anyway. Lets run 
with
this for a bit to see how it goes.
---
 stem/client/cell.py  | 272 ++-
 test/unit/client/cell.py |  32 +++---
 2 files changed, 75 insertions(+), 229 deletions(-)

diff --git a/stem/client/cell.py b/stem/client/cell.py
index 37c3d5b9..e2e589f5 100644
--- a/stem/client/cell.py
+++ b/stem/client/cell.py
@@ -126,7 +126,7 @@ class Cell(object):
 return cls._unpack(payload, circ_id, link_version), content
 
   def pack(self, link_version):
-raise NotImplementedError('Unpacking not yet implemented for %s cells' % 
cls.NAME)
+raise NotImplementedError('Unpacking not yet implemented for %s cells' % 
type(self).NAME)
 
   @classmethod
   def _pack(cls, link_version, payload, circ_id = 0):
@@ -223,24 +223,16 @@ class PaddingCell(Cell):
   VALUE = 0
   IS_FIXED_SIZE = True
 
-  def __init__(self, payload):
+  def __init__(self, payload = None):
+if not payload:
+  payload = os.urandom(FIXED_PAYLOAD_LEN)
+elif len(payload) != FIXED_PAYLOAD_LEN:
+  raise ValueError('Padding payload should be %i bytes, but was %i' % 
(FIXED_PAYLOAD_LEN, len(payload)))
+
 self.payload = payload
 
   def pack(self, link_version):
-return PaddingCell.pack(link_version, self.payload)
-
-  @classmethod
-  def pack(cls, link_version, payload = None):
-"""
-Provides a randomized padding payload.
-
-:param int link_version: link protocol version
-:param bytes payload: padding payload
-
-:returns: **bytes** with randomized content
-"""
-
-return cls._pack(link_version, payload if payload else 
os.urandom(FIXED_PAYLOAD_LEN))
+return PaddingCell._pack(link_version, self.payload)
 
   @classmethod
   def _unpack(cls, content, circ_id, link_version):
@@ -297,34 +289,15 @@ class RelayCell(CircuitCell):
   raise ValueError('%s relay cells concern the circuit itself and cannot 
have a stream id' % self.command)
 
   def pack(self, link_version):
-return RelayCell.pack(link_version, self.circ_id, self.command_int, 
self.data, self.digest, self.stream_id)
-
-  @classmethod
-  def pack(cls, link_version, circ_id, command, data, digest, stream_id = 0):
-"""
-Provides payload of a relay cell.
-
-:param int link_version: link protocol version
-:param int circ_id: circuit id
-:param stem.client.RelayCommand command: reason the circuit is being closed
-:param bytes data: payload of the cell
-:param int digest: running digest held with the relay
-:param int stream_id: specific stream this concerns
-
-:returns: **bytes** to close the circuit
-"""
-
-cell = RelayCell(circ_id, command, data, digest, stream_id)
-
 payload = io.BytesIO()
-payload.write(Size.CHAR.pack(cell.command_int))
+payload.write(Size.CHAR.pack(self.command_int))
 payload.write(Size.SHORT.pack(0))  # 'recognized' field
-payload.write(Size.SHORT.pack(cell.stream_id))
-payload.write(Size.LONG.pack(cell.digest))
-payload.write(Size.SHORT.pack(len(cell.data)))
-payload.write(cell.data)
+payload.write(Size.SHORT.pack(self.stream_id))
+payload.write(Size.LONG.pack(self.digest))
+payload.write(Size.SHORT.pack(len(self.data)))
+payload.write(self.data)
 
-return cls._pack(link_version, payload.getvalue(), circ_id)
+return RelayCell._pack(link_version, payload.getvalue(), self.circ_id)
 
   @classmethod
   def _unpack(cls, content, circ_id, link_version):
@@ -353,26 +326,12 @@ class DestroyCell(CircuitCell):
   VALUE = 4
   IS_FIXED_SIZE = True
 
-  def __init__(self, circ_id, reason):
+  def __init__(self, circ_id, reason = stem.client.CloseReason.NONE):
 super(DestroyCell, self).__init__(circ_id)
 self.reason, self.reason_int = stem.client.CloseReason.get(reason)
 
   def pack(self, link_version):
-return DestroyCell.pack(link_version, self.circ_id, self.reason_int)
-
-  @classmethod
-  def pack(cls, link_version, circ_id, reason = stem.client.CloseReason.NONE):
-"""
-Provides payload to close the given circuit.
-
-:param int link_version: link protocol version
-:param int circ_id: circuit id
-:param stem.client.CloseReason reason: reason to close the circuit
-
-:returns: **bytes** to close the circuit
-"""
-
-return cls._pack(link_version, 
Size.CHAR.pack(stem.client.CloseReason.get(reason)[1]), circ_id)
+return DestroyCell._pack(link_version, Size.CHAR.pack(self.reason_int), 
self.circ_id)
 
   @classmethod
   def _unpack(cls, content, circ_id, 

[tor-commits] [stem/master] Replace kdf_tor function with a KDF class

2018-02-07 Thread atagar
commit e2e7b5d58fdc14014df8c476c59457b1b5483c2e
Author: Damian Johnson 
Date:   Tue Jan 30 12:21:04 2018 -0800

Replace kdf_tor function with a KDF class

On reflection callers actually don't care about the KDF-TOR value. Rather, 
they
care about its derived attributes.
---
 stem/client/__init__.py | 47 -
 test/unit/client/kdf_tor.py | 21 +---
 2 files changed, 52 insertions(+), 16 deletions(-)

diff --git a/stem/client/__init__.py b/stem/client/__init__.py
index 663bc048..4c6bdb12 100644
--- a/stem/client/__init__.py
+++ b/stem/client/__init__.py
@@ -12,7 +12,7 @@ a wrapper for :class:`~stem.socket.RelaySocket`, much the 
same way as
 ::
 
   split - splits bytes into substrings
-  kdf_tor - calculates the derived key using the KDF-TOR protocol
+  KDF - KDF-TOR key derivative for TAP, CREATE_FAST handshakes, and hidden 
serivces
 
   Field - Packable and unpackable datatype.
 |- Size - Field of a static size.
@@ -461,24 +461,45 @@ class Certificate(Field):
 return _hash_attr(self, 'type_int', 'value')
 
 
-def kdf_tor(key):
+class KDF(object):
+  """
+  Tor's derived key for TAP, CREATE_FAST handshakes, and hidden service
+  protocols as defined tor-spec section 5.2.1.
+
+  :var bytes key_hash: expected derived key that proves knowledge of our shared
+computed key
+  :var bytes forward_digest: forward digest hash seed
+  :var bytes backward_digest: backward digest hash seed
+  :var bytes forward_key: forward encryption key
+  :var bytes backward_key: backward encryption key
   """
-  Tor's key derivation function used by TAP, CREATE_FAST handshakes, and hidden
-  service protocols as defined in section 5.2.1 of the tor spec.
 
-  :param bytes key: shared key with endpoint (K0 in the spec)
+  def __init__(self, key_material):
+value = KDF._value(key_material)
 
-  :returns: **bytes** with the KDF-TOR of the key
-  """
+self.key_hash, value = split(value, HASH_LEN)
+self.forward_digest, value = split(value, HASH_LEN)
+self.backward_digest, value = split(value, HASH_LEN)
+self.forward_key, value = split(value, KEY_LEN)
+self.backward_key, value = split(value, KEY_LEN)
+
+  @staticmethod
+  def _value(key):
+"""
+Computes the KDF-TOR value...
+
+  K = H(K0 | [00]) | H(K0 | [01]) | H(K0 | [02]) | ...
+"""
 
-  derived_key_len = KEY_LEN * 2 + HASH_LEN * 3
-  derived_key, counter = '', 0
+derived_key = ''
+derived_key_len = KEY_LEN * 2 + HASH_LEN * 3
+counter = 0
 
-  while len(derived_key) < derived_key_len:
-derived_key += hashlib.sha1(key + Size.CHAR.pack(counter)).digest()
-counter += 1
+while len(derived_key) < derived_key_len:
+  derived_key += hashlib.sha1(key + Size.CHAR.pack(counter)).digest()
+  counter += 1
 
-  return derived_key[:derived_key_len]
+return derived_key[:derived_key_len]
 
 
 setattr(Size, 'CHAR', Size('CHAR', 1, '!B'))
diff --git a/test/unit/client/kdf_tor.py b/test/unit/client/kdf_tor.py
index 894d4fae..f356d2cd 100644
--- a/test/unit/client/kdf_tor.py
+++ b/test/unit/client/kdf_tor.py
@@ -14,6 +14,21 @@ DERIVED_2 = 
'\xbc0\xf99\x8e;Te\xbb+\xdb\xabR3l\xb9f?\x07KZC8\xe7\xa15\xd1IS\xd9\
 
 
 class TestKdfTor(unittest.TestCase):
-  def test_kdf_tor(self):
-self.assertEqual(DERIVED_1, stem.client.kdf_tor(KEY_1))
-self.assertEqual(DERIVED_2, stem.client.kdf_tor(KEY_2))
+  def test_kdf_value(self):
+self.assertEqual(DERIVED_1, stem.client.KDF._value(KEY_1))
+self.assertEqual(DERIVED_2, stem.client.KDF._value(KEY_2))
+
+  def test_kdf_attributes(self):
+k1 = stem.client.KDF(KEY_1)
+
self.assertEqual('\xca+\x81\x05\x14\x9d)o\xa6\x82\xe9B\xa8?\xf2\xaf\x85\x1b]6', 
k1.key_hash)
+
self.assertEqual('\xac\xcc\xbc\x91\xb1\xaf\xd7\xe0\xe9\x9dF#\xd8\xdbz\xe8\xe6\xca\x83,',
 k1.forward_digest)
+self.assertEqual('*\xe5scX\xbb+\xca 
\xcb\xa4\xbc\xad\x0f\x95\x0cO\xcc\xac\xf1', k1.backward_digest)
+
self.assertEqual('\xc3\xbe\xc9\xe1\xf4\x90f\xdai\xf3\xf3\xf5\x14\xb5\xb9\x03', 
k1.forward_key)
+self.assertEqual('U\xaf\x1e\x1b\xb1q||\x86A<_\xf7\xa0%\x86', 
k1.backward_key)
+
+k2 = stem.client.KDF(KEY_1)
+
self.assertEqual('\xca+\x81\x05\x14\x9d)o\xa6\x82\xe9B\xa8?\xf2\xaf\x85\x1b]6', 
k2.key_hash)
+
self.assertEqual('\xac\xcc\xbc\x91\xb1\xaf\xd7\xe0\xe9\x9dF#\xd8\xdbz\xe8\xe6\xca\x83,',
 k2.forward_digest)
+self.assertEqual('*\xe5scX\xbb+\xca 
\xcb\xa4\xbc\xad\x0f\x95\x0cO\xcc\xac\xf1', k2.backward_digest)
+
self.assertEqual('\xc3\xbe\xc9\xe1\xf4\x90f\xdai\xf3\xf3\xf5\x14\xb5\xb9\x03', 
k2.forward_key)
+self.assertEqual('U\xaf\x1e\x1b\xb1q||\x86A<_\xf7\xa0%\x86', 
k2.backward_key)



___
tor-commits mailing list
tor-commits@lists.torproject.org
https://lists.torproject.org/cgi-bin/mailman/listinfo/tor-commits


[tor-commits] [stem/master] Change KDF to a named tuple

2018-02-07 Thread atagar
commit 984add2da2e62b8c102f60a671717b240a004bac
Author: Damian Johnson 
Date:   Wed Jan 31 11:57:51 2018 -0800

Change KDF to a named tuple

Been going back and forth on this but yeah, think it's a bit nicer this way.
---
 stem/client/__init__.py | 46 +++--
 test/settings.cfg   |  2 +-
 test/unit/client/__init__.py|  2 +-
 test/unit/client/{kdf_tor.py => kdf.py} | 17 
 4 files changed, 28 insertions(+), 39 deletions(-)

diff --git a/stem/client/__init__.py b/stem/client/__init__.py
index 4c6bdb12..f3e842c6 100644
--- a/stem/client/__init__.py
+++ b/stem/client/__init__.py
@@ -12,7 +12,9 @@ a wrapper for :class:`~stem.socket.RelaySocket`, much the 
same way as
 ::
 
   split - splits bytes into substrings
-  KDF - KDF-TOR key derivative for TAP, CREATE_FAST handshakes, and hidden 
serivces
+
+  KDF - KDF-TOR derivatived attributes
++- from_value - parses key material
 
   Field - Packable and unpackable datatype.
 |- Size - Field of a static size.
@@ -107,6 +109,7 @@ a wrapper for :class:`~stem.socket.RelaySocket`, much the 
same way as
   = ===
 """
 
+import collections
 import hashlib
 import io
 import struct
@@ -461,45 +464,38 @@ class Certificate(Field):
 return _hash_attr(self, 'type_int', 'value')
 
 
-class KDF(object):
+class KDF(collections.namedtuple('KDF', ['key_hash', 'forward_digest', 
'backward_digest', 'forward_key', 'backward_key'])):
   """
-  Tor's derived key for TAP, CREATE_FAST handshakes, and hidden service
-  protocols as defined tor-spec section 5.2.1.
+  Computed KDF-TOR derived values for TAP, CREATE_FAST handshakes, and hidden
+  service protocols as defined tor-spec section 5.2.1.
 
-  :var bytes key_hash: expected derived key that proves knowledge of our shared
-computed key
+  :var bytes key_hash: hash that proves knowledge of our shared key
   :var bytes forward_digest: forward digest hash seed
   :var bytes backward_digest: backward digest hash seed
   :var bytes forward_key: forward encryption key
   :var bytes backward_key: backward encryption key
   """
 
-  def __init__(self, key_material):
-value = KDF._value(key_material)
-
-self.key_hash, value = split(value, HASH_LEN)
-self.forward_digest, value = split(value, HASH_LEN)
-self.backward_digest, value = split(value, HASH_LEN)
-self.forward_key, value = split(value, KEY_LEN)
-self.backward_key, value = split(value, KEY_LEN)
-
   @staticmethod
-  def _value(key):
-"""
-Computes the KDF-TOR value...
-
-  K = H(K0 | [00]) | H(K0 | [01]) | H(K0 | [02]) | ...
-"""
+  def from_value(key_material):
+# Derived key material, as per...
+#
+#   K = H(K0 | [00]) | H(K0 | [01]) | H(K0 | [02]) | ...
 
 derived_key = ''
-derived_key_len = KEY_LEN * 2 + HASH_LEN * 3
 counter = 0
 
-while len(derived_key) < derived_key_len:
-  derived_key += hashlib.sha1(key + Size.CHAR.pack(counter)).digest()
+while len(derived_key) < KEY_LEN * 2 + HASH_LEN * 3:
+  derived_key += hashlib.sha1(key_material + 
Size.CHAR.pack(counter)).digest()
   counter += 1
 
-return derived_key[:derived_key_len]
+key_hash, derived_key = split(derived_key, HASH_LEN)
+forward_digest, derived_key = split(derived_key, HASH_LEN)
+backward_digest, derived_key = split(derived_key, HASH_LEN)
+forward_key, derived_key = split(derived_key, KEY_LEN)
+backward_key, derived_key = split(derived_key, KEY_LEN)
+
+return KDF(key_hash, forward_digest, backward_digest, forward_key, 
backward_key)
 
 
 setattr(Size, 'CHAR', Size('CHAR', 1, '!B'))
diff --git a/test/settings.cfg b/test/settings.cfg
index 7af57181..4080ca2a 100644
--- a/test/settings.cfg
+++ b/test/settings.cfg
@@ -233,7 +233,7 @@ test.unit_tests
 |test.unit.client.size.TestSize
 |test.unit.client.address.TestAddress
 |test.unit.client.certificate.TestCertificate
-|test.unit.client.kdf_tor.TestKdfTor
+|test.unit.client.kdf.TestKDF
 |test.unit.client.cell.TestCell
 |test.unit.connection.authentication.TestAuthenticate
 |test.unit.connection.connect.TestConnect
diff --git a/test/unit/client/__init__.py b/test/unit/client/__init__.py
index ba93b3e6..91d3b2be 100644
--- a/test/unit/client/__init__.py
+++ b/test/unit/client/__init__.py
@@ -6,7 +6,7 @@ __all__ = [
   'address',
   'cell',
   'certificate',
-  'kdf_tor',
+  'kdf',
   'size',
 ]
 
diff --git a/test/unit/client/kdf_tor.py b/test/unit/client/kdf.py
similarity index 59%
rename from test/unit/client/kdf_tor.py
rename to test/unit/client/kdf.py
index f356d2cd..56665d31 100644
--- a/test/unit/client/kdf_tor.py
+++ b/test/unit/client/kdf.py
@@ -1,5 +1,5 @@
 """
-Unit tests for stem.client.kdf_tor.
+Unit tests for stem.client.KDF.
 """
 
 import unittest
@@ -9,24 +9,17 @@ import stem.client
 KEY_1 = 

[tor-commits] [stem/master] Add kdf_tor function

2018-02-07 Thread atagar
commit 73ba1f3506d44e8d65c439b404f7cd40eed5ceb9
Author: Damian Johnson 
Date:   Tue Jan 30 11:35:25 2018 -0800

Add kdf_tor function

Supporting KDF-TOR for the CREATE_FAST handshake. Test data is derived from
what endosome's function provides.
---
 stem/client/__init__.py  | 24 
 stem/client/cell.py  |  3 +--
 test/settings.cfg|  1 +
 test/unit/client/__init__.py |  1 +
 test/unit/client/kdf_tor.py  | 19 +++
 5 files changed, 46 insertions(+), 2 deletions(-)

diff --git a/stem/client/__init__.py b/stem/client/__init__.py
index fb0f899d..663bc048 100644
--- a/stem/client/__init__.py
+++ b/stem/client/__init__.py
@@ -12,6 +12,7 @@ a wrapper for :class:`~stem.socket.RelaySocket`, much the 
same way as
 ::
 
   split - splits bytes into substrings
+  kdf_tor - calculates the derived key using the KDF-TOR protocol
 
   Field - Packable and unpackable datatype.
 |- Size - Field of a static size.
@@ -106,6 +107,7 @@ a wrapper for :class:`~stem.socket.RelaySocket`, much the 
same way as
   = ===
 """
 
+import hashlib
 import io
 import struct
 
@@ -115,6 +117,8 @@ import stem.util.enum
 from stem.util import _hash_attr
 
 ZERO = '\x00'
+HASH_LEN = 20
+KEY_LEN = 16
 
 __all__ = [
   'cell',
@@ -457,6 +461,26 @@ class Certificate(Field):
 return _hash_attr(self, 'type_int', 'value')
 
 
+def kdf_tor(key):
+  """
+  Tor's key derivation function used by TAP, CREATE_FAST handshakes, and hidden
+  service protocols as defined in section 5.2.1 of the tor spec.
+
+  :param bytes key: shared key with endpoint (K0 in the spec)
+
+  :returns: **bytes** with the KDF-TOR of the key
+  """
+
+  derived_key_len = KEY_LEN * 2 + HASH_LEN * 3
+  derived_key, counter = '', 0
+
+  while len(derived_key) < derived_key_len:
+derived_key += hashlib.sha1(key + Size.CHAR.pack(counter)).digest()
+counter += 1
+
+  return derived_key[:derived_key_len]
+
+
 setattr(Size, 'CHAR', Size('CHAR', 1, '!B'))
 setattr(Size, 'SHORT', Size('SHORT', 2, '!H'))
 setattr(Size, 'LONG', Size('LONG', 4, '!L'))
diff --git a/stem/client/cell.py b/stem/client/cell.py
index 59fbc14c..9b0c3274 100644
--- a/stem/client/cell.py
+++ b/stem/client/cell.py
@@ -47,12 +47,11 @@ import sys
 import stem.client
 
 from stem import UNDEFINED
-from stem.client import ZERO, Address, Size, split
+from stem.client import HASH_LEN, ZERO, Address, Size, split
 from stem.util import _hash_attr, datetime_to_unix
 
 FIXED_PAYLOAD_LEN = 509
 AUTH_CHALLENGE_SIZE = 32
-HASH_LEN = 20
 
 
 class Cell(object):
diff --git a/test/settings.cfg b/test/settings.cfg
index 518ae2b2..7af57181 100644
--- a/test/settings.cfg
+++ b/test/settings.cfg
@@ -233,6 +233,7 @@ test.unit_tests
 |test.unit.client.size.TestSize
 |test.unit.client.address.TestAddress
 |test.unit.client.certificate.TestCertificate
+|test.unit.client.kdf_tor.TestKdfTor
 |test.unit.client.cell.TestCell
 |test.unit.connection.authentication.TestAuthenticate
 |test.unit.connection.connect.TestConnect
diff --git a/test/unit/client/__init__.py b/test/unit/client/__init__.py
index 7e745352..ba93b3e6 100644
--- a/test/unit/client/__init__.py
+++ b/test/unit/client/__init__.py
@@ -6,6 +6,7 @@ __all__ = [
   'address',
   'cell',
   'certificate',
+  'kdf_tor',
   'size',
 ]
 
diff --git a/test/unit/client/kdf_tor.py b/test/unit/client/kdf_tor.py
new file mode 100644
index ..894d4fae
--- /dev/null
+++ b/test/unit/client/kdf_tor.py
@@ -0,0 +1,19 @@
+"""
+Unit tests for stem.client.kdf_tor.
+"""
+
+import unittest
+
+import stem.client
+
+KEY_1 = 
'\xec\xec.\xeb7R\xf2\n\xcb\xce\x97\xf4\x86\x82\x19#\x10\x0f\x08\xf0\xa2Z\xdeJ\x8f2\x8cc\xf6\xfa\x0e\t\x83f\xc5\xe2\xb3\x94\xa8\x13'
+KEY_2 = 
'\xe0v\xe4\xfaTB\x91\x1c\x81Gz\xa0\tI\xcb{\xc56\xcfV\xc2\xa0\x19\x9c\x98\x9a\x06\x0e\xc5\xfa\xb0z\x83\xa6\x10\xf6r"

[tor-commits] [stem/master] Initial ORPort integ tests

2018-02-07 Thread atagar
commit 3fe2221ae2bad6d826c05fd0ce96e5c09a21fc01
Author: Damian Johnson 
Date:   Sat Feb 3 14:13:27 2018 -0800

Initial ORPort integ tests

Nothing too interesting yet.
---
 stem/relay.py| 54 +---
 test/integ/__init__.py   |  1 +
 test/integ/client/__init__.py|  7 ++
 test/integ/client/connection.py  | 49 
 test/integ/control/controller.py |  4 +--
 test/runner.py   |  4 ++-
 test/settings.cfg|  1 +
 7 files changed, 103 insertions(+), 17 deletions(-)

diff --git a/stem/relay.py b/stem/relay.py
index 7d1e8282..20341721 100644
--- a/stem/relay.py
+++ b/stem/relay.py
@@ -15,30 +15,34 @@ a wrapper for :class:`~stem.socket.RelaySocket`, much the 
same way as
 | +- connect - Establishes a connection with a relay.
 """
 
+import stem
 import stem.client
 import stem.client.cell
 import stem.socket
 import stem.util.connection
 
-DEFAULT_LINK_VERSIONS = (3, 4, 5)
+DEFAULT_LINK_PROTOCOLS = (3, 4, 5)
 
 
 class Relay(object):
   """
   Connection with a Tor relay's ORPort.
+
+  :var int link_protocol: link protocol version we established
   """
 
-  def __init__(self, orport):
+  def __init__(self, orport, link_protocol):
+self.link_protocol = link_protocol
 self._orport = orport
 
   @staticmethod
-  def connect(address, port, link_versions = DEFAULT_LINK_VERSIONS):
+  def connect(address, port, link_protocols = DEFAULT_LINK_PROTOCOLS):
 """
 Establishes a connection with the given ORPort.
 
 :param str address: ip address of the relay
 :param int port: ORPort of the relay
-:param tuple link_versions: acceptable link protocol versions
+:param tuple link_protocols: acceptable link protocol versions
 
 :raises:
   * **ValueError** if address or port are invalid
@@ -52,20 +56,42 @@ class Relay(object):
 else:
   raise ValueError("'%s' isn't an IPv4 or IPv6 address" % address)
 
-if not stem.util.connection.is_port(port):
+if not stem.util.connection.is_valid_port(port):
   raise ValueError("'%s' isn't a valid port" % port)
+elif not link_protocols:
+  raise ValueError("Connection can't be established without a link 
protocol.")
+
+try:
+  conn = stem.socket.RelaySocket(address, port)
+except stem.SocketError as exc:
+  if 'Connection refused' in str(exc):
+raise stem.SocketError("Failed to connect to %s:%i. Maybe it isn't an 
ORPort?" % (address, port))
+  elif 'SSL: UNKNOWN_PROTOCOL' in str(exc):
+raise stem.SocketError("Failed to SSL authenticate to %s:%i. Maybe it 
isn't an ORPort?" % (address, port))
+  else:
+raise
+
+conn.send(stem.client.cell.VersionsCell(link_protocols).pack())
+response = conn.recv()
+
+# Link negotiation ends right away if we lack a common protocol
+# version. (#25139)
 
-conn = stem.socket.RelaySocket(address, port)
-conn.send(stem.client.cell.VersionsCell(link_versions).pack())
-versions_reply = stem.client.cell.Cell.pop(conn.recv(), 2)[0]
+if not response:
+  conn.close()
+  raise stem.SocketError('Unable to establish a common link protocol with 
%s:%i' % (address, port))
+
+versions_reply = stem.client.cell.Cell.pop(response, 2)[0]
+common_protocols = 
set(link_protocols).intersection(versions_reply.versions)
+
+if not common_protocols:
+  conn.close()
+  raise stem.SocketError('Unable to find a common link protocol. We 
support %s but %s:%i supports %s.' % (', '.join(link_protocols), address, port, 
', '.join(versions_reply.versions)))
 
-# TODO: determine the highest common link versions
 # TODO: we should fill in our address, right?
 # TODO: what happens if we skip the NETINFO?
 
-link_version = 3
-conn.send(stem.client.cell.NetinfoCell(stem.client.Address(address, 
addr_type), []).pack(link_version))
-
-# TODO: what if no link protocol versions are acceptable?
+link_protocol = max(common_protocols)
+conn.send(stem.client.cell.NetinfoCell(stem.client.Address(address, 
addr_type), []).pack(link_protocol))
 
-return Relay(conn)
+return Relay(conn, link_protocol)
diff --git a/test/integ/__init__.py b/test/integ/__init__.py
index 886d1c89..31e6084f 100644
--- a/test/integ/__init__.py
+++ b/test/integ/__init__.py
@@ -3,6 +3,7 @@ Integration tests for the stem library.
 """
 
 __all__ = [
+  'client',
   'connection',
   'control',
   'descriptor',
diff --git a/test/integ/client/__init__.py b/test/integ/client/__init__.py
new file mode 100644
index ..8d77a653
--- /dev/null
+++ b/test/integ/client/__init__.py
@@ -0,0 +1,7 @@
+"""
+Integration tests for tor's ORPort (stem.relay and stem.client).
+"""
+
+__all__ = [
+  'connection',
+]
diff --git a/test/integ/client/connection.py b/test/integ/client/connection.py
new file mode 100644
index ..bb6ae762
--- /dev/null
+++ 

[tor-commits] [stem/master] Support CREATE_FAST and CREATED_FAST cells

2018-02-07 Thread atagar
commit 32188dd28f20170f8d2b2dd1da73e29b47bac1a2
Author: Damian Johnson 
Date:   Sun Jan 21 20:24:35 2018 -0800

Support CREATE_FAST and CREATED_FAST cells
---
 stem/client/cell.py  | 125 ++-
 test/unit/client/cell.py |  31 
 2 files changed, 133 insertions(+), 23 deletions(-)

diff --git a/stem/client/cell.py b/stem/client/cell.py
index 3a596b9c..6f107b79 100644
--- a/stem/client/cell.py
+++ b/stem/client/cell.py
@@ -49,6 +49,7 @@ from stem.util import _hash_attr, datetime_to_unix
 
 FIXED_PAYLOAD_LEN = 509
 AUTH_CHALLENGE_SIZE = 32
+HASH_LEN = 20
 
 
 class Cell(object):
@@ -120,7 +121,7 @@ class Cell(object):
   raise ValueError('%s cell should have a payload of %i bytes, but only 
had %i' % (cls.NAME, payload_len, len(content)))
 
 payload, content = split(content, payload_len)
-return cls._unpack(payload, link_version, circ_id), content
+return cls._unpack(payload, circ_id, link_version), content
 
   @classmethod
   def _pack(cls, link_version, payload, circ_id = 0):
@@ -144,6 +145,15 @@ class Cell(object):
 :raise: **ValueError** if cell type invalid or payload is too large
 """
 
+if isinstance(cls, CircuitCell) and circ_id is None:
+  if cls.NAME.startswith('CREATE'):
+# Since we're initiating the circuit we pick any value from a range
+# that's determined by our link version.
+
+circ_id = 0x8000 if link_version > 3 else 0x01
+  else:
+raise ValueError('%s cells require a circ_id' % cls.NAME)
+
 cell = io.BytesIO()
 cell.write(Size.LONG.pack(circ_id) if link_version > 3 else 
Size.SHORT.pack(circ_id))
 cell.write(Size.CHAR.pack(cls.VALUE))
@@ -189,30 +199,12 @@ class Cell(object):
 class CircuitCell(Cell):
   """
   Cell concerning circuits.
-  """
-
-  @classmethod
-  def _pack(cls, link_version, payload, circ_id):
-"""
-Provides bytes that can be used on the wire for these cell attributes.
-
-:param str name: cell command
-:param int link_version: link protocol version
-:param bytes payload: cell payload
-:param int circ_id: circuit id
-
-:raise: **ValueError** if cell type invalid or payload is too large
-"""
-
-if circ_id is None and cls.NAME.startswith('CREATE'):
-  # Since we're initiating the circuit we pick any value from a range
-  # that's determined by our link version.
 
-  circ_id = 0x8000 if link_version > 3 else 0x01
-else:
-  raise ValueError('%s cells require a circ_id' % cls.NAME)
+  :var int circ_id: circuit id
+  """
 
-return Cell._pack(link_version, payload, circ_id)
+  def __init__(self, circ_id):
+self.circ_id = circ_id
 
 
 class PaddingCell(Cell):
@@ -275,16 +267,103 @@ class DestroyCell(CircuitCell):
 
 
 class CreateFastCell(CircuitCell):
+  """
+  Create a circuit with our first hop. This is lighter weight than further hops
+  because we've already established the relay's identity and secret key.
+
+  :var bytes key_material: randomized key material
+  """
+
   NAME = 'CREATE_FAST'
   VALUE = 5
   IS_FIXED_SIZE = True
 
+  def __init__(self, circ_id, key_material):
+super(CreateFastCell, self).__init__(circ_id)
+self.key_material = key_material
+
+  @classmethod
+  def pack(cls, link_version, circ_id, key_material = None):
+"""
+Provides a randomized circuit construction payload.
+
+:param int link_version: link protocol version
+:param int circ_id: circuit id
+:param bytes key_material: randomized key material
+
+:returns: **bytes** with our randomized key material
+"""
+
+if key_material and len(key_material) != HASH_LEN:
+  raise ValueError('Key material should be %i bytes, but was %i' % 
(HASH_LEN, len(key_material)))
+
+return cls._pack(link_version, key_material if key_material else 
os.urandom(HASH_LEN), circ_id)
+
+  @classmethod
+  def _unpack(cls, content, circ_id, link_version):
+content = content.rstrip(ZERO)
+
+if len(content) != HASH_LEN:
+  raise ValueError('Key material should be %i bytes, but was %i' % 
(HASH_LEN, len(content)))
+
+return CreateFastCell(circ_id, content)
+
+  def __hash__(self):
+return _hash_attr(self, 'key_material')
+
 
 class CreatedFastCell(CircuitCell):
+  """
+  CREATE_FAST reply.
+
+  :var bytes key_material: randomized key material
+  :var bytes derivative_key: hash proving the relay knows our shared key
+  """
+
   NAME = 'CREATED_FAST'
   VALUE = 6
   IS_FIXED_SIZE = True
 
+  def __init__(self, circ_id, key_material, derivative_key):
+super(CreatedFastCell, self).__init__(circ_id)
+self.key_material = key_material
+self.derivative_key = derivative_key
+
+  @classmethod
+  def pack(cls, link_version, circ_id, derivative_key, key_material = None):
+"""
+Provides a randomized circuit construction payload.
+
+:param int link_version: link protocol version
+:param int circ_id: circuit id
+:param 

[tor-commits] [stem/master] Initial attempt at a Circuit class

2018-02-07 Thread atagar
commit ce8d1ff8f922ccda30a9edeef91adf61eded7024
Author: Damian Johnson 
Date:   Wed Jan 31 12:34:28 2018 -0800

Initial attempt at a Circuit class

Haven't a clue if this is close to what we want, but lets just get something
down to get this ball rolling.
---
 stem/client/__init__.py | 38 +++---
 1 file changed, 35 insertions(+), 3 deletions(-)

diff --git a/stem/client/__init__.py b/stem/client/__init__.py
index f3e842c6..0accaa59 100644
--- a/stem/client/__init__.py
+++ b/stem/client/__init__.py
@@ -13,9 +13,6 @@ a wrapper for :class:`~stem.socket.RelaySocket`, much the 
same way as
 
   split - splits bytes into substrings
 
-  KDF - KDF-TOR derivatived attributes
-+- from_value - parses key material
-
   Field - Packable and unpackable datatype.
 |- Size - Field of a static size.
 |- Address - Relay address.
@@ -25,6 +22,9 @@ a wrapper for :class:`~stem.socket.RelaySocket`, much the 
same way as
 |- unpack - decodes content
 +- pop - decodes content with remainder
 
+  KDF - KDF-TOR derivatived attributes
++- from_value - parses key material
+
 .. data:: AddrType (enum)
 
   Form an address takes.
@@ -114,6 +114,7 @@ import hashlib
 import io
 import struct
 
+import stem.prereq
 import stem.util.connection
 import stem.util.enum
 
@@ -498,6 +499,37 @@ class KDF(collections.namedtuple('KDF', ['key_hash', 
'forward_digest', 'backward
 return KDF(key_hash, forward_digest, backward_digest, forward_key, 
backward_key)
 
 
+class Circuit(collections.namedtuple('Circuit', ['id', 'forward_digest', 
'backward_digest', 'forward_key', 'backward_key'])):
+  """
+  Circuit through which requests can be made of a `Tor relay's ORPort
+  `_.
+
+  :var int id: circuit id
+  :var hashlib.sha1 forward_digest: digest for forward integrity check
+  :var hashlib.sha1 backward_digest: digest for backward integrity check
+  :var bytes forward_key: forward encryption key
+  :var bytes backward_key: backward encryption key
+  """
+
+  @staticmethod
+  def from_kdf(circ_id, kdf):
+if not stem.prereq.is_crypto_available():
+  raise ImportError('Circuit construction requires the cryptography 
module')
+
+from cryptography.hazmat.primitives.ciphers import Cipher, algorithms, 
modes
+from cryptography.hazmat.backends import default_backend
+
+ctr = modes.CTR(ZERO * (algorithms.AES.block_size / 8))
+
+return Circuit(
+  circ_id,
+  hashlib.sha1(kdf.forward_digest),
+  hashlib.sha1(kdf.backward_digest),
+  Cipher(algorithms.AES(kdf.forward_key), ctr, 
default_backend()).encryptor(),
+  Cipher(algorithms.AES(kdf.backward_key), ctr, 
default_backend()).decryptor(),
+)
+
+
 setattr(Size, 'CHAR', Size('CHAR', 1, '!B'))
 setattr(Size, 'SHORT', Size('SHORT', 2, '!H'))
 setattr(Size, 'LONG', Size('LONG', 4, '!L'))



___
tor-commits mailing list
tor-commits@lists.torproject.org
https://lists.torproject.org/cgi-bin/mailman/listinfo/tor-commits


[tor-commits] [stem/master] Initial circuit creation function

2018-02-07 Thread atagar
commit 47a331d642f766af9f45d438b16dcf675b602608
Author: Damian Johnson 
Date:   Fri Feb 2 13:35:56 2018 -0800

Initial circuit creation function

Finally our first function that actually interacts with a socket. Just 
circuit
creation to start with. Still needs tests. This is the first tidbit we'll be
able to integ test!
---
 stem/client/__init__.py | 24 ++--
 stem/client/cell.py |  4 ++--
 2 files changed, 24 insertions(+), 4 deletions(-)

diff --git a/stem/client/__init__.py b/stem/client/__init__.py
index 0accaa59..cbeed403 100644
--- a/stem/client/__init__.py
+++ b/stem/client/__init__.py
@@ -499,11 +499,12 @@ class KDF(collections.namedtuple('KDF', ['key_hash', 
'forward_digest', 'backward
 return KDF(key_hash, forward_digest, backward_digest, forward_key, 
backward_key)
 
 
-class Circuit(collections.namedtuple('Circuit', ['id', 'forward_digest', 
'backward_digest', 'forward_key', 'backward_key'])):
+class Circuit(collections.namedtuple('Circuit', ['socket', 'id', 
'forward_digest', 'backward_digest', 'forward_key', 'backward_key'])):
   """
   Circuit through which requests can be made of a `Tor relay's ORPort
   `_.
 
+  :var stem.socket.RelaySocket socket: socket through which this circuit has 
been established
   :var int id: circuit id
   :var hashlib.sha1 forward_digest: digest for forward integrity check
   :var hashlib.sha1 backward_digest: digest for backward integrity check
@@ -512,16 +513,35 @@ class Circuit(collections.namedtuple('Circuit', ['id', 
'forward_digest', 'backwa
   """
 
   @staticmethod
-  def from_kdf(circ_id, kdf):
+  def create(relay_socket, circ_id, link_version):
+"""
+Constructs a new circuit over the given ORPort.
+"""
+
 if not stem.prereq.is_crypto_available():
   raise ImportError('Circuit construction requires the cryptography 
module')
 
 from cryptography.hazmat.primitives.ciphers import Cipher, algorithms, 
modes
 from cryptography.hazmat.backends import default_backend
 
+create_fast_cell = stem.client.cell.CreateFastCell(circ_id)
+relay_socket.send(create_fast_cell.pack(link_version))
+
+response = stem.client.cell.Cell.unpack(relay_socket.recv(), link_version)
+created_fast_cells = filter(lambda cell: isinstance(cell, 
stem.client.cell.CreatedFastCell), response)
+
+if not created_fast_cells:
+  raise ValueError('We should get a CREATED_FAST response from a 
CREATE_FAST request')
+
+created_fast_cell = created_fast_cells[0]
+kdf = KDF.from_value(create_fast_cell.key_material + 
created_fast_cell.key_material)
 ctr = modes.CTR(ZERO * (algorithms.AES.block_size / 8))
 
+if created_fast_cell.derivative_key != kdf.key_hash:
+  raise ValueError('Remote failed to prove that it knows our shared key')
+
 return Circuit(
+  relay_socket,
   circ_id,
   hashlib.sha1(kdf.forward_digest),
   hashlib.sha1(kdf.backward_digest),
diff --git a/stem/client/cell.py b/stem/client/cell.py
index 9b0c3274..2bae4fc5 100644
--- a/stem/client/cell.py
+++ b/stem/client/cell.py
@@ -277,7 +277,7 @@ class RelayCell(CircuitCell):
   """
   Command concerning a relay circuit.
 
-  :var stem.client.RelayCommand command: reason the circuit is being closed
+  :var stem.client.RelayCommand command: command to be issued
   :var int command_int: integer value of our command
   :var bytes data: payload of the cell
   :var int digest: running digest held with the relay
@@ -295,7 +295,7 @@ class RelayCell(CircuitCell):
   VALUE = 3
   IS_FIXED_SIZE = True
 
-  def __init__(self, circ_id, command, data, digest, stream_id = 0):
+  def __init__(self, circ_id, command, data, digest = 0, stream_id = 0):
 super(RelayCell, self).__init__(circ_id)
 self.command, self.command_int = stem.client.RelayCommand.get(command)
 self.data = data



___
tor-commits mailing list
tor-commits@lists.torproject.org
https://lists.torproject.org/cgi-bin/mailman/listinfo/tor-commits


[tor-commits] [stem/master] Initial RelayCell class

2018-02-07 Thread atagar
commit 961600046020086be4ead33bff0a35d6a79bee07
Author: Damian Johnson 
Date:   Wed Jan 24 12:36:22 2018 -0800

Initial RelayCell class

No test yet since I'm having trouble getting data I'm seeing from Endosome 
to
match up. Trouble is probably that this is the first encrypted cell type.
---
 stem/client/__init__.py | 20 +
 stem/client/cell.py | 77 +
 2 files changed, 92 insertions(+), 5 deletions(-)

diff --git a/stem/client/__init__.py b/stem/client/__init__.py
index 42ce9966..0c900fb7 100644
--- a/stem/client/__init__.py
+++ b/stem/client/__init__.py
@@ -209,6 +209,26 @@ CloseReason = _IntegerEnum(
   ('NOSUCHSERVICE', 12),
 )
 
+STREAM_ID_REQUIRED = (
+  RelayCommand.BEGIN,
+  RelayCommand.DATA,
+  RelayCommand.END,
+  RelayCommand.CONNECTED,
+  RelayCommand.RESOLVE,
+  RelayCommand.RESOLVED,
+  RelayCommand.BEGIN_DIR,
+)
+
+STREAM_ID_DISALLOWED = (
+  RelayCommand.EXTEND,
+  RelayCommand.EXTENDED,
+  RelayCommand.TRUNCATE,
+  RelayCommand.TRUNCATED,
+  RelayCommand.DROP,
+  RelayCommand.EXTEND2,
+  RelayCommand.EXTENDED2,
+)
+
 
 def split(content, size):
   """
diff --git a/stem/client/cell.py b/stem/client/cell.py
index 9813a85e..e6f08b0b 100644
--- a/stem/client/cell.py
+++ b/stem/client/cell.py
@@ -43,8 +43,10 @@ import os
 import random
 import sys
 
+import stem.client
+
 from stem import UNDEFINED
-from stem.client import ZERO, Address, Certificate, CloseReason, Size, split
+from stem.client import ZERO, Address, Size, split
 from stem.util import _hash_attr, datetime_to_unix
 
 FIXED_PAYLOAD_LEN = 509
@@ -259,12 +261,77 @@ class RelayCell(CircuitCell):
   Command concerning a relay circuit.
 
   :var stem.client.RelayCommand command: reason the circuit is being closed
+  :var int command_int: integer value of our command
+  :var bytes data: payload of the cell
+  :var int digest: running digest held with the relay
+  :var int stream_id: specific stream this concerns
   """
 
+  # TODO: Relay cells also have a 'recognized' field but from the spec I really
+  # haven't a clue what the heck it is. The spec makes multiple mentions to
+  # "when the 'recognized' field of a RELAY cell is zero" but no mention to if
+  # it's non-zero or what the field actually is. :/
+  #
+  # For now just leaving it out. I'll file a ticket to ask about it later.
+
   NAME = 'RELAY'
   VALUE = 3
   IS_FIXED_SIZE = True
 
+  def __init__(self, circ_id, command, data, digest, stream_id = 0):
+super(RelayCell, self).__init__(circ_id)
+self.command, self.command_int = stem.client.RelayCommand.get(command)
+self.data = data
+self.digest = digest
+self.stream_id = stream_id
+
+if not stream_id and self.command in stem.client.STREAM_ID_REQUIRED:
+  raise ValueError('%s relay cells require a stream id' % self.command)
+elif stream_id and self.command in stem.client.STREAM_ID_DISALLOWED:
+  raise ValueError('%s relay cells concern the circuit itself and cannot 
have a stream id' % self.command)
+
+  @classmethod
+  def pack(cls, link_version, circ_id, command, data, digest, stream_id = 0):
+"""
+Provides payload of a relay cell.
+
+:param int link_version: link protocol version
+:param int circ_id: circuit id
+:param stem.client.RelayCommand command: reason the circuit is being closed
+:param int command_int: integer value of our command
+:param bytes data: payload of the cell
+:param int digest: running digest held with the relay
+:param int stream_id: specific stream this concerns
+
+:returns: **bytes** to close the circuit
+"""
+
+cell = RelayCell(circ_id, command, data, digest, stream_id)
+
+payload = io.BytesIO()
+payload.write(Size.CHAR.pack(cell.command))
+payload.write(Size.SHORT.pack(0))  # 'recognized' field
+payload.write(Size.SHORT.pack(cell.stream_id))
+payload.write(Size.LONG.pack(cell.digest))
+payload.write(Size.SHORT.pack(len(cell.data)))
+payload.write(cell.data)
+
+return cls._pack(link_version, payload.getvalue(), circ_id)
+
+  @classmethod
+  def _unpack(cls, content, circ_id, link_version):
+command, content = Size.CHAR.pop(content)
+_, content = Size.SHORT.pop(content)  # 'recognized' field
+stream_id, content = Size.SHORT.pop(content)
+digest, content = Size.LONG.pop(content)
+data_len, content = Size.SHORT.pop(content)
+data, content = split(content, data_len)
+
+return RelayCell(circ_id, command, data, digest, stream_id)
+
+  def __hash__(self):
+return _hash_attr(self, 'command_int', 'stream_id', 'digest', 'data')
+
 
 class DestroyCell(CircuitCell):
   """
@@ -280,10 +347,10 @@ class DestroyCell(CircuitCell):
 
   def __init__(self, circ_id, reason):
 super(DestroyCell, self).__init__(circ_id)
-self.reason, self.reason_int = CloseReason.get(reason)
+self.reason, self.reason_int = stem.client.CloseReason.get(reason)
 
   @classmethod
-  

[tor-commits] [stem/master] Bundle enums with the numbers they map to

2018-02-07 Thread atagar
commit ab2dfc63394d0caa06a07ce14acc1fd0c784974e
Author: Damian Johnson 
Date:   Tue Jan 23 11:57:56 2018 -0800

Bundle enums with the numbers they map to

Putting this all in one place both makes usage nicer, as well as less error
prone for adding new values.
---
 stem/client/__init__.py | 162 +---
 stem/client/cell.py |  57 +
 2 files changed, 86 insertions(+), 133 deletions(-)

diff --git a/stem/client/__init__.py b/stem/client/__init__.py
index fcd0a238..a247c7ba 100644
--- a/stem/client/__init__.py
+++ b/stem/client/__init__.py
@@ -120,56 +120,93 @@ __all__ = [
   'cell',
 ]
 
-AddrType = stem.util.enum.UppercaseEnum(
-  'HOSTNAME',
-  'IPv4',
-  'IPv6',
-  'ERROR_TRANSIENT',
-  'ERROR_PERMANENT',
-  'UNKNOWN',
+
+class _IntegerEnum(stem.util.enum.Enum):
+  """
+  Integer backed enumeration. Enumerations of this type always have an implicit
+  **UNKNOWN** value for integer values that lack a mapping.
+  """
+
+  def __init__(self, *args):
+self._enum_to_int = {}
+self._int_to_enum = {}
+parent_args = []
+
+for entry in args:
+  if len(entry) == 2:
+enum, int_val = entry
+str_val = enum
+  elif len(entry) == 3:
+enum, str_val, int_val = entry
+  else:
+raise ValueError('IntegerEnums can only be constructed with two or 
three value tuples: %s' % repr(entry))
+
+  self._enum_to_int[enum] = int_val
+  self._int_to_enum[int_val] = enum
+  parent_args.append((enum, str_val))
+
+parent_args.append(('UNKNOWN', 'UNKNOWN'))
+super(_IntegerEnum, self).__init__(*parent_args)
+
+  def get(self, val):
+"""
+Privides the (enum, int_value) tuple for a given value.
+"""
+
+if isinstance(val, int):
+  return self._int_to_enum.get(val, self.UNKNOWN), val
+elif val in self:
+  return val, self._enum_to_int.get(val, val)
+else:
+  raise ValueError('Invalid %s type: %s' % (self.__name__, val))
+
+
+AddrType = _IntegerEnum(
+  ('HOSTNAME', 0),
+  ('IPv4', 4),
+  ('IPv6', 6),
+  ('ERROR_TRANSIENT', 16),
+  ('ERROR_PERMANENT', 17),
 )
 
-RelayCommand = stem.util.enum.Enum(
-  ('BEGIN', 'RELAY_BEGIN'),
-  ('DATA', 'RELAY_DATA'),
-  ('END', 'RELAY_END'),
-  ('CONNECTED', 'RELAY_CONNECTED'),
-  ('SENDME', 'RELAY_SENDME'),
-  ('EXTEND', 'RELAY_EXTEND'),
-  ('EXTENDED', 'RELAY_EXTENDED'),
-  ('TRUNCATE', 'RELAY_TRUNCATE'),
-  ('TRUNCATED', 'RELAY_TRUNCATED'),
-  ('DROP', 'RELAY_DROP'),
-  ('RESOLVE', 'RELAY_RESOLVE'),
-  ('RESOLVED', 'RELAY_RESOLVED'),
-  ('BEGIN_DIR', 'RELAY_BEGIN_DIR'),
-  ('EXTEND2', 'RELAY_EXTEND2'),
-  ('EXTENDED2', 'RELAY_EXTENDED2'),
-  ('UNKNOWN', 'UNKNOWN'),
+RelayCommand = _IntegerEnum(
+  ('BEGIN', 'RELAY_BEGIN', 1),
+  ('DATA', 'RELAY_DATA', 2),
+  ('END', 'RELAY_END', 3),
+  ('CONNECTED', 'RELAY_CONNECTED', 4),
+  ('SENDME', 'RELAY_SENDME', 5),
+  ('EXTEND', 'RELAY_EXTEND', 6),
+  ('EXTENDED', 'RELAY_EXTENDED', 7),
+  ('TRUNCATE', 'RELAY_TRUNCATE', 8),
+  ('TRUNCATED', 'RELAY_TRUNCATED', 9),
+  ('DROP', 'RELAY_DROP', 10),
+  ('RESOLVE', 'RELAY_RESOLVE', 11),
+  ('RESOLVED', 'RELAY_RESOLVED', 12),
+  ('BEGIN_DIR', 'RELAY_BEGIN_DIR', 13),
+  ('EXTEND2', 'RELAY_EXTEND2', 14),
+  ('EXTENDED2', 'RELAY_EXTENDED2', 15),
 )
 
-CertType = stem.util.enum.UppercaseEnum(
-  'LINK',
-  'IDENTITY',
-  'AUTHENTICATE',
-  'UNKNOWN',
+CertType = _IntegerEnum(
+  ('LINK', 1),
+  ('IDENTITY', 2),
+  ('AUTHENTICATE', 3),
 )
 
-CloseReason = stem.util.enum.UppercaseEnum(
-  'NONE',
-  'PROTOCOL',
-  'INTERNAL',
-  'REQUESTED',
-  'HIBERNATING',
-  'RESOURCELIMIT',
-  'CONNECTFAILED',
-  'OR_IDENTITY',
-  'OR_CONN_CLOSED',
-  'FINISHED',
-  'TIMEOUT',
-  'DESTROYED',
-  'NOSUCHSERVICE',
-  'UNKNOWN',
+CloseReason = _IntegerEnum(
+  ('NONE', 0),
+  ('PROTOCOL', 1),
+  ('INTERNAL', 2),
+  ('REQUESTED', 3),
+  ('HIBERNATING', 4),
+  ('RESOURCELIMIT', 5),
+  ('CONNECTFAILED', 6),
+  ('OR_IDENTITY', 7),
+  ('OR_CONN_CLOSED', 8),
+  ('FINISHED', 9),
+  ('TIMEOUT', 10),
+  ('DESTROYED', 11),
+  ('NOSUCHSERVICE', 12),
 )
 
 
@@ -298,25 +335,8 @@ class Address(Field):
   :var bytes value_bin: encoded address value
   """
 
-  TYPE_FOR_INT = {
-0: AddrType.HOSTNAME,
-4: AddrType.IPv4,
-6: AddrType.IPv6,
-16: AddrType.ERROR_TRANSIENT,
-17: AddrType.ERROR_PERMANENT,
-  }
-
-  INT_FOR_TYPE = dict((v, k) for k, v in TYPE_FOR_INT.items())
-
   def __init__(self, addr_type, value):
-if isinstance(addr_type, int):
-  self.type = Address.TYPE_FOR_INT.get(addr_type, AddrType.UNKNOWN)
-  self.type_int = addr_type
-elif addr_type in AddrType:
-  self.type = addr_type
-  self.type_int = Address.INT_FOR_TYPE.get(addr_type, -1)
-else:
-  raise ValueError('Invalid address type: %s' % addr_type)
+self.type, self.type_int = AddrType.get(addr_type)
 
 if self.type == AddrType.IPv4:
   if stem.util.connection.is_valid_ipv4_address(value):
@@ -383,24 +403,8 @@ class 

[tor-commits] [stem/master] Enumerate RELAY cell commands

2018-02-07 Thread atagar
commit dfa5fe1efe6ef62a278c6d7ee642a24018931eef
Author: Damian Johnson 
Date:   Tue Jan 23 11:26:56 2018 -0800

Enumerate RELAY cell commands
---
 stem/client/__init__.py | 51 +
 stem/client/cell.py | 30 +++--
 2 files changed, 79 insertions(+), 2 deletions(-)

diff --git a/stem/client/__init__.py b/stem/client/__init__.py
index 01c6b749..fcd0a238 100644
--- a/stem/client/__init__.py
+++ b/stem/client/__init__.py
@@ -37,6 +37,38 @@ a wrapper for :class:`~stem.socket.RelaySocket`, much the 
same way as
   **UNKNOWN**   unrecognized address type
   = ===
 
+.. data:: RelayCommand (enum)
+
+  Command concerning streams and circuits we've established with a relay.
+  Commands have two characteristics...
+
+  * **forward/backward**: **forward** commands are issued from the orgin,
+whereas **backward** come from the relay
+
+  * **stream/circuit**: **steam** commands concern an individual steam, whereas
+**circuit** concern the entire circuit we've established with a relay
+
+  = ===
+  RelayCommand  Description
+  = ===
+  **BEGIN** begin a stream (**forward**, **stream**)
+  **DATA**  transmit data (**forward/backward**, **stream**)
+  **END**   end a stream (**forward/backward**, **stream**)
+  **CONNECTED** BEGIN reply (**backward**, **stream**)
+  **SENDME**ready to accept more cells (**forward/backward**, 
**stream/circuit**)
+  **EXTEND**extend the circuit through another relay (**forward**, 
**circuit**)
+  **EXTENDED**  EXTEND reply (**backward**, **circuit**)
+  **TRUNCATE**  remove last circuit hop (**forward**, **circuit**)
+  **TRUNCATED** TRUNCATE reply (**backward**, **circuit**)
+  **DROP**  ignorable no-op (**forward/backward**, **circuit**)
+  **RESOLVE**   request DNS resolution (**forward**, **stream**)
+  **RESOLVED**  RESOLVE reply (**backward**, **stream**)
+  **BEGIN_DIR** request descriptor (**forward**, **steam**)
+  **EXTEND2**   ntor EXTEND request (**forward**, **circuit**)
+  **EXTENDED2** EXTEND2 reply (**backward**, **circuit**)
+  **UNKNOWN**   unrecognized command
+  = ===
+
 .. data:: CertType (enum)
 
   Relay certificate type.
@@ -97,6 +129,25 @@ AddrType = stem.util.enum.UppercaseEnum(
   'UNKNOWN',
 )
 
+RelayCommand = stem.util.enum.Enum(
+  ('BEGIN', 'RELAY_BEGIN'),
+  ('DATA', 'RELAY_DATA'),
+  ('END', 'RELAY_END'),
+  ('CONNECTED', 'RELAY_CONNECTED'),
+  ('SENDME', 'RELAY_SENDME'),
+  ('EXTEND', 'RELAY_EXTEND'),
+  ('EXTENDED', 'RELAY_EXTENDED'),
+  ('TRUNCATE', 'RELAY_TRUNCATE'),
+  ('TRUNCATED', 'RELAY_TRUNCATED'),
+  ('DROP', 'RELAY_DROP'),
+  ('RESOLVE', 'RELAY_RESOLVE'),
+  ('RESOLVED', 'RELAY_RESOLVED'),
+  ('BEGIN_DIR', 'RELAY_BEGIN_DIR'),
+  ('EXTEND2', 'RELAY_EXTEND2'),
+  ('EXTENDED2', 'RELAY_EXTENDED2'),
+  ('UNKNOWN', 'UNKNOWN'),
+)
+
 CertType = stem.util.enum.UppercaseEnum(
   'LINK',
   'IDENTITY',
diff --git a/stem/client/cell.py b/stem/client/cell.py
index 76a75108..0f292c10 100644
--- a/stem/client/cell.py
+++ b/stem/client/cell.py
@@ -14,7 +14,7 @@ Messages communicated over a Tor relay's ORPort.
 |- CircuitCell - Circuit management.
 |  |- CreateCell - Create a circuit.  (section 5.1)
 |  |- CreatedCell - Acknowledge create.   (section 5.1)
-|  |- RelayCell - End-to-end data.(section 5.5 and 6)
+|  |- RelayCell - End-to-end data.(section 6.1)
 |  |- DestroyCell - Stop using a circuit. (section 5.4)
 |  |- CreateFastCell - Create a circuit, no PK.   (section 5.1)
 |  |- CreatedFastCell - Circuit created, no PK.   (section 5.1)
@@ -44,7 +44,7 @@ import random
 import sys
 
 from stem import UNDEFINED
-from stem.client import ZERO, Address, Certificate, CloseReason, Size, split
+from stem.client import ZERO, Address, Certificate, CloseReason, RelayCommand, 
Size, split
 from stem.util import _hash_attr, datetime_to_unix
 
 FIXED_PAYLOAD_LEN = 509
@@ -255,10 +255,36 @@ class CreatedCell(CircuitCell):
 
 
 class RelayCell(CircuitCell):
+  """
+  Command concerning a relay circuit.
+
+  :var stem.client.RelayCommand command: reason the circuit is being closed
+  """
+
   NAME = 'RELAY'
   VALUE = 3
   IS_FIXED_SIZE = True
 
+  COMMAND_FOR_INT = {
+1: RelayCommand.BEGIN,
+2: RelayCommand.DATA,
+3: RelayCommand.END,
+4: RelayCommand.CONNECTED,
+5: RelayCommand.SENDME,
+6: RelayCommand.EXTEND,
+7: RelayCommand.EXTENDED,
+8: RelayCommand.TRUNCATE,
+9: RelayCommand.TRUNCATED,
+10: RelayCommand.DROP,
+11: RelayCommand.RESOLVE,
+12: RelayCommand.RESOLVED,
+13: RelayCommand.BEGIN_DIR,
+14: RelayCommand.EXTEND2,
+15: 

[tor-commits] [stem/master] Add pack instance method to Cell classes

2018-02-07 Thread atagar
commit eb65f340e0c9cbc429777dc5ce85aede198da138
Author: Damian Johnson 
Date:   Fri Jan 26 12:46:35 2018 -0800

Add pack instance method to Cell classes

While a class method is useful, it's also nice to be able to easily pack 
when
you have a cell instance.
---
 stem/client/cell.py | 50 --
 1 file changed, 44 insertions(+), 6 deletions(-)

diff --git a/stem/client/cell.py b/stem/client/cell.py
index 4062edcf..37c3d5b9 100644
--- a/stem/client/cell.py
+++ b/stem/client/cell.py
@@ -125,6 +125,9 @@ class Cell(object):
 payload, content = split(content, payload_len)
 return cls._unpack(payload, circ_id, link_version), content
 
+  def pack(self, link_version):
+raise NotImplementedError('Unpacking not yet implemented for %s cells' % 
cls.NAME)
+
   @classmethod
   def _pack(cls, link_version, payload, circ_id = 0):
 """
@@ -223,6 +226,9 @@ class PaddingCell(Cell):
   def __init__(self, payload):
 self.payload = payload
 
+  def pack(self, link_version):
+return PaddingCell.pack(link_version, self.payload)
+
   @classmethod
   def pack(cls, link_version, payload = None):
 """
@@ -290,6 +296,9 @@ class RelayCell(CircuitCell):
 elif stream_id and self.command in stem.client.STREAM_ID_DISALLOWED:
   raise ValueError('%s relay cells concern the circuit itself and cannot 
have a stream id' % self.command)
 
+  def pack(self, link_version):
+return RelayCell.pack(link_version, self.circ_id, self.command_int, 
self.data, self.digest, self.stream_id)
+
   @classmethod
   def pack(cls, link_version, circ_id, command, data, digest, stream_id = 0):
 """
@@ -348,6 +357,9 @@ class DestroyCell(CircuitCell):
 super(DestroyCell, self).__init__(circ_id)
 self.reason, self.reason_int = stem.client.CloseReason.get(reason)
 
+  def pack(self, link_version):
+return DestroyCell.pack(link_version, self.circ_id, self.reason_int)
+
   @classmethod
   def pack(cls, link_version, circ_id, reason = stem.client.CloseReason.NONE):
 """
@@ -389,10 +401,18 @@ class CreateFastCell(CircuitCell):
   VALUE = 5
   IS_FIXED_SIZE = True
 
-  def __init__(self, circ_id, key_material):
+  def __init__(self, circ_id = None, key_material = None):
+if not key_material:
+  key_material = os.urandom(HASH_LEN)
+elif len(key_material) != HASH_LEN:
+  raise ValueError('Key material should be %i bytes, but was %i' % 
(HASH_LEN, len(key_material)))
+
 super(CreateFastCell, self).__init__(circ_id)
 self.key_material = key_material
 
+  def pack(self, link_version):
+return CreateFastCell.pack(link_version, self.circ_id, self.key_material)
+
   @classmethod
   def pack(cls, link_version, circ_id = None, key_material = None):
 """
@@ -405,16 +425,16 @@ class CreateFastCell(CircuitCell):
 :returns: **bytes** with our randomized key material
 """
 
-if circ_id is None:
+cell = CreateFastCell(circ_id, key_material)
+circ_id = cell.circ_id
+
+if not circ_id:
   # When initiating a circuit the v4 link protocol requires us to set the
   # most significant bit. Otherwise any id will do.
 
   circ_id = 0x8000 if link_version >= 4 else 0x01
 
-if key_material and len(key_material) != HASH_LEN:
-  raise ValueError('Key material should be %i bytes, but was %i' % 
(HASH_LEN, len(key_material)))
-
-return cls._pack(link_version, key_material if key_material else 
os.urandom(HASH_LEN), circ_id)
+return cls._pack(link_version, cell.key_material, circ_id)
 
   @classmethod
   def _unpack(cls, content, circ_id, link_version):
@@ -446,6 +466,9 @@ class CreatedFastCell(CircuitCell):
 self.key_material = key_material
 self.derivative_key = derivative_key
 
+  def pack(self, link_version):
+return CreatedFastCell.pack(link_version, self.circ_id, delf.derived_key, 
self.key_material)
+
   @classmethod
   def pack(cls, link_version, circ_id, derivative_key, key_material = None):
 """
@@ -496,6 +519,9 @@ class VersionsCell(Cell):
   def __init__(self, versions):
 self.versions = versions
 
+  def pack(self, link_version):
+return VersionsCell.pack(self.versions)
+
   @classmethod
   def pack(cls, versions):
 """
@@ -544,6 +570,9 @@ class NetinfoCell(Cell):
 self.receiver_address = receiver_address
 self.sender_addresses = sender_addresses
 
+  def pack(self, link_version):
+return NetinfoCell.pack(link_version, self.receiver_address, 
self.sender_address, self.timestamp)
+
   @classmethod
   def pack(cls, link_version, receiver_address, sender_addresses, timestamp = 
None):
 """
@@ -629,6 +658,9 @@ class VPaddingCell(Cell):
   def __init__(self, payload):
 self.payload = payload
 
+  def pack(self, link_version):
+return VPaddingCell.pack(link_version, payload = self.payload)
+
   @classmethod
   def pack(cls, link_version, size = None, payload = None):
 """
@@ -674,6 +706,9 @@ class 

[tor-commits] [stem/master] Use minimum valid circuit id by default for CREATE_FAST

2018-02-07 Thread atagar
commit 6a4f46614043e8423c8a45a203acf6ffcf736952
Author: Damian Johnson 
Date:   Fri Jan 26 12:23:19 2018 -0800

Use minimum valid circuit id by default for CREATE_FAST

To work a CREATE_FAST cell must specify a circuit id. Endosome picks one 
based
on the link version with a similar comment to the one we're including here.
Endosome also has an 'is_initiator' flag which I'm omitting right now since 
I
suspect that's only relevant if we attempt to implement *being* a relay 
which
isn't in the cards right now.
---
 stem/client/cell.py | 8 +++-
 1 file changed, 7 insertions(+), 1 deletion(-)

diff --git a/stem/client/cell.py b/stem/client/cell.py
index a0737765..4062edcf 100644
--- a/stem/client/cell.py
+++ b/stem/client/cell.py
@@ -394,7 +394,7 @@ class CreateFastCell(CircuitCell):
 self.key_material = key_material
 
   @classmethod
-  def pack(cls, link_version, circ_id, key_material = None):
+  def pack(cls, link_version, circ_id = None, key_material = None):
 """
 Provides a randomized circuit construction payload.
 
@@ -405,6 +405,12 @@ class CreateFastCell(CircuitCell):
 :returns: **bytes** with our randomized key material
 """
 
+if circ_id is None:
+  # When initiating a circuit the v4 link protocol requires us to set the
+  # most significant bit. Otherwise any id will do.
+
+  circ_id = 0x8000 if link_version >= 4 else 0x01
+
 if key_material and len(key_material) != HASH_LEN:
   raise ValueError('Key material should be %i bytes, but was %i' % 
(HASH_LEN, len(key_material)))
 



___
tor-commits mailing list
tor-commits@lists.torproject.org
https://lists.torproject.org/cgi-bin/mailman/listinfo/tor-commits


[tor-commits] [stem/master] Support DESTROY cells

2018-02-07 Thread atagar
commit aeb17f9d150a7e3f404a37f57c29759325ab3221
Author: Damian Johnson 
Date:   Mon Jan 22 12:10:21 2018 -0800

Support DESTROY cells
---
 stem/client/__init__.py  | 40 +
 stem/client/cell.py  | 76 ++--
 test/unit/client/cell.py | 20 -
 3 files changed, 132 insertions(+), 4 deletions(-)

diff --git a/stem/client/__init__.py b/stem/client/__init__.py
index 1fd05f9d..01c6b749 100644
--- a/stem/client/__init__.py
+++ b/stem/client/__init__.py
@@ -49,6 +49,29 @@ a wrapper for :class:`~stem.socket.RelaySocket`, much the 
same way as
   **AUTHENTICATE**  RSA1024 AUTHENTICATE cell link certificate
   **UNKNOWN**   unrecognized certificate type
   = ===
+
+.. data:: CloseReason (enum)
+
+  Reason a relay is closed.
+
+  = ===
+  CloseReason   Description
+  = ===
+  **NONE**  no reason given
+  **PROTOCOL**  tor protocol violation
+  **INTERNAL**  internal error
+  **REQUESTED** client sent a TRUNCATE command
+  **HIBERNATING**   relay suspended, trying to save bandwidth
+  **RESOURCELIMIT** out of memory, sockets, or circuit IDs
+  **CONNECTFAILED** unable to reach relay
+  **OR_IDENTITY**   connected, but its OR identity was not as expected
+  **OR_CONN_CLOSED**connection that was carrying this circuit died
+  **FINISHED**  circuit has expired for being dirty or old
+  **TIMEOUT**   circuit construction took too long
+  **DESTROYED** circuit was destroyed without a client TRUNCATE
+  **NOSUCHSERVICE** request was for an unknown hidden service
+  **UNKNOWN**   unrecognized reason
+  = ===
 """
 
 import io
@@ -81,6 +104,23 @@ CertType = stem.util.enum.UppercaseEnum(
   'UNKNOWN',
 )
 
+CloseReason = stem.util.enum.UppercaseEnum(
+  'NONE',
+  'PROTOCOL',
+  'INTERNAL',
+  'REQUESTED',
+  'HIBERNATING',
+  'RESOURCELIMIT',
+  'CONNECTFAILED',
+  'OR_IDENTITY',
+  'OR_CONN_CLOSED',
+  'FINISHED',
+  'TIMEOUT',
+  'DESTROYED',
+  'NOSUCHSERVICE',
+  'UNKNOWN',
+)
+
 
 def split(content, size):
   """
diff --git a/stem/client/cell.py b/stem/client/cell.py
index 6f107b79..76a75108 100644
--- a/stem/client/cell.py
+++ b/stem/client/cell.py
@@ -44,7 +44,7 @@ import random
 import sys
 
 from stem import UNDEFINED
-from stem.client import ZERO, Address, Certificate, Size, split
+from stem.client import ZERO, Address, Certificate, CloseReason, Size, split
 from stem.util import _hash_attr, datetime_to_unix
 
 FIXED_PAYLOAD_LEN = 509
@@ -261,10 +261,80 @@ class RelayCell(CircuitCell):
 
 
 class DestroyCell(CircuitCell):
+  """
+  Closes the given circuit.
+
+  :var stem.client.CloseReason reason: reason the circuit is being closed
+  :var int reason_int: integer value of our closure reason
+  """
+
   NAME = 'DESTROY'
   VALUE = 4
   IS_FIXED_SIZE = True
 
+  REASON_FOR_INT = {
+0: CloseReason.NONE,
+1: CloseReason.PROTOCOL,
+2: CloseReason.INTERNAL,
+3: CloseReason.REQUESTED,
+4: CloseReason.HIBERNATING,
+5: CloseReason.RESOURCELIMIT,
+6: CloseReason.CONNECTFAILED,
+7: CloseReason.OR_IDENTITY,
+8: CloseReason.OR_CONN_CLOSED,
+9: CloseReason.FINISHED,
+10: CloseReason.TIMEOUT,
+11: CloseReason.DESTROYED,
+12: CloseReason.NOSUCHSERVICE,
+  }
+
+  INT_FOR_REASON = dict((v, k) for k, v in REASON_FOR_INT.items())
+
+  def __init__(self, circ_id, reason):
+super(DestroyCell, self).__init__(circ_id)
+
+if isinstance(reason, int):
+  self.reason = DestroyCell.REASON_FOR_INT.get(reason, CloseReason.UNKNOWN)
+  self.reason_int = reason
+elif reason in CloseReason:
+  self.reason = reason
+  self.reason_int = DestroyCell.INT_FOR_REASON.get(reason, -1)
+else:
+  raise ValueError('Invalid closure reason: %s' % reason)
+
+  @classmethod
+  def pack(cls, link_version, circ_id, reason = CloseReason.NONE):
+"""
+Provides payload to close the given circuit.
+
+:param int link_version: link protocol version
+:param int circ_id: circuit id
+:param stem.client.CloseReason reason: reason to close the circuit
+
+:returns: **bytes** to close the circuit
+"""
+
+reason = DestroyCell.INT_FOR_REASON.get(reason, reason)
+
+if not isinstance(reason, int):
+  raise ValueError('Invalid closure reason: %s' % reason)
+
+return cls._pack(link_version, Size.CHAR.pack(reason), circ_id)
+
+  @classmethod
+  def _unpack(cls, content, circ_id, link_version):
+content = content.rstrip(ZERO)
+
+if not content:
+  content = ZERO
+elif len(content) > 1:
+  raise ValueError('Circuit closure reason should be a single byte, but 
was %i' % len(content))
+
+return DestroyCell(circ_id, Size.CHAR.unpack(content))
+
+  def __hash__(self):
+return _hash_attr(self, 'circ_id', 

[tor-commits] [stem/master] Test new enum class

2018-02-07 Thread atagar
commit e64e96f108ad350c59bc83dd257043009aa26de3
Author: Damian Johnson 
Date:   Wed Jan 24 09:34:44 2018 -0800

Test new enum class

We pretty well excercised it via our existing tests, but we didn't 
explicitly
check its error handling.
---
 stem/client/__init__.py | 2 +-
 test/unit/client/address.py | 7 +++
 2 files changed, 8 insertions(+), 1 deletion(-)

diff --git a/stem/client/__init__.py b/stem/client/__init__.py
index a247c7ba..42ce9966 100644
--- a/stem/client/__init__.py
+++ b/stem/client/__init__.py
@@ -158,7 +158,7 @@ class _IntegerEnum(stem.util.enum.Enum):
 elif val in self:
   return val, self._enum_to_int.get(val, val)
 else:
-  raise ValueError('Invalid %s type: %s' % (self.__name__, val))
+  raise ValueError("Invalid enumeration '%s', options are %s" % (val, ', 
'.join(self)))
 
 
 AddrType = _IntegerEnum(
diff --git a/test/unit/client/address.py b/test/unit/client/address.py
index acda251b..f5dc4a00 100644
--- a/test/unit/client/address.py
+++ b/test/unit/client/address.py
@@ -12,6 +12,13 @@ ExpectedAddress = collections.namedtuple('ExpectedAddress', 
['type', 'type_int',
 
 
 class TestAddress(unittest.TestCase):
+  def test_enum(self):
+self.assertEqual(('IPv4', 4), AddrType.get(AddrType.IPv4))
+self.assertEqual(('IPv4', 4), AddrType.get(4))
+
+self.assertEqual(('UNKNOWN', 25), AddrType.get(25))
+self.assertRaisesRegexp(ValueError, "Invalid enumeration 'boom', options 
are HOSTNAME, IPv4, IPv6, ERROR_TRANSIENT, ERROR_PERMANENT, UNKNOWN", 
AddrType.get, 'boom')
+
   def test_constructor(self):
 test_data = (
   ((4, '\x7f\x00\x00\x01'), ExpectedAddress(AddrType.IPv4, 4, '127.0.0.1', 
'\x7f\x00\x00\x01')),



___
tor-commits mailing list
tor-commits@lists.torproject.org
https://lists.torproject.org/cgi-bin/mailman/listinfo/tor-commits


[tor-commits] [translation/mat-gui] Update translations for mat-gui

2018-02-07 Thread translation
commit fc9fa5327192ec912b85ac93f93b21c276c20237
Author: Translation commit bot 
Date:   Wed Feb 7 18:46:27 2018 +

Update translations for mat-gui
---
 ti.po | 2 +-
 1 file changed, 1 insertion(+), 1 deletion(-)

diff --git a/ti.po b/ti.po
index d4146d1e7..a4f7160a6 100644
--- a/ti.po
+++ b/ti.po
@@ -8,7 +8,7 @@ msgstr ""
 "Project-Id-Version: The Tor Project\n"
 "Report-Msgid-Bugs-To: \n"
 "POT-Creation-Date: 2016-02-10 23:06+0100\n"
-"PO-Revision-Date: 2018-02-05 22:56+\n"
+"PO-Revision-Date: 2018-02-07 18:38+\n"
 "Last-Translator: carolyn \n"
 "Language-Team: Tigrinya 
(http://www.transifex.com/otf/torproject/language/ti/)\n"
 "MIME-Version: 1.0\n"

___
tor-commits mailing list
tor-commits@lists.torproject.org
https://lists.torproject.org/cgi-bin/mailman/listinfo/tor-commits


[tor-commits] [tor/master] remove blank line between function-comment and function

2018-02-07 Thread arma
commit bf91da75abf84a6a61aa92adc5156ba1d5c15998
Author: Roger Dingledine 
Date:   Wed Feb 7 12:51:05 2018 -0500

remove blank line between function-comment and function

also be more consistent about punctuation in doxygen comments
---
 src/or/channel.c| 268 ++--
 src/or/channel.h|   1 -
 src/or/channeltls.c | 109 +++--
 3 files changed, 130 insertions(+), 248 deletions(-)

diff --git a/src/or/channel.c b/src/or/channel.c
index f1d3ea6e2..ff1cfde2a 100644
--- a/src/or/channel.c
+++ b/src/or/channel.c
@@ -52,7 +52,6 @@
  * Define this so channel.h gives us things only channel_t subclasses
  * should touch.
  */
-
 #define TOR_CHANNEL_INTERNAL_
 
 /* This one's for stuff only channel.c and the test suite should see */
@@ -175,9 +174,8 @@ static void channel_listener_force_xfree(channel_listener_t 
*chan_l);
  **/
 
 /**
- * Indicate whether a given channel state is valid
+ * Indicate whether a given channel state is valid.
  */
-
 int
 channel_state_is_valid(channel_state_t state)
 {
@@ -201,9 +199,8 @@ channel_state_is_valid(channel_state_t state)
 }
 
 /**
- * Indicate whether a given channel listener state is valid
+ * Indicate whether a given channel listener state is valid.
  */
-
 int
 channel_listener_state_is_valid(channel_listener_state_t state)
 {
@@ -225,13 +222,12 @@ channel_listener_state_is_valid(channel_listener_state_t 
state)
 }
 
 /**
- * Indicate whether a channel state transition is valid
+ * Indicate whether a channel state transition is valid.
  *
  * This function takes two channel states and indicates whether a
  * transition between them is permitted (see the state definitions and
  * transition table in or.h at the channel_state_t typedef).
  */
-
 int
 channel_state_can_transition(channel_state_t from, channel_state_t to)
 {
@@ -272,13 +268,12 @@ channel_state_can_transition(channel_state_t from, 
channel_state_t to)
 }
 
 /**
- * Indicate whether a channel listener state transition is valid
+ * Indicate whether a channel listener state transition is valid.
  *
  * This function takes two channel listener states and indicates whether a
  * transition between them is permitted (see the state definitions and
  * transition table in or.h at the channel_listener_state_t typedef).
  */
-
 int
 channel_listener_state_can_transition(channel_listener_state_t from,
   channel_listener_state_t to)
@@ -309,9 +304,8 @@ 
channel_listener_state_can_transition(channel_listener_state_t from,
 }
 
 /**
- * Return a human-readable description for a channel state
+ * Return a human-readable description for a channel state.
  */
-
 const char *
 channel_state_to_string(channel_state_t state)
 {
@@ -345,9 +339,8 @@ channel_state_to_string(channel_state_t state)
 }
 
 /**
- * Return a human-readable description for a channel listenier state
+ * Return a human-readable description for a channel listener state.
  */
-
 const char *
 channel_listener_state_to_string(channel_listener_state_t state)
 {
@@ -379,12 +372,11 @@ channel_listener_state_to_string(channel_listener_state_t 
state)
  ***/
 
 /**
- * Register a channel
+ * Register a channel.
  *
  * This function registers a newly created channel in the global lists/maps
  * of active channels.
  */
-
 void
 channel_register(channel_t *chan)
 {
@@ -437,12 +429,11 @@ channel_register(channel_t *chan)
 }
 
 /**
- * Unregister a channel
+ * Unregister a channel.
  *
  * This function removes a channel from the global lists and maps and is used
  * when freeing a closed/errored channel.
  */
-
 void
 channel_unregister(channel_t *chan)
 {
@@ -477,12 +468,11 @@ channel_unregister(channel_t *chan)
 }
 
 /**
- * Register a channel listener
+ * Register a channel listener.
  *
- * This function registers a newly created channel listner in the global
+ * This function registers a newly created channel listener in the global
  * lists/maps of active channel listeners.
  */
-
 void
 channel_listener_register(channel_listener_t *chan_l)
 {
@@ -519,12 +509,11 @@ channel_listener_register(channel_listener_t *chan_l)
 }
 
 /**
- * Unregister a channel listener
+ * Unregister a channel listener.
  *
  * This function removes a channel listener from the global lists and maps
  * and is used when freeing a closed/errored channel listener.
  */
-
 void
 channel_listener_unregister(channel_listener_t *chan_l)
 {
@@ -555,13 +544,12 @@ channel_listener_unregister(channel_listener_t *chan_l)
  */
 
 /**
- * Add a channel to the digest map
+ * Add a channel to the digest map.
  *
  * This function adds a channel to the digest map and inserts it into the
  * correct linked list if channels with that remote endpoint identity digest
  * already exist.
  */
-
 STATIC void
 channel_add_to_digest_map(channel_t *chan)
 {
@@ -594,12 +582,11 @@ 

[tor-commits] [tor/master] rephist: Stop tracking relay connection status

2018-02-07 Thread nickm
commit 93ebcc2b8f8f22f2628cf74cc92674c8fbeb7b9a
Author: David Goulet 
Date:   Tue Feb 6 12:51:43 2018 -0500

rephist: Stop tracking relay connection status

Remove a series of connection counters that were only used when dumping the
rephist statistics with SIGUSR1 signal.

This reduces the or_history_t structure size.

Closes #25163

Signed-off-by: David Goulet 
---
 changes/ticket25163|   4 ++
 src/or/channel.c   |   1 -
 src/or/connection_or.c |   4 --
 src/or/rephist.c   | 140 +
 src/or/rephist.h   |   4 --
 5 files changed, 5 insertions(+), 148 deletions(-)

diff --git a/changes/ticket25163 b/changes/ticket25163
new file mode 100644
index 0..6d237db75
--- /dev/null
+++ b/changes/ticket25163
@@ -0,0 +1,4 @@
+  o Code simplification and refactoring (rephist):
+- Remove a series of counters used to track circuit extend attemps and
+  connection status but that in reality we aren't using for anything other
+  than stats logged by a SIGUSR1 signal. Closes ticket 25163.
diff --git a/src/or/channel.c b/src/or/channel.c
index 1afd45190..8db974bb3 100644
--- a/src/or/channel.c
+++ b/src/or/channel.c
@@ -1884,7 +1884,6 @@ channel_do_open_actions(channel_t *chan)
 
   if (started_here) {
 circuit_build_times_network_is_live(get_circuit_build_times_mutable());
-rep_hist_note_connect_succeeded(chan->identity_digest, now);
 router_set_status(chan->identity_digest, 1);
   } else {
 /* only report it to the geoip module if it's not a known router */
diff --git a/src/or/connection_or.c b/src/or/connection_or.c
index 455bb66cb..272a086a3 100644
--- a/src/or/connection_or.c
+++ b/src/or/connection_or.c
@@ -705,7 +705,6 @@ connection_or_finished_connecting(or_connection_t *or_conn)
 void
 connection_or_about_to_close(or_connection_t *or_conn)
 {
-  time_t now = time(NULL);
   connection_t *conn = TO_CONN(or_conn);
 
   /* Tell the controlling channel we're closed */
@@ -725,7 +724,6 @@ connection_or_about_to_close(or_connection_t *or_conn)
 if (connection_or_nonopen_was_started_here(or_conn)) {
   const or_options_t *options = get_options();
   connection_or_note_state_when_broken(or_conn);
-  rep_hist_note_connect_failed(or_conn->identity_digest, now);
   /* Tell the new guard API about the channel failure */
   entry_guard_chan_failed(TLS_CHAN_TO_BASE(or_conn->chan));
   if (conn->state >= OR_CONN_STATE_TLS_HANDSHAKING) {
@@ -741,11 +739,9 @@ connection_or_about_to_close(or_connection_t *or_conn)
   } else if (conn->hold_open_until_flushed) {
 /* We only set hold_open_until_flushed when we're intentionally
  * closing a connection. */
-rep_hist_note_disconnect(or_conn->identity_digest, now);
 control_event_or_conn_status(or_conn, OR_CONN_EVENT_CLOSED,
 tls_error_to_orconn_end_reason(or_conn->tls_error));
   } else if (!tor_digest_is_zero(or_conn->identity_digest)) {
-rep_hist_note_connection_died(or_conn->identity_digest, now);
 control_event_or_conn_status(or_conn, OR_CONN_EVENT_CLOSED,
 tls_error_to_orconn_end_reason(or_conn->tls_error));
   }
diff --git a/src/or/rephist.c b/src/or/rephist.c
index 7d5394da2..830cd6826 100644
--- a/src/or/rephist.c
+++ b/src/or/rephist.c
@@ -116,20 +116,6 @@ typedef struct or_history_t {
   time_t since;
   /** When did we most recently note a change to this OR? */
   time_t changed;
-  /** How many times did we successfully connect? */
-  unsigned long n_conn_ok;
-  /** How many times did we try to connect and fail?*/
-  unsigned long n_conn_fail;
-  /** How many seconds have we been connected to this OR before
-   * 'up_since'? */
-  unsigned long uptime;
-  /** How many seconds have we been unable to connect to this OR before
-   * 'down_since'? */
-  unsigned long downtime;
-  /** If nonzero, we have been connected since this time. */
-  time_t up_since;
-  /** If nonzero, we have been unable to connect since this time. */
-  time_t down_since;
 
   /** The address at which we most recently connected to this OR
* successfully. */
@@ -233,23 +219,6 @@ free_or_history(void *_hist)
   tor_free(hist);
 }
 
-/** Update an or_history_t object hist so that its uptime/downtime
- * count is up-to-date as of when.
- */
-static void
-update_or_history(or_history_t *hist, time_t when)
-{
-  tor_assert(hist);
-  if (hist->up_since) {
-tor_assert(!hist->down_since);
-hist->uptime += (when - hist->up_since);
-hist->up_since = when;
-  } else if (hist->down_since) {
-hist->downtime += (when - hist->down_since);
-hist->down_since = when;
-  }
-}
-
 /** Initialize the static data structures for tracking history. */
 void
 rep_hist_init(void)
@@ -259,99 +228,6 @@ rep_hist_init(void)
   predicted_ports_alloc();
 }
 
-/** Helper: note that we are no longer connected to the router with history
- * hist.  If 

[tor-commits] [tor/master] Merge remote-tracking branch 'dgoulet/ticket25163_033_01'

2018-02-07 Thread nickm
commit 12b58ba551311db26ef6d769a5ee6eee9c294e01
Merge: a7440d9c9 93ebcc2b8
Author: Nick Mathewson 
Date:   Wed Feb 7 12:46:27 2018 -0500

Merge remote-tracking branch 'dgoulet/ticket25163_033_01'

 changes/ticket25163|   4 +
 src/or/channel.c   |   1 -
 src/or/circuitbuild.c  |  40 ---
 src/or/circuitbuild.h  |   1 -
 src/or/circuitlist.c   |   4 +-
 src/or/connection_or.c |   4 -
 src/or/rephist.c   | 281 ++---
 src/or/rephist.h   |   7 --
 8 files changed, 11 insertions(+), 331 deletions(-)

___
tor-commits mailing list
tor-commits@lists.torproject.org
https://lists.torproject.org/cgi-bin/mailman/listinfo/tor-commits


[tor-commits] [tor/master] rephist: Stop tracking EXTEND attempts

2018-02-07 Thread nickm
commit 199bc37290d60b155bdd4c82c5f2d4b9096bd496
Author: David Goulet 
Date:   Tue Feb 6 12:43:55 2018 -0500

rephist: Stop tracking EXTEND attempts

This removes the code that tracks the extend attemps a client makes. We 
don't
use it and it was only used to provide statistics on a SIGUSR1 from the
rephist dump stats function.

Part of #25163

Signed-off-by: David Goulet 
---
 src/or/circuitbuild.c |  40 --
 src/or/circuitbuild.h |   1 -
 src/or/circuitlist.c  |   4 +-
 src/or/rephist.c  | 141 ++
 src/or/rephist.h  |   3 --
 5 files changed, 6 insertions(+), 183 deletions(-)

diff --git a/src/or/circuitbuild.c b/src/or/circuitbuild.c
index 9c049a24b..b05ed033c 100644
--- a/src/or/circuitbuild.c
+++ b/src/or/circuitbuild.c
@@ -347,45 +347,6 @@ circuit_log_path(int severity, unsigned int domain, 
origin_circuit_t *circ)
   tor_free(s);
 }
 
-/** Tell the rep(utation)hist(ory) module about the status of the links
- * in circ.  Hops that have become OPEN are marked as successfully
- * extended; the _first_ hop that isn't open (if any) is marked as
- * unable to extend.
- */
-/*  Someday we should learn from OR circuits too. */
-void
-circuit_rep_hist_note_result(origin_circuit_t *circ)
-{
-  crypt_path_t *hop;
-  const char *prev_digest = NULL;
-  hop = circ->cpath;
-  if (!hop) /* circuit hasn't started building yet. */
-return;
-  if (server_mode(get_options())) {
-const routerinfo_t *me = router_get_my_routerinfo();
-if (!me)
-  return;
-prev_digest = me->cache_info.identity_digest;
-  }
-  do {
-const node_t *node = node_get_by_id(hop->extend_info->identity_digest);
-if (node) { /* Why do we check this?  We know the identity. -NM  */
-  if (prev_digest) {
-if (hop->state == CPATH_STATE_OPEN)
-  rep_hist_note_extend_succeeded(prev_digest, node->identity);
-else {
-  rep_hist_note_extend_failed(prev_digest, node->identity);
-  break;
-}
-  }
-  prev_digest = node->identity;
-} else {
-  prev_digest = NULL;
-}
-hop=hop->next;
-  } while (hop!=circ->cpath);
-}
-
 /** Return 1 iff every node in circ's cpath definitely supports ntor. */
 static int
 circuit_cpath_supports_ntor(const origin_circuit_t *circ)
@@ -1075,7 +1036,6 @@ circuit_build_no_more_hops(origin_circuit_t *circ)
   }
 
   pathbias_count_build_success(circ);
-  circuit_rep_hist_note_result(circ);
   if (is_usable_for_streams)
 circuit_has_opened(circ); /* do other actions as necessary */
 
diff --git a/src/or/circuitbuild.h b/src/or/circuitbuild.h
index 101447766..bea31ad0d 100644
--- a/src/or/circuitbuild.h
+++ b/src/or/circuitbuild.h
@@ -17,7 +17,6 @@ char *circuit_list_path(origin_circuit_t *circ, int verbose);
 char *circuit_list_path_for_controller(origin_circuit_t *circ);
 void circuit_log_path(int severity, unsigned int domain,
   origin_circuit_t *circ);
-void circuit_rep_hist_note_result(origin_circuit_t *circ);
 origin_circuit_t *origin_circuit_init(uint8_t purpose, int flags);
 origin_circuit_t *circuit_establish_circuit(uint8_t purpose,
 extend_info_t *exit,
diff --git a/src/or/circuitlist.c b/src/or/circuitlist.c
index 8c02cd1c1..2704798eb 100644
--- a/src/or/circuitlist.c
+++ b/src/or/circuitlist.c
@@ -1986,8 +1986,7 @@ circuit_mark_all_dirty_circs_as_unusable(void)
  *   - If state is onionskin_pending, remove circ from the onion_pending
  * list.
  *   - If circ isn't open yet: call circuit_build_failed() if we're
- * the origin, and in either case call circuit_rep_hist_note_result()
- * to note stats.
+ * the origin.
  *   - If purpose is C_INTRODUCE_ACK_WAIT, report the intro point
  * failure we just had to the hidden service client module.
  *   - If purpose is C_INTRODUCING and reason isn't TIMEOUT,
@@ -2123,7 +2122,6 @@ circuit_about_to_free(circuit_t *circ)
 if (CIRCUIT_IS_ORIGIN(circ)) {
   origin_circuit_t *ocirc = TO_ORIGIN_CIRCUIT(circ);
   circuit_build_failed(ocirc); /* take actions if necessary */
-  circuit_rep_hist_note_result(ocirc);
 }
   }
   if (circ->state == CIRCUIT_STATE_CHAN_WAIT) {
diff --git a/src/or/rephist.c b/src/or/rephist.c
index 15fb674ff..7d5394da2 100644
--- a/src/or/rephist.c
+++ b/src/or/rephist.c
@@ -110,18 +110,6 @@ uint32_t rephist_total_num=0;
  * 20X as much as one that ended a month ago, and routers that have had no
  * uptime data for about half a year will get forgotten.) */
 
-/** History of an OR-\>OR link. */
-typedef struct link_history_t {
-  /** When did we start tracking this list? */
-  time_t since;
-  /** When did we most recently note a change to this link */
-  time_t changed;
-  /** How many times did extending from OR1 to OR2 succeed? */
-  unsigned long n_extend_ok;
-  /** How many times did extending from 

[tor-commits] [tor/master] more fixes for typos, grammar, whitespace, etc

2018-02-07 Thread arma
commit a7440d9c9df1141a5ff52c1358bc28a8bb27bea3
Author: Roger Dingledine 
Date:   Wed Feb 7 12:22:29 2018 -0500

more fixes for typos, grammar, whitespace, etc

some of these ought to have been noticed by the "misspell" tool,
so if anybody is debugging it, here are some bug reports :)
---
 ChangeLog   |  2 +-
 ReleaseNotes|  2 +-
 src/common/compat.c |  2 +-
 src/common/crypto.c |  2 +-
 src/or/channel.c| 19 ---
 src/or/channelpadding.c |  2 +-
 src/or/channeltls.c |  2 +-
 src/or/command.c|  2 +-
 src/or/cpuworker.c  |  2 +-
 src/or/hs_cache.c   |  2 +-
 src/or/hs_circuit.c | 10 +-
 src/or/main.c   |  2 +-
 src/or/or.h |  2 +-
 src/or/rendcache.c  |  2 +-
 src/or/rendservice.c|  2 +-
 src/or/routerlist.c |  4 ++--
 src/or/scheduler_kist.c |  2 +-
 src/or/status.c |  2 +-
 18 files changed, 30 insertions(+), 33 deletions(-)

diff --git a/ChangeLog b/ChangeLog
index fa1a9e573..b97d2f9eb 100644
--- a/ChangeLog
+++ b/ChangeLog
@@ -444,7 +444,7 @@ Changes in version 0.3.2.9 - 2018-01-09
   o Minor bugfixes (portability, msvc):
 - Fix a bug in the bit-counting parts of our timing-wheel code on
   MSVC. (Note that MSVC is still not a supported build platform, due
-  to cyptographic timing channel risks.) Fixes bug 24633; bugfix
+  to cryptographic timing channel risks.) Fixes bug 24633; bugfix
   on 0.2.9.1-alpha.
 
 
diff --git a/ReleaseNotes b/ReleaseNotes
index 4adba49d7..6c31d8ab0 100644
--- a/ReleaseNotes
+++ b/ReleaseNotes
@@ -621,7 +621,7 @@ Changes in version 0.3.2.9 - 2018-01-09
   Hurd. Fixes bug 23098; bugfix on 0.3.1.1-alpha.
 - Fix a bug in the bit-counting parts of our timing-wheel code on
   MSVC. (Note that MSVC is still not a supported build platform, due
-  to cyptographic timing channel risks.) Fixes bug 24633; bugfix
+  to cryptographic timing channel risks.) Fixes bug 24633; bugfix
   on 0.2.9.1-alpha.
 
   o Minor bugfixes (relay):
diff --git a/src/common/compat.c b/src/common/compat.c
index 39d2f18f4..4cb346dfa 100644
--- a/src/common/compat.c
+++ b/src/common/compat.c
@@ -2890,7 +2890,7 @@ compute_num_cpus(void)
 /** Helper: Deal with confused or out-of-bounds values from localtime_r and
  * friends.  (On some platforms, they can give out-of-bounds values or can
  * return NULL.)  If islocal, this is a localtime result; otherwise
- * it's from gmtime.  The function returned r, when given timep
+ * it's from gmtime.  The function returns r, when given timep
  * as its input. If we need to store new results, store them in
  * resultbuf. */
 static struct tm *
diff --git a/src/common/crypto.c b/src/common/crypto.c
index 6e420ab05..affcda40f 100644
--- a/src/common/crypto.c
+++ b/src/common/crypto.c
@@ -1915,7 +1915,7 @@ crypto_strongest_rand_syscall(uint8_t *out, size_t 
out_len)
 
   return 0;
 #elif defined(__linux__) && defined(SYS_getrandom)
-  static int getrandom_works = 1; /* Be optimitic about our chances... */
+  static int getrandom_works = 1; /* Be optimistic about our chances... */
 
   /* getrandom() isn't as straightforward as getentropy(), and has
* no glibc wrapper.
diff --git a/src/or/channel.c b/src/or/channel.c
index e5cdf9bc7..76d1167a4 100644
--- a/src/or/channel.c
+++ b/src/or/channel.c
@@ -1435,7 +1435,6 @@ channel_clear_remote_end(channel_t *chan)
 /**
  * Write to a channel the given packed cell.
  *
- *
  * Two possible errors can happen. Either the channel is not opened or the
  * lower layer (specialized channel) failed to write it. In both cases, it is
  * the caller responsibility to free the cell.
@@ -1864,12 +1863,11 @@ channel_listener_process_incoming(channel_listener_t 
*listener)
  * this comes from the old connection_or_set_state_open() of connection_or.c.
  *
  * Because of this mechanism, future channel_t subclasses should take care
- * not to change a channel to from CHANNEL_STATE_OPENING to CHANNEL_STATE_OPEN
+ * not to change a channel from CHANNEL_STATE_OPENING to CHANNEL_STATE_OPEN
  * until there is positive confirmation that the network is operational.
  * In particular, anything UDP-based should not make this transition until a
  * packet is received from the other side.
  */
-
 void
 channel_do_open_actions(channel_t *chan)
 {
@@ -3199,7 +3197,7 @@ channel_num_cells_writeable(channel_t *chan)
  /
 
 /**
- * Update the created timestamp for a channel
+ * Update the created timestamp for a channel.
  *
  * This updates the channel's created timestamp and should only be called
  * from channel_init().
@@ -3216,7 +3214,7 @@ channel_timestamp_created(channel_t *chan)
 }
 
 /**
- * Update the created timestamp for a channel listener
+ * Update the created timestamp for a channel listener.
  *
  * This updates the channel listener's created timestamp and should only be
  * called from channel_init_listener().
@@ -3233,7 

[tor-commits] [metrics-web/master] Preserve UTF-8 encoding of table data.

2018-02-07 Thread karsten
commit 50ae3c4579709fca8e95bfcab136a21de5acfe70
Author: Karsten Loesing 
Date:   Wed Feb 7 17:35:02 2018 +0100

Preserve UTF-8 encoding of table data.

Fixes #25167.
---
 src/main/java/org/torproject/metrics/web/RObjectGenerator.java | 3 ++-
 1 file changed, 2 insertions(+), 1 deletion(-)

diff --git a/src/main/java/org/torproject/metrics/web/RObjectGenerator.java 
b/src/main/java/org/torproject/metrics/web/RObjectGenerator.java
index 06177bf..c7d0041 100644
--- a/src/main/java/org/torproject/metrics/web/RObjectGenerator.java
+++ b/src/main/java/org/torproject/metrics/web/RObjectGenerator.java
@@ -14,6 +14,7 @@ import java.io.File;
 import java.io.FileInputStream;
 import java.io.IOException;
 import java.io.InputStreamReader;
+import java.nio.charset.StandardCharsets;
 import java.util.ArrayList;
 import java.util.Arrays;
 import java.util.HashMap;
@@ -222,7 +223,7 @@ public class RObjectGenerator implements 
ServletContextListener {
 /* Write the table content to a map. */
 List> result = new ArrayList<>();
 try (BufferedReader br = new BufferedReader(new InputStreamReader(
-new ByteArrayInputStream(tableBytes {
+new ByteArrayInputStream(tableBytes), StandardCharsets.UTF_8))) {
   String line = br.readLine();
   if (line != null) {
 List headers = new ArrayList<>(Arrays.asList(line.split(",")));

___
tor-commits mailing list
tor-commits@lists.torproject.org
https://lists.torproject.org/cgi-bin/mailman/listinfo/tor-commits


[tor-commits] [tor/master] test: Bump to 10 msec gap in the monotonic test

2018-02-07 Thread nickm
commit fe3dfe7e38b4ad0c11ff05b7dbd0a9b1d7efc4a8
Author: David Goulet 
Date:   Wed Feb 7 10:23:24 2018 -0500

test: Bump to 10 msec gap in the monotonic test

On slow system, 1 msec between one read and the other was too tight. For
instance, it failed on armel with a 4msec gap:

  https://buildd.debian.org/status/package.php?p=tor=experimental

Increase to 10 msec for now to address slow system. It is important that we
keep this OP_LE test in so we make sure the msec/usec/nsec read aren't
desynchronized by huge gaps. We'll adjust again if we ever encounter a 
system
that goes slower than 10 msec between calls.

Fixes #25113

Signed-off-by: David Goulet 
---
 changes/bug25113 | 5 +
 src/test/test_util.c | 8 
 2 files changed, 9 insertions(+), 4 deletions(-)

diff --git a/changes/bug25113 b/changes/bug25113
new file mode 100644
index 0..4a020b784
--- /dev/null
+++ b/changes/bug25113
@@ -0,0 +1,5 @@
+  o Minor bugfixes (unit test, monotonic time):
+- Bump a gap of 1msec to 10msec used in the monotonic time test that makes
+  sure the nsec/usec/msec time read are synchronized. This change was
+  needed to accommodate slow system like armel or when the clock_gettime()
+  is not a VDSO on the running kernel. Fixes bug 25113; bugfix on 0.2.9.1.
diff --git a/src/test/test_util.c b/src/test/test_util.c
index 0b707caee..dd122b250 100644
--- a/src/test/test_util.c
+++ b/src/test/test_util.c
@@ -5541,10 +5541,10 @@ test_util_monotonic_time(void *arg)
   tt_u64_op(usec1, OP_GE, nsec1 / 1000);
   tt_u64_op(msecc1, OP_GE, nsecc1 / 100);
   tt_u64_op(usecc1, OP_GE, nsecc1 / 1000);
-  tt_u64_op(msec1, OP_LE, nsec1 / 100 + 1);
-  tt_u64_op(usec1, OP_LE, nsec1 / 1000 + 1000);
-  tt_u64_op(msecc1, OP_LE, nsecc1 / 100 + 1);
-  tt_u64_op(usecc1, OP_LE, nsecc1 / 1000 + 1000);
+  tt_u64_op(msec1, OP_LE, nsec1 / 100 + 10);
+  tt_u64_op(usec1, OP_LE, nsec1 / 1000 + 1);
+  tt_u64_op(msecc1, OP_LE, nsecc1 / 100 + 10);
+  tt_u64_op(usecc1, OP_LE, nsecc1 / 1000 + 1);
 
  done:
   ;



___
tor-commits mailing list
tor-commits@lists.torproject.org
https://lists.torproject.org/cgi-bin/mailman/listinfo/tor-commits


[tor-commits] [tor/master] Merge remote-tracking branch 'dgoulet/bug25113_029_01'

2018-02-07 Thread nickm
commit 78382d557ab3da0b11f4fbda829f463067fc808f
Merge: 86498e5aa fe3dfe7e3
Author: Nick Mathewson 
Date:   Wed Feb 7 11:33:14 2018 -0500

Merge remote-tracking branch 'dgoulet/bug25113_029_01'

 changes/bug25113 | 5 +
 src/test/test_util.c | 8 
 2 files changed, 9 insertions(+), 4 deletions(-)

diff --cc src/test/test_util.c
index ba4ac3c06,dd122b250..b67fad58e
--- a/src/test/test_util.c
+++ b/src/test/test_util.c
@@@ -5838,16 -5541,11 +5838,16 @@@ test_util_monotonic_time(void *arg
tt_u64_op(usec1, OP_GE, nsec1 / 1000);
tt_u64_op(msecc1, OP_GE, nsecc1 / 100);
tt_u64_op(usecc1, OP_GE, nsecc1 / 1000);
-   tt_u64_op(msec1, OP_LE, nsec1 / 100 + 1);
-   tt_u64_op(usec1, OP_LE, nsec1 / 1000 + 1000);
-   tt_u64_op(msecc1, OP_LE, nsecc1 / 100 + 1);
-   tt_u64_op(usecc1, OP_LE, nsecc1 / 1000 + 1000);
+   tt_u64_op(msec1, OP_LE, nsec1 / 100 + 10);
+   tt_u64_op(usec1, OP_LE, nsec1 / 1000 + 1);
+   tt_u64_op(msecc1, OP_LE, nsecc1 / 100 + 10);
+   tt_u64_op(usecc1, OP_LE, nsecc1 / 1000 + 1);
  
 +  uint64_t coarse_stamp_diff =
 +monotime_coarse_stamp_units_to_approx_msec(stamp2-stamp1);
 +  tt_u64_op(coarse_stamp_diff, OP_GE, 120);
 +  tt_u64_op(coarse_stamp_diff, OP_LE, 1200);
 +
   done:
;
  }

___
tor-commits mailing list
tor-commits@lists.torproject.org
https://lists.torproject.org/cgi-bin/mailman/listinfo/tor-commits


[tor-commits] [onionoo/master] Change 3 month weights graph to 24 hours detail.

2018-02-07 Thread karsten
commit 3f7a2fc1fe2a6f168e92b9a0210743ee25015047
Author: Karsten Loesing 
Date:   Wed Feb 7 16:28:47 2018 +0100

Change 3 month weights graph to 24 hours detail.

We recently changed the 3 month bandwidth graph to 24 hours detail,
and we changed the compression of various status files to support 6
month graphs with 24 hours detail. However, we did not consider that
we currently need weights data for the last 3 months on a detail of 12
hours. This commit adapts the output file by using the data that we
now have. Maybe it even makes sense to use the same detail in both
graphs, though that was not the original intention.
---
 src/main/java/org/torproject/onionoo/writer/WeightsDocumentWriter.java | 2 +-
 1 file changed, 1 insertion(+), 1 deletion(-)

diff --git 
a/src/main/java/org/torproject/onionoo/writer/WeightsDocumentWriter.java 
b/src/main/java/org/torproject/onionoo/writer/WeightsDocumentWriter.java
index c701f41..7d5f1d1 100644
--- a/src/main/java/org/torproject/onionoo/writer/WeightsDocumentWriter.java
+++ b/src/main/java/org/torproject/onionoo/writer/WeightsDocumentWriter.java
@@ -69,7 +69,7 @@ public class WeightsDocumentWriter implements DocumentWriter {
   private long[] dataPointIntervals = new long[] {
   DateTimeHelper.ONE_HOUR,
   DateTimeHelper.FOUR_HOURS,
-  DateTimeHelper.TWELVE_HOURS,
+  DateTimeHelper.ONE_DAY,
   DateTimeHelper.TWO_DAYS,
   DateTimeHelper.TEN_DAYS };
 



___
tor-commits mailing list
tor-commits@lists.torproject.org
https://lists.torproject.org/cgi-bin/mailman/listinfo/tor-commits


[tor-commits] [onionoo/master] Prepare for 5.0-1.10.1 release.

2018-02-07 Thread karsten
commit a66bfd14af743c460573e9770d402d3cf1dad48c
Author: Karsten Loesing 
Date:   Wed Feb 7 16:30:24 2018 +0100

Prepare for 5.0-1.10.1 release.
---
 CHANGELOG.md | 7 +++
 build.xml| 2 +-
 2 files changed, 8 insertions(+), 1 deletion(-)

diff --git a/CHANGELOG.md b/CHANGELOG.md
index 9ce16b1..08360ba 100644
--- a/CHANGELOG.md
+++ b/CHANGELOG.md
@@ -1,8 +1,15 @@
+# Changes in version 5.0-1.10.1 - 2018-02-07
+
+ * Medium changes
+   - Change 3 month weights graph to 24 hours detail.
+
+
 # Changes in version 5.0-1.10.0 - 2018-02-07
 
  * Medium changes
- Make writing of bandwidth, clients, uptime, and weights documents
  independent of system time.
+   - Change 3 month bandwidth graph to 24 hours detail.
 
 
 # Changes in version 5.0-1.9.0 - 2017-12-20
diff --git a/build.xml b/build.xml
index 48ce4ad..f1d6149 100644
--- a/build.xml
+++ b/build.xml
@@ -10,7 +10,7 @@
   
   
   
+value="${onionoo.protocol.version}-1.10.1"/>
   
   
   https://lists.torproject.org/cgi-bin/mailman/listinfo/tor-commits


[tor-commits] [onionoo/master] Bump version to 5.0-1.10.1-dev.

2018-02-07 Thread karsten
commit 934bdd961a7235c90dc11f2dd68201756018c807
Author: Karsten Loesing 
Date:   Wed Feb 7 16:50:22 2018 +0100

Bump version to 5.0-1.10.1-dev.
---
 build.xml | 2 +-
 1 file changed, 1 insertion(+), 1 deletion(-)

diff --git a/build.xml b/build.xml
index f1d6149..aafbd50 100644
--- a/build.xml
+++ b/build.xml
@@ -10,7 +10,7 @@
   
   
   
+value="${onionoo.protocol.version}-1.10.1-dev"/>
   
   
   https://lists.torproject.org/cgi-bin/mailman/listinfo/tor-commits


[tor-commits] [onionoo/release] Prepare for 5.0-1.10.1 release.

2018-02-07 Thread karsten
commit a66bfd14af743c460573e9770d402d3cf1dad48c
Author: Karsten Loesing 
Date:   Wed Feb 7 16:30:24 2018 +0100

Prepare for 5.0-1.10.1 release.
---
 CHANGELOG.md | 7 +++
 build.xml| 2 +-
 2 files changed, 8 insertions(+), 1 deletion(-)

diff --git a/CHANGELOG.md b/CHANGELOG.md
index 9ce16b1..08360ba 100644
--- a/CHANGELOG.md
+++ b/CHANGELOG.md
@@ -1,8 +1,15 @@
+# Changes in version 5.0-1.10.1 - 2018-02-07
+
+ * Medium changes
+   - Change 3 month weights graph to 24 hours detail.
+
+
 # Changes in version 5.0-1.10.0 - 2018-02-07
 
  * Medium changes
- Make writing of bandwidth, clients, uptime, and weights documents
  independent of system time.
+   - Change 3 month bandwidth graph to 24 hours detail.
 
 
 # Changes in version 5.0-1.9.0 - 2017-12-20
diff --git a/build.xml b/build.xml
index 48ce4ad..f1d6149 100644
--- a/build.xml
+++ b/build.xml
@@ -10,7 +10,7 @@
   
   
   
+value="${onionoo.protocol.version}-1.10.1"/>
   
   
   https://lists.torproject.org/cgi-bin/mailman/listinfo/tor-commits


[tor-commits] [onionoo/release] Change 3 month weights graph to 24 hours detail.

2018-02-07 Thread karsten
commit 3f7a2fc1fe2a6f168e92b9a0210743ee25015047
Author: Karsten Loesing 
Date:   Wed Feb 7 16:28:47 2018 +0100

Change 3 month weights graph to 24 hours detail.

We recently changed the 3 month bandwidth graph to 24 hours detail,
and we changed the compression of various status files to support 6
month graphs with 24 hours detail. However, we did not consider that
we currently need weights data for the last 3 months on a detail of 12
hours. This commit adapts the output file by using the data that we
now have. Maybe it even makes sense to use the same detail in both
graphs, though that was not the original intention.
---
 src/main/java/org/torproject/onionoo/writer/WeightsDocumentWriter.java | 2 +-
 1 file changed, 1 insertion(+), 1 deletion(-)

diff --git 
a/src/main/java/org/torproject/onionoo/writer/WeightsDocumentWriter.java 
b/src/main/java/org/torproject/onionoo/writer/WeightsDocumentWriter.java
index c701f41..7d5f1d1 100644
--- a/src/main/java/org/torproject/onionoo/writer/WeightsDocumentWriter.java
+++ b/src/main/java/org/torproject/onionoo/writer/WeightsDocumentWriter.java
@@ -69,7 +69,7 @@ public class WeightsDocumentWriter implements DocumentWriter {
   private long[] dataPointIntervals = new long[] {
   DateTimeHelper.ONE_HOUR,
   DateTimeHelper.FOUR_HOURS,
-  DateTimeHelper.TWELVE_HOURS,
+  DateTimeHelper.ONE_DAY,
   DateTimeHelper.TWO_DAYS,
   DateTimeHelper.TEN_DAYS };
 



___
tor-commits mailing list
tor-commits@lists.torproject.org
https://lists.torproject.org/cgi-bin/mailman/listinfo/tor-commits


[tor-commits] [onionoo/release] Bump version to 5.0-1.10.0-dev.

2018-02-07 Thread karsten
commit 469caa6b251bec501da987d19c3c47755918e2d9
Author: Karsten Loesing 
Date:   Wed Feb 7 12:21:10 2018 +0100

Bump version to 5.0-1.10.0-dev.
---
 build.xml | 2 +-
 1 file changed, 1 insertion(+), 1 deletion(-)

diff --git a/build.xml b/build.xml
index 762202c..48ce4ad 100644
--- a/build.xml
+++ b/build.xml
@@ -10,7 +10,7 @@
   
   
   
+value="${onionoo.protocol.version}-1.10.0-dev"/>
   
   
   https://lists.torproject.org/cgi-bin/mailman/listinfo/tor-commits


[tor-commits] [tor/master] Fix wide lines from typo-fix patch.

2018-02-07 Thread nickm
commit 86498e5aa59a74babd9454c336681a48019f479b
Author: Nick Mathewson 
Date:   Wed Feb 7 10:46:05 2018 -0500

Fix wide lines from typo-fix patch.
---
 src/common/crypto_ed25519.c | 4 ++--
 src/or/hs_descriptor.c  | 8 
 2 files changed, 6 insertions(+), 6 deletions(-)

diff --git a/src/common/crypto_ed25519.c b/src/common/crypto_ed25519.c
index a5a61cba1..b962a59de 100644
--- a/src/common/crypto_ed25519.c
+++ b/src/common/crypto_ed25519.c
@@ -225,8 +225,8 @@ ed25519_public_key_is_zero(const ed25519_public_key_t 
*pubkey)
 
 /* Return a heap-allocated array that contains msg prefixed by the
  * string prefix_str. Set final_msg_len_out to the size of the
- * final array. If an error occurred, return NULL. It's the resonsibility of 
the
- * caller to free the returned array. */
+ * final array. If an error occurred, return NULL. It's the responsibility of
+ * the caller to free the returned array. */
 static uint8_t *
 get_prefixed_msg(const uint8_t *msg, size_t msg_len,
  const char *prefix_str,
diff --git a/src/or/hs_descriptor.c b/src/or/hs_descriptor.c
index 34c7b4a52..7388807bc 100644
--- a/src/or/hs_descriptor.c
+++ b/src/or/hs_descriptor.c
@@ -745,8 +745,8 @@ get_fake_auth_client_lines(void)
 
 /* Create the inner layer of the descriptor (which includes the intro points,
  * etc.). Return a newly-allocated string with the layer plaintext, or NULL if
- * an error occurred. It's the responsibility of the caller to free the 
returned
- * string. */
+ * an error occurred. It's the responsibility of the caller to free the
+ * returned string. */
 static char *
 get_inner_encrypted_layer_plaintext(const hs_descriptor_t *desc)
 {
@@ -802,8 +802,8 @@ get_inner_encrypted_layer_plaintext(const hs_descriptor_t 
*desc)
 /* Create the middle layer of the descriptor, which includes the client auth
  * data and the encrypted inner layer (provided as a base64 string at
  * layer2_b64_ciphertext). Return a newly-allocated string with the
- * layer plaintext, or NULL if an error occurred. It's the responsibility of 
the
- * caller to free the returned string. */
+ * layer plaintext, or NULL if an error occurred. It's the responsibility of
+ * the caller to free the returned string. */
 static char *
 get_outer_encrypted_layer_plaintext(const hs_descriptor_t *desc,
 const char *layer2_b64_ciphertext)

___
tor-commits mailing list
tor-commits@lists.torproject.org
https://lists.torproject.org/cgi-bin/mailman/listinfo/tor-commits


[tor-commits] [tor/master] changes file for 23650 typo fixes

2018-02-07 Thread nickm
commit a45b56753c7db521a62a9c8f8bad4986c1c66302
Author: Nick Mathewson 
Date:   Wed Feb 7 10:44:21 2018 -0500

changes file for 23650 typo fixes
---
 changes/ticket23650 | 4 
 1 file changed, 4 insertions(+)

diff --git a/changes/ticket23650 b/changes/ticket23650
new file mode 100644
index 0..cf5eb39d5
--- /dev/null
+++ b/changes/ticket23650
@@ -0,0 +1,4 @@
+  o Minor bugfixes (all versions of Tor):
+- Use the "misspell" tool to detect and fix typos throughout the source
+  code. Fixes bug 23650; bugfix on various versions of Tor. Patch
+  from Deepesh Pathak.



___
tor-commits mailing list
tor-commits@lists.torproject.org
https://lists.torproject.org/cgi-bin/mailman/listinfo/tor-commits


[tor-commits] [tor/master] Fix spelling mistakes corresponding to ticket #23650

2018-02-07 Thread nickm
commit ca6682f3f86dbcf2b5346ae69d45293e8a59322b
Author: Deepesh Pathak 
Date:   Wed Jan 24 14:25:15 2018 +0530

Fix spelling mistakes corresponding to ticket #23650
---
 .gitlab-ci.yml   |  2 +-
 ChangeLog| 24 
 ReleaseNotes | 16 
 configure.ac |  2 +-
 contrib/operator-tools/linux-tor-prio.sh |  2 +-
 doc/HACKING/GettingStartedRust.md|  2 +-
 doc/HACKING/Tracing.md   |  2 +-
 doc/HACKING/android/Simpleperf.md|  2 +-
 doc/tor.1.txt|  4 ++--
 scripts/maint/redox.py   |  2 +-
 scripts/maint/updateFallbackDirs.py  |  6 +++---
 src/common/address.c |  2 +-
 src/common/compat.c  |  2 +-
 src/common/compat_openssl.h  |  2 +-
 src/common/compat_time.c |  2 +-
 src/common/crypto.c  |  4 ++--
 src/common/crypto_ed25519.c  | 10 +-
 src/common/crypto_rsa.c  |  2 +-
 src/common/timers.c  |  2 +-
 src/common/tortls.c  |  2 +-
 src/common/util.c|  6 +++---
 src/ext/ed25519/donna/ed25519_tor.c  |  2 +-
 src/or/bridges.c |  2 +-
 src/or/channel.c |  8 
 src/or/circpathbias.c|  4 ++--
 src/or/circuitbuild.c|  2 +-
 src/or/circuitlist.c |  4 ++--
 src/or/circuitstats.c| 16 
 src/or/circuituse.c  |  2 +-
 src/or/config.c  |  2 +-
 src/or/connection.c  |  4 ++--
 src/or/control.c |  6 +++---
 src/or/directory.c   | 10 +-
 src/or/dirserv.c |  4 ++--
 src/or/dirserv.h |  2 +-
 src/or/dirvote.c |  2 +-
 src/or/dns.c |  2 +-
 src/or/hs_cache.c|  4 ++--
 src/or/hs_client.c   |  2 +-
 src/or/hs_config.c   |  2 +-
 src/or/hs_descriptor.c   |  6 +++---
 src/or/hs_intropoint.c   |  2 +-
 src/or/hs_service.c  | 20 ++--
 src/or/main.c|  2 +-
 src/or/onion_fast.c  |  2 +-
 src/or/or.h  |  6 +++---
 src/or/policies.c|  2 +-
 src/or/reasons.c |  2 +-
 src/or/rendcache.c   |  4 ++--
 src/or/rendcache.h   |  2 +-
 src/or/rendclient.c  |  2 +-
 src/or/rendservice.c |  6 +++---
 src/or/rendservice.h |  2 +-
 src/or/rephist.c |  2 +-
 src/or/routerlist.c  |  4 ++--
 src/or/shared_random.c   |  2 +-
 src/or/shared_random_state.c |  6 +++---
 src/or/status.c  |  2 +-
 src/or/transports.c  |  2 +-
 src/test/test.c  |  2 +-
 src/test/test_cell_formats.c |  2 +-
 src/test/test_channelpadding.c   |  8 
 src/test/test_config.c   |  4 ++--
 src/test/test_connection.c   |  2 +-
 src/test/test_dir.c  |  2 +-
 src/test/test_entrynodes.c   |  2 +-
 src/test/test_hs.c   |  2 +-
 src/test/test_hs_descriptor.c|  2 +-
 src/test/test_hs_intropoint.c|  4 ++--
 src/test/test_hs_service.c   |  2 +-
 src/test/test_options.c  | 10 +-
 src/test/test_shared_random.c|  4 ++--
 src/test/test_util.c | 10 +-
 src/trunnel/hs/cell_introduce1.trunnel   |  2 +-
 74 files changed, 156 insertions(+), 156 deletions(-)

diff --git a/.gitlab-ci.yml b/.gitlab-ci.yml
index ba981d5f1..d2d0d55dd 100644
--- a/.gitlab-ci.yml
+++ b/.gitlab-ci.yml
@@ -26,7 +26,7 @@ update:
 - ssh-add <(echo "$DEPLOY_KEY")
 
 # For Docker builds disable host key checking. Be aware that by adding that
-# you are suspectible to man-in-the-middle attacks.
+# you are susceptible to man-in-the-middle attacks.
 # WARNING: Use this only with the Docker executor, if you use it with shell
 # you will overwrite your user's SSH config.
 - mkdir -p ~/.ssh
diff --git a/ChangeLog b/ChangeLog
index 96629e37f..fa1a9e573 100644
--- a/ChangeLog
+++ b/ChangeLog
@@ -8267,7 +8267,7 @@ Changes in version 0.2.6.5-rc - 2015-03-18
   o Major bugfixes (pluggable transports):
 - Initialize the extended OR Port authentication cookie before
   launching pluggable transports. This prevents a race 

[tor-commits] [translation/tor-and-https] Update translations for tor-and-https

2018-02-07 Thread translation
commit 5d5cca2294fbd5f482e6964ee6805c4cbeaa845d
Author: Translation commit bot 
Date:   Wed Feb 7 14:48:17 2018 +

Update translations for tor-and-https
---
 om.po | 2 +-
 1 file changed, 1 insertion(+), 1 deletion(-)

diff --git a/om.po b/om.po
index caf186e5a..1f75a20f1 100644
--- a/om.po
+++ b/om.po
@@ -114,7 +114,7 @@ msgstr ""
 #: C/tor-and-https.svg:363
 #, no-wrap
 msgid "Key"
-msgstr ""
+msgstr "Furtuu"
 
 #. (itstool) path: defs/text
 #: C/tor-and-https.svg:363

___
tor-commits mailing list
tor-commits@lists.torproject.org
https://lists.torproject.org/cgi-bin/mailman/listinfo/tor-commits


[tor-commits] [tor/master] Improve doc of `primary_guards_up_to_date`.

2018-02-07 Thread nickm
commit 13f5adc86c30101a32fedcd1713443eb4c43a397
Author: George Kadianakis 
Date:   Wed Feb 7 11:46:30 2018 +0200

Improve doc of `primary_guards_up_to_date`.
---
 src/or/entrynodes.h | 7 ---
 1 file changed, 4 insertions(+), 3 deletions(-)

diff --git a/src/or/entrynodes.h b/src/or/entrynodes.h
index b7b110eeb..d56249831 100644
--- a/src/or/entrynodes.h
+++ b/src/or/entrynodes.h
@@ -220,9 +220,10 @@ struct guard_selection_s {
   guard_selection_type_t type;
 
   /**
-   * A value of 1 means that primary_entry_guards is up-to-date; 0
-   * means we need to recalculate it before using primary_entry_guards
-   * or the is_primary flag on any guard.
+   * A value of 1 means that primary_entry_guards is up-to-date with respect to
+   * the consensus and status info that we currently have; 0 means we need to
+   * recalculate it before using primary_entry_guards or the is_primary flag on
+   * any guard.
*/
   int primary_guards_up_to_date;
 

___
tor-commits mailing list
tor-commits@lists.torproject.org
https://lists.torproject.org/cgi-bin/mailman/listinfo/tor-commits


[tor-commits] [translation/mat-gui] Update translations for mat-gui

2018-02-07 Thread translation
commit 73e080e654c8be2c646f4e77faf6f25bfc6f4f62
Author: Translation commit bot 
Date:   Wed Feb 7 13:46:28 2018 +

Update translations for mat-gui
---
 om.po | 2 +-
 1 file changed, 1 insertion(+), 1 deletion(-)

diff --git a/om.po b/om.po
index 618689fc4..e79bb6b34 100644
--- a/om.po
+++ b/om.po
@@ -148,7 +148,7 @@ msgstr ""
 
 #: data/mat.glade:187
 msgid "Add"
-msgstr ""
+msgstr "itti dabali"
 
 #: data/mat.glade:256
 msgid "State"

___
tor-commits mailing list
tor-commits@lists.torproject.org
https://lists.torproject.org/cgi-bin/mailman/listinfo/tor-commits


[tor-commits] [translation/tails-greeter-2] Update translations for tails-greeter-2

2018-02-07 Thread translation
commit f9d46a37ad01dfbda0e0dc1a3930cfbda7052a8c
Author: Translation commit bot 
Date:   Wed Feb 7 13:20:37 2018 +

Update translations for tails-greeter-2
---
 om/om.po | 2 +-
 1 file changed, 1 insertion(+), 1 deletion(-)

diff --git a/om/om.po b/om/om.po
index 5ebdb868a..a5e7d79dd 100644
--- a/om/om.po
+++ b/om/om.po
@@ -255,7 +255,7 @@ msgstr "Haqi"
 
 #: ../tailsgreeter/gui.py:608
 msgid "Add"
-msgstr ""
+msgstr "itti dabali"
 
 #: ../tailsgreeter/gui.py:616
 msgid "Back"

___
tor-commits mailing list
tor-commits@lists.torproject.org
https://lists.torproject.org/cgi-bin/mailman/listinfo/tor-commits


[tor-commits] [translation/torbutton-torbuttondtd] Update translations for torbutton-torbuttondtd

2018-02-07 Thread translation
commit 8a734bf62f53f67cb41a9cac0565bf0e83852d9e
Author: Translation commit bot 
Date:   Wed Feb 7 13:17:54 2018 +

Update translations for torbutton-torbuttondtd
---
 uk/torbutton.dtd | 12 ++--
 1 file changed, 6 insertions(+), 6 deletions(-)

diff --git a/uk/torbutton.dtd b/uk/torbutton.dtd
index 0dc2d8477..3f2eeb283 100644
--- a/uk/torbutton.dtd
+++ b/uk/torbutton.dtd
@@ -32,19 +32,19 @@
 
 
 
-
+
 
 
 
-
+
 
 
-
+
 
 
 
 
-
-
-
+
+
+
 

___
tor-commits mailing list
tor-commits@lists.torproject.org
https://lists.torproject.org/cgi-bin/mailman/listinfo/tor-commits


[tor-commits] [translation/torbutton-torbuttondtd] Update translations for torbutton-torbuttondtd

2018-02-07 Thread translation
commit 1098e18334393d9af4de009eae161d73d59d79b3
Author: Translation commit bot 
Date:   Wed Feb 7 12:47:57 2018 +

Update translations for torbutton-torbuttondtd
---
 uk/torbutton.dtd | 18 +-
 1 file changed, 9 insertions(+), 9 deletions(-)

diff --git a/uk/torbutton.dtd b/uk/torbutton.dtd
index 839b69770..0dc2d8477 100644
--- a/uk/torbutton.dtd
+++ b/uk/torbutton.dtd
@@ -33,17 +33,17 @@
 
 
 
-
-
-
+
+
+
 
-
-
+
+
 
-
-
-
-
+
+
+
+
 
 
 

___
tor-commits mailing list
tor-commits@lists.torproject.org
https://lists.torproject.org/cgi-bin/mailman/listinfo/tor-commits


[tor-commits] [translation/tails-misc] Update translations for tails-misc

2018-02-07 Thread translation
commit b0beb349dacf80bb87bea8f250848afd5804b07f
Author: Translation commit bot 
Date:   Wed Feb 7 12:47:06 2018 +

Update translations for tails-misc
---
 uk.po | 2 +-
 1 file changed, 1 insertion(+), 1 deletion(-)

diff --git a/uk.po b/uk.po
index e3741742d..33ebad7c6 100644
--- a/uk.po
+++ b/uk.po
@@ -19,7 +19,7 @@ msgstr ""
 "Project-Id-Version: The Tor Project\n"
 "Report-Msgid-Bugs-To: \n"
 "POT-Creation-Date: 2017-09-13 20:10+0200\n"
-"PO-Revision-Date: 2018-02-05 12:56+\n"
+"PO-Revision-Date: 2018-02-07 12:44+\n"
 "Last-Translator: O Herenko \n"
 "Language-Team: Ukrainian 
(http://www.transifex.com/otf/torproject/language/uk/)\n"
 "MIME-Version: 1.0\n"

___
tor-commits mailing list
tor-commits@lists.torproject.org
https://lists.torproject.org/cgi-bin/mailman/listinfo/tor-commits


[tor-commits] [translation/tails-misc_completed] Update translations for tails-misc_completed

2018-02-07 Thread translation
commit 977bea85a027d6791efa927c8f9c600a553bb1ca
Author: Translation commit bot 
Date:   Wed Feb 7 12:47:14 2018 +

Update translations for tails-misc_completed
---
 uk.po | 2 +-
 1 file changed, 1 insertion(+), 1 deletion(-)

diff --git a/uk.po b/uk.po
index e3741742d..33ebad7c6 100644
--- a/uk.po
+++ b/uk.po
@@ -19,7 +19,7 @@ msgstr ""
 "Project-Id-Version: The Tor Project\n"
 "Report-Msgid-Bugs-To: \n"
 "POT-Creation-Date: 2017-09-13 20:10+0200\n"
-"PO-Revision-Date: 2018-02-05 12:56+\n"
+"PO-Revision-Date: 2018-02-07 12:44+\n"
 "Last-Translator: O Herenko \n"
 "Language-Team: Ukrainian 
(http://www.transifex.com/otf/torproject/language/uk/)\n"
 "MIME-Version: 1.0\n"

___
tor-commits mailing list
tor-commits@lists.torproject.org
https://lists.torproject.org/cgi-bin/mailman/listinfo/tor-commits


[tor-commits] [webwml/master] Bug 24027: update the FAQ to point to the new Tor Browser git repository

2018-02-07 Thread boklm
commit afba226bd6eec49726f694d4adf48fed1f45c23c
Author: Nicolas Vigier 
Date:   Wed Feb 7 12:41:54 2018 +0100

Bug 24027: update the FAQ to point to the new Tor Browser git repository
---
 docs/en/faq.wml | 2 +-
 1 file changed, 1 insertion(+), 1 deletion(-)

diff --git a/docs/en/faq.wml b/docs/en/faq.wml
index 88f81b15..b15de6f2 100644
--- a/docs/en/faq.wml
+++ b/docs/en/faq.wml
@@ -1514,7 +1514,7 @@ 
href="http://www.crowdstrike.com/community-tools/index.html#tool-79;>proposed
 Tor Browser? How do I verify a build?
 
 
-Start with https://gitweb.torproject.org/builders/tor-browser-bundle.git;>https://gitweb.torproject.org/builders/tor-browser-bundle.git
 and https://gitweb.torproject.org/builders/tor-browser-bundle.git/tree/gitian/README.build;>https://gitweb.torproject.org/builders/tor-browser-bundle.git/tree/gitian/README.build.
+Tor Browser is built from the https://gitweb.torproject.org/builders/tor-browser-build.git/;>tor-browser-build.git
 git repository. You can have a look at the https://gitweb.torproject.org/builders/tor-browser-build.git/tree/README;>README
 file for the build instructions. There is also some informations in the https://trac.torproject.org/projects/tor/wiki/doc/TorBrowser/Hacking;>Tor 
Browser Hacking Guide.
 
 
 

___
tor-commits mailing list
tor-commits@lists.torproject.org
https://lists.torproject.org/cgi-bin/mailman/listinfo/tor-commits


[tor-commits] [onionoo/master] Bump version to 5.0-1.10.0-dev.

2018-02-07 Thread karsten
commit 469caa6b251bec501da987d19c3c47755918e2d9
Author: Karsten Loesing 
Date:   Wed Feb 7 12:21:10 2018 +0100

Bump version to 5.0-1.10.0-dev.
---
 build.xml | 2 +-
 1 file changed, 1 insertion(+), 1 deletion(-)

diff --git a/build.xml b/build.xml
index 762202c..48ce4ad 100644
--- a/build.xml
+++ b/build.xml
@@ -10,7 +10,7 @@
   
   
   
+value="${onionoo.protocol.version}-1.10.0-dev"/>
   
   
   https://lists.torproject.org/cgi-bin/mailman/listinfo/tor-commits


[tor-commits] [onionoo/release] Retain more detailed histories for a longer time.

2018-02-07 Thread karsten
commit d153681176ba492af159e1126f9dde7d133d2720
Author: Karsten Loesing 
Date:   Fri Feb 2 15:38:03 2018 +0100

Retain more detailed histories for a longer time.

Previously, we'd have compressed histories to a resolution of 48 hours
after 3 months. But we're now planning to introduce a 6 month graph
with a resolution of 24 hours. With this change we're retaining
detailed histories for three months longer.

Related to #24729.
---
 src/main/java/org/torproject/onionoo/docs/BandwidthStatus.java | 4 ++--
 src/main/java/org/torproject/onionoo/docs/ClientsStatus.java   | 2 +-
 src/main/java/org/torproject/onionoo/docs/DateTimeHelper.java  | 2 ++
 src/main/java/org/torproject/onionoo/docs/WeightsStatus.java   | 4 ++--
 4 files changed, 7 insertions(+), 5 deletions(-)

diff --git a/src/main/java/org/torproject/onionoo/docs/BandwidthStatus.java 
b/src/main/java/org/torproject/onionoo/docs/BandwidthStatus.java
index ba22dd4..252a018 100644
--- a/src/main/java/org/torproject/onionoo/docs/BandwidthStatus.java
+++ b/src/main/java/org/torproject/onionoo/docs/BandwidthStatus.java
@@ -134,8 +134,8 @@ public class BandwidthStatus extends Document {
   <= DateTimeHelper.ROUGHLY_ONE_MONTH) {
 intervalLengthMillis = DateTimeHelper.FOUR_HOURS;
   } else if (lastSeenMillis - endMillis
-  <= DateTimeHelper.ROUGHLY_THREE_MONTHS) {
-intervalLengthMillis = DateTimeHelper.TWELVE_HOURS;
+  <= DateTimeHelper.ROUGHLY_SIX_MONTHS) {
+intervalLengthMillis = DateTimeHelper.ONE_DAY;
   } else if (lastSeenMillis - endMillis
   <= DateTimeHelper.ROUGHLY_ONE_YEAR) {
 intervalLengthMillis = DateTimeHelper.TWO_DAYS;
diff --git a/src/main/java/org/torproject/onionoo/docs/ClientsStatus.java 
b/src/main/java/org/torproject/onionoo/docs/ClientsStatus.java
index a5bc8e8..2e11b50 100644
--- a/src/main/java/org/torproject/onionoo/docs/ClientsStatus.java
+++ b/src/main/java/org/torproject/onionoo/docs/ClientsStatus.java
@@ -77,7 +77,7 @@ public class ClientsStatus extends Document {
 for (ClientsHistory responses : uncompressedHistory) {
   long intervalLengthMillis;
   if (lastSeenMillis - responses.getEndMillis()
-  <= DateTimeHelper.ROUGHLY_THREE_MONTHS) {
+  <= DateTimeHelper.ROUGHLY_SIX_MONTHS) {
 intervalLengthMillis = DateTimeHelper.ONE_DAY;
   } else if (lastSeenMillis - responses.getEndMillis()
   <= DateTimeHelper.ROUGHLY_ONE_YEAR) {
diff --git a/src/main/java/org/torproject/onionoo/docs/DateTimeHelper.java 
b/src/main/java/org/torproject/onionoo/docs/DateTimeHelper.java
index c80514e..7966af8 100644
--- a/src/main/java/org/torproject/onionoo/docs/DateTimeHelper.java
+++ b/src/main/java/org/torproject/onionoo/docs/DateTimeHelper.java
@@ -57,6 +57,8 @@ public class DateTimeHelper {
 
   public static final long ROUGHLY_THREE_MONTHS = 92L * ONE_DAY;
 
+  public static final long ROUGHLY_SIX_MONTHS = 183L * ONE_DAY;
+
   public static final long ROUGHLY_ONE_YEAR = 366L * ONE_DAY;
 
   public static final long ROUGHLY_FIVE_YEARS = 5L * ROUGHLY_ONE_YEAR;
diff --git a/src/main/java/org/torproject/onionoo/docs/WeightsStatus.java 
b/src/main/java/org/torproject/onionoo/docs/WeightsStatus.java
index 94efda6..c221fdd 100644
--- a/src/main/java/org/torproject/onionoo/docs/WeightsStatus.java
+++ b/src/main/java/org/torproject/onionoo/docs/WeightsStatus.java
@@ -146,8 +146,8 @@ public class WeightsStatus extends Document {
   <= DateTimeHelper.ROUGHLY_ONE_MONTH) {
 intervalLengthMillis = DateTimeHelper.FOUR_HOURS;
   } else if (lastSeenMillis - endMillis
-  <= DateTimeHelper.ROUGHLY_THREE_MONTHS) {
-intervalLengthMillis = DateTimeHelper.TWELVE_HOURS;
+  <= DateTimeHelper.ROUGHLY_SIX_MONTHS) {
+intervalLengthMillis = DateTimeHelper.ONE_DAY;
   } else if (lastSeenMillis - endMillis
   <= DateTimeHelper.ROUGHLY_ONE_YEAR) {
 intervalLengthMillis = DateTimeHelper.TWO_DAYS;



___
tor-commits mailing list
tor-commits@lists.torproject.org
https://lists.torproject.org/cgi-bin/mailman/listinfo/tor-commits


[tor-commits] [onionoo/release] Change 3 month bandwidth graph to 24 hours detail.

2018-02-07 Thread karsten
commit bc90de89712bff8a62290adfa61667c013380504
Author: Karsten Loesing 
Date:   Fri Feb 2 15:33:21 2018 +0100

Change 3 month bandwidth graph to 24 hours detail.

Relays and bridges have recently changed their bandwidth statistics
reporting interval from 4 hours to 24 hours. As a result, our 3 month
bandwidth graph cannot accommodate new bandwidth statistics anymore.
Increasing the bandwidth graph interval to 24 hours changes this, by
reducing data resolution from 184 to 92 data points.

Fixes part of #24729.
---
 .../java/org/torproject/onionoo/writer/BandwidthDocumentWriter.java | 2 +-
 1 file changed, 1 insertion(+), 1 deletion(-)

diff --git 
a/src/main/java/org/torproject/onionoo/writer/BandwidthDocumentWriter.java 
b/src/main/java/org/torproject/onionoo/writer/BandwidthDocumentWriter.java
index 7089c06..ad66bde 100644
--- a/src/main/java/org/torproject/onionoo/writer/BandwidthDocumentWriter.java
+++ b/src/main/java/org/torproject/onionoo/writer/BandwidthDocumentWriter.java
@@ -83,7 +83,7 @@ public class BandwidthDocumentWriter implements 
DocumentWriter {
   DateTimeHelper.FIFTEEN_MINUTES,
   DateTimeHelper.ONE_HOUR,
   DateTimeHelper.FOUR_HOURS,
-  DateTimeHelper.TWELVE_HOURS,
+  DateTimeHelper.ONE_DAY,
   DateTimeHelper.TWO_DAYS,
   DateTimeHelper.TEN_DAYS };
 



___
tor-commits mailing list
tor-commits@lists.torproject.org
https://lists.torproject.org/cgi-bin/mailman/listinfo/tor-commits


[tor-commits] [onionoo/release] Compile graph histories in a single place.

2018-02-07 Thread karsten
commit 314feacaf18dae7e1f29861b39a74fc3df2d1330
Author: Karsten Loesing 
Date:   Wed Jan 17 20:29:11 2018 +0100

Compile graph histories in a single place.
---
 .../org/torproject/onionoo/docs/UptimeHistory.java |   4 +
 .../onionoo/writer/BandwidthDocumentWriter.java| 120 +---
 .../onionoo/writer/ClientsDocumentWriter.java  | 130 +
 .../onionoo/writer/GraphHistoryCompiler.java   | 254 +
 .../onionoo/writer/UptimeDocumentWriter.java   | 312 +++--
 .../onionoo/writer/WeightsDocumentWriter.java  | 124 +---
 .../writer/BandwidthDocumentWriterTest.java|   4 +-
 .../onionoo/writer/GraphHistoryCompilerTest.java   | 203 ++
 .../onionoo/writer/UptimeDocumentWriterTest.java   |  14 +-
 9 files changed, 606 insertions(+), 559 deletions(-)

diff --git a/src/main/java/org/torproject/onionoo/docs/UptimeHistory.java 
b/src/main/java/org/torproject/onionoo/docs/UptimeHistory.java
index 60e283f..f8cc116 100644
--- a/src/main/java/org/torproject/onionoo/docs/UptimeHistory.java
+++ b/src/main/java/org/torproject/onionoo/docs/UptimeHistory.java
@@ -32,6 +32,10 @@ public class UptimeHistory implements 
Comparable {
 return this.uptimeHours;
   }
 
+  public long getEndMillis() {
+return this.startMillis + DateTimeHelper.ONE_HOUR * this.uptimeHours;
+  }
+
   private SortedSet flags;
 
   public SortedSet getFlags() {
diff --git 
a/src/main/java/org/torproject/onionoo/writer/BandwidthDocumentWriter.java 
b/src/main/java/org/torproject/onionoo/writer/BandwidthDocumentWriter.java
index 2f27271..71595e2 100644
--- a/src/main/java/org/torproject/onionoo/writer/BandwidthDocumentWriter.java
+++ b/src/main/java/org/torproject/onionoo/writer/BandwidthDocumentWriter.java
@@ -15,12 +15,7 @@ import org.torproject.onionoo.docs.UpdateStatus;
 import org.slf4j.Logger;
 import org.slf4j.LoggerFactory;
 
-import java.time.LocalDateTime;
 import java.time.Period;
-import java.time.ZoneOffset;
-import java.util.ArrayList;
-import java.util.LinkedHashMap;
-import java.util.List;
 import java.util.Map;
 import java.util.SortedMap;
 import java.util.SortedSet;
@@ -100,114 +95,17 @@ public class BandwidthDocumentWriter implements 
DocumentWriter {
 
   private Map compileGraphType(long lastSeenMillis,
   SortedMap history) {
-Map graphs = new LinkedHashMap<>();
+GraphHistoryCompiler ghc = new GraphHistoryCompiler(
+lastSeenMillis + DateTimeHelper.ONE_HOUR);
 for (int i = 0; i < this.graphIntervals.length; i++) {
-  String graphName = this.graphNames[i];
-  Period graphInterval = this.graphIntervals[i];
-  long dataPointInterval = this.dataPointIntervals[i];
-  List dataPoints = new ArrayList<>();
-  long graphEndMillis = ((lastSeenMillis + DateTimeHelper.ONE_HOUR)
-  / dataPointInterval) * dataPointInterval;
-  long graphStartMillis = LocalDateTime
-  .ofEpochSecond(graphEndMillis / 1000L, 0, ZoneOffset.UTC)
-  .minus(graphInterval)
-  .toEpochSecond(ZoneOffset.UTC) * 1000L;
-  long intervalStartMillis = graphStartMillis;
-  long totalMillis = 0L;
-  long totalBandwidth = 0L;
-  for (long[] v : history.values()) {
-long endMillis = v[1];
-if (endMillis <= intervalStartMillis) {
-  continue;
-} else if (endMillis > graphEndMillis) {
-  break;
-}
-long startMillis = v[0];
-if (endMillis - startMillis > dataPointInterval) {
-  /* This history interval is too long for this graph's data point
-   * interval.  Maybe the next graph will contain it, but not this
-   * one. */
-  continue;
-}
-while ((intervalStartMillis / dataPointInterval)
-!= ((endMillis - 1L) / dataPointInterval)) {
-  dataPoints.add(totalMillis * 5L < dataPointInterval
-  ? -1L : (totalBandwidth * DateTimeHelper.ONE_SECOND)
-  / totalMillis);
-  totalBandwidth = 0L;
-  totalMillis = 0L;
-  intervalStartMillis += dataPointInterval;
-}
-long bandwidth = v[2];
-totalBandwidth += bandwidth;
-totalMillis += (endMillis - startMillis);
-  }
-  dataPoints.add(totalMillis * 5L < dataPointInterval
-  ? -1L : (totalBandwidth * DateTimeHelper.ONE_SECOND)
-  / totalMillis);
-  long maxValue = 1L;
-  int firstNonNullIndex = -1;
-  int lastNonNullIndex = -1;
-  for (int j = 0; j < dataPoints.size(); j++) {
-long dataPoint = dataPoints.get(j);
-if (dataPoint >= 0L) {
-  if (firstNonNullIndex < 0) {
-firstNonNullIndex = j;
-  }
-  lastNonNullIndex = j;
-  if (dataPoint > maxValue) {
-maxValue = dataPoint;
-  }
-}
-  }
-  if (firstNonNullIndex < 0) {
-continue;
-  }
-  

[tor-commits] [onionoo/release] Add a comment to avoid future 'detective work'.

2018-02-07 Thread karsten
commit 70e5f3f741fa899531e0ad42e3a702db6bfcb122
Author: iwakeh 
Date:   Wed Jan 17 19:29:14 2018 +

Add a comment to avoid future 'detective work'.
---
 src/main/java/org/torproject/onionoo/server/NodeIndexer.java | 1 +
 1 file changed, 1 insertion(+)

diff --git a/src/main/java/org/torproject/onionoo/server/NodeIndexer.java 
b/src/main/java/org/torproject/onionoo/server/NodeIndexer.java
index 69baa53..e95eda9 100644
--- a/src/main/java/org/torproject/onionoo/server/NodeIndexer.java
+++ b/src/main/java/org/torproject/onionoo/server/NodeIndexer.java
@@ -125,6 +125,7 @@ public class NodeIndexer implements ServletContextListener, 
Runnable {
 indexerThread.interrupt();
   }
 
+  /* specialTime is only used for testing, see ResourceServletTest */
   private long specialTime = -1L;
 
   private void indexNodeStatuses() {



___
tor-commits mailing list
tor-commits@lists.torproject.org
https://lists.torproject.org/cgi-bin/mailman/listinfo/tor-commits


[tor-commits] [onionoo/release] Make old code comply to new standard.

2018-02-07 Thread karsten
commit 3a50a4635b5799c5e8f6e56969976a35c56fce86
Author: iwakeh 
Date:   Wed Jan 17 19:29:13 2018 +

Make old code comply to new standard.
---
 src/main/java/org/torproject/onionoo/server/ResponseBuilder.java | 4 ++--
 1 file changed, 2 insertions(+), 2 deletions(-)

diff --git a/src/main/java/org/torproject/onionoo/server/ResponseBuilder.java 
b/src/main/java/org/torproject/onionoo/server/ResponseBuilder.java
index dbe911f..80ee223 100644
--- a/src/main/java/org/torproject/onionoo/server/ResponseBuilder.java
+++ b/src/main/java/org/torproject/onionoo/server/ResponseBuilder.java
@@ -113,8 +113,8 @@ public class ResponseBuilder {
   }
 
   public void buildResponse(PrintWriter pw) {
-writeRelays(orderedRelays, pw);
-writeBridges(orderedBridges, pw);
+writeRelays(this.orderedRelays, pw);
+writeBridges(this.orderedBridges, pw);
   }
 
   private int charsWritten = 0;



___
tor-commits mailing list
tor-commits@lists.torproject.org
https://lists.torproject.org/cgi-bin/mailman/listinfo/tor-commits


[tor-commits] [onionoo/release] Use constants consistently.

2018-02-07 Thread karsten
commit 372ddc7b7e74ccb3c3cf8f870419ec239585c9fd
Author: iwakeh 
Date:   Wed Jan 17 19:29:12 2018 +

Use constants consistently.

Avoid multiple definitions of date-time related constants.
---
 src/main/java/org/torproject/onionoo/server/NodeIndexer.java | 7 +++
 1 file changed, 3 insertions(+), 4 deletions(-)

diff --git a/src/main/java/org/torproject/onionoo/server/NodeIndexer.java 
b/src/main/java/org/torproject/onionoo/server/NodeIndexer.java
index 1a85a35..69baa53 100644
--- a/src/main/java/org/torproject/onionoo/server/NodeIndexer.java
+++ b/src/main/java/org/torproject/onionoo/server/NodeIndexer.java
@@ -3,6 +3,9 @@
 
 package org.torproject.onionoo.server;
 
+import static org.torproject.onionoo.docs.DateTimeHelper.ONE_DAY;
+import static org.torproject.onionoo.docs.DateTimeHelper.ONE_MINUTE;
+
 import org.torproject.onionoo.docs.DocumentStore;
 import org.torproject.onionoo.docs.DocumentStoreFactory;
 import org.torproject.onionoo.docs.SummaryDocument;
@@ -97,10 +100,6 @@ public class NodeIndexer implements ServletContextListener, 
Runnable {
 }
   }
 
-  private static final long ONE_MINUTE = 60L * 1000L;
-
-  private static final long ONE_DAY = 24L * 60L * ONE_MINUTE;
-
   @Override
   public void run() {
 try {



___
tor-commits mailing list
tor-commits@lists.torproject.org
https://lists.torproject.org/cgi-bin/mailman/listinfo/tor-commits


[tor-commits] [onionoo/release] Use exact periods for graphs covering months/years.

2018-02-07 Thread karsten
commit 5cefee7b9de2a746ccaff42c6a0adb27cac8578a
Author: Karsten Loesing 
Date:   Mon Jan 15 15:20:02 2018 +0100

Use exact periods for graphs covering months/years.
---
 .../onionoo/writer/BandwidthDocumentWriter.java| 32 ++
 .../onionoo/writer/ClientsDocumentWriter.java  | 29 
 .../onionoo/writer/UptimeDocumentWriter.java   | 29 
 .../onionoo/writer/WeightsDocumentWriter.java  | 29 
 4 files changed, 74 insertions(+), 45 deletions(-)

diff --git 
a/src/main/java/org/torproject/onionoo/writer/BandwidthDocumentWriter.java 
b/src/main/java/org/torproject/onionoo/writer/BandwidthDocumentWriter.java
index f1c5041..2f27271 100644
--- a/src/main/java/org/torproject/onionoo/writer/BandwidthDocumentWriter.java
+++ b/src/main/java/org/torproject/onionoo/writer/BandwidthDocumentWriter.java
@@ -15,6 +15,9 @@ import org.torproject.onionoo.docs.UpdateStatus;
 import org.slf4j.Logger;
 import org.slf4j.LoggerFactory;
 
+import java.time.LocalDateTime;
+import java.time.Period;
+import java.time.ZoneOffset;
 import java.util.ArrayList;
 import java.util.LinkedHashMap;
 import java.util.List;
@@ -79,13 +82,13 @@ public class BandwidthDocumentWriter implements 
DocumentWriter {
   "1_year",
   "5_years" };
 
-  private long[] graphIntervals = new long[] {
-  DateTimeHelper.THREE_DAYS,
-  DateTimeHelper.ONE_WEEK,
-  DateTimeHelper.ROUGHLY_ONE_MONTH,
-  DateTimeHelper.ROUGHLY_THREE_MONTHS,
-  DateTimeHelper.ROUGHLY_ONE_YEAR,
-  DateTimeHelper.ROUGHLY_FIVE_YEARS };
+  private Period[] graphIntervals = new Period[] {
+  Period.ofDays(3),
+  Period.ofWeeks(1),
+  Period.ofMonths(1),
+  Period.ofMonths(3),
+  Period.ofYears(1),
+  Period.ofYears(5) };
 
   private long[] dataPointIntervals = new long[] {
   DateTimeHelper.FIFTEEN_MINUTES,
@@ -100,12 +103,15 @@ public class BandwidthDocumentWriter implements 
DocumentWriter {
 Map graphs = new LinkedHashMap<>();
 for (int i = 0; i < this.graphIntervals.length; i++) {
   String graphName = this.graphNames[i];
-  long graphInterval = this.graphIntervals[i];
+  Period graphInterval = this.graphIntervals[i];
   long dataPointInterval = this.dataPointIntervals[i];
   List dataPoints = new ArrayList<>();
   long graphEndMillis = ((lastSeenMillis + DateTimeHelper.ONE_HOUR)
   / dataPointInterval) * dataPointInterval;
-  long graphStartMillis = graphEndMillis - graphInterval;
+  long graphStartMillis = LocalDateTime
+  .ofEpochSecond(graphEndMillis / 1000L, 0, ZoneOffset.UTC)
+  .minus(graphInterval)
+  .toEpochSecond(ZoneOffset.UTC) * 1000L;
   long intervalStartMillis = graphStartMillis;
   long totalMillis = 0L;
   long totalBandwidth = 0L;
@@ -159,9 +165,11 @@ public class BandwidthDocumentWriter implements 
DocumentWriter {
   }
   long firstDataPointMillis = graphStartMillis + firstNonNullIndex
   * dataPointInterval + dataPointInterval / 2L;
-  if (i > 0 && !graphs.isEmpty() && firstDataPointMillis >=
-  ((lastSeenMillis + DateTimeHelper.ONE_HOUR) / dataPointInterval)
-  * dataPointInterval - graphIntervals[i - 1]) {
+  if (i > 0 && !graphs.isEmpty() && firstDataPointMillis >= LocalDateTime
+  .ofEpochSecond(graphEndMillis / 1000L, 0, ZoneOffset.UTC)
+  .minus(graphIntervals[i - 1])
+  .toEpochSecond(ZoneOffset.UTC) * 1000L) {
+
 /* Skip bandwidth history object, because it doesn't contain
  * anything new that wasn't already contained in the last
  * bandwidth history object(s).  Unless we did not include any of
diff --git 
a/src/main/java/org/torproject/onionoo/writer/ClientsDocumentWriter.java 
b/src/main/java/org/torproject/onionoo/writer/ClientsDocumentWriter.java
index 81168f5..4eca33a 100644
--- a/src/main/java/org/torproject/onionoo/writer/ClientsDocumentWriter.java
+++ b/src/main/java/org/torproject/onionoo/writer/ClientsDocumentWriter.java
@@ -17,6 +17,9 @@ import org.torproject.onionoo.util.FormattingUtils;
 import org.slf4j.Logger;
 import org.slf4j.LoggerFactory;
 
+import java.time.LocalDateTime;
+import java.time.Period;
+import java.time.ZoneOffset;
 import java.util.ArrayList;
 import java.util.LinkedHashMap;
 import java.util.List;
@@ -94,12 +97,12 @@ public class ClientsDocumentWriter implements 
DocumentWriter {
   "1_year",
   "5_years" };
 
-  private long[] graphIntervals = new long[] {
-  DateTimeHelper.ONE_WEEK,
-  DateTimeHelper.ROUGHLY_ONE_MONTH,
-  DateTimeHelper.ROUGHLY_THREE_MONTHS,
-  DateTimeHelper.ROUGHLY_ONE_YEAR,
-  DateTimeHelper.ROUGHLY_FIVE_YEARS };
+  private Period[] graphIntervals = new Period[] {
+  Period.ofWeeks(1),
+  Period.ofMonths(1),
+  Period.ofMonths(3),
+  Period.ofYears(1),
+  Period.ofYears(5) };
 
   

[tor-commits] [onionoo/release] Prepare for 5.0-1.10.0 release.

2018-02-07 Thread karsten
commit 9830f7ae5736ad0e3b94d311328b3ef84589b183
Author: Karsten Loesing 
Date:   Wed Feb 7 11:27:57 2018 +0100

Prepare for 5.0-1.10.0 release.
---
 CHANGELOG.md | 2 +-
 build.xml| 2 +-
 2 files changed, 2 insertions(+), 2 deletions(-)

diff --git a/CHANGELOG.md b/CHANGELOG.md
index 1873443..9ce16b1 100644
--- a/CHANGELOG.md
+++ b/CHANGELOG.md
@@ -1,4 +1,4 @@
-# Changes in version ??
+# Changes in version 5.0-1.10.0 - 2018-02-07
 
  * Medium changes
- Make writing of bandwidth, clients, uptime, and weights documents
diff --git a/build.xml b/build.xml
index 7833807..762202c 100644
--- a/build.xml
+++ b/build.xml
@@ -10,7 +10,7 @@
   
   
   
+value="${onionoo.protocol.version}-1.10.0"/>
   
   
   https://lists.torproject.org/cgi-bin/mailman/listinfo/tor-commits


[tor-commits] [onionoo/release] Rename lastSeenMillis to mostRecentStatusMillis.

2018-02-07 Thread karsten
commit 88bc0219725b01d24110f6d48528dc88d4fa3839
Author: Karsten Loesing 
Date:   Wed Feb 7 10:56:45 2018 +0100

Rename lastSeenMillis to mostRecentStatusMillis.
---
 .../onionoo/writer/BandwidthDocumentWriter.java  | 20 ++--
 .../onionoo/writer/ClientsDocumentWriter.java|  8 
 .../onionoo/writer/DetailsDocumentWriter.java|  2 +-
 .../torproject/onionoo/writer/DocumentWriter.java|  2 +-
 .../onionoo/writer/DocumentWriterRunner.java | 13 +++--
 .../onionoo/writer/SummaryDocumentWriter.java|  2 +-
 .../onionoo/writer/UptimeDocumentWriter.java | 18 +-
 .../onionoo/writer/WeightsDocumentWriter.java| 20 ++--
 8 files changed, 43 insertions(+), 42 deletions(-)

diff --git 
a/src/main/java/org/torproject/onionoo/writer/BandwidthDocumentWriter.java 
b/src/main/java/org/torproject/onionoo/writer/BandwidthDocumentWriter.java
index ad66bde..47eaa3e 100644
--- a/src/main/java/org/torproject/onionoo/writer/BandwidthDocumentWriter.java
+++ b/src/main/java/org/torproject/onionoo/writer/BandwidthDocumentWriter.java
@@ -31,7 +31,7 @@ public class BandwidthDocumentWriter implements 
DocumentWriter {
   }
 
   @Override
-  public void writeDocuments(long lastSeenMillis) {
+  public void writeDocuments(long mostRecentStatusMillis) {
 UpdateStatus updateStatus = this.documentStore.retrieve(
 UpdateStatus.class, true);
 long updatedMillis = updateStatus != null
@@ -45,7 +45,7 @@ public class BandwidthDocumentWriter implements 
DocumentWriter {
 continue;
   }
   BandwidthDocument bandwidthDocument = this.compileBandwidthDocument(
-  fingerprint, lastSeenMillis, bandwidthStatus);
+  fingerprint, mostRecentStatusMillis, bandwidthStatus);
   this.documentStore.store(bandwidthDocument, fingerprint);
 }
 log.info("Wrote bandwidth document files");
@@ -53,13 +53,13 @@ public class BandwidthDocumentWriter implements 
DocumentWriter {
 
 
   private BandwidthDocument compileBandwidthDocument(String fingerprint,
-  long lastSeenMillis, BandwidthStatus bandwidthStatus) {
+  long mostRecentStatusMillis, BandwidthStatus bandwidthStatus) {
 BandwidthDocument bandwidthDocument = new BandwidthDocument();
 bandwidthDocument.setFingerprint(fingerprint);
-bandwidthDocument.setWriteHistory(this.compileGraphType(lastSeenMillis,
-bandwidthStatus.getWriteHistory()));
-bandwidthDocument.setReadHistory(this.compileGraphType(lastSeenMillis,
-bandwidthStatus.getReadHistory()));
+bandwidthDocument.setWriteHistory(this.compileGraphType(
+mostRecentStatusMillis, bandwidthStatus.getWriteHistory()));
+bandwidthDocument.setReadHistory(this.compileGraphType(
+mostRecentStatusMillis, bandwidthStatus.getReadHistory()));
 return bandwidthDocument;
   }
 
@@ -87,10 +87,10 @@ public class BandwidthDocumentWriter implements 
DocumentWriter {
   DateTimeHelper.TWO_DAYS,
   DateTimeHelper.TEN_DAYS };
 
-  private Map compileGraphType(long lastSeenMillis,
-  SortedMap history) {
+  private Map compileGraphType(
+  long mostRecentStatusMillis, SortedMap history) {
 GraphHistoryCompiler ghc = new GraphHistoryCompiler(
-lastSeenMillis + DateTimeHelper.ONE_HOUR);
+mostRecentStatusMillis + DateTimeHelper.ONE_HOUR);
 for (int i = 0; i < this.graphIntervals.length; i++) {
   ghc.addGraphType(this.graphNames[i], this.graphIntervals[i],
   this.dataPointIntervals[i]);
diff --git 
a/src/main/java/org/torproject/onionoo/writer/ClientsDocumentWriter.java 
b/src/main/java/org/torproject/onionoo/writer/ClientsDocumentWriter.java
index 7ed2048..de63893 100644
--- a/src/main/java/org/torproject/onionoo/writer/ClientsDocumentWriter.java
+++ b/src/main/java/org/torproject/onionoo/writer/ClientsDocumentWriter.java
@@ -55,7 +55,7 @@ public class ClientsDocumentWriter implements DocumentWriter {
   private int writtenDocuments = 0;
 
   @Override
-  public void writeDocuments(long lastSeenMillis) {
+  public void writeDocuments(long mostRecentStatusMillis) {
 UpdateStatus updateStatus = this.documentStore.retrieve(
 UpdateStatus.class, true);
 long updatedMillis = updateStatus != null
@@ -70,7 +70,7 @@ public class ClientsDocumentWriter implements DocumentWriter {
   }
   SortedSet history = clientsStatus.getHistory();
   ClientsDocument clientsDocument = this.compileClientsDocument(
-  hashedFingerprint, lastSeenMillis, history);
+  hashedFingerprint, mostRecentStatusMillis, history);
   this.documentStore.store(clientsDocument, hashedFingerprint);
   this.writtenDocuments++;
 }
@@ -99,10 +99,10 @@ public class ClientsDocumentWriter implements 
DocumentWriter {
   DateTimeHelper.TEN_DAYS };
 
   private ClientsDocument 

[tor-commits] [onionoo/release] Use the same last-seen time for writing documents.

2018-02-07 Thread karsten
commit 5fbc7fd5d6e6510e9e02f18bda8dec0e6bd2c8d1
Author: Karsten Loesing 
Date:   Fri Feb 2 15:27:27 2018 +0100

Use the same last-seen time for writing documents.

Previously, we'd have used the last-seen time of the relay/bridge that
we're writing a document for. But that doesn't make much sense,
because we don't have to provide, e.g., a 1 week graph for a relay
that has been offline for years. This change is going to shrink the
out/ directory to a similar size as it was when we used current system
time for writing documents.
---
 .../onionoo/writer/BandwidthDocumentWriter.java| 20 ++--
 .../onionoo/writer/ClientsDocumentWriter.java  | 16 -
 .../onionoo/writer/DetailsDocumentWriter.java  |  2 +-
 .../torproject/onionoo/writer/DocumentWriter.java  |  2 +-
 .../onionoo/writer/DocumentWriterRunner.java   | 18 +-
 .../onionoo/writer/SummaryDocumentWriter.java  |  2 +-
 .../onionoo/writer/UptimeDocumentWriter.java   | 12 --
 .../onionoo/writer/WeightsDocumentWriter.java  |  9 +--
 .../writer/BandwidthDocumentWriterTest.java|  9 ++-
 .../onionoo/writer/DetailsDocumentWriterTest.java  |  8 +++
 .../onionoo/writer/UptimeDocumentWriterTest.java   | 28 ++
 11 files changed, 55 insertions(+), 71 deletions(-)

diff --git 
a/src/main/java/org/torproject/onionoo/writer/BandwidthDocumentWriter.java 
b/src/main/java/org/torproject/onionoo/writer/BandwidthDocumentWriter.java
index 71595e2..7089c06 100644
--- a/src/main/java/org/torproject/onionoo/writer/BandwidthDocumentWriter.java
+++ b/src/main/java/org/torproject/onionoo/writer/BandwidthDocumentWriter.java
@@ -9,7 +9,6 @@ import org.torproject.onionoo.docs.DateTimeHelper;
 import org.torproject.onionoo.docs.DocumentStore;
 import org.torproject.onionoo.docs.DocumentStoreFactory;
 import org.torproject.onionoo.docs.GraphHistory;
-import org.torproject.onionoo.docs.NodeStatus;
 import org.torproject.onionoo.docs.UpdateStatus;
 
 import org.slf4j.Logger;
@@ -32,7 +31,7 @@ public class BandwidthDocumentWriter implements 
DocumentWriter {
   }
 
   @Override
-  public void writeDocuments() {
+  public void writeDocuments(long lastSeenMillis) {
 UpdateStatus updateStatus = this.documentStore.retrieve(
 UpdateStatus.class, true);
 long updatedMillis = updateStatus != null
@@ -40,18 +39,13 @@ public class BandwidthDocumentWriter implements 
DocumentWriter {
 SortedSet updateBandwidthDocuments = this.documentStore.list(
 BandwidthStatus.class, updatedMillis);
 for (String fingerprint : updateBandwidthDocuments) {
-  NodeStatus nodeStatus = this.documentStore.retrieve(NodeStatus.class,
-  true, fingerprint);
-  if (null == nodeStatus) {
-continue;
-  }
   BandwidthStatus bandwidthStatus = this.documentStore.retrieve(
   BandwidthStatus.class, true, fingerprint);
   if (bandwidthStatus == null) {
 continue;
   }
   BandwidthDocument bandwidthDocument = this.compileBandwidthDocument(
-  fingerprint, nodeStatus, bandwidthStatus);
+  fingerprint, lastSeenMillis, bandwidthStatus);
   this.documentStore.store(bandwidthDocument, fingerprint);
 }
 log.info("Wrote bandwidth document files");
@@ -59,13 +53,13 @@ public class BandwidthDocumentWriter implements 
DocumentWriter {
 
 
   private BandwidthDocument compileBandwidthDocument(String fingerprint,
-  NodeStatus nodeStatus, BandwidthStatus bandwidthStatus) {
+  long lastSeenMillis, BandwidthStatus bandwidthStatus) {
 BandwidthDocument bandwidthDocument = new BandwidthDocument();
 bandwidthDocument.setFingerprint(fingerprint);
-bandwidthDocument.setWriteHistory(this.compileGraphType(
-nodeStatus.getLastSeenMillis(), bandwidthStatus.getWriteHistory()));
-bandwidthDocument.setReadHistory(this.compileGraphType(
-nodeStatus.getLastSeenMillis(), bandwidthStatus.getReadHistory()));
+bandwidthDocument.setWriteHistory(this.compileGraphType(lastSeenMillis,
+bandwidthStatus.getWriteHistory()));
+bandwidthDocument.setReadHistory(this.compileGraphType(lastSeenMillis,
+bandwidthStatus.getReadHistory()));
 return bandwidthDocument;
   }
 
diff --git 
a/src/main/java/org/torproject/onionoo/writer/ClientsDocumentWriter.java 
b/src/main/java/org/torproject/onionoo/writer/ClientsDocumentWriter.java
index aba45cf..7ed2048 100644
--- a/src/main/java/org/torproject/onionoo/writer/ClientsDocumentWriter.java
+++ b/src/main/java/org/torproject/onionoo/writer/ClientsDocumentWriter.java
@@ -9,7 +9,6 @@ import org.torproject.onionoo.docs.ClientsStatus;
 import org.torproject.onionoo.docs.DateTimeHelper;
 import org.torproject.onionoo.docs.DocumentStore;
 import org.torproject.onionoo.docs.DocumentStoreFactory;
-import org.torproject.onionoo.docs.NodeStatus;
 import org.torproject.onionoo.docs.UpdateStatus;
 

[tor-commits] [onionoo/release] Fix off-by-one bug in writing history documents.

2018-02-07 Thread karsten
commit bd2c7af771a64dd393970e2e483c59778b32dbfc
Author: Karsten Loesing 
Date:   Mon Jan 15 11:12:51 2018 +0100

Fix off-by-one bug in writing history documents.

When we consider a history interval from start to end, we really mean
the interval [start, end[. Fixing a few off-by-one bugs in the code.
---
 .../java/org/torproject/onionoo/writer/BandwidthDocumentWriter.java   | 4 ++--
 .../java/org/torproject/onionoo/writer/ClientsDocumentWriter.java | 4 ++--
 src/main/java/org/torproject/onionoo/writer/UptimeDocumentWriter.java | 4 ++--
 .../java/org/torproject/onionoo/writer/WeightsDocumentWriter.java | 4 ++--
 4 files changed, 8 insertions(+), 8 deletions(-)

diff --git 
a/src/main/java/org/torproject/onionoo/writer/BandwidthDocumentWriter.java 
b/src/main/java/org/torproject/onionoo/writer/BandwidthDocumentWriter.java
index 99a5a00..f1c5041 100644
--- a/src/main/java/org/torproject/onionoo/writer/BandwidthDocumentWriter.java
+++ b/src/main/java/org/torproject/onionoo/writer/BandwidthDocumentWriter.java
@@ -111,7 +111,7 @@ public class BandwidthDocumentWriter implements 
DocumentWriter {
   long totalBandwidth = 0L;
   for (long[] v : history.values()) {
 long endMillis = v[1];
-if (endMillis < intervalStartMillis) {
+if (endMillis <= intervalStartMillis) {
   continue;
 } else if (endMillis > graphEndMillis) {
   break;
@@ -124,7 +124,7 @@ public class BandwidthDocumentWriter implements 
DocumentWriter {
   continue;
 }
 while ((intervalStartMillis / dataPointInterval)
-!= (endMillis / dataPointInterval)) {
+!= ((endMillis - 1L) / dataPointInterval)) {
   dataPoints.add(totalMillis * 5L < dataPointInterval
   ? -1L : (totalBandwidth * DateTimeHelper.ONE_SECOND)
   / totalMillis);
diff --git 
a/src/main/java/org/torproject/onionoo/writer/ClientsDocumentWriter.java 
b/src/main/java/org/torproject/onionoo/writer/ClientsDocumentWriter.java
index 834df9c..81168f5 100644
--- a/src/main/java/org/torproject/onionoo/writer/ClientsDocumentWriter.java
+++ b/src/main/java/org/torproject/onionoo/writer/ClientsDocumentWriter.java
@@ -140,13 +140,13 @@ public class ClientsDocumentWriter implements 
DocumentWriter {
 long millis = 0L;
 double responses = 0.0;
 for (ClientsHistory hist : history) {
-  if (hist.getEndMillis() < intervalStartMillis) {
+  if (hist.getEndMillis() <= intervalStartMillis) {
 continue;
   } else if (hist.getEndMillis() > graphEndMillis) {
 break;
   }
   while ((intervalStartMillis / dataPointInterval)
-  != (hist.getEndMillis() / dataPointInterval)) {
+  != ((hist.getEndMillis() - 1L) / dataPointInterval)) {
 dataPoints.add(millis * 2L < dataPointInterval
 ? -1.0 : responses * ((double) DateTimeHelper.ONE_DAY)
 / (((double) millis) * 10.0));
diff --git 
a/src/main/java/org/torproject/onionoo/writer/UptimeDocumentWriter.java 
b/src/main/java/org/torproject/onionoo/writer/UptimeDocumentWriter.java
index f739b9e..2aee7a1 100644
--- a/src/main/java/org/torproject/onionoo/writer/UptimeDocumentWriter.java
+++ b/src/main/java/org/torproject/onionoo/writer/UptimeDocumentWriter.java
@@ -175,7 +175,7 @@ public class UptimeDocumentWriter implements DocumentWriter 
{
   }
   long histEndMillis = hist.getStartMillis() + DateTimeHelper.ONE_HOUR
   * hist.getUptimeHours();
-  if (histEndMillis < intervalStartMillis) {
+  if (histEndMillis <= intervalStartMillis) {
 continue;
   } else if (histEndMillis > graphEndMillis) {
 histEndMillis = graphEndMillis;
@@ -218,7 +218,7 @@ public class UptimeDocumentWriter implements DocumentWriter 
{
   }
   long histEndMillis = hist.getStartMillis() + DateTimeHelper.ONE_HOUR
   * hist.getUptimeHours();
-  if (histEndMillis < intervalStartMillis) {
+  if (histEndMillis <= intervalStartMillis) {
 continue;
   } else if (histEndMillis > graphEndMillis) {
 histEndMillis = graphEndMillis;
diff --git 
a/src/main/java/org/torproject/onionoo/writer/WeightsDocumentWriter.java 
b/src/main/java/org/torproject/onionoo/writer/WeightsDocumentWriter.java
index ad54fea..10d8a94 100644
--- a/src/main/java/org/torproject/onionoo/writer/WeightsDocumentWriter.java
+++ b/src/main/java/org/torproject/onionoo/writer/WeightsDocumentWriter.java
@@ -132,13 +132,13 @@ public class WeightsDocumentWriter implements 
DocumentWriter {
   long startMillis = e.getKey()[0];
   long endMillis = e.getKey()[1];
   double weight = e.getValue()[graphTypeIndex];
-  if (endMillis < intervalStartMillis) {
+  if (endMillis <= intervalStartMillis) {
 continue;
   } else if (endMillis > graphEndMillis) {
 break;
   }
   while ((intervalStartMillis / dataPointInterval)
-  != (endMillis / 

[tor-commits] [onionoo/release] Bump version to 5.0-1.9.0-dev.

2018-02-07 Thread karsten
commit 7fc763699142a93fd75389da8bb3f4c7e9b667fd
Author: Karsten Loesing 
Date:   Wed Dec 20 17:16:02 2017 +0100

Bump version to 5.0-1.9.0-dev.
---
 build.xml | 2 +-
 1 file changed, 1 insertion(+), 1 deletion(-)

diff --git a/build.xml b/build.xml
index d2db15d..7833807 100644
--- a/build.xml
+++ b/build.xml
@@ -10,7 +10,7 @@
   
   
   
+value="${onionoo.protocol.version}-1.9.0-dev"/>
   
   
   https://lists.torproject.org/cgi-bin/mailman/listinfo/tor-commits


[tor-commits] [onionoo/release] Fix comparison in writing uptime documents.

2018-02-07 Thread karsten
commit 203d5d885d4155ed719c5168430ba237bad734aa
Author: Karsten Loesing 
Date:   Mon Jan 15 11:11:20 2018 +0100

Fix comparison in writing uptime documents.

In the spec we write: "Contained graph history objects may contain
null values if less than 20% of network statuses have been processed
for a given time period."

However, in the code we checked less than or equal. We should fix
that.
---
 .../onionoo/writer/UptimeDocumentWriter.java   | 12 +++---
 .../onionoo/writer/UptimeDocumentWriterTest.java   | 44 +-
 2 files changed, 49 insertions(+), 7 deletions(-)

diff --git 
a/src/main/java/org/torproject/onionoo/writer/UptimeDocumentWriter.java 
b/src/main/java/org/torproject/onionoo/writer/UptimeDocumentWriter.java
index 96537ef..f739b9e 100644
--- a/src/main/java/org/torproject/onionoo/writer/UptimeDocumentWriter.java
+++ b/src/main/java/org/torproject/onionoo/writer/UptimeDocumentWriter.java
@@ -225,8 +225,8 @@ public class UptimeDocumentWriter implements DocumentWriter 
{
   }
   while (hist.getStartMillis() >= intervalStartMillis
   + dataPointInterval) {
-statusDataPoints.add(statusHours * 5 > dataPointIntervalHours
-? statusHours : -1);
+statusDataPoints.add(statusHours * 5 < dataPointIntervalHours
+? -1 : statusHours);
 statusHours = -1;
 intervalStartMillis += dataPointInterval;
   }
@@ -238,8 +238,8 @@ public class UptimeDocumentWriter implements DocumentWriter 
{
 - Math.max(Math.max(hist.getStartMillis(),
 firstStatusStartMillis), intervalStartMillis))
 / DateTimeHelper.ONE_HOUR);
-statusDataPoints.add(statusHours * 5 > dataPointIntervalHours
-? statusHours : -1);
+statusDataPoints.add(statusHours * 5 < dataPointIntervalHours
+? -1 : statusHours);
 statusHours = -1;
 intervalStartMillis += dataPointInterval;
   }
@@ -251,8 +251,8 @@ public class UptimeDocumentWriter implements DocumentWriter 
{
   intervalStartMillis)) / DateTimeHelper.ONE_HOUR);
 }
 if (statusHours > 0) {
-  statusDataPoints.add(statusHours * 5 > dataPointIntervalHours
-  ? statusHours : -1);
+  statusDataPoints.add(statusHours * 5 < dataPointIntervalHours
+  ? -1 : statusHours);
 }
 List dataPoints = new ArrayList<>();
 for (int dataPointIndex = 0; dataPointIndex < statusDataPoints.size();
diff --git 
a/src/test/java/org/torproject/onionoo/writer/UptimeDocumentWriterTest.java 
b/src/test/java/org/torproject/onionoo/writer/UptimeDocumentWriterTest.java
index 3504509..b1ba2ed 100644
--- a/src/test/java/org/torproject/onionoo/writer/UptimeDocumentWriterTest.java
+++ b/src/test/java/org/torproject/onionoo/writer/UptimeDocumentWriterTest.java
@@ -77,6 +77,12 @@ public class UptimeDocumentWriterTest {
 (int) (FOUR_HOURS / ONE_SECOND), count, values);
   }
 
+  private void assertFiveYearGraph(UptimeDocument document, int graphs,
+  String first, String last, int count, List values) {
+this.assertGraph(document, graphs, "5_years", first, last,
+(int) (DateTimeHelper.TEN_DAYS / ONE_SECOND), count, values);
+  }
+
   private void assertGraph(UptimeDocument document, int graphs,
   String graphName, String first, String last, int interval,
   int count, List values) {
@@ -93,7 +99,7 @@ public class UptimeDocumentWriterTest {
 (int) history.getInterval());
 assertEquals("Factor should be 1.0 / 999.0.", 1.0 / 999.0,
 (double) history.getFactor(), 0.01);
-assertEquals("There should be one data point per hour.", count,
+assertEquals("There should be " + count + " data points.", count,
 (int) history.getCount());
 assertEquals("Count should be the same as the number of values.",
 count, history.getValues().size());
@@ -244,5 +250,41 @@ public class UptimeDocumentWriterTest {
 "2014-03-16 14:00:00", 2,
 Arrays.asList(new Integer[] { 499, 249 }));
   }
+
+  @Test
+  public void testFiveYearsLessThan20Percent() {
+/* This relay was running for exactly 11 days and 23 hours over 2 years 
ago.
+ * This time period exactly matches 100% of a data point interval of 10 
days
+ * plus a tiny bit less than 20% of the next data point interval. */
+this.addStatusOneWeekSample("r 2012-03-05-00 287\n",
+"r 2012-03-05-00 287\n");
+UptimeDocumentWriter writer = new UptimeDocumentWriter();
+DescriptorSourceFactory.getDescriptorSource().readDescriptors();
+writer.writeDocuments();
+assertEquals("Should write exactly one document.", 1,
+this.documentStore.getPerformedStoreOperations());
+UptimeDocument document = this.documentStore.getDocument(
+UptimeDocument.class, GABELMOO_FINGERPRINT);
+assertEquals("Should not contain any graph.", 0,
+document.getUptime().size());
+  }
+
+  @Test
+  public 

[tor-commits] [onionoo/release] Update copyright to 2018.

2018-02-07 Thread karsten
commit 0049663b19caad900342dc2d76909d7642deadd5
Author: Karsten Loesing 
Date:   Tue Jan 9 10:18:08 2018 +0100

Update copyright to 2018.
---
 src/main/java/org/torproject/onionoo/cron/Main.java | 2 +-
 src/main/java/org/torproject/onionoo/docs/BandwidthDocument.java| 2 +-
 src/main/java/org/torproject/onionoo/docs/BandwidthStatus.java  | 2 +-
 src/main/java/org/torproject/onionoo/docs/ClientsDocument.java  | 2 +-
 src/main/java/org/torproject/onionoo/docs/ClientsHistory.java   | 2 +-
 src/main/java/org/torproject/onionoo/docs/ClientsStatus.java| 2 +-
 src/main/java/org/torproject/onionoo/docs/DateTimeHelper.java   | 2 +-
 src/main/java/org/torproject/onionoo/docs/DetailsDocument.java  | 2 +-
 src/main/java/org/torproject/onionoo/docs/DetailsDocumentFields.java| 2 +-
 src/main/java/org/torproject/onionoo/docs/DetailsStatus.java| 2 +-
 src/main/java/org/torproject/onionoo/docs/Document.java | 2 +-
 src/main/java/org/torproject/onionoo/docs/DocumentStore.java| 2 +-
 src/main/java/org/torproject/onionoo/docs/DocumentStoreFactory.java | 2 +-
 src/main/java/org/torproject/onionoo/docs/GraphHistory.java | 2 +-
 src/main/java/org/torproject/onionoo/docs/NodeStatus.java   | 2 +-
 src/main/java/org/torproject/onionoo/docs/SummaryDocument.java  | 2 +-
 src/main/java/org/torproject/onionoo/docs/UpdateStatus.java | 2 +-
 src/main/java/org/torproject/onionoo/docs/UptimeDocument.java   | 2 +-
 src/main/java/org/torproject/onionoo/docs/UptimeHistory.java| 2 +-
 src/main/java/org/torproject/onionoo/docs/UptimeStatus.java | 2 +-
 src/main/java/org/torproject/onionoo/docs/WeightsDocument.java  | 2 +-
 src/main/java/org/torproject/onionoo/docs/WeightsStatus.java| 2 +-
 src/main/java/org/torproject/onionoo/server/Counter.java| 2 +-
 .../java/org/torproject/onionoo/server/HttpServletRequestWrapper.java   | 2 +-
 .../java/org/torproject/onionoo/server/HttpServletResponseWrapper.java  | 2 +-
 src/main/java/org/torproject/onionoo/server/IntegerDistribution.java| 2 +-
 src/main/java/org/torproject/onionoo/server/MostFrequentString.java | 2 +-
 src/main/java/org/torproject/onionoo/server/NodeIndex.java  | 2 +-
 src/main/java/org/torproject/onionoo/server/NodeIndexer.java| 2 +-
 src/main/java/org/torproject/onionoo/server/NodeIndexerFactory.java | 2 +-
 src/main/java/org/torproject/onionoo/server/OrderParameterValues.java   | 2 +-
 src/main/java/org/torproject/onionoo/server/PerformanceMetrics.java | 2 +-
 src/main/java/org/torproject/onionoo/server/RequestHandler.java | 2 +-
 src/main/java/org/torproject/onionoo/server/ResourceServlet.java| 2 +-
 src/main/java/org/torproject/onionoo/server/ResponseBuilder.java| 2 +-
 src/main/java/org/torproject/onionoo/server/ServerMain.java | 2 +-
 .../java/org/torproject/onionoo/server/SummaryDocumentComparator.java   | 2 +-
 .../java/org/torproject/onionoo/updater/BandwidthStatusUpdater.java | 2 +-
 src/main/java/org/torproject/onionoo/updater/ClientsStatusUpdater.java  | 2 +-
 src/main/java/org/torproject/onionoo/updater/DescriptorHistory.java | 2 +-
 src/main/java/org/torproject/onionoo/updater/DescriptorListener.java| 2 +-
 src/main/java/org/torproject/onionoo/updater/DescriptorQueue.java   | 2 +-
 src/main/java/org/torproject/onionoo/updater/DescriptorSource.java  | 2 +-
 .../java/org/torproject/onionoo/updater/DescriptorSourceFactory.java| 2 +-
 src/main/java/org/torproject/onionoo/updater/DescriptorType.java| 2 +-
 src/main/java/org/torproject/onionoo/updater/LookupResult.java  | 2 +-
 src/main/java/org/torproject/onionoo/updater/LookupService.java | 2 +-
 .../java/org/torproject/onionoo/updater/NodeDetailsStatusUpdater.java   | 2 +-
 src/main/java/org/torproject/onionoo/updater/RdnsLookupRequest.java | 2 +-
 src/main/java/org/torproject/onionoo/updater/RdnsLookupWorker.java  | 2 +-
 .../java/org/torproject/onionoo/updater/ReverseDomainNameResolver.java  | 2 +-
 src/main/java/org/torproject/onionoo/updater/StatusUpdateRunner.java| 2 +-
 src/main/java/org/torproject/onionoo/updater/StatusUpdater.java | 2 +-
 src/main/java/org/torproject/onionoo/updater/UptimeStatusUpdater.java   | 2 +-
 src/main/java/org/torproject/onionoo/updater/WeightsStatusUpdater.java  | 2 +-
 src/main/java/org/torproject/onionoo/util/FormattingUtils.java  | 2 +-
 .../java/org/torproject/onionoo/writer/BandwidthDocumentWriter.java | 2 +-
 src/main/java/org/torproject/onionoo/writer/ClientsDocumentWriter.java  | 2 +-
 src/main/java/org/torproject/onionoo/writer/DetailsDocumentWriter.java  | 2 +-
 src/main/java/org/torproject/onionoo/writer/DocumentWriter.java | 2 +-
 

[tor-commits] [onionoo/release] Don't rely on system time for compressing histories.

2018-02-07 Thread karsten
commit 8b14cb159b7ee5b4f4e2c11a9a4b03269bda6974
Author: Karsten Loesing 
Date:   Thu Jan 11 12:45:09 2018 +0100

Don't rely on system time for compressing histories.

Related to not relying on system time for writing histories, we also
shouldn't rely on it for compressing histories anymore. Otherwise we
might be compressing the history of a relay or bridge that recently
went offline while expecting an uncompressed history of that relay for
writing history documents. In short, let's do the same when updating
*Status objects as we do when writing *Document objects.

Related to #16513, but not strictly part of it.
---
 .../torproject/onionoo/docs/BandwidthStatus.java   | 23 ++
 .../org/torproject/onionoo/docs/ClientsStatus.java |  7 +++
 .../org/torproject/onionoo/docs/WeightsStatus.java | 11 +--
 .../onionoo/updater/BandwidthStatusUpdater.java|  7 ++-
 .../onionoo/updater/ClientsStatusUpdater.java  |  7 ++-
 .../onionoo/updater/WeightsStatusUpdater.java  |  7 ++-
 .../torproject/onionoo/docs/WeightsStatusTest.java | 14 ++---
 7 files changed, 43 insertions(+), 33 deletions(-)

diff --git a/src/main/java/org/torproject/onionoo/docs/BandwidthStatus.java 
b/src/main/java/org/torproject/onionoo/docs/BandwidthStatus.java
index 1a81d20..ba22dd4 100644
--- a/src/main/java/org/torproject/onionoo/docs/BandwidthStatus.java
+++ b/src/main/java/org/torproject/onionoo/docs/BandwidthStatus.java
@@ -108,16 +108,13 @@ public class BandwidthStatus extends Document {
 }
   }
 
-  public void compressHistory() {
-this.compressHistory(System.currentTimeMillis());
+  public void compressHistory(long lastSeenMillis) {
+this.compressHistory(this.writeHistory, lastSeenMillis);
+this.compressHistory(this.readHistory, lastSeenMillis);
   }
 
-  public void compressHistory(long now) {
-this.compressHistory(this.writeHistory, now);
-this.compressHistory(this.readHistory, now);
-  }
-
-  private void compressHistory(SortedMap history, long now) {
+  private void compressHistory(SortedMap history,
+  long lastSeenMillis) {
 SortedMap uncompressedHistory = new TreeMap<>(history);
 history.clear();
 long lastStartMillis = 0L;
@@ -129,17 +126,17 @@ public class BandwidthStatus extends Document {
   long endMillis = v[1];
   long bandwidth = v[2];
   long intervalLengthMillis;
-  if (now - endMillis <= DateTimeHelper.THREE_DAYS) {
+  if (lastSeenMillis - endMillis <= DateTimeHelper.THREE_DAYS) {
 intervalLengthMillis = DateTimeHelper.FIFTEEN_MINUTES;
-  } else if (now - endMillis <= DateTimeHelper.ONE_WEEK) {
+  } else if (lastSeenMillis - endMillis <= DateTimeHelper.ONE_WEEK) {
 intervalLengthMillis = DateTimeHelper.ONE_HOUR;
-  } else if (now - endMillis
+  } else if (lastSeenMillis - endMillis
   <= DateTimeHelper.ROUGHLY_ONE_MONTH) {
 intervalLengthMillis = DateTimeHelper.FOUR_HOURS;
-  } else if (now - endMillis
+  } else if (lastSeenMillis - endMillis
   <= DateTimeHelper.ROUGHLY_THREE_MONTHS) {
 intervalLengthMillis = DateTimeHelper.TWELVE_HOURS;
-  } else if (now - endMillis
+  } else if (lastSeenMillis - endMillis
   <= DateTimeHelper.ROUGHLY_ONE_YEAR) {
 intervalLengthMillis = DateTimeHelper.TWO_DAYS;
   } else {
diff --git a/src/main/java/org/torproject/onionoo/docs/ClientsStatus.java 
b/src/main/java/org/torproject/onionoo/docs/ClientsStatus.java
index 5310abf..a5bc8e8 100644
--- a/src/main/java/org/torproject/onionoo/docs/ClientsStatus.java
+++ b/src/main/java/org/torproject/onionoo/docs/ClientsStatus.java
@@ -69,18 +69,17 @@ public class ClientsStatus extends Document {
 
   /** Compresses the history of clients objects by merging adjacent
* intervals, depending on how far back in the past they lie. */
-  public void compressHistory() {
+  public void compressHistory(long lastSeenMillis) {
 SortedSet uncompressedHistory = new 
TreeSet<>(this.history);
 history.clear();
 ClientsHistory lastResponses = null;
 String lastMonthString = "1970-01";
-long now = System.currentTimeMillis();
 for (ClientsHistory responses : uncompressedHistory) {
   long intervalLengthMillis;
-  if (now - responses.getEndMillis()
+  if (lastSeenMillis - responses.getEndMillis()
   <= DateTimeHelper.ROUGHLY_THREE_MONTHS) {
 intervalLengthMillis = DateTimeHelper.ONE_DAY;
-  } else if (now - responses.getEndMillis()
+  } else if (lastSeenMillis - responses.getEndMillis()
   <= DateTimeHelper.ROUGHLY_ONE_YEAR) {
 intervalLengthMillis = DateTimeHelper.TWO_DAYS;
   } else {
diff --git a/src/main/java/org/torproject/onionoo/docs/WeightsStatus.java 
b/src/main/java/org/torproject/onionoo/docs/WeightsStatus.java
index 0dfd4f1..94efda6 100644
--- 

[tor-commits] [onionoo/release] Don't rely on system time for writing histories.

2018-02-07 Thread karsten
commit a7418b7c4d1b84ae1c1c062df847b013cb002e82
Author: Karsten Loesing 
Date:   Tue Jan 9 11:48:25 2018 +0100

Don't rely on system time for writing histories.

Rather than on system time we're now depending on the last time a
relay or bridge was seen in a consensus or status to determine when
history ends for this relay.

This has the advantage of making the write step deterministic, and it
produces the exact same graph intervals for the different documents of
a given relay or bridge.

A minor downside is that we're now depending on node statuses _and_
another status file in order to produce a history document. Should be
okay.

Define graph end as last full data point before the relay/bridge was
last seen.

Also make sure that graphs end at that defined graph end and do not
continue just because there's more history available. This is mostly
to exclude falsely-reported statistics.

Implements #16513.
---
 CHANGELOG.md   |  7 +++
 .../onionoo/writer/BandwidthDocumentWriter.java| 38 ---
 .../onionoo/writer/ClientsDocumentWriter.java  | 34 --
 .../onionoo/writer/UptimeDocumentWriter.java   | 44 +++---
 .../onionoo/writer/WeightsDocumentWriter.java  | 48 +++
 .../writer/BandwidthDocumentWriterTest.java| 23 -
 .../onionoo/writer/UptimeDocumentWriterTest.java   | 54 +-
 7 files changed, 127 insertions(+), 121 deletions(-)

diff --git a/CHANGELOG.md b/CHANGELOG.md
index 8dad79f..1873443 100644
--- a/CHANGELOG.md
+++ b/CHANGELOG.md
@@ -1,3 +1,10 @@
+# Changes in version ??
+
+ * Medium changes
+   - Make writing of bandwidth, clients, uptime, and weights documents
+ independent of system time.
+
+
 # Changes in version 5.0-1.9.0 - 2017-12-20
 
  * Medium changes
diff --git 
a/src/main/java/org/torproject/onionoo/writer/BandwidthDocumentWriter.java 
b/src/main/java/org/torproject/onionoo/writer/BandwidthDocumentWriter.java
index f0ab771..99a5a00 100644
--- a/src/main/java/org/torproject/onionoo/writer/BandwidthDocumentWriter.java
+++ b/src/main/java/org/torproject/onionoo/writer/BandwidthDocumentWriter.java
@@ -9,6 +9,7 @@ import org.torproject.onionoo.docs.DateTimeHelper;
 import org.torproject.onionoo.docs.DocumentStore;
 import org.torproject.onionoo.docs.DocumentStoreFactory;
 import org.torproject.onionoo.docs.GraphHistory;
+import org.torproject.onionoo.docs.NodeStatus;
 import org.torproject.onionoo.docs.UpdateStatus;
 
 import org.slf4j.Logger;
@@ -28,11 +29,8 @@ public class BandwidthDocumentWriter implements 
DocumentWriter {
 
   private DocumentStore documentStore;
 
-  private long now;
-
   public BandwidthDocumentWriter() {
 this.documentStore = DocumentStoreFactory.getDocumentStore();
-this.now = System.currentTimeMillis();
   }
 
   @Override
@@ -44,13 +42,18 @@ public class BandwidthDocumentWriter implements 
DocumentWriter {
 SortedSet updateBandwidthDocuments = this.documentStore.list(
 BandwidthStatus.class, updatedMillis);
 for (String fingerprint : updateBandwidthDocuments) {
+  NodeStatus nodeStatus = this.documentStore.retrieve(NodeStatus.class,
+  true, fingerprint);
+  if (null == nodeStatus) {
+continue;
+  }
   BandwidthStatus bandwidthStatus = this.documentStore.retrieve(
   BandwidthStatus.class, true, fingerprint);
   if (bandwidthStatus == null) {
 continue;
   }
   BandwidthDocument bandwidthDocument = this.compileBandwidthDocument(
-  fingerprint, bandwidthStatus);
+  fingerprint, nodeStatus, bandwidthStatus);
   this.documentStore.store(bandwidthDocument, fingerprint);
 }
 log.info("Wrote bandwidth document files");
@@ -58,13 +61,13 @@ public class BandwidthDocumentWriter implements 
DocumentWriter {
 
 
   private BandwidthDocument compileBandwidthDocument(String fingerprint,
-  BandwidthStatus bandwidthStatus) {
+  NodeStatus nodeStatus, BandwidthStatus bandwidthStatus) {
 BandwidthDocument bandwidthDocument = new BandwidthDocument();
 bandwidthDocument.setFingerprint(fingerprint);
 bandwidthDocument.setWriteHistory(this.compileGraphType(
-bandwidthStatus.getWriteHistory()));
+nodeStatus.getLastSeenMillis(), bandwidthStatus.getWriteHistory()));
 bandwidthDocument.setReadHistory(this.compileGraphType(
-bandwidthStatus.getReadHistory()));
+nodeStatus.getLastSeenMillis(), bandwidthStatus.getReadHistory()));
 return bandwidthDocument;
   }
 
@@ -92,7 +95,7 @@ public class BandwidthDocumentWriter implements 
DocumentWriter {
   DateTimeHelper.TWO_DAYS,
   DateTimeHelper.TEN_DAYS };
 
-  private Map compileGraphType(
+  private Map compileGraphType(long lastSeenMillis,
   SortedMap history) 

[tor-commits] [metrics-lib/release] Add new descriptor type for web server access logs.

2018-02-07 Thread karsten
commit 3cd814d8481c87ee3609783d66ae4e2eec81d290
Author: iwakeh 
Date:   Fri Sep 15 14:07:08 2017 +

Add new descriptor type for web server access logs.

Implements task-22983 and is based on the log-descriptor
specification.
---
 CHANGELOG.md   |   7 +
 .../org/torproject/descriptor/LogDescriptor.java   |  47 ++
 .../torproject/descriptor/WebServerAccessLog.java  |  65 
 .../descriptor/impl/DescriptorParserImpl.java  |  12 +-
 .../torproject/descriptor/index/package-info.java  |   6 +-
 .../torproject/descriptor/internal/FileType.java   |  53 +-
 .../descriptor/internal/package-info.java  |  10 +-
 .../descriptor/log/InternalLogDescriptor.java  |  63 
 .../descriptor/log/InternalWebServerAccessLog.java |  17 ++
 .../descriptor/log/LogDescriptorImpl.java  | 163 +++
 .../descriptor/log/WebServerAccessLogImpl.java | 119 ++
 .../descriptor/log/WebServerAccessLogLine.java | 135 
 .../torproject/descriptor/log/package-info.java|  14 ++
 .../org/torproject/descriptor/package-info.java|   6 +-
 .../descriptor/log/LogDescriptorTest.java  | 178 +
 .../descriptor/log/WebServerAccessLogLineTest.java | 140 
 .../descriptor/log/WebServerAccessLogTest.java |  94 +++
 .../descriptor/log/WebServerModuleTest.java| 113 +
 ...eotrichon.torproject.org_access.log_20151007.xz | Bin 0 -> 4056 bytes
 ...rver.org_dummy.host.net_access.log_2011.bz2 | Bin 0 -> 76 bytes
 ...meronense.torproject.org_access.log_20170530.gz | Bin 0 -> 388 bytes
 ...meronense.torproject.org_access.log_20170531.gz | Bin 0 -> 388 bytes
 ...eronense.torproject.org_access.log_20170530.log |  26 +++
 ...eronense.torproject.org_access.log_20170607.log |  26 +++
 24 files changed, 1280 insertions(+), 14 deletions(-)

diff --git a/CHANGELOG.md b/CHANGELOG.md
index cd0dc6a..42e0e09 100644
--- a/CHANGELOG.md
+++ b/CHANGELOG.md
@@ -1,3 +1,10 @@
+# Changes in version 2.2.0 - 2018-01-??
+
+ * Major changes
+   - Add new descriptor type WebServerAccessLog to parse web server
+ access logs.
+
+
 # Changes in version 2.1.1 - 2017-10-09
 
  * Minor changes
diff --git a/src/main/java/org/torproject/descriptor/LogDescriptor.java 
b/src/main/java/org/torproject/descriptor/LogDescriptor.java
new file mode 100644
index 000..ff02cae
--- /dev/null
+++ b/src/main/java/org/torproject/descriptor/LogDescriptor.java
@@ -0,0 +1,47 @@
+/* Copyright 2017--2018 The Tor Project
+ * See LICENSE for licensing information */
+
+package org.torproject.descriptor;
+
+import java.util.List;
+
+/**
+ * Contains a log file.
+ *
+ * Unlike other descriptors, logs can get very large and are typically 
stored
+ * on disk in compressed form. However, all access to log contents through this
+ * interface and its subinterfaces is made available in uncompressed form.
+ *
+ * @since 2.2.0
+ */
+public interface LogDescriptor extends Descriptor {
+
+  /**
+   * Returns the decompressed raw descriptor bytes of the log.
+   *
+   * @since 2.2.0
+   */
+  @Override
+  public byte[] getRawDescriptorBytes();
+
+  /**
+   * Returns annotations found in the log file, which may be an empty List if a
+   * log format does not support adding annotations.
+   *
+   * @since 2.2.0
+   */
+  @Override
+  public List getAnnotations();
+
+  /**
+   * Returns unrecognized lines encountered while parsing the log, which may be
+   * an empty list or a fixed-size list with only a few entries, depending on
+   * the log type.
+   *
+   * @since 2.2.0
+   */
+  @Override
+  public List getUnrecognizedLines();
+
+}
+
diff --git a/src/main/java/org/torproject/descriptor/WebServerAccessLog.java 
b/src/main/java/org/torproject/descriptor/WebServerAccessLog.java
new file mode 100644
index 000..b94bc30
--- /dev/null
+++ b/src/main/java/org/torproject/descriptor/WebServerAccessLog.java
@@ -0,0 +1,65 @@
+/* Copyright 2017--2018 The Tor Project
+ * See LICENSE for licensing information */
+
+package org.torproject.descriptor;
+
+import java.time.LocalDate;
+import java.util.List;
+
+/**
+ * Contains a sanitized web server access log file from a {@code 
torproject.org}
+ * web server.
+ *
+ * Parsing non-sanitized web server access logs from {@code torproject.org}
+ * web servers or other web servers is not explicitly supported, but may work
+ * anyway.
+ *
+ * @since 2.2.0
+ */
+public interface WebServerAccessLog extends LogDescriptor {
+
+  /**
+   * Returns the date when requests contained in the log have been started,
+   * which is parsed from the log file path.
+   *
+   * Typical web server access logs may contain date information in their
+   * file path, too, but that would be the date when the log file was rotated,
+   * which is not necessary the same date as the date in contained request
+   * lines.
+   *
+   * @since 2.2.0
+   */
+  public 

[tor-commits] [metrics-lib/release] Reduce memory footprint of log lines.

2018-02-07 Thread karsten
commit 8578de6d64569b410678b3c847e7b82b267501ad
Author: iwakeh 
Date:   Wed Jan 31 12:35:31 2018 +

Reduce memory footprint of log lines.

Also make validation optional for internal web log constructor.
CollecTor uses this for storing freshly sanitized logs,
which don't need to be validated a second time.
---
 .../descriptor/log/WebServerAccessLogImpl.java | 19 +++--
 .../descriptor/log/WebServerAccessLogLine.java | 46 --
 2 files changed, 49 insertions(+), 16 deletions(-)

diff --git 
a/src/main/java/org/torproject/descriptor/log/WebServerAccessLogImpl.java 
b/src/main/java/org/torproject/descriptor/log/WebServerAccessLogImpl.java
index 6708c3a..f02b1d7 100644
--- a/src/main/java/org/torproject/descriptor/log/WebServerAccessLogImpl.java
+++ b/src/main/java/org/torproject/descriptor/log/WebServerAccessLogImpl.java
@@ -44,6 +44,8 @@ public class WebServerAccessLogImpl extends LogDescriptorImpl
 
   private final LocalDate logDate;
 
+  private boolean validate = true;
+
   /**
* Creates a WebServerAccessLog from the given bytes and filename.
*
@@ -65,13 +67,20 @@ public class WebServerAccessLogImpl extends 
LogDescriptorImpl
   }
 
   /** For internal use only. */
-  public WebServerAccessLogImpl(Collection lines, String filename)
-  throws DescriptorParseException {
-this(LogDescriptorImpl.collectionToBytes(lines), new File(filename));
+  public WebServerAccessLogImpl(Collection lines, String filename,
+  boolean validate) throws DescriptorParseException {
+this(LogDescriptorImpl.collectionToBytes(lines), new File(filename),
+FileType.XZ, validate);
   }
 
   private WebServerAccessLogImpl(byte[] logBytes, File file,
   FileType defaultCompression) throws DescriptorParseException {
+this(logBytes, file, defaultCompression, true);
+  }
+
+  private WebServerAccessLogImpl(byte[] logBytes, File file,
+  FileType defaultCompression, boolean validate)
+  throws DescriptorParseException {
 super(logBytes, file, defaultCompression);
 try {
   String fn = file.toPath().getFileName().toString();
@@ -91,7 +100,9 @@ public class WebServerAccessLogImpl extends LogDescriptorImpl
   this.logDate = LocalDate.parse(ymd, DateTimeFormatter.BASIC_ISO_DATE);
   this.setValidator((line)
   -> WebServerAccessLogLine.makeLine(line).isValid());
-  this.validate();
+  if (validate) {
+this.validate();
+  }
 } catch (DescriptorParseException dpe) {
   throw dpe; // escalate
 } catch (Exception pe) {
diff --git 
a/src/main/java/org/torproject/descriptor/log/WebServerAccessLogLine.java 
b/src/main/java/org/torproject/descriptor/log/WebServerAccessLogLine.java
index fdbf5c1..2f27441 100644
--- a/src/main/java/org/torproject/descriptor/log/WebServerAccessLogLine.java
+++ b/src/main/java/org/torproject/descriptor/log/WebServerAccessLogLine.java
@@ -10,6 +10,9 @@ import java.time.LocalDate;
 import java.time.ZoneOffset;
 import java.time.ZonedDateTime;
 import java.time.format.DateTimeFormatter;
+import java.util.Collections;
+import java.util.HashMap;
+import java.util.Map;
 import java.util.Optional;
 import java.util.regex.Matcher;
 import java.util.regex.Pattern;
@@ -31,15 +34,23 @@ public class WebServerAccessLogLine {
   + "\"([A-Z]+) ([^\"]+) ([A-Z]+/\\d\\.\\d)\" "
   + "(\\d{3}) (\\d+|-)(.*)");
 
+  private static Map ipMap
+  = Collections.synchronizedMap(new HashMap<>());
+  private static Map dateMap
+  = Collections.synchronizedMap(new HashMap<>());
+  private static Map protocolMap
+  = Collections.synchronizedMap(new HashMap<>());
+  private static Map requestMap
+  = Collections.synchronizedMap(new HashMap<>());
+
   private String ip;
   private int response;
   private String request;
   private Method method;
   private LocalDate date;
-  private String protocol;
   private int size = -1;
   private boolean valid = false;
-  private String type;
+  private String protocol;
 
   /** Returns a log line string. Possibly empty. */
   public String toLogString() {
@@ -53,10 +64,11 @@ public class WebServerAccessLogLine {
   public String toString() {
 return String.format("%s - - [%s:00:00:00 +] \"%s %s %s\" %d %s",
 this.ip, this.getDateString(), this.method.name(), this.request,
-this.type, this.response, this.size < 0 ? DASH : this.size);
+this.protocol, this.response, this.size < 0 ? DASH : this.size);
   }
 
-  /** Returns the string of the date using 'mmdd' format. */
+  /** Only used internally during sanitization.
+   * Returns the string of the date using 'dd/MMM/' format. */
   public String getDateString() {
 return this.date.format(DateTimeFormatter.ofPattern(DATE_PATTERN));
   }
@@ -68,7 +80,7 @@ public class WebServerAccessLogLine {
 
   /** Only used internally during sanitization. */
   

[tor-commits] [metrics-lib/release] Prepare date strings lazily in order to improve performance.

2018-02-07 Thread karsten
commit be9624a17b7df9246cefa0ec27a0ffd6d0bf5c3e
Author: iwakeh 
Date:   Wed Jan 31 12:35:25 2018 +

Prepare date strings lazily in order to improve performance.
---
 .../java/org/torproject/descriptor/log/WebServerAccessLogLine.java | 7 ++-
 1 file changed, 2 insertions(+), 5 deletions(-)

diff --git 
a/src/main/java/org/torproject/descriptor/log/WebServerAccessLogLine.java 
b/src/main/java/org/torproject/descriptor/log/WebServerAccessLogLine.java
index ab20dd2..09cd06a 100644
--- a/src/main/java/org/torproject/descriptor/log/WebServerAccessLogLine.java
+++ b/src/main/java/org/torproject/descriptor/log/WebServerAccessLogLine.java
@@ -34,7 +34,6 @@ public class WebServerAccessLogLine {
   private int response;
   private String request;
   private String method;
-  private String dateString;
   private LocalDate date;
   private String protocol;
   private Optional size;
@@ -52,13 +51,13 @@ public class WebServerAccessLogLine {
   @Override
   public String toString() {
 return String.format("%s - - [%s:00:00:00 +] \"%s %s %s\" %d %s",
-this.ip, this.dateString, this.method, this.request, this.type,
+this.ip, this.getDateString(), this.method, this.request, this.type,
 this.response, this.size.isPresent() ? this.size.get() : "-");
   }
 
   /** Returns the string of the date using 'mmdd' format. */
   public String getDateString() {
-return dateString;
+return this.date.format(DateTimeFormatter.ofPattern(DATE_PATTERN));
   }
 
   /** Returns a string containing the ip. */
@@ -113,8 +112,6 @@ public class WebServerAccessLogLine {
 res.date = ZonedDateTime.parse(dateTimeString,
 dateTimeFormatter).withZoneSameInstant(ZoneOffset.UTC)
 .toLocalDate();
-res.dateString = res.date
-.format(DateTimeFormatter.ofPattern(DATE_PATTERN));
 res.ip = mat.group(1);
 res.request = mat.group(8);
 res.type = mat.group(9);



___
tor-commits mailing list
tor-commits@lists.torproject.org
https://lists.torproject.org/cgi-bin/mailman/listinfo/tor-commits


[tor-commits] [metrics-lib/release] Bump version to 2.1.1-dev.

2018-02-07 Thread karsten
commit 03bc88c23bee7e5bdea45987252ed5b6d28dbcf1
Author: Karsten Loesing 
Date:   Tue Oct 17 21:21:18 2017 +0200

Bump version to 2.1.1-dev.
---
 build.xml | 2 +-
 1 file changed, 1 insertion(+), 1 deletion(-)

diff --git a/build.xml b/build.xml
index badaf37..72c1de1 100644
--- a/build.xml
+++ b/build.xml
@@ -6,7 +6,7 @@
 
 
 
-  
+  
   
   
   



___
tor-commits mailing list
tor-commits@lists.torproject.org
https://lists.torproject.org/cgi-bin/mailman/listinfo/tor-commits


[tor-commits] [metrics-lib/release] Added a space.

2018-02-07 Thread karsten
commit c29327ddc90e488c1dc31dfa46776345ef022a84
Author: iwakeh 
Date:   Fri Sep 15 14:07:06 2017 +

Added a space.
---
 src/main/java/org/torproject/descriptor/impl/KeyValueMap.java | 2 +-
 1 file changed, 1 insertion(+), 1 deletion(-)

diff --git a/src/main/java/org/torproject/descriptor/impl/KeyValueMap.java 
b/src/main/java/org/torproject/descriptor/impl/KeyValueMap.java
index c048b94..08ad84e 100644
--- a/src/main/java/org/torproject/descriptor/impl/KeyValueMap.java
+++ b/src/main/java/org/torproject/descriptor/impl/KeyValueMap.java
@@ -60,7 +60,7 @@ public class KeyValueMap extends TreeMap {
 } catch (IllegalArgumentException | InvocationTargetException e) {
   value = null;
 } catch (NoSuchMethodException e) { // use the String value
-  value = (T)keyAndValue[1];
+  value = (T) keyAndValue[1];
 }
   }
   this.putPair(key, value, line, listElement, keyLength);



___
tor-commits mailing list
tor-commits@lists.torproject.org
https://lists.torproject.org/cgi-bin/mailman/listinfo/tor-commits


[tor-commits] [metrics-lib/release] Update copyright to 2018.

2018-02-07 Thread karsten
commit 2152ece320cf2ed797fe438ff61882ccc7a30b2f
Author: Karsten Loesing 
Date:   Tue Jan 9 10:24:25 2018 +0100

Update copyright to 2018.
---
 src/main/java/org/torproject/descriptor/BandwidthHistory.java   | 2 +-
 src/main/java/org/torproject/descriptor/BridgeExtraInfoDescriptor.java  | 2 +-
 src/main/java/org/torproject/descriptor/BridgeNetworkStatus.java| 2 +-
 src/main/java/org/torproject/descriptor/BridgePoolAssignment.java   | 2 +-
 src/main/java/org/torproject/descriptor/BridgeServerDescriptor.java | 2 +-
 src/main/java/org/torproject/descriptor/Descriptor.java | 2 +-
 src/main/java/org/torproject/descriptor/DescriptorCollector.java| 2 +-
 src/main/java/org/torproject/descriptor/DescriptorParseException.java   | 2 +-
 src/main/java/org/torproject/descriptor/DescriptorParser.java   | 2 +-
 src/main/java/org/torproject/descriptor/DescriptorReader.java   | 2 +-
 src/main/java/org/torproject/descriptor/DescriptorSourceFactory.java| 2 +-
 src/main/java/org/torproject/descriptor/DirSourceEntry.java | 2 +-
 src/main/java/org/torproject/descriptor/DirectoryKeyCertificate.java| 2 +-
 src/main/java/org/torproject/descriptor/DirectorySignature.java | 2 +-
 src/main/java/org/torproject/descriptor/ExitList.java   | 2 +-
 src/main/java/org/torproject/descriptor/ExtraInfoDescriptor.java| 2 +-
 src/main/java/org/torproject/descriptor/Microdescriptor.java| 2 +-
 src/main/java/org/torproject/descriptor/NetworkStatusEntry.java | 2 +-
 src/main/java/org/torproject/descriptor/RelayDirectory.java | 2 +-
 src/main/java/org/torproject/descriptor/RelayExtraInfoDescriptor.java   | 2 +-
 src/main/java/org/torproject/descriptor/RelayNetworkStatus.java | 2 +-
 .../java/org/torproject/descriptor/RelayNetworkStatusConsensus.java | 2 +-
 src/main/java/org/torproject/descriptor/RelayNetworkStatusVote.java | 2 +-
 src/main/java/org/torproject/descriptor/RelayServerDescriptor.java  | 2 +-
 src/main/java/org/torproject/descriptor/RouterStatusEntry.java  | 2 +-
 src/main/java/org/torproject/descriptor/ServerDescriptor.java   | 2 +-
 src/main/java/org/torproject/descriptor/TorperfResult.java  | 2 +-
 src/main/java/org/torproject/descriptor/UnparseableDescriptor.java  | 2 +-
 src/main/java/org/torproject/descriptor/impl/BandwidthHistoryImpl.java  | 2 +-
 src/main/java/org/torproject/descriptor/impl/BlockingIteratorImpl.java  | 2 +-
 .../org/torproject/descriptor/impl/BridgeExtraInfoDescriptorImpl.java   | 2 +-
 .../java/org/torproject/descriptor/impl/BridgeNetworkStatusImpl.java| 2 +-
 .../java/org/torproject/descriptor/impl/BridgePoolAssignmentImpl.java   | 2 +-
 .../java/org/torproject/descriptor/impl/BridgeServerDescriptorImpl.java | 2 +-
 src/main/java/org/torproject/descriptor/impl/DescriptorImpl.java| 2 +-
 src/main/java/org/torproject/descriptor/impl/DescriptorParserImpl.java  | 2 +-
 src/main/java/org/torproject/descriptor/impl/DescriptorReaderImpl.java  | 2 +-
 src/main/java/org/torproject/descriptor/impl/DirSourceEntryImpl.java| 2 +-
 .../org/torproject/descriptor/impl/DirectoryKeyCertificateImpl.java | 2 +-
 .../java/org/torproject/descriptor/impl/DirectorySignatureImpl.java | 2 +-
 src/main/java/org/torproject/descriptor/impl/ExitListEntryImpl.java | 2 +-
 src/main/java/org/torproject/descriptor/impl/ExitListImpl.java  | 2 +-
 .../java/org/torproject/descriptor/impl/ExtraInfoDescriptorImpl.java| 2 +-
 src/main/java/org/torproject/descriptor/impl/KeyValueMap.java   | 2 +-
 src/main/java/org/torproject/descriptor/impl/MicrodescriptorImpl.java   | 2 +-
 .../java/org/torproject/descriptor/impl/NetworkStatusEntryImpl.java | 2 +-
 src/main/java/org/torproject/descriptor/impl/NetworkStatusImpl.java | 2 +-
 src/main/java/org/torproject/descriptor/impl/ParseHelper.java   | 2 +-
 src/main/java/org/torproject/descriptor/impl/RelayDirectoryImpl.java| 2 +-
 .../org/torproject/descriptor/impl/RelayExtraInfoDescriptorImpl.java| 2 +-
 .../org/torproject/descriptor/impl/RelayNetworkStatusConsensusImpl.java | 2 +-
 .../java/org/torproject/descriptor/impl/RelayNetworkStatusImpl.java | 2 +-
 .../java/org/torproject/descriptor/impl/RelayNetworkStatusVoteImpl.java | 2 +-
 .../java/org/torproject/descriptor/impl/RelayServerDescriptorImpl.java  | 2 +-
 src/main/java/org/torproject/descriptor/impl/RouterStatusEntryImpl.java | 2 +-
 src/main/java/org/torproject/descriptor/impl/ServerDescriptorImpl.java  | 2 +-
 src/main/java/org/torproject/descriptor/impl/TorperfResultImpl.java | 2 +-
 .../java/org/torproject/descriptor/impl/UnparseableDescriptorImpl.java  | 2 +-
 .../java/org/torproject/descriptor/index/DescriptorIndexCollector.java  | 2 +-
 src/main/java/org/torproject/descriptor/index/DirectoryNode.java| 2 +-
 

[tor-commits] [metrics-lib/release] Fail early when 'null' values are added.

2018-02-07 Thread karsten
commit 6dd7cb9676b1bb4c1e76a12afbc37da951a96209
Author: iwakeh 
Date:   Sat Feb 3 08:19:56 2018 +

Fail early when 'null' values are added.

And, allow for roughly a years worth of entries in dateMap and requestMap 
before
re-hashing by setting initial capacity.  Defaults are fine for the small 
ipMap
and protocolMap.
---
 .../java/org/torproject/descriptor/log/WebServerAccessLogLine.java | 7 ---
 1 file changed, 4 insertions(+), 3 deletions(-)

diff --git 
a/src/main/java/org/torproject/descriptor/log/WebServerAccessLogLine.java 
b/src/main/java/org/torproject/descriptor/log/WebServerAccessLogLine.java
index 4884733..c9d73cc 100644
--- a/src/main/java/org/torproject/descriptor/log/WebServerAccessLogLine.java
+++ b/src/main/java/org/torproject/descriptor/log/WebServerAccessLogLine.java
@@ -13,6 +13,7 @@ import java.time.format.DateTimeFormatter;
 import java.util.Collections;
 import java.util.HashMap;
 import java.util.Map;
+import java.util.Objects;
 import java.util.Optional;
 import java.util.regex.Matcher;
 import java.util.regex.Pattern;
@@ -37,11 +38,11 @@ public class WebServerAccessLogLine {
   private static Map ipMap
   = Collections.synchronizedMap(new HashMap<>());
   private static Map dateMap
-  = Collections.synchronizedMap(new HashMap<>());
+  = Collections.synchronizedMap(new HashMap<>(500));
   private static Map protocolMap
   = Collections.synchronizedMap(new HashMap<>());
   private static Map requestMap
-  = Collections.synchronizedMap(new HashMap<>());
+  = Collections.synchronizedMap(new HashMap<>(50_000));
 
   private String ip;
   private int response;
@@ -147,7 +148,7 @@ public class WebServerAccessLogLine {
 
   private static  T fromMap(T val, Map map) {
 synchronized (map) {
-  map.putIfAbsent(val, val);
+  map.putIfAbsent(Objects.requireNonNull(val), val);
   return map.get(val);
 }
   }



___
tor-commits mailing list
tor-commits@lists.torproject.org
https://lists.torproject.org/cgi-bin/mailman/listinfo/tor-commits


[tor-commits] [metrics-lib/release] Prepare for 2.2.0 release.

2018-02-07 Thread karsten
commit 678ddfd166c5a7bb9bfde2f5005c5b7e27139ec5
Author: Karsten Loesing 
Date:   Wed Jan 31 13:35:24 2018 +0100

Prepare for 2.2.0 release.
---
 CHANGELOG.md | 2 +-
 build.xml| 2 +-
 2 files changed, 2 insertions(+), 2 deletions(-)

diff --git a/CHANGELOG.md b/CHANGELOG.md
index 42e0e09..5939e38 100644
--- a/CHANGELOG.md
+++ b/CHANGELOG.md
@@ -1,4 +1,4 @@
-# Changes in version 2.2.0 - 2018-01-??
+# Changes in version 2.2.0 - 2018-01-31
 
  * Major changes
- Add new descriptor type WebServerAccessLog to parse web server
diff --git a/build.xml b/build.xml
index 72c1de1..3f081f7 100644
--- a/build.xml
+++ b/build.xml
@@ -6,7 +6,7 @@
 
 
 
-  
+  
   
   
   



___
tor-commits mailing list
tor-commits@lists.torproject.org
https://lists.torproject.org/cgi-bin/mailman/listinfo/tor-commits


  1   2   >