torproject / stem

Python controller library for Tor
https://stem.torproject.org/
GNU Lesser General Public License v3.0
280 stars 76 forks source link

Server descriptor hibernating is true when the item is not present #92

Closed juga0 closed 3 years ago

juga0 commented 3 years ago

While working on this sbws' patch, using the ServerDescriptor hibernating attribute, I realized that it's always returning 1. You can see this in the Gitlab job where integration tests are running with chutney.

Looking at stem's code (https://github.com/torproject/stem/blob/master/stem/descriptor/server_descriptor.py#L336), it's returning 1 when the item is not found, but the spec says at most once and if the value is 1, so i interpret that if it's not present, it's not hibernating.

Here an example of a relay from descriptors cached by chutney without that item:

@downloaded-at 2021-03-22 17:32:40
@source "127.0.0.1"
router test000a 127.0.0.1 5000 0 7000
identity-ed25519
-----BEGIN ED25519 CERT-----
AQQABty7Ad6v2gm3qpOPpSl00Sx2otQB1sB5bkSm9wBkZPjC3soFAQAgBABP1YTv
lYqSmrtt/Md7+gzmiQ12L5Lx6eChjiwJiWrxHAMEtEM+FUhQfMJVww4Vg4P41otI
DLy8bIb6U4BJa+Gm3CBuBFXj0n/SUJYsLB9u7d3YiqWgRDgcXp3xsBek+wg=
-----END ED25519 CERT-----
master-key-ed25519 T9WE75WKkpq7bfzHe/oM5okNdi+S8engoY4sCYlq8Rw
or-address [::]:5000
platform Tor 0.4.5.7-dev on Linux
proto Cons=1-2 Desc=1-2 DirCache=2 FlowCtrl=1 HSDir=1-2 HSIntro=3-5 HSRend=1-2 Link=1-5 LinkAuth=1,3 Microdesc=1-2 Padding=2 Relay=1-3
published 2021-03-22 17:32:25
fingerprint 8D9F 84AF 88A1 8584 71E9 22A7 6F14 2DF9 02A3 9A76
uptime 1
bandwidth 1073741824 1073741824 314368
extra-info-digest 802E55941FB596A490205A7B8078C965409700CE OnrUFROikiTdG2P1Up/c5Cf5Ipdfd5bYRvgokhbGLDs
caches-extra-info
onion-key
-----BEGIN RSA PUBLIC KEY-----
MIGJAoGBAMBkUcTq/nuhA94ItAX2+PB5wl3fRaDYehapQ1M7+uAOaOywnfi0LiRH
qjzGwkgzTBnu5UNszWai+6IBM/W0hLgwNPW9HW5nleguQo2MoFT7FfB5saib/fzh
45FCArzwDqcx7LbezOUKKHzhBu9YEsv2/DTeP49Tdnd7vLVM4D0xAgMBAAE=
-----END RSA PUBLIC KEY-----
signing-key
-----BEGIN RSA PUBLIC KEY-----
MIGJAoGBALRvQZO9GhCJMcekNBLQHjLREQD9whM3sU3pze5UMvbgf4hmFs7or8Vi
9kvAFrOLaeqY5StBuhp2LRbu5NBBlPLxy2zst4+L0Ry0AsR+k1Gk7YdkcjWgLlrE
+LXd/32h+1ZV2omiQyrf4gb841umpkGMykU2mI23hK1rk+mpkvXHAgMBAAE=
-----END RSA PUBLIC KEY-----
onion-key-crosscert
-----BEGIN CROSSCERT-----
VvxjWFECye/XnyBuYQBCBSfwiaS1U1qn2bh8Mm/3SnAl1eFAvlbKuQS+t/Ib9VF5
Q8XuBw5SxV3tOIp04L/ISfa2kUa5YllRMslHj1Nm0IZ+uM22cT+tiBlp63zJ3+8s
u9S5zH/XngvcYfQmdD/iKg7TxGuJRd2NOBGRPqDbo9Q=
-----END CROSSCERT-----
ntor-onion-key-crosscert 1
-----BEGIN ED25519 CERT-----
AQoABtySAU/VhO+VipKau238x3v6DOaJDXYvkvHp4KGOLAmJavEcAKmXNr74H4xL
RBxPI17m0/Bg9pb0PhAvn64JMlX4SyksZ+BkPk57UXxhG+UyikuA6E4TFCkIusU0
HH/SWrkjJwE=
-----END ED25519 CERT-----
hidden-service-dir
contact auth0@test.test
ntor-onion-key HE4ygSlCLb6u52NGTtB502IbTx8Uzk7pJxgL+JL8QHo
reject *:*
tunnelled-dir-server
router-sig-ed25519 mLSsb6m4QlZSC2pjYSFRPimmqTqTxbhKYLTH3EtGVEuByDYxX4kHgxYQCw8OPTyW3LtLNqJoKIURUS9U7oc4BQ
router-signature
-----BEGIN SIGNATURE-----
UeV8Yx1RygyqI05YrC+Wv8gil+vxLNnpoI0cBR9T/aeZIlCGuKqkev7dQYxi8ivF
xHYfhd5nTEwt2ePvAuJA1np4Bcwv11ozatVPmTOX34koQaQ1JwMuJlXODgNDlUHS
GTizBK7hieKLiqLG0omjqePj7h4Dc58hf57N48H6hPM=
-----END SIGNATURE-----
atagar commented 3 years ago

Hi Juga. Unless I'm missing something when a 'hibernating' line is not present the attribute should be (and is) False. An attribute's default value when the line is not present is the first value of the following tuple...

https://github.com/torproject/stem/blob/master/stem/descriptor/server_descriptor.py#L538

When I parse the descriptor you have above I get the correct result...

from stem.descriptor.server_descriptor import RelayDescriptor

DESC = """\
router test000a 127.0.0.1 5000 0 7000
identity-ed25519
-----BEGIN ED25519 CERT-----
AQQABty7Ad6v2gm3qpOPpSl00Sx2otQB1sB5bkSm9wBkZPjC3soFAQAgBABP1YTv
lYqSmrtt/Md7+gzmiQ12L5Lx6eChjiwJiWrxHAMEtEM+FUhQfMJVww4Vg4P41otI
DLy8bIb6U4BJa+Gm3CBuBFXj0n/SUJYsLB9u7d3YiqWgRDgcXp3xsBek+wg=
-----END ED25519 CERT-----
master-key-ed25519 T9WE75WKkpq7bfzHe/oM5okNdi+S8engoY4sCYlq8Rw
or-address [::]:5000
platform Tor 0.4.5.7-dev on Linux
... etc...
""""

desc = RelayDescriptor.from_str(DESC)

print('hibernating: %s' % desc.hibernating)
% python demo.py 
hibernating: False

Feel free to reopen if I'm missing something.

juga0 commented 3 years ago

Thanks for pointing me at that part of the code i didn't see.

Yes, it works as expected using your code.

I guess the issue was that chutney set relays to hibernate in the previous run, when stopping them.

Thanks!