respondd_client.py 2.5 KB

12345678910111213141516171819202122232425262728293031323334353637383940414243444546474849505152535455565758596061626364656667686970717273747576777879808182838485
  1. #!/usr/bin/env python3
  2. from lib.ratelimit import rateLimit
  3. from lib.nodeinfo import Nodeinfo
  4. from lib.neighbours import Neighbours
  5. from lib.statistics import Statistics
  6. import socket
  7. import select
  8. import struct
  9. import json
  10. class ResponddClient:
  11. def __init__(self, config):
  12. self._config = config
  13. if 'addr' in self._config:
  14. addr = self._config['addr']
  15. else:
  16. addr = 'ff02::2:1001'
  17. if 'addr' in self._config:
  18. port = self._config['port']
  19. else:
  20. port = 1001
  21. if_idx = socket.if_nametoindex(self._config["bridge"])
  22. group = socket.inet_pton(socket.AF_INET6, addr) + struct.pack("I", if_idx)
  23. self._sock = socket.socket(socket.AF_INET6, socket.SOCK_DGRAM)
  24. self._sock.setsockopt(socket.IPPROTO_IPV6, socket.IPV6_JOIN_GROUP, group)
  25. self._sock.bind(('::', port))
  26. if 'rate_limit' in self._config:
  27. if not 'rate_limit_burst' in self._config:
  28. self._config['rate_limit_burst'] = 10
  29. self.__RateLimit = rateLimit(self._config['rate_limit'], self._config['rate_limit_burst'])
  30. else:
  31. self.__RateLimit = None
  32. self._nodeinfo = Nodeinfo(self._config)
  33. self._neighbours = Neighbours(self._config)
  34. self._statistics = Statistics(self._config)
  35. def start(self):
  36. while True:
  37. if select.select([self._sock], [], [], 1)[0]:
  38. msg, sender = self._sock.recvfrom(2048)
  39. # if options["verbose"]:
  40. # print(msg)
  41. msg_spl = str(msg, 'UTF-8').split(" ")
  42. if msg_spl[0] == 'GET': # multi_request
  43. for req in msg_spl[1:]:
  44. self.sendResponse(sender, req, True)
  45. else: # single_request
  46. self.sendResponse(sender, msg_spl[0], False)
  47. def sendResponse(self, sender, request, compress):
  48. if not self.__RateLimit is None and not self.__RateLimit.limit():
  49. print("rate limit reached!")
  50. return
  51. response = None
  52. if request == 'statistics':
  53. response = self._statistics
  54. elif request == 'nodeinfo':
  55. response = self._nodeinfo
  56. elif request == 'neighbours':
  57. response = self._neighbours
  58. else:
  59. print("unknown command: " + request)
  60. return
  61. if not self._config["dry_run"]:
  62. if compress:
  63. sock.sendto(response.getJSONCompressed(request), sender)
  64. else:
  65. sock.sendto(response.getJSON(request), sender)
  66. if self._config["verbose"] or self._config["dry_run"]:
  67. print("%35s %5d %13s: " % (sender[0], sender[1], request), end='')
  68. print(json.dumps(response.getStruct(), sort_keys=True, indent=4))