def __init__(self, app): # # Setup the zmq socket used for receiving images. # self.zmq_factory = ZmqFactory() # # Socket for pushing images and crops to the automatic processing servers. # endpoint = ZmqEndpoint( 'bind', 'tcp://*:{zmq_port}'.format(zmq_port=gs.ZMQ_AUTO_WORKER_PUSH)) self.push_socket = ZmqPushConnection(self.zmq_factory, endpoint) # # Socket for pulling results from the automatic processing servers. # endpoint = ZmqEndpoint( 'bind', 'tcp://*:{zmq_port}'.format(zmq_port=gs.ZMQ_AUTO_WORKER_PULL)) self.pull_socket = ZmqPullConnection(self.zmq_factory, endpoint) self.pull_socket.onPull = self.handleNewMessage self.app = app
class BenchmarkWorker: def __init__(self,server,port,secret,requests,concurrency,username,password, verb=False,timeout=600,rate=1000): logname = "/tmp/trbctl-worker-{}.log".format(os.environ.get("LOGID",0)) log.startLogging(open(logname,'w')) self.timeout = timeout self.pusher = ZmqPushConnection(ZmqFactory(), ZmqEndpoint('connect', 'ipc:///tmp/toughbt-message')) self.pusher.push("write worker %s log into %s" % (os.getpid(),logname)) log.msg("init BenchmarkWorker pusher : %s " % repr(self.pusher)) # define client cycle list raddict = dictionary.Dictionary(os.path.join(os.path.dirname(__file__),"dictionary")) new_cli = lambda : RadAuthClient(str(secret), raddict, server,port=port,debug=verb,stat_push=self.pusher) clis = itertools.cycle([new_cli() for c in range(concurrency)]) # send radius message send = lambda:next(clis).sendAuth(**{'User-Name' : username,'User-Password':password}) send_rate = 1.0/rate send_delay = send_rate for i in xrange(requests): reactor.callLater(send_delay,send) send_delay += send_rate reactor.callLater(self.timeout,self.on_timeout) def on_timeout(self): self.pusher.push("logger: BenchmarkWorker timeout, running times: %s" % self.timeout) reactor.stop()
class RADIUSMaster(protocol.DatagramProtocol): """ radius协议监听主进程, 本身不处理任何业务逻辑, 只做消息的路由与转发。 auth_master 和 acct_master 可以以独立的进程来运行, 保证认证与记账业务互不影响。 消息通过msgpack进行二进制封装转发, 保证性能和兼容性。 """ def __init__(self, config, service = 'auth'): self.config = config self.service = service self.pusher = ZmqPushConnection(ZmqFactory(), ZmqEndpoint('bind', config.mqproxy[self.service + '_message'])) self.puller = ZmqPullConnection(ZmqFactory(), ZmqEndpoint('bind', config.mqproxy[self.service + '_result'])) self.puller.onPull = self.radiusReply logger.info('%s master message bind @ %s' % (self.service, self.pusher)) logger.info('%s master result bind @ %s' % (self.service, self.puller)) def datagramReceived(self, datagram, addr): host, port = addr logger.info('request from %s:%s' % (host, port)) message = msgpack.packb([datagram, host, port]) self.pusher.push(message) def radiusReply(self, result): data, host, port = msgpack.unpackb(result[0]) self.transport.write(data, (host, int(port)))
class ZeroMQDelegatorService(Service): """ This is an outbound PUSH connection to the web API ZeroMQRepeaterService that allows a worker to delegate any sub-links it finds (instead of taking a detour to crawl them on their own). """ def __init__(self): self.conn = None def startService(self): factory = ZmqFactory() log.msg("Delegator connecting to repeater: %s" % ZMQ_REPEATER) endpoint = ZmqEndpoint('connect', ZMQ_REPEATER) self.conn = ZmqPushConnection(factory, endpoint) def send_message(self, message): """ Matches the signature of ZeroMQBroadcastService so we can use them interchangably in the job queue code. :param str message: A JSON crawler message. """ log.msg("Delegating job: %s" % message) self.conn.push(message)
def __init__(self, worker): log.msg("Initializing auto server") # # Setup the zmq socket used for receiving images. # self.zmq_factory = ZmqFactory() # # Socket for pulling images and crops from the automatic client. # endpoint = ZmqEndpoint( 'connect', 'tcp://localhost:{zmq_port}'.format( zmq_port=gs.ZMQ_AUTO_WORKER_PUSH)) self.pull_socket = ZmqPullConnection(self.zmq_factory, endpoint) self.pull_socket.onPull = self.handleNewMessage # # Socket for pushing results to the automatic client. # endpoint = ZmqEndpoint( 'connect', 'tcp://localhost:{zmq_port}'.format( zmq_port=gs.ZMQ_AUTO_WORKER_PULL)) self.push_socket = ZmqPushConnection(self.zmq_factory, endpoint) self.worker = worker
def __init__(self, config, dbengine, radcache=None): self.config = config self.dict = dictionary.Dictionary( os.path.join(os.path.dirname(toughradius.__file__), 'dictionarys/dictionary')) self.db_engine = dbengine or get_engine(config) self.mcache = radcache self.pusher = ZmqPushConnection( ZmqFactory(), ZmqEndpoint('connect', 'ipc:///tmp/radiusd-acct-result')) self.stat_pusher = ZmqPushConnection( ZmqFactory(), ZmqEndpoint('connect', 'ipc:///tmp/radiusd-stat-task')) self.puller = ZmqPullConnection( ZmqFactory(), ZmqEndpoint('connect', 'ipc:///tmp/radiusd-acct-message')) self.puller.onPull = self.process logger.info("init acct worker pusher : %s " % (self.pusher)) logger.info("init acct worker puller : %s " % (self.puller)) logger.info("init auth stat pusher : %s " % (self.stat_pusher)) self.acct_class = { STATUS_TYPE_START: RadiusAcctStart, STATUS_TYPE_STOP: RadiusAcctStop, STATUS_TYPE_UPDATE: RadiusAcctUpdate, STATUS_TYPE_ACCT_ON: RadiusAcctOnoff, STATUS_TYPE_ACCT_OFF: RadiusAcctOnoff }
class TwistedZmqClient(object): def __init__(self, service): zf = ZmqFactory() e = ZmqEndpoint('connect', 'tcp://%s:%s' % (service.host, service.port)) self.conn = ZmqPushConnection(zf, e) def send(self, clientid, levellist): self.conn.push(json.dumps({'clientid': clientid, 'levellist': levellist}))
def __init__(self, config, service = 'auth'): self.config = config self.service = service self.pusher = ZmqPushConnection(ZmqFactory(), ZmqEndpoint('bind', config.mqproxy[self.service + '_message'])) self.puller = ZmqPullConnection(ZmqFactory(), ZmqEndpoint('bind', config.mqproxy[self.service + '_result'])) self.puller.onPull = self.radiusReply logger.info('%s master message bind @ %s' % (self.service, self.pusher)) logger.info('%s master result bind @ %s' % (self.service, self.puller))
class TwistedZmqClient(object): def __init__(self, service): zf = ZmqFactory() e = ZmqEndpoint('connect', 'tcp://%s:%s' % (service.host, service.port)) self.conn = ZmqPushConnection(zf, e) def send(self, msg): self.conn.push(msg)
def add_push(self, endpoint): ''' :param endpoint: :return: ''' if endpoint: logger.debug("开始运行 PUSH 服务器,监听地址为:{}...".format(endpoint)) self.push_ = ZmqPushConnection(ZmqFactory(), ZmqEndpoint('connect', endpoint))
def __init__(self, config, dbengine): self.config = config self.dict = dictionary.Dictionary( os.path.join(os.path.dirname(toughradius.__file__), 'dictionarys/dictionary')) self.db_engine = dbengine or get_engine(config) self.aes = utils.AESCipher(key=self.config.system.secret) self.mcache = mcache.Mcache() self.pusher = ZmqPushConnection(ZmqFactory(), ZmqEndpoint('connect', 'ipc:///tmp/radiusd-auth-result')) self.stat_pusher = ZmqPushConnection(ZmqFactory(), ZmqEndpoint('connect', 'ipc:///tmp/radiusd-stat-task')) self.puller = ZmqPullConnection(ZmqFactory(), ZmqEndpoint('connect', 'ipc:///tmp/radiusd-auth-message')) self.puller.onPull = self.process logger.info("init auth worker pusher : %s " % (self.pusher)) logger.info("init auth worker puller : %s " % (self.puller)) logger.info("init auth stat pusher : %s " % (self.stat_pusher))
class BenchmarkWorker: def __init__(self, server, port, secret, requests, concurrency, username, password, verb=False, timeout=600, rate=1000): logname = "/tmp/trbctl-worker-{}.log".format(os.environ.get( "LOGID", 0)) log.startLogging(open(logname, 'w')) self.timeout = timeout self.pusher = ZmqPushConnection( ZmqFactory(), ZmqEndpoint('connect', 'ipc:///tmp/toughbt-message')) self.pusher.push("write worker %s log into %s" % (os.getpid(), logname)) log.msg("init BenchmarkWorker pusher : %s " % repr(self.pusher)) # define client cycle list raddict = dictionary.Dictionary( os.path.join(os.path.dirname(__file__), "dictionary")) new_cli = lambda: RadAuthClient(str(secret), raddict, server, port=port, debug=verb, stat_push=self.pusher) clis = itertools.cycle([new_cli() for c in range(concurrency)]) # send radius message send = lambda: next(clis).sendAuth(**{ 'User-Name': username, 'User-Password': password }) send_rate = 1.0 / rate send_delay = send_rate for i in xrange(requests): reactor.callLater(send_delay, send) send_delay += send_rate reactor.callLater(self.timeout, self.on_timeout) def on_timeout(self): self.pusher.push("logger: BenchmarkWorker timeout, running times: %s" % self.timeout) reactor.stop()
def __init__(self, config, dbengine, radcache=None): self.config = config self.dict = dictionary.Dictionary( os.path.join(os.path.dirname(toughradius.__file__), 'dictionarys/dictionary')) self.db_engine = dbengine or get_engine(config) self.aes = utils.AESCipher(key=self.config.system.secret) self.mcache = radcache self.pusher = ZmqPushConnection(ZmqFactory(), ZmqEndpoint('connect', 'ipc:///tmp/radiusd-auth-result')) self.stat_pusher = ZmqPushConnection(ZmqFactory(), ZmqEndpoint('connect', 'ipc:///tmp/radiusd-stat-task')) self.puller = ZmqPullConnection(ZmqFactory(), ZmqEndpoint('connect', 'ipc:///tmp/radiusd-auth-message')) self.puller.onPull = self.process reactor.listenUDP(0, self) logger.info("init auth worker pusher : %s " % (self.pusher)) logger.info("init auth worker puller : %s " % (self.puller)) logger.info("init auth stat pusher : %s " % (self.stat_pusher))
def __init__(self, zmq_notice_port, zmq_files_port, vn=None): self._loadSearchArea() # # Setup the zmq socket used for sending notice of images. # zmq_factory = ZmqFactory() endpoint = ZmqEndpoint('bind', 'tcp://*:{zmq_port}'.format(zmq_port=zmq_notice_port)) self.zmq_socket = ZmqPushConnection(zmq_factory, endpoint) # # Setup the zmq socket used for sending the images. # endpoint = ZmqEndpoint('bind', 'tcp://*:{zmq_port}'.format(zmq_port=zmq_files_port)) self.zmq_files_socket = ImageFileServerConnection(zmq_factory, endpoint, ) # # Setup the zmq socket used for receiving detection results from the # jetson. # endpoint_rx = ZmqEndpoint('connect', 'tcp://{ip}:{port}'.format(ip=JETSON_IP, port=ADLC_RX_PORT)) self.adlc_rx_socket = ZmqPullConnection(zmq_factory, endpoint_rx) self.adlc_rx_socket.onPull = self.handleADLCResults # # Flag that controls the sending the images # self._send_images = threading.Event() self.manual_crop_cnt = 0 self.auto_crop_cnt = 0 self._img_counter = 0 self._adlc_count = 0 self._received_image_count = 0 self._vn = vn # # Start the upload thread. # Note: # I am using a separate thread for uploading in order to use an # upload queue. We had a problem where slow upload caused many upload # processes to start together and cause jamming in communication. # self.upload_queue = tQueue.Queue(0) self.upload_thread = thread.start_new_thread(upload_thread, (self.upload_queue,))
def __init__(self, config, dbengine, radcache = None): self.config = config self.load_plugins(load_types=['radius_auth_req', 'radius_accept']) self.dict = dictionary.Dictionary(os.path.join(os.path.dirname(taurusxradius.__file__), 'dictionarys/dictionary')) self.db_engine = dbengine or get_engine(config) self.aes = utils.AESCipher(key=self.config.system.secret) self.mcache = radcache self.reject_debug = int(self.get_param_value('radius_reject_debug', 0)) == 1 self.pusher = ZmqPushConnection(ZmqFactory(), ZmqEndpoint('connect', config.mqproxy['auth_result'])) self.stat_pusher = ZmqPushConnection(ZmqFactory(), ZmqEndpoint('connect', config.mqproxy['task_connect'])) self.puller = ZmqPullConnection(ZmqFactory(), ZmqEndpoint('connect', config.mqproxy['auth_message'])) self.puller.onPull = self.process logger.info('radius auth worker %s start' % os.getpid()) logger.info('init auth worker pusher : %s ' % self.pusher) logger.info('init auth worker puller : %s ' % self.puller) logger.info('init auth stat pusher : %s ' % self.stat_pusher) self.license_ulimit = 50000
def __init__(self, config, service='auth'): self.config = config self.service = service self.pusher = ZmqPushConnection(ZmqFactory(), ZmqEndpoint('bind', 'ipc:///tmp/radiusd-%s-message' % service)) self.puller = ZmqPullConnection(ZmqFactory(), ZmqEndpoint('bind', 'ipc:///tmp/radiusd-%s-result' % service)) self.puller.onPull = self.reply logger.info("init %s master pusher : %s " % (self.service, self.pusher)) logger.info("init %s master puller : %s " % (self.service, self.puller))
class ZeroMQBroadcastService(Service): """ This is used by the HTTP API to hand crawl jobs off to the crawler pool. """ def __init__(self): self.conn = None def startService(self): factory = ZmqFactory() bind_point = 'tcp://0.0.0.0:8050' log.msg("Broadcaster binding on: %s" % bind_point) endpoint = ZmqEndpoint('bind', bind_point) self.conn = ZmqPushConnection(factory, endpoint) def send_message(self, message): log.msg("Sent crawl announcement: %s" % message) self.conn.push(message)
def __init__(self, config, dbengine, radcache = None): self.config = config self.load_plugins(load_types=['radius_auth_req', 'radius_accept']) self.dict = dictionary.Dictionary(os.path.join(os.path.dirname(taurusxradius.__file__), 'dictionarys/dictionary')) self.db_engine = dbengine or get_engine(config) self.aes = utils.AESCipher(key=self.config.system.secret) self.mcache = radcache self.stat_pusher = ZmqPushConnection(ZmqFactory()) self.zmqrep = ZmqREPConnection(ZmqFactory()) self.stat_pusher.tcpKeepalive = 1 self.zmqrep.tcpKeepalive = 1 self.stat_pusher.addEndpoints([ZmqEndpoint('connect', config.mqproxy.task_connect)]) self.zmqrep.addEndpoints([ZmqEndpoint('connect', config.mqproxy.auth_connect)]) self.zmqrep.gotMessage = self.process self.reject_debug = int(self.get_param_value('radius_reject_debug', 0)) == 1 logger.info('radius auth worker %s start' % os.getpid()) logger.info('init auth worker : %s ' % self.zmqrep) logger.info('init auth stat pusher : %s ' % self.stat_pusher)
def push_proxy_async(address): """ :param address: :returns: PushProxyAsync """ socket = ZmqPushConnection(ZmqFactory(), ZmqEndpoint("connect", address)) return PushProxyAsync(socket)
def __init__(self, config, dbengine, radcache = None): self.config = config self.load_plugins(load_types=['radius_acct_req']) self.db_engine = dbengine or get_engine(config) self.mcache = radcache self.dict = dictionary.Dictionary(os.path.join(os.path.dirname(taurusxradius.__file__), 'dictionarys/dictionary')) self.stat_pusher = ZmqPushConnection(ZmqFactory(), ZmqEndpoint('connect', config.mqproxy['task_connect'])) self.pusher = ZmqPushConnection(ZmqFactory(), ZmqEndpoint('connect', config.mqproxy['acct_result'])) self.puller = ZmqPullConnection(ZmqFactory(), ZmqEndpoint('connect', config.mqproxy['acct_message'])) self.puller.onPull = self.process self.acct_class = {STATUS_TYPE_START: RadiusAcctStart, STATUS_TYPE_STOP: RadiusAcctStop, STATUS_TYPE_UPDATE: RadiusAcctUpdate, STATUS_TYPE_ACCT_ON: RadiusAcctOnoff, STATUS_TYPE_ACCT_OFF: RadiusAcctOnoff} logger.info('radius acct worker %s start' % os.getpid()) logger.info('init acct worker pusher : %s ' % self.pusher) logger.info('init acct worker puller : %s ' % self.puller) logger.info('init acct stat pusher : %s ' % self.stat_pusher)
def __init__(self, config, dbengine): self.config = config self.dict = dictionary.Dictionary( os.path.join(os.path.dirname(toughradius.__file__), 'dictionarys/dictionary')) self.db_engine = dbengine or get_engine(config) self.mcache = mcache.Mcache() self.pusher = ZmqPushConnection(ZmqFactory(), ZmqEndpoint('connect', 'ipc:///tmp/radiusd-acct-result')) self.stat_pusher = ZmqPushConnection(ZmqFactory(), ZmqEndpoint('connect', 'ipc:///tmp/radiusd-stat-task')) self.puller = ZmqPullConnection(ZmqFactory(), ZmqEndpoint('connect', 'ipc:///tmp/radiusd-acct-message')) self.puller.onPull = self.process logger.info("init acct worker pusher : %s " % (self.pusher)) logger.info("init acct worker puller : %s " % (self.puller)) logger.info("init auth stat pusher : %s " % (self.stat_pusher)) self.acct_class = { STATUS_TYPE_START: RadiusAcctStart, STATUS_TYPE_STOP: RadiusAcctStop, STATUS_TYPE_UPDATE: RadiusAcctUpdate, STATUS_TYPE_ACCT_ON: RadiusAcctOnoff, STATUS_TYPE_ACCT_OFF: RadiusAcctOnoff }
def __init__(self, gdata): self.gdata = gdata self.config = gdata.config self.que = deque() self.cache = gdata.cache self.db_engine = gdata.db_engine self.metadata = models.get_metadata(self.db_engine) self.ops = { 'radstart':self.start_session, 'radstop':self.stop_session } self.radstart = ZmqPullConnection(ZmqFactory(), ZmqEndpoint('connect', self.config.mqproxy.radstart_connect)) self.radstop = ZmqSubConnection(ZmqFactory(), ZmqEndpoint('connect',self.config.mqproxy.radstop_connect)) self.radresp = ZmqPushConnection(ZmqFactory(), ZmqEndpoint('connect', self.config.mqproxy.radresp_connect)) self.radstop.subscribe('radstop') self.radstop.gotMessage = self.subdataReceived self.radstart.onPull = self.dataReceived self.process_poll() logger.info("Start radstart %s" % self.radstart) logger.info("Start radstop %s" % self.radstop) logger.info("Start radresp %s" % self.radresp)
def onJoin(self, details): s = ZmqPullConnection(ZF, ZFE) ss = ZmqPushConnection(ZF, ZFE_SSL) def go_pull(sr): ss.push(sr) chan, sr = sr[0].split(' ', 1) sr = pickle.loads(sr) #print chan #print chan, sr['bdata_mode0']['updated'] self.publish(chan, sr) s.onPull = go_pull
class pushMode(): ''' zmq 推送者模型 ''' def __init__(self, endpoint): if endpoint: logger.debug("开始运行 PUSH 服务器,监听地址为:{}...".format(endpoint)) self._push = ZmqPushConnection(ZmqFactory(), ZmqEndpoint('connect', endpoint)) else: self._push = None def pushData(self, data): ''' :param data: :return: ''' if self._push: self._push.push(data) else: logger.error("Skipping, no pull consumers...")
class AutoClient(object): """Handle the communication with the automatic detection servers.""" def __init__(self, app): # # Setup the zmq socket used for receiving images. # self.zmq_factory = ZmqFactory() # # Socket for pushing images and crops to the automatic processing servers. # endpoint = ZmqEndpoint( 'bind', 'tcp://*:{zmq_port}'.format(zmq_port=gs.ZMQ_AUTO_WORKER_PUSH)) self.push_socket = ZmqPushConnection(self.zmq_factory, endpoint) # # Socket for pulling results from the automatic processing servers. # endpoint = ZmqEndpoint( 'bind', 'tcp://*:{zmq_port}'.format(zmq_port=gs.ZMQ_AUTO_WORKER_PULL)) self.pull_socket = ZmqPullConnection(self.zmq_factory, endpoint) self.pull_socket.onPull = self.handleNewMessage self.app = app def shutdown(self): """Shutdown the zmq connection.""" self.zmq_factory.shutdown() def sendNewImage(self, img_path, data_path): """Send a new image (got from the primary ip) to the auto server""" data = [gs.RESIZED_IMAGE, img_path, data_path] try: log.msg("Sending of img {img}.".format(img=img_path)) self.push_socket.push(data) except zmq.error.Again: log.msg("Skipping sending of {img}, no pull consumers...".format( img=img_path)) def sendNewCrop(self, crop_path, yaw, lat, lon): """Send a new (auto) crop from the primary ip to the auto server.""" data = [gs.AUTO_CROP, crop_path, yaw, lat, lon] try: log.msg("Sending of crop {crop}.".format(crop=crop_path)) self.push_socket.push(data) except zmq.error.Again: log.msg( "Skipping sending of crop {crop}, no pull consumers...".format( crop=crop_path)) def handleNewMessage(self, new_data_message, ignore_tag=None): """Analyze the data received from the auto server.""" try: data_type = new_data_message[0] if data_type == gs.CROP_REQUESTS: img_path, requested_crops = new_data_message[1], json.loads( new_data_message[2]) if len(requested_crops) == 0: log.msg('No target candidates found for image {img_name}'. format(img_name=os.path.split(img_path)[-1])) return self.app.downloadCrops(img_path, requested_crops) elif data_type == gs.TARGET_DATA: crop_path, target_details = new_data_message[1], json.loads( new_data_message[2]) if target_details is {}: log.msg('Crop {crop_name} not a target'.format( crop_name=os.path.split(crop_path)[-1])) return self.app.newTarget(crop_path, target_details) else: log.msg( "Unkown data type received from auto server: {data_type}". format(data_type=data_type)) except Exception as e: log.err(e, 'handleNewMessage')
def __init__(self, endpoint): if endpoint: logger.debug("开始运行 PUSH 服务器,监听地址为:{}...".format(endpoint)) self._push = ZmqPushConnection(ZmqFactory(), ZmqEndpoint('connect', endpoint)) else: self._push = None
class RADIUSAuthWorker(TraceMix): """ 认证子进程,处理认证授权逻辑,把结果推送个 radius 协议处理主进程 """ def __init__(self, config, dbengine, radcache = None): self.config = config self.load_plugins(load_types=['radius_auth_req', 'radius_accept']) self.dict = dictionary.Dictionary(os.path.join(os.path.dirname(taurusxradius.__file__), 'dictionarys/dictionary')) self.db_engine = dbengine or get_engine(config) self.aes = utils.AESCipher(key=self.config.system.secret) self.mcache = radcache self.stat_pusher = ZmqPushConnection(ZmqFactory()) self.zmqrep = ZmqREPConnection(ZmqFactory()) self.stat_pusher.tcpKeepalive = 1 self.zmqrep.tcpKeepalive = 1 self.stat_pusher.addEndpoints([ZmqEndpoint('connect', config.mqproxy.task_connect)]) self.zmqrep.addEndpoints([ZmqEndpoint('connect', config.mqproxy.auth_connect)]) self.zmqrep.gotMessage = self.process self.reject_debug = int(self.get_param_value('radius_reject_debug', 0)) == 1 logger.info('radius auth worker %s start' % os.getpid()) logger.info('init auth worker : %s ' % self.zmqrep) logger.info('init auth stat pusher : %s ' % self.stat_pusher) def get_account_bind_nas(self, account_number): def fetch_result(): with self.db_engine.begin() as conn: sql = '\n select bas.ip_addr \n from tr_bas as bas,tr_customer as cus,tr_account as usr,tr_bas_node as bn\n where cus.customer_id = usr.customer_id\n and cus.node_id = bn.node_id\n and bn.bas_id = bas.id\n and usr.account_number = :account_number\n ' cur = conn.execute(_sql(sql), account_number=account_number) ipaddrs = [ addr['ip_addr'] for addr in cur ] return ipaddrs return self.mcache.aget(account_bind_basip_key(account_number), fetch_result, expire=600) def do_stat(self, code): try: stat_msg = {'statattrs': [], 'raddata': {}} if code == packet.AccessRequest: stat_msg['statattrs'].append('auth_req') elif code == packet.AccessAccept: stat_msg['statattrs'].append('auth_accept') elif code == packet.AccessReject: stat_msg['statattrs'].append('auth_reject') else: stat_msg['statattrs'] = ['auth_drop'] self.stat_pusher.push(msgpack.packb(stat_msg)) except: pass def process(self, msgid, message): datagram, host, port = msgpack.unpackb(message) reply = self.processAuth(datagram, host, port) if not reply: return if reply.code == packet.AccessReject: logger.error(u'[Radiusd] :: Send Radius Reject %s' % repr(reply), tag='radius_auth_reject') else: logger.info(u'[Radiusd] :: Send radius response: %s' % repr(reply)) if self.config.system.debug: logger.debug(reply.format_str()) self.zmqrep.reply(msgid, msgpack.packb([reply.ReplyPacket(), host, port])) self.do_stat(reply.code) def createAuthPacket(self, **kwargs): vendor_id = kwargs.pop('vendor_id', 0) auth_message = message.AuthMessage(**kwargs) auth_message.vendor_id = vendor_id for plugin in self.auth_req_plugins: auth_message = plugin.plugin_func(auth_message) return auth_message def freeReply(self, req): reply = req.CreateReply() reply.vendor_id = req.vendor_id reply['Reply-Message'] = 'user:%s auth success' % req.get_user_name() reply.code = packet.AccessAccept reply_attrs = {'attrs': {}} reply_attrs['input_rate'] = int(self.get_param_value('radius_free_input_rate', 1048576)) reply_attrs['output_rate'] = int(self.get_param_value('radius_free_output_rate', 4194304)) reply_attrs['rate_code'] = self.get_param_value('radius_free_rate_code', 'freerate') reply_attrs['domain'] = self.get_param_value('radius_free_domain', 'freedomain') reply_attrs['attrs']['Session-Timeout'] = int(self.get_param_value('radius_max_session_timeout', 86400)) for plugin in self.auth_accept_plugins: reply = plugin.plugin_func(reply, reply_attrs) return reply def rejectReply(self, req, errmsg = ''): reply = req.CreateReply() reply.vendor_id = req.vendor_id reply['Reply-Message'] = errmsg reply.code = packet.AccessReject return reply def processAuth(self, datagram, host, port): try: bas = self.find_nas(host) if not bas: raise PacketError('[Radiusd] :: Dropping packet from unknown host %s' % host) secret, vendor_id = bas['bas_secret'], bas['vendor_id'] req = self.createAuthPacket(packet=datagram, dict=self.dict, secret=six.b(str(secret)), vendor_id=vendor_id) username = req.get_user_name() bypass = int(self.get_param_value('radius_bypass', 1)) if req.code != packet.AccessRequest: raise PacketError('non-AccessRequest packet on authentication socket') self.log_trace(host, port, req) self.do_stat(req.code) if self.config.system.debug: logger.debug('[Radiusd] :: Received radius request: %s' % req.format_str()) else: logger.info('[Radiusd] :: Received radius request: %s' % repr(req)) if bypass == 2: reply = self.freeReply(req) self.log_trace(host, port, req, reply) return reply if not self.user_exists(username): errmsg = u'[Radiusd] :: user:%s not exists' % username reply = self.rejectReply(req, errmsg) self.log_trace(host, port, req, reply) return reply bind_nas_list = self.get_account_bind_nas(username) if not bind_nas_list or host not in bind_nas_list: errmsg = u'[Radiusd] :: nas_addr:%s not bind for user:%s node' % (host, username) reply = self.rejectReply(req, errmsg) self.log_trace(host, port, req, reply) return reply aaa_request = dict(account_number=username, domain=req.get_domain(), macaddr=req.client_mac, nasaddr=req.get_nas_addr(), vlanid1=req.vlanid1, vlanid2=req.vlanid2, bypass=bypass, radreq=req) auth_resp = RadiusAuth(self.db_engine, self.mcache, self.aes, aaa_request).authorize() if auth_resp['code'] > 0: reply = self.rejectReply(req, auth_resp['msg']) self.log_trace(host, port, req, reply) return reply reply = req.CreateReply() reply.code = packet.AccessAccept reply.vendor_id = req.vendor_id reply['Reply-Message'] = 'user:%s auth success' % username reply_attrs = {} reply_attrs.update(auth_resp) reply_attrs.update(req.resp_attrs) for plugin in self.auth_accept_plugins: reply = plugin.plugin_func(reply, reply_attrs) if not req.VerifyReply(reply): raise PacketError('[Radiusd] :: user:%s auth verify reply error' % username) self.log_trace(host, port, req, reply) return reply except Exception as err: if not self.reject_debug: self.do_stat(0) logger.exception(err, tag='radius_auth_error') else: reply = self.rejectReply(req, repr(err)) self.log_trace(host, port, req, reply) return reply
class RadClientWorker(object): def __init__(self, gdata): self.gdata = gdata self.config = gdata.config self.que = deque() self.cache = gdata.cache self.db_engine = gdata.db_engine self.metadata = models.get_metadata(self.db_engine) self.ops = { 'radstart':self.start_session, 'radstop':self.stop_session } self.radstart = ZmqPullConnection(ZmqFactory(), ZmqEndpoint('connect', self.config.mqproxy.radstart_connect)) self.radstop = ZmqSubConnection(ZmqFactory(), ZmqEndpoint('connect',self.config.mqproxy.radstop_connect)) self.radresp = ZmqPushConnection(ZmqFactory(), ZmqEndpoint('connect', self.config.mqproxy.radresp_connect)) self.radstop.subscribe('radstop') self.radstop.gotMessage = self.subdataReceived self.radstart.onPull = self.dataReceived self.process_poll() logger.info("Start radstart %s" % self.radstart) logger.info("Start radstop %s" % self.radstop) logger.info("Start radresp %s" % self.radresp) def subdataReceived(self, request,tag): try: message = msgpack.unpackb(request) if self.config.system.debug: logger.debug(u"received radius start request:"+utils.safeunicode(message)) self.que.appendleft(message) except: traceback.print_exc() def dataReceived(self, request): try: message = msgpack.unpackb(request[0]) if self.config.system.debug: logger.debug(u"received radius start request:"+utils.safeunicode(message)) self.que.appendleft(message) except: traceback.print_exc() def start_session(self,userdata): username = userdata['username'] password = userdata['password'] radius_ipaddr = userdata['radius_ipaddr'] num = userdata.get("num",1) isresp = int(userdata.get("isresp",0)) sendresp = lambda r : self.radresp.push(msgpack.packb(['radstart_resp',r])) if isresp else None senderror = lambda e: self.radresp.push(msgpack.packb(['radstart_error',dict(code=1,msg=repr(e))])) if isresp else None for i in range(num): rad_session = RadiusSession(self.config,self.db_engine, statcache=self.gdata.statcache,radius_ipaddr=radius_ipaddr) rad_session.start(username,password).addCallbacks(sendresp,senderror) def stop_session(self,userdata): ipaddr = userdata.get('ipaddr','') session_id = userdata.get('session_id','') username = userdata.get('username','') RadiusSession.stop_session(ipaddr=ipaddr,session_id=session_id,username=username) self.radresp.push(msgpack.packb(['radstop_resp',dict(code=0,msg="session(%s,%s,%s) stop done"%(ipaddr,session_id,username))])) def process_poll(self): try: action, objdata = self.que.pop() except Exception as err: # logger.exception(err) reactor.callLater(1,self.process_poll) else: try: opfunc = self.ops.get(action) if opfunc: opfunc(objdata) else: logger.error('action %s not support'%action) except Exception as err: self.radresp.push(msgpack.packb(['%s_error'%action,dict(code=1,msg=repr(err))])) logger.exception(err) finally: reactor.callLater(0.001,self.process_poll)
def __init__(self): self.pusher = ZmqPushConnection( ZmqFactory(), ZmqEndpoint('bind', 'ipc:///tmp/tpsim-message')) self.logger.info('init TpSimMaster pusher : %s ' % self.pusher)
def init(gdata): appname = os.path.basename(gdata.app_dir) utils.update_tz(gdata.config.system.tz) syslog = logger.Logger(gdata.config, appname) dispatch.register(syslog) log.startLoggingWithObserver(syslog.emit, setStdout=0) gdata.db_engine = get_engine(gdata.config) gdata.db = scoped_session( sessionmaker(bind=gdata.db_engine, autocommit=False, autoflush=False)) # web 应用初始化 gdata.settings = dict( cookie_secret="12oETzKXQAGaYdkL5gEmGeJJFuYh7EQnp2XdTP1o/Vo=", login_url="/admin/login", template_path=os.path.join(os.path.dirname(__file__), "views"), static_path=os.path.join(os.path.dirname(__file__), "static"), xsrf_cookies=True, xheaders=True, conf=gdata.config) # 模板初始化 gdata.tp_lookup = TemplateLookup( directories=[gdata.settings['template_path']], default_filters=['decode.utf8'], input_encoding='utf-8', output_encoding='utf-8', encoding_errors='ignore', module_directory="/tmp/toughcloud") gdata.redisconf = redis_conf(gdata.config) gdata.session_manager = session.SessionManager( gdata.redisconf, gdata.settings["cookie_secret"], 7200) gdata.cache = CacheManager(gdata.redisconf, cache_name='Cache-%s' % os.getpid()) gdata.aes = utils.AESCipher(key=gdata.config.system.secret) # 数据库备份器初始化 gdata.db_backup = DBBackup(models.get_metadata(gdata.db_engine), excludes=[]) #cache event init dispatch.register(gdata.cache) # app handles init handler_dir = os.path.join(gdata.app_dir, 'handlers') load_handlers(handler_path=handler_dir, pkg_prefix="%s.handlers" % appname, excludes=[]) gdata.all_handlers = permit.all_handlers # app event init event_dir = os.path.abspath(os.path.join(gdata.app_dir, 'events')) load_events(event_dir, "%s.events" % appname) # init zmq gdata.radque = deque([], 8192) gdata.radstart = ZmqPushConnection( ZmqFactory(), ZmqEndpoint('bind', gdata.config.mqproxy.radstart_bind)) gdata.radstop = ZmqPubConnection( ZmqFactory(), ZmqEndpoint('bind', gdata.config.mqproxy.radstop_bind)) gdata.radresp = ZmqPullConnection( ZmqFactory(), ZmqEndpoint('bind', gdata.config.mqproxy.radresp_bind)) gdata.radresp.onPull = lambda m: gdata.radque.appendleft( msgpack.unpackb(m[0])) gdata.statcache = StatCounter(gdata) gdata.statcache.init() gdata.statcache.poll_calc() logger.info(gdata.radstart) logger.info(gdata.radstop) logger.info(gdata.radresp)
class RADIUSAuthWorker(protocol.DatagramProtocol,TraceMix): def __init__(self, config, dbengine, radcache=None): self.config = config self.dict = dictionary.Dictionary( os.path.join(os.path.dirname(toughradius.__file__), 'dictionarys/dictionary')) self.db_engine = dbengine or get_engine(config) self.aes = utils.AESCipher(key=self.config.system.secret) self.mcache = radcache self.pusher = ZmqPushConnection(ZmqFactory(), ZmqEndpoint('connect', 'ipc:///tmp/radiusd-auth-result')) self.stat_pusher = ZmqPushConnection(ZmqFactory(), ZmqEndpoint('connect', 'ipc:///tmp/radiusd-stat-task')) self.puller = ZmqPullConnection(ZmqFactory(), ZmqEndpoint('connect', 'ipc:///tmp/radiusd-auth-message')) self.puller.onPull = self.process reactor.listenUDP(0, self) logger.info("init auth worker pusher : %s " % (self.pusher)) logger.info("init auth worker puller : %s " % (self.puller)) logger.info("init auth stat pusher : %s " % (self.stat_pusher)) def find_nas(self,ip_addr): def fetch_result(): table = models.TrBas.__table__ with self.db_engine.begin() as conn: return conn.execute(table.select().where(table.c.ip_addr==ip_addr)).first() return self.mcache.aget(bas_cache_key(ip_addr),fetch_result, expire=600) def do_stat(self,code): try: stat_msg = {'statattrs':[],'raddata':{}} if code == packet.AccessRequest: stat_msg['statattrs'].append('auth_req') elif code == packet.AccessAccept: stat_msg['statattrs'].append('auth_accept') elif code == packet.AccessReject: stat_msg['statattrs'].append('auth_reject') else: stat_msg['statattrs'] = ['auth_drop'] self.stat_pusher.push(msgpack.packb(stat_msg)) except: pass def process(self, message): datagram, host, port = msgpack.unpackb(message[0]) reply = self.processAuth(datagram, host, port) if not reply: return logger.info("[Radiusd] :: Send radius response: %s" % repr(reply)) if self.config.system.debug: logger.debug(reply.format_str()) self.pusher.push(msgpack.packb([reply.ReplyPacket(),host,port])) # self.transport.write(reply.ReplyPacket(), (host,port)) self.do_stat(reply.code) def createAuthPacket(self, **kwargs): vendor_id = kwargs.pop('vendor_id',0) auth_message = message.AuthMessage(**kwargs) auth_message.vendor_id = vendor_id auth_message = mac_parse.process(auth_message) auth_message = vlan_parse.process(auth_message) return auth_message def processAuth(self, datagram, host, port): try: bas = self.find_nas(host) if not bas: raise PacketError('[Radiusd] :: Dropping packet from unknown host %s' % host) secret, vendor_id = bas['bas_secret'], bas['vendor_id'] req = self.createAuthPacket(packet=datagram, dict=self.dict, secret=six.b(str(secret)),vendor_id=vendor_id) self.log_trace(host,port,req) self.do_stat(req.code) logger.info("[Radiusd] :: Received radius request: %s" % (repr(req))) if self.config.system.debug: logger.debug(req.format_str()) if req.code != packet.AccessRequest: raise PacketError('non-AccessRequest packet on authentication socket') reply = req.CreateReply() reply.vendor_id = req.vendor_id aaa_request = dict( account_number=req.get_user_name(), domain=req.get_domain(), macaddr=req.client_mac, nasaddr=req.get_nas_addr() or host, vlanid1=req.vlanid1, vlanid2=req.vlanid2 ) auth_resp = RadiusAuth(self.db_engine,self.mcache,self.aes,aaa_request).authorize() if auth_resp['code'] > 0: reply['Reply-Message'] = auth_resp['msg'] reply.code = packet.AccessReject self.log_trace(host,port,req,reply) return reply if 'bypass' in auth_resp and int(auth_resp['bypass']) == 0: is_pwd_ok = True req.is_valid_pwd(auth_resp.get('passwd')) else: is_pwd_ok = req.is_valid_pwd(auth_resp.get('passwd')) if not is_pwd_ok: reply['Reply-Message'] = "password not match" reply.code = packet.AccessReject self.log_trace(host,port,req,reply) return reply else: if u"input_rate" in auth_resp and u"output_rate" in auth_resp: reply = rate_process.process( reply, input_rate=auth_resp['input_rate'], output_rate=auth_resp['output_rate']) attrs = auth_resp.get("attrs") or {} for attr_name in attrs: try: # todo: May have a type matching problem reply.AddAttribute(utils.safestr(attr_name), attrs[attr_name]) except Exception as err: errstr = "RadiusError:current radius cannot support attribute {0},{1}".format( attr_name,utils.safestr(err.message)) logger.error(RadiusError(err,errstr)) for attr, attr_val in req.resp_attrs.iteritems(): reply[attr] = attr_val reply['Reply-Message'] = 'success!' reply.code = packet.AccessAccept if not req.VerifyReply(reply): raise PacketError('VerifyReply error') self.log_trace(host,port,req,reply) return reply except Exception as err: self.do_stat(0) logger.exception(err)
class RADIUSAcctWorker(TraceMix): """ 记账子进程,处理计费逻辑,把结果推送个 radius 协议处理主进程, 记账是异步处理的,即每次收到记账消息时,立即推送响应,然后在后台异步处理计费逻辑。 """ def __init__(self, config, dbengine, radcache = None): self.config = config self.load_plugins(load_types=['radius_acct_req']) self.db_engine = dbengine or get_engine(config) self.mcache = radcache self.dict = dictionary.Dictionary(os.path.join(os.path.dirname(taurusxradius.__file__), 'dictionarys/dictionary')) self.stat_pusher = ZmqPushConnection(ZmqFactory()) self.zmqrep = ZmqREPConnection(ZmqFactory()) self.stat_pusher.tcpKeepalive = 1 self.zmqrep.tcpKeepalive = 1 self.stat_pusher.addEndpoints([ZmqEndpoint('connect', config.mqproxy.task_connect)]) self.zmqrep.addEndpoints([ZmqEndpoint('connect', config.mqproxy.acct_connect)]) self.zmqrep.gotMessage = self.process self.acct_class = {STATUS_TYPE_START: RadiusAcctStart, STATUS_TYPE_STOP: RadiusAcctStop, STATUS_TYPE_UPDATE: RadiusAcctUpdate, STATUS_TYPE_ACCT_ON: RadiusAcctOnoff, STATUS_TYPE_ACCT_OFF: RadiusAcctOnoff} logger.info('radius acct worker %s start' % os.getpid()) logger.info('init acct worker : %s ' % self.zmqrep) logger.info('init acct stat pusher : %s ' % self.stat_pusher) def do_stat(self, code, status_type = 0, req = None): try: stat_msg = {'statattrs': ['acct_drop'], 'raddata': {}} if code in (4, 5): stat_msg['statattrs'] = [] if code == packet.AccountingRequest: stat_msg['statattrs'].append('acct_req') elif code == packet.AccountingResponse: stat_msg['statattrs'].append('acct_resp') if status_type == 1: stat_msg['statattrs'].append('acct_start') elif status_type == 2: stat_msg['statattrs'].append('acct_stop') elif status_type == 3: stat_msg['statattrs'].append('acct_update') stat_msg['raddata']['input_total'] = req.get_input_total() stat_msg['raddata']['output_total'] = req.get_output_total() elif status_type == 7: stat_msg['statattrs'].append('acct_on') elif status_type == 8: stat_msg['statattrs'].append('acct_off') self.stat_pusher.push(msgpack.packb(stat_msg)) except: pass def process(self, msgid, message): datagram, host, port = msgpack.unpackb(message) reply = self.processAcct(datagram, host, port) self.zmqrep.reply(msgid, msgpack.packb([reply.ReplyPacket(), host, port])) def createAcctPacket(self, **kwargs): vendor_id = kwargs.pop('vendor_id', 0) acct_message = message.AcctMessage(**kwargs) acct_message.vendor_id = vendor_id for plugin in self.acct_req_plugins: acct_message = plugin.plugin_func(acct_message) return acct_message def processAcct(self, datagram, host, port): try: bas = self.find_nas(host) if not bas: raise PacketError('[Radiusd] :: Dropping packet from unknown host %s' % host) secret, vendor_id = bas['bas_secret'], bas['vendor_id'] req = self.createAcctPacket(packet=datagram, dict=self.dict, secret=six.b(str(secret)), vendor_id=vendor_id) self.log_trace(host, port, req) self.do_stat(req.code, req.get_acct_status_type(), req=req) if self.config.system.debug: logger.debug('[Radiusd] :: Received radius request: %s' % req.format_str()) else: logger.info('[Radiusd] :: Received radius request: %s' % repr(req)) if req.code != packet.AccountingRequest: raise PacketError('non-AccountingRequest packet on authentication socket') if not req.VerifyAcctRequest(): raise PacketError('VerifyAcctRequest error') status_type = req.get_acct_status_type() if status_type in self.acct_class: ticket = req.get_ticket() if not ticket.get('nas_addr'): ticket['nas_addr'] = host acct_func = self.acct_class[status_type](self.db_engine, self.mcache, None, ticket).acctounting reactor.callLater(0.05, acct_func) else: raise ValueError('status_type <%s> not support' % status_type) reply = req.CreateReply() reactor.callLater(0.05, self.log_trace, host, port, req, reply) reactor.callLater(0.05, self.do_stat, reply.code) if self.config.system.debug: logger.debug('[Radiusd] :: Send radius response: %s' % reply.format_str()) else: logger.info('[Radiusd] :: Send radius response: %s' % repr(reply)) return reply except Exception as err: self.do_stat(0) logger.exception(err, tag='radius_acct_drop') return
class RADIUSAuthWorker(object): def __init__(self, config, dbengine): self.config = config self.dict = dictionary.Dictionary( os.path.join(os.path.dirname(toughradius.__file__), 'dictionarys/dictionary')) self.db_engine = dbengine or get_engine(config) self.aes = utils.AESCipher(key=self.config.system.secret) self.mcache = mcache.Mcache() self.pusher = ZmqPushConnection(ZmqFactory(), ZmqEndpoint('connect', 'ipc:///tmp/radiusd-auth-result')) self.stat_pusher = ZmqPushConnection(ZmqFactory(), ZmqEndpoint('connect', 'ipc:///tmp/radiusd-stat-task')) self.puller = ZmqPullConnection(ZmqFactory(), ZmqEndpoint('connect', 'ipc:///tmp/radiusd-auth-message')) self.puller.onPull = self.process logger.info("init auth worker pusher : %s " % (self.pusher)) logger.info("init auth worker puller : %s " % (self.puller)) logger.info("init auth stat pusher : %s " % (self.stat_pusher)) def find_nas(self,ip_addr): def fetch_result(): table = models.TrBas.__table__ with self.db_engine.begin() as conn: return conn.execute(table.select().where(table.c.ip_addr==ip_addr)).first() return self.mcache.aget(bas_cache_key(ip_addr),fetch_result, expire=600) def do_stat(self,code): try: stat_msg = [] if code == packet.AccessRequest: stat_msg.append('auth_req') elif code == packet.AccessAccept: stat_msg.append('auth_accept') elif code == packet.AccessReject: stat_msg.append('auth_reject') else: stat_msg = ['auth_drop'] self.stat_pusher.push(msgpack.packb(stat_msg)) except: pass def process(self, message): datagram, host, port = msgpack.unpackb(message[0]) reply = self.processAuth(datagram, host, port) if not reply: return self.do_stat(reply.code) logger.info("[Radiusd] :: Send radius response: %s" % repr(reply)) if self.config.system.debug: logger.debug(reply.format_str()) self.pusher.push(msgpack.packb([reply.ReplyPacket(),host,port])) def createAuthPacket(self, **kwargs): vendor_id = kwargs.pop('vendor_id',0) auth_message = message.AuthMessage(**kwargs) auth_message.vendor_id = vendor_id auth_message = mac_parse.process(auth_message) auth_message = vlan_parse.process(auth_message) return auth_message def processAuth(self, datagram, host, port): try: bas = self.find_nas(host) if not bas: raise PacketError('[Radiusd] :: Dropping packet from unknown host %s' % host) secret, vendor_id = bas['bas_secret'], bas['vendor_id'] req = self.createAuthPacket(packet=datagram, dict=self.dict, secret=six.b(str(secret)),vendor_id=vendor_id) self.do_stat(req.code) logger.info("[Radiusd] :: Received radius request: %s" % (repr(req))) if self.config.system.debug: logger.debug(req.format_str()) if req.code != packet.AccessRequest: raise PacketError('non-AccessRequest packet on authentication socket') reply = req.CreateReply() reply.vendor_id = req.vendor_id aaa_request = dict( account_number=req.get_user_name(), domain=req.get_domain(), macaddr=req.client_mac, nasaddr=req.get_nas_addr(), vlanid1=req.vlanid1, vlanid2=req.vlanid2 ) auth_resp = RadiusAuth(self.db_engine,self.mcache,self.aes,aaa_request).authorize() if auth_resp['code'] > 0: reply['Reply-Message'] = auth_resp['msg'] reply.code = packet.AccessReject return reply if 'bypass' in auth_resp and int(auth_resp['bypass']) == 0: is_pwd_ok = True else: is_pwd_ok = req.is_valid_pwd(auth_resp.get('passwd')) if not is_pwd_ok: reply['Reply-Message'] = "password not match" reply.code = packet.AccessReject return reply else: if u"input_rate" in auth_resp and u"output_rate" in auth_resp: reply = rate_process.process( reply, input_rate=auth_resp['input_rate'], output_rate=auth_resp['output_rate']) attrs = auth_resp.get("attrs") or {} for attr_name in attrs: try: # todo: May have a type matching problem reply.AddAttribute(utils.safestr(attr_name), attrs[attr_name]) except Exception as err: errstr = "RadiusError:current radius cannot support attribute {0},{1}".format( attr_name,utils.safestr(err.message)) logger.error(errstr) for attr, attr_val in req.resp_attrs.iteritems(): reply[attr] = attr_val reply['Reply-Message'] = 'success!' reply.code = packet.AccessAccept if not req.VerifyReply(reply): raise PacketError('VerifyReply error') return reply except Exception as err: self.do_stat(0) errstr = 'RadiusError:Dropping invalid auth packet from {0} {1},{2}'.format( host, port, utils.safeunicode(err)) logger.error(errstr) import traceback traceback.print_exc()
class RADIUSAcctWorker(object): def __init__(self, config, dbengine): self.config = config self.dict = dictionary.Dictionary( os.path.join(os.path.dirname(toughradius.__file__), 'dictionarys/dictionary')) self.db_engine = dbengine or get_engine(config) self.mcache = mcache.Mcache() self.pusher = ZmqPushConnection(ZmqFactory(), ZmqEndpoint('connect', 'ipc:///tmp/radiusd-acct-result')) self.stat_pusher = ZmqPushConnection(ZmqFactory(), ZmqEndpoint('connect', 'ipc:///tmp/radiusd-stat-task')) self.puller = ZmqPullConnection(ZmqFactory(), ZmqEndpoint('connect', 'ipc:///tmp/radiusd-acct-message')) self.puller.onPull = self.process logger.info("init acct worker pusher : %s " % (self.pusher)) logger.info("init acct worker puller : %s " % (self.puller)) logger.info("init auth stat pusher : %s " % (self.stat_pusher)) self.acct_class = { STATUS_TYPE_START: RadiusAcctStart, STATUS_TYPE_STOP: RadiusAcctStop, STATUS_TYPE_UPDATE: RadiusAcctUpdate, STATUS_TYPE_ACCT_ON: RadiusAcctOnoff, STATUS_TYPE_ACCT_OFF: RadiusAcctOnoff } def find_nas(self,ip_addr): def fetch_result(): table = models.TrBas.__table__ with self.db_engine.begin() as conn: return conn.execute(table.select().where(table.c.ip_addr==ip_addr)).first() return self.mcache.aget(bas_cache_key(ip_addr),fetch_result, expire=600) def do_stat(self,code, status_type=0): try: stat_msg = ['acct_drop'] if code in (4,5): stat_msg = [] if code == packet.AccountingRequest: stat_msg.append('acct_req') elif code == packet.AccountingResponse: stat_msg.append('acct_resp') if status_type == 1: stat_msg.append('acct_start') elif status_type == 2: stat_msg.append('acct_stop') elif status_type == 3: stat_msg.append('acct_update') elif status_type == 7: stat_msg.append('acct_on') elif status_type == 8: stat_msg.append('acct_off') self.stat_pusher.push(msgpack.packb(stat_msg)) except: pass def process(self, message): datagram, host, port = msgpack.unpackb(message[0]) self.processAcct(datagram, host, port) def createAcctPacket(self, **kwargs): vendor_id = 0 if 'vendor_id' in kwargs: vendor_id = kwargs.pop('vendor_id') acct_message = message.AcctMessage(**kwargs) acct_message.vendor_id = vendor_id acct_message = mac_parse.process(acct_message) acct_message = vlan_parse.process(acct_message) return acct_message def processAcct(self, datagram, host, port): try: bas = self.find_nas(host) if not bas: raise PacketError('[Radiusd] :: Dropping packet from unknown host %s' % host) secret, vendor_id = bas['bas_secret'], bas['vendor_id'] req = self.createAcctPacket(packet=datagram, dict=self.dict, secret=six.b(str(secret)),vendor_id=vendor_id) self.do_stat(req.code, req.get_acct_status_type()) logger.info("[Radiusd] :: Received radius request: %s" % (repr(req))) if self.config.system.debug: logger.debug(req.format_str()) if req.code != packet.AccountingRequest: raise PacketError('non-AccountingRequest packet on authentication socket') if not req.VerifyAcctRequest(): raise PacketError('VerifyAcctRequest error') reply = req.CreateReply() self.pusher.push(msgpack.packb([reply.ReplyPacket(),host,port])) self.do_stat(reply.code) logger.info("[Radiusd] :: Send radius response: %s" % repr(reply)) if self.config.system.debug: logger.debug(reply.format_str()) status_type = req.get_acct_status_type() if status_type in self.acct_class: acct_func = self.acct_class[status_type]( self.db_engine,self.mcache,None,req.get_ticket()).acctounting reactor.callLater(0.1,acct_func) else: logger.error('status_type <%s> not support' % status_type) except Exception as err: self.do_stat(0) errstr = 'RadiusError:Dropping invalid acct packet from {0} {1},{2}'.format( host, port, utils.safeunicode(err)) logger.error(errstr) import traceback traceback.print_exc()
class ImagesServer(object): """The main server of the airborne computer. Manages the camera and the communication with the ground computer and ADLC onboard computer. """ def __init__(self, zmq_notice_port, zmq_files_port, vn=None): self._loadSearchArea() # # Setup the zmq socket used for sending notice of images. # zmq_factory = ZmqFactory() endpoint = ZmqEndpoint('bind', 'tcp://*:{zmq_port}'.format(zmq_port=zmq_notice_port)) self.zmq_socket = ZmqPushConnection(zmq_factory, endpoint) # # Setup the zmq socket used for sending the images. # endpoint = ZmqEndpoint('bind', 'tcp://*:{zmq_port}'.format(zmq_port=zmq_files_port)) self.zmq_files_socket = ImageFileServerConnection(zmq_factory, endpoint, ) # # Setup the zmq socket used for receiving detection results from the # jetson. # endpoint_rx = ZmqEndpoint('connect', 'tcp://{ip}:{port}'.format(ip=JETSON_IP, port=ADLC_RX_PORT)) self.adlc_rx_socket = ZmqPullConnection(zmq_factory, endpoint_rx) self.adlc_rx_socket.onPull = self.handleADLCResults # # Flag that controls the sending the images # self._send_images = threading.Event() self.manual_crop_cnt = 0 self.auto_crop_cnt = 0 self._img_counter = 0 self._adlc_count = 0 self._received_image_count = 0 self._vn = vn # # Start the upload thread. # Note: # I am using a separate thread for uploading in order to use an # upload queue. We had a problem where slow upload caused many upload # processes to start together and cause jamming in communication. # self.upload_queue = tQueue.Queue(0) self.upload_thread = thread.start_new_thread(upload_thread, (self.upload_queue,)) def __del__(self): self.upload_queue.put((None, None)) def _loadSearchArea(self): self._search_area = None if not HAS_SHAPELY: return # # Load the search area. # try: data_path = pkg_resources.resource_filename('AUVSIairborne', 'resources/search_area.txt') coords = [] with open(data_path, 'rb') as f: for line in f: line = line.strip() if line == '': continue coords.append(tuple(float(val) for val in line.split())) self._search_area = Polygon(coords).buffer(gs.SEARCH_AREA_BUFFER_DEG) except Exception as e: log.err(e, 'Failed to load search area data') def sendADLCImage(self, path, flight_data): """Send a new image to the ADLC onboard computer.""" if ADLC_PROCESS_URL: self.upload_queue.put((path, flight_data)) def handleADLCResults(self, message): """Handle the analysis result sent back from the ADLC onboard computer.""" path, results = pickle.loads(message[0]) try: message_data = message[0] # # Push the results down to the ground station. # data = [gs.AUTO_ANALYSIS, message_data] self.zmq_socket.push(data) log.msg( "Finished sending Jetson results for image: {path}, found {num} ROIS.".format( path=path, num=len(results) ) ) except zmq.error.Again: log.msg("Skipping sending of Jetson results, no pull consumers...") def handleNewImage(self, path, timestamp=None): """Handle a new image received from the camera.""" current_time = datetime.now() if timestamp is not None: img_time = timestamp else: img_time = current_time # # Handle the new image # img_path, resized_img_path, flight_data = IM.processImg(path, current_time, img_time, self._vn) resized_img_name = os.path.split(resized_img_path)[-1] send_to_adlc = True if self._received_image_count < ADLC_TEST_IMAGE_COUNT: # Send without filtering pass elif self._search_area is not None and 'src_gps' in flight_data \ and 'lat' in flight_data and 'lon' in flight_data and flight_data['src_gps'] is not None: lat = flight_data['lat'] * 1e-7 lon = flight_data['lon'] * 1e-7 send_to_adlc = self._search_area.contains(Point(lat, lon)) if send_to_adlc: log.msg('Image is inside search area, sending to ADLC server') else: log.msg('Image is outside search area, skipping sending to ADLC server') self._received_image_count += 1 if send_to_adlc: try: self.sendADLCImage( img_path if AUVSIcv.global_settings.ADLC_SEND_FULLSIZE else resized_img_path, flight_data ) except: log.err("Failed to send image to ADLC server.") # # Send the new image and flight_data # if self._send_images.isSet(): if self._img_counter == 0: resized_img_basename = os.path.splitext(resized_img_name)[0] log.msg("Sending notification for {img}...".format(img=resized_img_basename)) data = [ gs.RESIZED_IMAGE, resized_img_basename ] try: log.msg("Started sending of {img}.".format(img=resized_img_name)) self.zmq_socket.push(data) log.msg("Finished sending of {img}.".format(img=resized_img_name)) except zmq.error.Again: log.msg("Skipping sending of {img}, no pull consumers...".format(img=resized_img_name)) self._img_counter += 1 if self._img_counter >= SAMPLE_IMAGE_COUNT: self._img_counter = 0 def handleCrop(self, img_name, coords, yaw, lat, lon, crop_type): """Handle the request for a new crop""" # # Get the crop. # crop_img = IM.handleNewCrop(img_name, coords) # # Set paths # base_path = gs.CROPS_FOLDER random_str = str(uuid.uuid4()).split('-')[-1] if crop_type == gs.MANUAL_CROP: crop_name = 'manual_%03d_%s.jpg' % (self.manual_crop_cnt, random_str) self.manual_crop_cnt += 1 else: crop_name = 'auto_%03d_%s.jpg' % (self.auto_crop_cnt, random_str) self.auto_crop_cnt += 1 crop_path = os.path.join(base_path, crop_name) # # Save the crop # cv2.imwrite(crop_path, crop_img) # # Send the crop and its data. # with open(crop_path, 'rb') as f: data = [crop_type, img_name]+[str(c) for c in coords]+[yaw, lat, lon, os.path.split(crop_path)[-1], f.read()] try: self.zmq_socket.push(data) log.msg("Finished sending of crop {crop_name}.".format(crop_name=crop_name)) except zmq.error.Again: log.msg("Skipping sending of crop {crop_name}, no pull consumers...".format(crop_name=crop_name)) def sendImages(self, new_state): """Control the state of sending images to the ground station""" if new_state: log.msg("Start downloading images") self._send_images.set() else: log.msg("Stop downloading images") self._send_images.clear() self.sendDownloadState() def sendFlightData(self): """Send flight data (telemetry) to the ground station.""" fds = [] time = datetime.now() # # Get positioning from the vectornav. # if self._vn is not None: view = self._vn.getView() if view is not None: fds.append(view.dict) # # Get telemetry from the PixHawk. # try: fds.append(PH.queryPHdata(time.strftime(gs.BASE_TIMESTAMP))) except: pass if len(fds) == 0: return try: flight_data = IM.mergeFlightData(fds) flight_data['timestamp'] = time.strftime(gs.BASE_TIMESTAMP) except: return # # Send the data down to the ground station. # try: self.zmq_socket.push([gs.FLIGHT_DATA, json.dumps(flight_data)]) except zmq.error.Again: pass def sendDownloadState(self): self.zmq_socket.push([gs.STATE, gs.STATE_DOWNLOAD, gs.STATE_ON if self._send_images.isSet() else gs.STATE_OFF]) def sendCameraState(self, shooting): self.zmq_socket.push([gs.STATE, gs.STATE_SHOOT, gs.STATE_ON if shooting else gs.STATE_OFF]) def sendState(self, shooting): self.sendDownloadState() self.sendCameraState(shooting)
def __init__(self, service): zf = ZmqFactory() e = ZmqEndpoint('connect', 'tcp://%s:%s' % (service.host, service.port)) self.conn = ZmqPushConnection(zf, e)
class ZMQfactory(): def __init__(self): self.pub_ = None self.sub_ = None self.req_ = None self.rep_ = None self.push_ = None self.pull_ = None self.timeout = 0.95 def set_timeout(self, timeout): self.timeout = timeout # pub sub 相关 def add_pub(self, endpoint): if endpoint: logger.debug("开始运行 PUB 服务器,服务地址为:{}...".format(endpoint)) self.pub_ = ZmqPubConnection(ZmqFactory(), ZmqEndpoint("bind", endpoint)) def add_sub(self, endpoint): if endpoint: logger.debug("开始运行 SUB 客户端 , 连接的服务器地址为:{}...".format(endpoint)) self.sub_ = ZmqSubConnection(ZmqFactory(), ZmqEndpoint("connect", endpoint)) self.set_callback() def set_filter(self, filter_=None): ''' 请输入需要接受的主题(必须调用该函数,否则无法收到任何数据) :param filter_: type str_list :return: ''' if self.sub_: if filter_: for item in filter_: self.sub_.subscribe(item.encode()) else: self.sub_.subscribe(b'') else: logger.error("请初始化SUB端口") def set_callback(self): if self.sub_: self.sub_.gotMessage = self.subscribeReceived else: logger.error("请初始化SUB端口") def subscribeReceived(self, *args): ''' 当接收到广播数据时,会触发该函数 :param data: :return: ''' def publishData(self, tag, data): ''' 从push服务器向外推送数据 :param tag: :param data: :return: ''' # req-rep 相关 def add_req(self, endpoint): ''' 设置 req 对象 :param endpoint: :return: ''' if endpoint: logger.debug("开始运行 REQ 服务器,连接地址为:{}...".format(endpoint)) self.req_ = ZmqREQConnection(ZmqFactory(), ZmqEndpoint('connect', endpoint)) def add_rep(self, endpoint, callBack=onPrint): ''' 设置 rep 对象 :param endpoint: :param callBack: :return: ''' if endpoint: logger.debug("开始运行 REP 服务器,监听地址为:{}...".format(endpoint)) self.rep_ = ZmqREPConnection(ZmqFactory(), ZmqEndpoint('bind', endpoint)) self.rep_.gotMessage = callBack def sendReq(self, data, callBack=onPrint, errBack=onTimeout): ''' 发送 req 信息 :param data: :param callBack: :param errBack: :return: ''' try: d = self.req_.sendMsg(data, timeout=self.timeout) d.addCallback(callBack).addErrback(errBack) except Exception as e: logger.error(e) # push pull 相关 def add_push(self, endpoint): ''' :param endpoint: :return: ''' if endpoint: logger.debug("开始运行 PUSH 服务器,监听地址为:{}...".format(endpoint)) self.push_ = ZmqPushConnection(ZmqFactory(), ZmqEndpoint('connect', endpoint)) def add_pull(self, endpoint, callBack=onPrint): ''' :param endpoint: :param callBack: :return: ''' if endpoint: logger.debug("开始运行 PULL 服务器,连接地址为:{}...".format(endpoint)) self.pull_ = ZmqPullConnection(ZmqFactory(), ZmqEndpoint('bind', endpoint)) self.pull_.onPull = callBack def pushData(self, data): ''' :param data: :return: ''' try: self.push_.push(data) except zmq.error.Again: logger.error("Skipping, no pull consumers...")
class RADIUSAcctWorker(TraceMix): def __init__(self, config, dbengine,radcache=None): self.config = config self.dict = dictionary.Dictionary( os.path.join(os.path.dirname(toughradius.__file__), 'dictionarys/dictionary')) self.db_engine = dbengine or get_engine(config) self.mcache = radcache self.pusher = ZmqPushConnection(ZmqFactory(), ZmqEndpoint('connect', 'ipc:///tmp/radiusd-acct-result')) self.stat_pusher = ZmqPushConnection(ZmqFactory(), ZmqEndpoint('connect', 'ipc:///tmp/radiusd-stat-task')) self.puller = ZmqPullConnection(ZmqFactory(), ZmqEndpoint('connect', 'ipc:///tmp/radiusd-acct-message')) self.puller.onPull = self.process logger.info("init acct worker pusher : %s " % (self.pusher)) logger.info("init acct worker puller : %s " % (self.puller)) logger.info("init auth stat pusher : %s " % (self.stat_pusher)) self.acct_class = { STATUS_TYPE_START: RadiusAcctStart, STATUS_TYPE_STOP: RadiusAcctStop, STATUS_TYPE_UPDATE: RadiusAcctUpdate, STATUS_TYPE_ACCT_ON: RadiusAcctOnoff, STATUS_TYPE_ACCT_OFF: RadiusAcctOnoff } def find_nas(self,ip_addr): def fetch_result(): table = models.TrBas.__table__ with self.db_engine.begin() as conn: return conn.execute(table.select().where(table.c.ip_addr==ip_addr)).first() return self.mcache.aget(bas_cache_key(ip_addr),fetch_result, expire=600) def do_stat(self,code, status_type=0,req=None): try: stat_msg = {'statattrs':['acct_drop'],'raddata':{}} if code in (4,5): stat_msg['statattrs'] = [] if code == packet.AccountingRequest: stat_msg['statattrs'].append('acct_req') elif code == packet.AccountingResponse: stat_msg['statattrs'].append('acct_resp') if status_type == 1: stat_msg['statattrs'].append('acct_start') elif status_type == 2: stat_msg['statattrs'].append('acct_stop') elif status_type == 3: stat_msg['statattrs'].append('acct_update') stat_msg['raddata']['input_total'] = req.get_input_total() stat_msg['raddata']['output_total'] = req.get_output_total() elif status_type == 7: stat_msg['statattrs'].append('acct_on') elif status_type == 8: stat_msg['statattrs'].append('acct_off') self.stat_pusher.push(msgpack.packb(stat_msg)) except: pass def process(self, message): datagram, host, port = msgpack.unpackb(message[0]) self.processAcct(datagram, host, port) def createAcctPacket(self, **kwargs): vendor_id = 0 if 'vendor_id' in kwargs: vendor_id = kwargs.pop('vendor_id') acct_message = message.AcctMessage(**kwargs) acct_message.vendor_id = vendor_id acct_message = mac_parse.process(acct_message) acct_message = vlan_parse.process(acct_message) return acct_message def processAcct(self, datagram, host, port): try: bas = self.find_nas(host) if not bas: raise PacketError('[Radiusd] :: Dropping packet from unknown host %s' % host) secret, vendor_id = bas['bas_secret'], bas['vendor_id'] req = self.createAcctPacket(packet=datagram, dict=self.dict, secret=six.b(str(secret)),vendor_id=vendor_id) self.log_trace(host,port,req) self.do_stat(req.code, req.get_acct_status_type(),req=req) logger.info("[Radiusd] :: Received radius request: %s" % (repr(req))) if self.config.system.debug: logger.debug(req.format_str()) if req.code != packet.AccountingRequest: raise PacketError('non-AccountingRequest packet on authentication socket') if not req.VerifyAcctRequest(): raise PacketError('VerifyAcctRequest error') reply = req.CreateReply() self.log_trace(host,port,req,reply) self.pusher.push(msgpack.packb([reply.ReplyPacket(),host,port])) self.do_stat(reply.code) logger.info("[Radiusd] :: Send radius response: %s" % repr(reply)) if self.config.system.debug: logger.debug(reply.format_str()) status_type = req.get_acct_status_type() if status_type in self.acct_class: ticket = req.get_ticket() if not ticket.get('nas_addr'): ticket['nas_addr'] = host acct_func = self.acct_class[status_type]( self.db_engine,self.mcache,None,ticket).acctounting reactor.callLater(0.1,acct_func) else: logger.error('status_type <%s> not support' % status_type) except Exception as err: self.do_stat(0) logger.exception(error)
class AutoServer(object): """Handle the communication of the automatic detection servers.""" def __init__(self, worker): log.msg("Initializing auto server") # # Setup the zmq socket used for receiving images. # self.zmq_factory = ZmqFactory() # # Socket for pulling images and crops from the automatic client. # endpoint = ZmqEndpoint( 'connect', 'tcp://localhost:{zmq_port}'.format( zmq_port=gs.ZMQ_AUTO_WORKER_PUSH)) self.pull_socket = ZmqPullConnection(self.zmq_factory, endpoint) self.pull_socket.onPull = self.handleNewMessage # # Socket for pushing results to the automatic client. # endpoint = ZmqEndpoint( 'connect', 'tcp://localhost:{zmq_port}'.format( zmq_port=gs.ZMQ_AUTO_WORKER_PULL)) self.push_socket = ZmqPushConnection(self.zmq_factory, endpoint) self.worker = worker def shutdown(self): """Shutdown the zmq connection.""" self.zmq_factory.shutdown() def requestCrops(self, img_path, crops): """Send a request from a worker to the auto client for crops.""" data = [gs.CROP_REQUESTS, img_path, json.dumps(crops)] try: log.msg("Sending crop requests for img {img}: {crops}.".format( img=img_path, crops=crops)) self.push_socket.push(data) except zmq.error.Again: log.msg("Failed sending crops request") def sendTarget(self, crop_path, target_details): """Send the details of a target (from a worker to the auto client).""" data = [gs.TARGET_DATA, crop_path, json.dumps(target_details)] try: log.msg("Sending of target in {crop}, with {data}.".format( crop=crop_path, data=data)) self.push_socket.push(data) except zmq.error.Again: log.msg( "Skipping sending of crop {crop}, no pull consumers...".format( crop=crop_path)) def handleNewMessage(self, new_data_message, ignore_tag=None): """Analyze the data received from the auto client.""" try: data_type = new_data_message[0] if data_type == gs.RESIZED_IMAGE: img_path, data_path = new_data_message[1:] crops = self.worker.processNewImage(img_path, data_path) self.requestCrops(img_path, crops) elif data_type == gs.AUTO_CROP: crop_path, yaw, lat, lon = new_data_message[1:] yaw = float(yaw) lat = float(lat) lon = float(lon) target_details = self.worker.processNewCrop( crop_path, yaw, lat, lon) self.sendTarget(crop_path, target_details) else: log.msg( "Unkown data type received from auto server: {data_type}". format(data_type=data_type)) except Exception as e: log.err(e, 'handleNewMessage')
def startService(self): factory = ZmqFactory() bind_point = 'tcp://0.0.0.0:8050' log.msg("Broadcaster binding on: %s" % bind_point) endpoint = ZmqEndpoint('bind', bind_point) self.conn = ZmqPushConnection(factory, endpoint)
def startService(self): factory = ZmqFactory() log.msg("Delegator connecting to repeater: %s" % ZMQ_REPEATER) endpoint = ZmqEndpoint('connect', ZMQ_REPEATER) self.conn = ZmqPushConnection(factory, endpoint)
from txzmq import ZmqEndpoint, ZmqFactory, ZmqPushConnection, ZmqPullConnection parser = OptionParser("") parser.add_option("-m", "--method", dest="method", help="0MQ socket connection: bind|connect") parser.add_option("-e", "--endpoint", dest="endpoint", help="0MQ Endpoint") parser.add_option("-M", "--mode", dest="mode", help="Mode: push|pull") parser.set_defaults(method="connect", endpoint="ipc:///tmp/txzmq-pc-demo") (options, args) = parser.parse_args() zf = ZmqFactory() e = ZmqEndpoint(options.method, options.endpoint) if options.mode == "push": s = ZmqPushConnection(zf, e) def produce(): data = [str(time.time()), socket.gethostname()] print "producing %r" % data try: s.push(data) except zmq.error.Again: print "Skipping, no pull consumers..." reactor.callLater(1, produce) reactor.callWhenRunning(reactor.callLater, 1, produce) else: s = ZmqPullConnection(zf, e)