Skip to content

Commit

Permalink
cleanup: Make pylint and mypy happy with bootstrap_node_info.py.
Browse files Browse the repository at this point in the history
  • Loading branch information
iphydf committed May 6, 2020
1 parent 3851cfb commit 4375cf1
Showing 1 changed file with 71 additions and 48 deletions.
119 changes: 71 additions & 48 deletions other/fun/bootstrap_node_info.py
Original file line number Diff line number Diff line change
Expand Up @@ -20,15 +20,16 @@
OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
THE SOFTWARE.
"""

from socket import *
import socket
import sys

if sys.version_info[0] == 2:
print("This script requires Python 3+ in order to run.")
sys.exit(1)

def printHelp():

def print_help() -> None:
"""Print program usage to stdout."""
print("Usage: " + sys.argv[0] + " <ipv4|ipv6> <ip/hostname> <port>")
print(" Example: " + sys.argv[0] + " ipv4 192.210.149.121 33445")
print(" Example: " + sys.argv[0] + " ipv4 23.226.230.47 33445")
Expand All @@ -42,57 +43,79 @@ def printHelp():
print(" 2 - didn't receive any reply from a node")
print(" 3 - received a malformed/unexpected reply")

if len(sys.argv) != 4:
printHelp()
sys.exit(1)

protocol = sys.argv[1]
ip = sys.argv[2]
port = int(sys.argv[3])

INFO_PACKET_ID = b"\xF0" # https://github.com/irungentoo/toxcore/blob/4940c4c62b6014d1f0586aa6aca7bf6e4ecfcf29/toxcore/network.h#L128
INFO_REQUEST_PACKET_LENGTH = 78 # https://github.com/irungentoo/toxcore/blob/881b2d900d1998981fb6b9938ec66012d049635f/other/bootstrap_node_packets.c#L28
# first byte is INFO_REQUEST_ID, other bytes don't matter as long as reqest's length matches INFO_REQUEST_LENGTH
INFO_REQUEST_PACKET = INFO_PACKET_ID + ( b"0" * (INFO_REQUEST_PACKET_LENGTH - len(INFO_PACKET_ID)) )
# https://github.com/irungentoo/toxcore/blob/4940c4c62b6014d1f0586aa6aca7bf6e4ecfcf29/toxcore/network.h#L128
INFO_PACKET_ID = b"\xF0"
# https://github.com/irungentoo/toxcore/blob/881b2d900d1998981fb6b9938ec66012d049635f/other/bootstrap_node_packets.c#L28
INFO_REQUEST_PACKET_LENGTH = 78
# first byte is INFO_REQUEST_ID, other bytes don't matter as long as reqest's
# length matches INFO_REQUEST_LENGTH
INFO_REQUEST_PACKET = INFO_PACKET_ID + (
b"0" * (INFO_REQUEST_PACKET_LENGTH - len(INFO_PACKET_ID)))

PACKET_ID_LENGTH = len(INFO_PACKET_ID)
VERSION_LENGTH = 4 # https://github.com/irungentoo/toxcore/blob/881b2d900d1998981fb6b9938ec66012d049635f/other/bootstrap_node_packets.c#L44
MAX_MOTD_LENGTH = 256 # https://github.com/irungentoo/toxcore/blob/881b2d900d1998981fb6b9938ec66012d049635f/other/bootstrap_node_packets.c#L26
# https://github.com/irungentoo/toxcore/blob/881b2d900d1998981fb6b9938ec66012d049635f/other/bootstrap_node_packets.c#L44
VERSION_LENGTH = 4
# https://github.com/irungentoo/toxcore/blob/881b2d900d1998981fb6b9938ec66012d049635f/other/bootstrap_node_packets.c#L26
MAX_MOTD_LENGTH = 256

MAX_INFO_RESPONSE_PACKET_LENGTH = PACKET_ID_LENGTH + VERSION_LENGTH + MAX_MOTD_LENGTH

SOCK_TIMEOUT_SECONDS = 1.0

sock = None

if protocol == "ipv4":
sock = socket(AF_INET, SOCK_DGRAM)
elif protocol == "ipv6":
sock = socket(AF_INET6, SOCK_DGRAM)
else:
print("Invalid first argument")
printHelp()
sys.exit(1)

sock.sendto(INFO_REQUEST_PACKET, (ip, port))

sock.settimeout(SOCK_TIMEOUT_SECONDS)

try:
data, addr = sock.recvfrom(MAX_INFO_RESPONSE_PACKET_LENGTH)
except timeout:
print("The DHT bootstrap node didn't reply in " + str(SOCK_TIMEOUT_SECONDS) + " sec.")
print("The likely reason for that is that the DHT bootstrap node is either offline or has no info set.")
sys.exit(2)

packetId = data[:PACKET_ID_LENGTH]
if packetId != INFO_PACKET_ID:
print("Bad response, first byte should be", INFO_PACKET_ID, "but got", packetId, "(", data, ")")
print("Are you sure that you are pointing the script at a Tox DHT bootstrap node and that the script is up to date?")
sys.exit(3)

version = int.from_bytes(data[PACKET_ID_LENGTH:PACKET_ID_LENGTH + VERSION_LENGTH], byteorder='big')
motd = data[PACKET_ID_LENGTH + VERSION_LENGTH:].decode("utf-8")
print("Version: " + str(version))
print("MOTD: " + motd)
sys.exit(0)
def main(protocol: str, host: str, port: int) -> None:
"""Call the bootstrap node info RPC and output the response."""
if protocol == "ipv4":
sock = socket.socket(socket.AF_INET, socket.SOCK_DGRAM)
elif protocol == "ipv6":
sock = socket.socket(socket.AF_INET6, socket.SOCK_DGRAM)
else:
print("Invalid first argument")
print_help()
sys.exit(1)

sock.sendto(INFO_REQUEST_PACKET, (host, port))

sock.settimeout(SOCK_TIMEOUT_SECONDS)

try:
data, _ = sock.recvfrom(MAX_INFO_RESPONSE_PACKET_LENGTH)
except socket.timeout:
print("The DHT bootstrap node didn't reply in " +
str(SOCK_TIMEOUT_SECONDS) + " sec.")
print("The likely reason for that is that the DHT bootstrap node "
"is either offline or has no info set.")
sys.exit(2)

packet_id = data[:PACKET_ID_LENGTH]
if packet_id != INFO_PACKET_ID:
print("Bad response, first byte should be {info_packet_id} "
"but got {packet_id}({data})".format({
"info_packet_id": INFO_PACKET_ID,
"packet_id": packet_id,
"data": data,
}))
print("Are you sure that you are pointing the script at a Tox "
"DHT bootstrap node and that the script is up to date?")
sys.exit(3)

version = int.from_bytes(data[PACKET_ID_LENGTH:PACKET_ID_LENGTH +
VERSION_LENGTH],
byteorder="big")
motd = data[PACKET_ID_LENGTH + VERSION_LENGTH:].decode("utf-8")
print("Version: " + str(version))
print("MOTD: " + motd)
sys.exit(0)


if __name__ == "__main__":
if len(sys.argv) != 4:
print_help()
sys.exit(1)

main(
protocol=sys.argv[1],
host=sys.argv[2],
port=int(sys.argv[3]),
)

0 comments on commit 4375cf1

Please sign in to comment.