respondd_client.py 2.4 KB

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