respondd_client.py 2.4 KB

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