respondd_client.py 2.6 KB

1234567891011121314151617181920212223242526272829303132333435363738394041424344454647484950515253545556575859606162636465666768697071727374757677787980818283
  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, sourceAddress = self._sock.recvfrom(2048)
  39. msgSplit = str(msg, 'UTF-8').split(" ")
  40. if msgSplit[0] == 'GET': # multi_request
  41. for request in msgSplit[1:]:
  42. self.sendResponse(sourceAddress, request, True)
  43. else: # single_request
  44. self.sendResponse(sourceAddress, msgSplit[0], False)
  45. def sendResponse(self, destAddress, responseType, withCompression):
  46. if not self.__RateLimit is None and not self.__RateLimit.limit():
  47. print("rate limit reached!")
  48. return
  49. responseClass = None
  50. if responseType == 'statistics':
  51. responseClass = self._statistics
  52. elif responseType == 'nodeinfo':
  53. responseClass = self._nodeinfo
  54. elif responseType == 'neighbours':
  55. responseClass = self._neighbours
  56. else:
  57. print("unknown command: " + responseType)
  58. return
  59. if not self._config["dry_run"]:
  60. if withCompression:
  61. self._sock.sendto(responseClass.getJSONCompressed(responseType), destAddress)
  62. else:
  63. self._sock.sendto(responseClass.getJSON(responseType), destAddress)
  64. if self._config["verbose"] or self._config["dry_run"]:
  65. print("%35s %5d %13s: " % (destAddress[0], destAddress[1], responseType), end='')
  66. print(json.dumps(responseClass.getStruct(responseType), sort_keys=True, indent=4))