1234567891011121314151617181920212223242526272829303132333435363738394041424344454647484950515253545556575859606162636465666768697071727374757677787980818283 |
- #!/usr/bin/env python3
- from lib.ratelimit import rateLimit
- from lib.nodeinfo import Nodeinfo
- from lib.neighbours import Neighbours
- from lib.statistics import Statistics
- import socket
- import select
- import struct
- import json
- class ResponddClient:
- def __init__(self, config):
- self._config = config
- if 'addr' in self._config:
- addr = self._config['addr']
- else:
- addr = 'ff02::2:1001'
- if 'addr' in self._config:
- port = self._config['port']
- else:
- port = 1001
- if_idx = socket.if_nametoindex(self._config["bridge"])
- group = socket.inet_pton(socket.AF_INET6, addr) + struct.pack("I", if_idx)
- self._sock = socket.socket(socket.AF_INET6, socket.SOCK_DGRAM)
- self._sock.setsockopt(socket.IPPROTO_IPV6, socket.IPV6_JOIN_GROUP, group)
- self._sock.bind(('::', port))
- if 'rate_limit' in self._config:
- if not 'rate_limit_burst' in self._config:
- self._config['rate_limit_burst'] = 10
- self.__RateLimit = rateLimit(self._config['rate_limit'], self._config['rate_limit_burst'])
- else:
- self.__RateLimit = None
- self._nodeinfo = Nodeinfo(self._config)
- self._neighbours = Neighbours(self._config)
- self._statistics = Statistics(self._config)
- def start(self):
- while True:
- if select.select([self._sock], [], [], 1)[0]:
- msg, sourceAddress = self._sock.recvfrom(2048)
- msgSplit = str(msg, 'UTF-8').split(" ")
- if msgSplit[0] == 'GET': # multi_request
- for request in msgSplit[1:]:
- self.sendResponse(sourceAddress, request, True)
- else: # single_request
- self.sendResponse(sourceAddress, msgSplit[0], False)
- def sendResponse(self, destAddress, responseType, withCompression):
- if not self.__RateLimit is None and not self.__RateLimit.limit():
- print("rate limit reached!")
- return
- responseClass = None
- if responseType == 'statistics':
- responseClass = self._statistics
- elif responseType == 'nodeinfo':
- responseClass = self._nodeinfo
- elif responseType == 'neighbours':
- responseClass = self._neighbours
- else:
- print("unknown command: " + responseType)
- return
- if not self._config["dry_run"]:
- if withCompression:
- self._sock.sendto(responseClass.getJSONCompressed(responseType), destAddress)
- else:
- self._sock.sendto(responseClass.getJSON(responseType), destAddress)
- if self._config["verbose"] or self._config["dry_run"]:
- print("%35s %5d %13s: " % (destAddress[0], destAddress[1], responseType), end='')
- print(json.dumps(responseClass.getStruct(responseType), sort_keys=True, indent=4))
|