示例#1
0
文件: db_transfer.py 项目: Dearms/SSR
	def pull_db_users(self, conn):
		try:
			switchrule = importloader.load('switchrule')
			keys = switchrule.getKeys(self.key_list)
		except Exception as e:
			keys = self.key_list

		cur = conn.cursor()

		node_info_keys = ['traffic_rate']
		cur.execute("SELECT " + ','.join(node_info_keys) +" FROM ss_node where `id`='" + str(self.cfg["node_id"]) + "'")
		nodeinfo = cur.fetchone()

		if nodeinfo == None:
			rows = []
			cur.close()
			conn.commit()
			return rows
		cur.close()

		node_info_dict = {}
		for column in range(len(nodeinfo)):
			node_info_dict[node_info_keys[column]] = nodeinfo[column]
		self.cfg['transfer_mul'] = float(node_info_dict['traffic_rate'])

		cur = conn.cursor()
		cur.execute("SELECT " + ','.join(keys) + " FROM user")
		rows = []
		for r in cur.fetchall():
			d = {}
			for column in range(len(keys)):
				d[keys[column]] = r[column]
			rows.append(d)
		cur.close()
		return rows
    def pull_db_users(self, conn):
        keys = copy.copy(self.key_list)
        try:
            switchrule = importloader.load('switchrule')
            keymap = switchrule.getRowMap()
            for key in keymap:
                if keymap[key] in keys:
                    keys.remove(keymap[key])
                keys.append(key)
            keys = switchrule.getKeys(keys)
        except Exception as e:
            logging.error('load switchrule.py fail')

        cur = conn.cursor()

        if self.update_node_state:
            node_info_keys = ['traffic_rate']
            try:
                cur.execute("SELECT " + ','.join(node_info_keys) +
                            " FROM node where `id`='" +
                            str(self.cfg["node_id"]) + "'")
                nodeinfo = cur.fetchone()
            except Exception as e:
                logging.error(e)
                nodeinfo = None

            if nodeinfo == None:
                rows = []
                cur.close()
                conn.commit()
                logging.warn(
                    'None result when select node info from ss_node in db, maybe you set the incorrect node id'
                )
                return rows
            cur.close()

            node_info_dict = {}
            for column in range(len(nodeinfo)):
                node_info_dict[node_info_keys[column]] = nodeinfo[column]
            self.cfg['transfer_mul'] = float(node_info_dict['traffic_rate'])

        cur = conn.cursor()
        try:
            rows = []
            cur.execute("SELECT " + ','.join(keys) +
                        " FROM user WHERE port > 0")
            for r in cur.fetchall():
                d = {}
                for column in range(len(keys)):
                    d[keys[column]] = r[column]
                rows.append(d)
        except Exception as e:
            logging.error(e)
        cur.close()
        return rows
示例#3
0
    def pull_db_users(self, conn):
        '''拉取所有符合要求的用户'''
        try:
            switchrule = importloader.load('switchrule')
            keys = switchrule.getKeys(self.key_list)
        except Exception as e:
            keys = self.key_list

        # 节点信息的获取
        cur = conn.cursor()
        # 增加节点等级字段
        node_info_keys = ['traffic_rate', 'level']
        try:
            sql = "SELECT " + \
                ','.join(node_info_keys) + " FROM ss_node where `id`='" + \
                str(self.cfg["node_id"]) + "'"
            cur.execute(sql)
            nodeinfo = cur.fetchone()
        except Exception as e:
            logging.error(e)
            nodeinfo = None

        if nodeinfo == None:
            rows = []
            cur.close()
            conn.commit()
            logging.warn(
                '没有查询到满足要求的user,请检查自己的node_id!')
            return rows
        cur.close()
        # 流量比例设置
        node_info_dict = {}
        for column in range(len(nodeinfo)):
            node_info_dict[node_info_keys[column]] = nodeinfo[column]
        self.cfg['transfer_mul'] = float(node_info_dict['traffic_rate'])

        cur = conn.cursor()
        try:
            rows = []
            # 增加用户等级判断
            # 只适用于django-sspanel
            sql = "SELECT " + \
                ','.join(keys) + " FROM user WHERE `level` >=" + \
                str(node_info_dict['level'])
            cur.execute(sql)
            for r in cur.fetchall():
                d = {}
                for column in range(len(keys)):
                    d[keys[column]] = r[column]
                rows.append(d)
        except Exception as e:
            logging.error(e)
        cur.close()
        return rows
示例#4
0
    def pull_db_users(self, conn):
        try:
            switchrule = importloader.load('switchrule')
            keys = switchrule.getKeys(self.key_list)
        except Exception as e:
            keys = self.key_list

        cur = conn.cursor()

        if self.update_node_state:
            node_info_keys = ['traffic_rate']
            try:
                cur.execute("SELECT " + ','.join(node_info_keys) +
                            " FROM ss_node where `id`='" +
                            str(self.cfg["node_id"]) + "'")
                nodeinfo = cur.fetchone()
            except Exception as e:
                logging.error(e)
                nodeinfo = None

            if nodeinfo == None:
                rows = []
                cur.close()
                conn.commit()
                logging.warn(
                    'None result when select node info from ss_node in db, maybe you set the incorrect node id'
                )
                return rows
            cur.close()

            node_info_dict = {}
            for column in range(len(nodeinfo)):
                node_info_dict[node_info_keys[column]] = nodeinfo[column]
            self.cfg['transfer_mul'] = float(node_info_dict['traffic_rate'])

        cur = conn.cursor()
        try:
            rows = []
            cur.execute("SELECT " + ','.join(keys) +
                        " FROM ssr_user where enable = 1 and serverId=" +
                        str(self.cfg["node_id"]))
            for r in cur.fetchall():
                d = {}
                for column in range(len(keys)):
                    d[keys[column]] = r[column]
                rows.append(d)
        except Exception as e:
            logging.error(e)
        cur.close()
        return rows
示例#5
0
	def pull_db_users(self, conn):
		#拉取所有符合要求的用户
		try:
			switchrule = importloader.load('switchrule')
			keys = switchrule.getKeys(self.key_list)
		except Exception as e:
			keys = self.key_list

		# 节点信息的获取
	#	cur = conn.cursor()
	#	node_info_keys = ['traffic_rate']
	#	try:
	#		cur.execute("SELECT " + ','.join(node_info_keys) +" FROM ss_node where `id`='" + str(self.cfg["node_id"]) + "'")
	#		nodeinfo = cur.fetchone()
	#	except Exception as e:
	#		logging.error(e)
	#		nodeinfo = None

	#	if nodeinfo == None:
	#		rows = []
	#		cur.close()
	#		conn.commit()
	#		logging.warn('None result when select node info from ss_node in db, maybe you set the incorrect node id')
	#		return rows
	#	cur.close()

		# 流量比例设置
	#	node_info_dict = {}
	#	for column in range(len(nodeinfo)):
	#		node_info_dict[node_info_keys[column]] = nodeinfo[column]
	#	self.cfg['transfer_mul'] = float(node_info_dict['traffic_rate'])

		cur = conn.cursor()
		try:
			rows = []
			if isinstance(self.cfg["node_class"],int):
				cur.execute("SELECT " + ','.join(keys) + " FROM user WHERE user_class >= " + str(self.cfg["node_class"]))
			else:
				cur.execute("SELECT " + ','.join(keys) + " FROM user WHERE user_class = '" + self.cfg["node_class"] +"'")
			for r in cur.fetchall():
				d = {}
				for column in range(len(keys)):
					d[keys[column]] = r[column]
				rows.append(d)
		except Exception as e:
			logging.error(e)
		cur.close()
		return rows
示例#6
0
	def pull_db_users(self, conn):
		try:
			switchrule = importloader.load('switchrule')
			keys = switchrule.getKeys(self.key_list)
		except Exception as e:
			keys = self.key_list

		cur = conn.cursor()
		cur.execute("SELECT " + ','.join(keys) + " FROM user")
		rows = []
		for r in cur.fetchall():
			d = {}
			for column in range(len(keys)):
				d[keys[column]] = r[column]
			rows.append(d)
		cur.close()
		return rows
示例#7
0
    def pull_db_users(self, conn):
        try:
            switchrule = importloader.load('switchrule')
            keys = switchrule.getKeys(self.key_list)
        except Exception as e:
            keys = self.key_list

        cur = conn.cursor()
        cur.execute("SELECT " + ','.join(keys) + " FROM user")
        rows = []
        for r in cur.fetchall():
            d = {}
            for column in range(len(keys)):
                d[keys[column]] = r[column]
            rows.append(d)
        cur.close()
        return rows
示例#8
0
	def pull_db_users(self, conn):
		try:
			switchrule = importloader.load('switchrule')
			keys = switchrule.getKeys(self.key_list)
		except Exception as e:
			keys = self.key_list

		cur = conn.cursor()

		if self.update_node_state:
			node_info_keys = ['traffic_rate']
			try:
				cur.execute("SELECT " + ','.join(node_info_keys) +" FROM ss_node where `id`='" + str(self.cfg["node_id"]) + "'")
				nodeinfo = cur.fetchone()
			except Exception as e:
				logging.error(e)
				nodeinfo = None

			if nodeinfo == None:
				rows = []
				cur.close()
				conn.commit()
				logging.warn('None result when select node info from ss_node in db, maybe you set the incorrect node id')
				return rows
			cur.close()

			node_info_dict = {}
			for column in range(len(nodeinfo)):
				node_info_dict[node_info_keys[column]] = nodeinfo[column]
			self.cfg['transfer_mul'] = float(node_info_dict['traffic_rate'])

		cur = conn.cursor()
		try:
			rows = []
			cur.execute("SELECT " + ','.join(keys) + " FROM user")
			for r in cur.fetchall():
				d = {}
				for column in range(len(keys)):
					d[keys[column]] = r[column]
				rows.append(d)
		except Exception as e:
			logging.error(e)
		cur.close()
		return rows
示例#9
0
    def pull_db_users(self, conn):
        keys = copy.copy(self.key_list)
        try:
            switchrule = importloader.load('switchrule')
            keymap = switchrule.getRowMap()
            for key in keymap:
                if keymap[key] in keys:
                    keys.remove(keymap[key])
                keys.append(key)
            keys = switchrule.getKeys(keys)
        except Exception as e:
            logging.error('load switchrule.py fail')

        cur = conn.cursor()

        # 这里获取节点的sort 等级
        if self.update_node_state:
            try:
                cur.execute("SELECT " + 'level' +
                            " FROM ss_node where `id`='" +
                            str(self.cfg["node_id"]) + "'")
                nodeinfo = cur.fetchone()
            except Exception as e:
                logging.error(e)
                nodeinfo = None
            node_level = float(nodeinfo[0])
            cur.close()

        cur = conn.cursor()
        try:
            rows = []
            cur.execute(
                "SELECT " + ','.join(keys) +
                " FROM user where port != 0 and status = 1 and level >= " +
                str(node_level))  #这里获取等级大于node_level的节点
            for r in cur.fetchall():
                d = {}
                for column in range(len(keys)):
                    d[keys[column]] = r[column]
                rows.append(d)
        except Exception as e:
            logging.error(e)
        cur.close()
        return rows
示例#10
0
    def pull_db_users(self, conn):
        try:
            switchrule = importloader.load('switchrule')
            keys = switchrule.getKeys(self.key_list)
        except Exception as e:
            keys = self.key_list


# 注释理由同上
#		cur = conn.cursor()

#		node_info_keys = ['traffic_rate']
#		cur.execute("SELECT " + ','.join(node_info_keys) +" FROM ss_node where `id`='" + str(self.cfg["node_id"]) + "'")
#		nodeinfo = cur.fetchone()

#		if nodeinfo == None:
#			rows = []
#			cur.close()
#			conn.commit()
#			logging.warn('None result when select node info from ss_node in db, maybe you set the incorrect node id')
#			return rows
#		cur.close()

#		node_info_dict = {}
#		for column in range(len(nodeinfo)):
#			node_info_dict[node_info_keys[column]] = nodeinfo[column]
#		self.cfg['transfer_mul'] = float(node_info_dict['traffic_rate'])

        cur = conn.cursor()
        cur.execute("SELECT " + ','.join(keys) + " FROM user")
        rows = []
        for r in cur.fetchall():
            d = {}
            for column in range(len(keys)):
                d[keys[column]] = r[column]
            rows.append(d)
        cur.close()
        return rows
示例#11
0
	def pull_db_users(self, conn):
		keys = copy.copy(self.key_list)
		try:
			switchrule = importloader.load('switchrule')
			keymap = switchrule.getRowMap()
			for key in keymap:
				if keymap[key] in keys:
					keys.remove(keymap[key])
				keys.append(key)
			keys = switchrule.getKeys(keys)
		except Exception as e:
			logging.error('load switchrule.py fail')

		cur = conn.cursor()
		cur.execute("SELECT " + ','.join(keys) + " FROM user")
		rows = []
		for r in cur.fetchall():
			d = {}
			for column in range(len(keys)):
				d[keys[column]] = r[column]
			rows.append(d)
		cur.close()
		return rows
示例#12
0
	def del_server_out_of_bound_safe(self, last_rows, rows):
		#停止超流量的服务
		#启动没超流量的服务
		#需要动态载入switchrule,以便实时修改规则


		try:
			switchrule = importloader.load('switchrule')
		except Exception as e:
			logging.error('load switchrule.py fail')
		cur_servers = {}
		new_servers = {}

		md5_users = {}

		for row in rows:
			if row['is_multi_user'] == 1:
				continue
			
			md5_users[row['id']] = row.copy()
			del md5_users[row['id']]['u']
			del md5_users[row['id']]['d']
			if md5_users[row['id']]['disconnect_ip'] == None:
				md5_users[row['id']]['disconnect_ip'] = ''

			if md5_users[row['id']]['forbidden_ip'] == None:
				md5_users[row['id']]['forbidden_ip'] = ''

			if md5_users[row['id']]['forbidden_port'] == None:
				md5_users[row['id']]['forbidden_port'] = ''
			md5_users[row['id']]['md5'] = common.get_md5(str(row['id']) + row['passwd'] + row['method'] + row['obfs'] + row['protocol'])

		for row in rows:

			port = row['port']
			passwd = common.to_bytes(row['passwd'])
			cfg = {'password': passwd}

			self.port_uid_table[row['port']] = row['id']
			self.uid_port_table[row['id']] = row['port']

			read_config_keys = ['method', 'obfs','obfs_param' , 'protocol', 'protocol_param' ,'forbidden_ip', 'forbidden_port' , 'node_speedlimit','forbidden_ip','forbidden_port','disconnect_ip','is_multi_user']

			for name in read_config_keys:
				if name in row and row[name]:
					cfg[name] = row[name]



			merge_config_keys = ['password'] + read_config_keys
			for name in cfg.keys():
				if hasattr(cfg[name], 'encode'):
					cfg[name] = cfg[name].encode('utf-8')

			if 'node_speedlimit' in cfg:
				if float(self.node_speedlimit) > 0.0 or float(cfg['node_speedlimit']) > 0.0 :
					cfg['node_speedlimit'] = max(float(self.node_speedlimit),float(cfg['node_speedlimit']))
			else:
				cfg['node_speedlimit'] = max(float(self.node_speedlimit),float(0.00))

			if 'disconnect_ip' not in cfg:
				cfg['disconnect_ip'] = ''

			if 'forbidden_ip' not in cfg:
				cfg['forbidden_ip'] = ''

			if 'forbidden_port' not in cfg:
				cfg['forbidden_port'] = ''

			if 'protocol_param' not in cfg:
				cfg['protocol_param'] = ''

			if 'obfs_param' not in cfg:
				cfg['obfs_param'] = ''

			if 'is_multi_user' not in cfg:
				cfg['is_multi_user'] = 0

			if port not in cur_servers:
				cur_servers[port] = passwd
			else:
				logging.error('more than one user use the same port [%s]' % (port,))
				continue

			if get_config().MULTI_THREAD == 0:
				cfg['node_speedlimit'] = 0.00

			cfg['detect_text_list'] = self.detect_text_list.copy()
			cfg['detect_hex_list'] = self.detect_hex_list.copy()

			if cfg['is_multi_user'] == 1:
				cfg['users_table'] = md5_users.copy()


			if ServerPool.get_instance().server_is_run(port) > 0:
				cfgchange = False
				if self.detect_text_ischanged == True or self.detect_hex_ischanged == True:
					cfgchange = True
				if row['is_multi_user'] == 1:
					if port in ServerPool.get_instance().tcp_servers_pool:
						ServerPool.get_instance().tcp_servers_pool[port].modify_multi_user_table(md5_users)
					if port in ServerPool.get_instance().tcp_ipv6_servers_pool:
						ServerPool.get_instance().tcp_ipv6_servers_pool[port].modify_multi_user_table(md5_users)
					if port in ServerPool.get_instance().udp_servers_pool:
						ServerPool.get_instance().udp_servers_pool[port].modify_multi_user_table(md5_users)
					if port in ServerPool.get_instance().udp_ipv6_servers_pool:
						ServerPool.get_instance().udp_ipv6_servers_pool[port].modify_multi_user_table(md5_users)

				if port in ServerPool.get_instance().tcp_servers_pool:
					relay = ServerPool.get_instance().tcp_servers_pool[port]
					for name in merge_config_keys:
						if name in cfg and not self.cmp(cfg[name], relay._config[name]):
							cfgchange = True
							break;
				if not cfgchange and port in ServerPool.get_instance().tcp_ipv6_servers_pool:
					relay = ServerPool.get_instance().tcp_ipv6_servers_pool[port]
					for name in merge_config_keys:
						if name in cfg and not self.cmp(cfg[name], relay._config[name]):
							cfgchange = True
							break;
				#config changed
				if cfgchange:
					logging.info('db stop server at port [%s] reason: config changed!' % (port))
					ServerPool.get_instance().cb_del_server(port)
					if port in self.last_update_transfer:
						del self.last_update_transfer[port]
					new_servers[port] = (passwd, cfg)
			elif ServerPool.get_instance().server_run_status(port) is False:
				#new_servers[port] = passwd
				protocol = cfg.get('protocol', ServerPool.get_instance().config.get('protocol', 'origin'))
				obfs = cfg.get('obfs', ServerPool.get_instance().config.get('obfs', 'plain'))
				logging.info('db start server at port [%s] pass [%s] protocol [%s] obfs [%s]' % (port, passwd, protocol, obfs))
				ServerPool.get_instance().new_server(port, cfg)

		ServerPool.get_instance().push_uid_port_table(self.uid_port_table)

		for row in last_rows:
			if row['port'] in cur_servers:
				pass
			else:
				logging.info('db stop server at port [%s] reason: port not exist' % (row['port']))
				ServerPool.get_instance().cb_del_server(row['port'])
				if row['port'] in self.last_update_transfer:
					del self.last_update_transfer[row['port']]
				del self.port_uid_table[row['port']]

		if len(new_servers) > 0:
			from shadowsocks import eventloop
			self.event.wait(eventloop.TIMEOUT_PRECISION + eventloop.TIMEOUT_PRECISION / 2)
			for port in new_servers.keys():
				passwd, cfg = new_servers[port]
				protocol = cfg.get('protocol', ServerPool.get_instance().config.get('protocol', 'origin'))
				obfs = cfg.get('obfs', ServerPool.get_instance().config.get('obfs', 'plain'))
				logging.info('db start server at port [%s] pass [%s] protocol [%s] obfs [%s]' % (port, passwd, protocol, obfs))
				self.port_uid_table[row['port']] = row['id']
				ServerPool.get_instance().new_server(port, cfg)
示例#13
0
	def pull_db_all_user(self):
		import cymysql
		#数据库所有用户信息
		try:
			switchrule = importloader.load('switchrule')
			keys = switchrule.getKeys()
		except Exception as e:
			keys = ['id' , 'port', 'u', 'd', 'transfer_enable', 'passwd', 'enable' ,'method','protocol','protocol_param','obfs','obfs_param','node_speedlimit','forbidden_ip','forbidden_port','disconnect_ip','is_multi_user']

		if get_config().MYSQL_SSL_ENABLE == 1:
			conn = cymysql.connect(host=get_config().MYSQL_HOST, port=get_config().MYSQL_PORT, user=get_config().MYSQL_USER,
										passwd=get_config().MYSQL_PASS, db=get_config().MYSQL_DB, charset='utf8',ssl={'ca':get_config().MYSQL_SSL_CA,'cert':get_config().MYSQL_SSL_CERT,'key':get_config().MYSQL_SSL_KEY})
		else:
			conn = cymysql.connect(host=get_config().MYSQL_HOST, port=get_config().MYSQL_PORT, user=get_config().MYSQL_USER,
										passwd=get_config().MYSQL_PASS, db=get_config().MYSQL_DB, charset='utf8')
		conn.autocommit(True)

		cur = conn.cursor()

		cur.execute("SELECT `node_group`,`node_class`,`node_speedlimit`,`traffic_rate` FROM ss_node where `id`='" + str(get_config().NODE_ID) + "' AND (`node_bandwidth`<`node_bandwidth_limit` OR `node_bandwidth_limit`=0)")
		nodeinfo = cur.fetchone()

		if nodeinfo == None :
			rows = []
			cur.close()
			conn.commit()
			conn.close()
			return rows

		cur.close()

		self.node_speedlimit = float(nodeinfo[2])
		self.traffic_rate = float(nodeinfo[3])

		if nodeinfo[0] == 0 :
			node_group_sql = ""
		else:
			node_group_sql = "AND `node_group`=" + str(nodeinfo[0])

		cur = conn.cursor()
		cur.execute("SELECT " + ','.join(keys) + " FROM user WHERE `class`>="+ str(nodeinfo[1]) +" "+node_group_sql+" AND`enable`=1 AND `expire_in`>now() AND `transfer_enable`>`u`+`d`")
		rows = []
		for r in cur.fetchall():
			d = {}
			for column in range(len(keys)):
				d[keys[column]] = r[column]
			rows.append(d)
		cur.close()

		#读取审计规则,数据包匹配部分
		keys_detect = ['id','regex']

		cur = conn.cursor()
		cur.execute("SELECT " + ','.join(keys_detect) + " FROM detect_list where `type` = 1")

		exist_id_list = []

		for r in cur.fetchall():
			id = long(r[0])
			exist_id_list.append(id)
			if r[0] not in self.detect_text_list:
				d = {}
				d['id'] = id
				d['regex'] = r[1]
				self.detect_text_list[id] = d
				self.detect_text_ischanged = True
			else:
				if r[1] != self.detect_text_list[r[0]]['regex']:
					del self.detect_text_list[id]
					d = {}
					d['id'] = r[0]
					d['regex'] = r[1]
					self.detect_text_list[id] = d
					self.detect_text_ischanged = True

		deleted_id_list = []
		for id in self.detect_text_list:
			if id not in exist_id_list:
				deleted_id_list.append(id)
				self.detect_text_ischanged = True


		for id in deleted_id_list:
			del self.detect_text_list[id]


		cur = conn.cursor()
		cur.execute("SELECT " + ','.join(keys_detect) + " FROM detect_list where `type` = 2")

		exist_id_list = []

		for r in cur.fetchall():
			id = long(r[0])
			exist_id_list.append(id)
			if r[0] not in self.detect_hex_list:
				d = {}
				d['id'] = id
				d['regex'] = r[1]
				self.detect_hex_list[id] = d
				self.detect_hex_ischanged = True
			else:
				if r[1] != self.detect_hex_list[r[0]]['regex']:
					del self.detect_hex_list[id]
					d = {}
					d['id'] = r[0]
					d['regex'] = r[1]
					self.detect_hex_list[id] = d
					self.detect_hex_ischanged = True

		deleted_id_list = []
		for id in self.detect_hex_list:
			if id not in exist_id_list:
				deleted_id_list.append(id)
				self.detect_hex_ischanged = True


		for id in deleted_id_list:
			del self.detect_hex_list[id]

		cur.close()
		conn.close()
		return rows
示例#14
0
    def del_server_out_of_bound_safe(self, last_rows, rows):
        # 停止超流量的服务
        # 启动没超流量的服务
        # 需要动态载入switchrule,以便实时修改规则

        try:
            switchrule = importloader.load('switchrule')
        except Exception as e:
            logging.error('load switchrule.py fail')
        cur_servers = {}
        new_servers = {}

        md5_users = {}

        self.mu_port_list = []

        for row in rows:
            if row['is_multi_user'] != 0:
                self.mu_port_list.append(int(row['port']))
                continue

            md5_users[row['id']] = row.copy()
            del md5_users[row['id']]['u']
            del md5_users[row['id']]['d']
            if md5_users[row['id']]['disconnect_ip'] is None:
                md5_users[row['id']]['disconnect_ip'] = ''

            if md5_users[row['id']]['forbidden_ip'] is None:
                md5_users[row['id']]['forbidden_ip'] = ''

            if md5_users[row['id']]['forbidden_port'] is None:
                md5_users[row['id']]['forbidden_port'] = ''
            md5_users[row['id']]['md5'] = common.get_md5(
                str(row['id']) + row['passwd'] + row['method'] + row['obfs'] +
                row['protocol'])

        for row in rows:
            self.port_uid_table[row['port']] = row['id']
            self.uid_port_table[row['id']] = row['port']

        if self.mu_only == 1 or self.mu_only == 2:
            i = 0
            while i < len(rows):
                if rows[i]['is_multi_user'] == 0:
                    rows.pop(i)
                    i -= 1
                else:
                    pass
                i += 1

        if self.mu_only == -1:
            i = 0
            while i < len(rows):
                if rows[i]['is_multi_user'] != 0:
                    rows.pop(i)
                    i -= 1
                else:
                    pass
                i += 1

        for row in rows:
            port = row['port']
            user_id = row['id']
            passwd = common.to_bytes(row['passwd'])
            cfg = {'password': passwd}

            read_config_keys = [
                'method', 'obfs', 'obfs_param', 'protocol', 'protocol_param',
                'forbidden_ip', 'forbidden_port', 'node_speedlimit',
                'disconnect_ip', 'is_multi_user'
            ]

            for name in read_config_keys:
                if name in row and row[name]:
                    cfg[name] = row[name]

            merge_config_keys = ['password'] + read_config_keys
            for name in cfg.keys():
                if hasattr(cfg[name], 'encode'):
                    try:
                        cfg[name] = cfg[name].encode('utf-8')
                    except Exception as e:
                        logging.warning('encode cfg key "%s" fail, val "%s"' %
                                        (name, cfg[name]))

            if 'node_speedlimit' in cfg:
                if float(self.node_speedlimit) > 0.0 or float(
                        cfg['node_speedlimit']) > 0.0:
                    cfg['node_speedlimit'] = max(float(self.node_speedlimit),
                                                 float(cfg['node_speedlimit']))
            else:
                cfg['node_speedlimit'] = max(float(self.node_speedlimit),
                                             float(0.00))

            if 'disconnect_ip' not in cfg:
                cfg['disconnect_ip'] = ''

            if 'forbidden_ip' not in cfg:
                cfg['forbidden_ip'] = ''

            if 'forbidden_port' not in cfg:
                cfg['forbidden_port'] = ''

            if 'protocol_param' not in cfg:
                cfg['protocol_param'] = ''

            if 'obfs_param' not in cfg:
                cfg['obfs_param'] = ''

            if 'is_multi_user' not in cfg:
                cfg['is_multi_user'] = 0

            if port not in cur_servers:
                cur_servers[port] = passwd
            else:
                logging.error('more than one user use the same port [%s]' %
                              (port, ))
                continue

            if cfg['is_multi_user'] != 0:
                cfg['users_table'] = md5_users.copy()

            cfg['detect_hex_list'] = self.detect_hex_list.copy()
            cfg['detect_text_list'] = self.detect_text_list.copy()

            if self.is_relay and row['is_multi_user'] != 2:
                temp_relay_rules = {}
                for id in self.relay_rule_list:
                    if ((self.relay_rule_list[id]['user_id'] == user_id
                         or self.relay_rule_list[id]['user_id'] == 0)
                            or row['is_multi_user'] != 0) and (
                                self.relay_rule_list[id]['port'] == 0
                                or self.relay_rule_list[id]['port'] == port):
                        has_higher_priority = False
                        for priority_id in self.relay_rule_list:
                            if (
                                (self.relay_rule_list[priority_id]['priority']
                                 > self.relay_rule_list[id]['priority']
                                 and self.relay_rule_list[id]['id'] !=
                                 self.relay_rule_list[priority_id]['id']) or
                                (self.relay_rule_list[priority_id]['priority']
                                 == self.relay_rule_list[id]['priority']
                                 and self.relay_rule_list[id]['id'] >
                                 self.relay_rule_list[priority_id]['id'])
                            ) and (self.relay_rule_list[priority_id]['user_id']
                                   == user_id or
                                   self.relay_rule_list[priority_id]['user_id']
                                   == 0) and (self.relay_rule_list[priority_id]
                                              ['port'] == port or
                                              self.relay_rule_list[priority_id]
                                              ['port'] == 0):
                                has_higher_priority = True
                                continue

                        if has_higher_priority:
                            continue

                        if self.relay_rule_list[id][
                                'dist_ip'] == '0.0.0.0' and row[
                                    'is_multi_user'] == 0:
                            continue

                        temp_relay_rules[id] = self.relay_rule_list[id]

                cfg['relay_rules'] = temp_relay_rules.copy()
            else:
                temp_relay_rules = {}

                cfg['relay_rules'] = temp_relay_rules.copy()

            if ServerPool.get_instance().server_is_run(port) > 0:
                cfgchange = False

                if port in ServerPool.get_instance().tcp_servers_pool:
                    ServerPool.get_instance(
                    ).tcp_servers_pool[port].modify_detect_text_list(
                        self.detect_text_list)
                    ServerPool.get_instance(
                    ).tcp_servers_pool[port].modify_detect_hex_list(
                        self.detect_hex_list)
                if port in ServerPool.get_instance().tcp_ipv6_servers_pool:
                    ServerPool.get_instance(
                    ).tcp_ipv6_servers_pool[port].modify_detect_text_list(
                        self.detect_text_list)
                    ServerPool.get_instance(
                    ).tcp_ipv6_servers_pool[port].modify_detect_hex_list(
                        self.detect_hex_list)
                if port in ServerPool.get_instance().udp_servers_pool:
                    ServerPool.get_instance(
                    ).udp_servers_pool[port].modify_detect_text_list(
                        self.detect_text_list)
                    ServerPool.get_instance(
                    ).udp_servers_pool[port].modify_detect_hex_list(
                        self.detect_hex_list)
                if port in ServerPool.get_instance().udp_ipv6_servers_pool:
                    ServerPool.get_instance(
                    ).udp_ipv6_servers_pool[port].modify_detect_text_list(
                        self.detect_text_list)
                    ServerPool.get_instance(
                    ).udp_ipv6_servers_pool[port].modify_detect_hex_list(
                        self.detect_hex_list)

                if row['is_multi_user'] != 0:
                    if port in ServerPool.get_instance().tcp_servers_pool:
                        ServerPool.get_instance().tcp_servers_pool[
                            port].modify_multi_user_table(md5_users)
                    if port in ServerPool.get_instance().tcp_ipv6_servers_pool:
                        ServerPool.get_instance().tcp_ipv6_servers_pool[
                            port].modify_multi_user_table(md5_users)
                    if port in ServerPool.get_instance().udp_servers_pool:
                        ServerPool.get_instance().udp_servers_pool[
                            port].modify_multi_user_table(md5_users)
                    if port in ServerPool.get_instance().udp_ipv6_servers_pool:
                        ServerPool.get_instance().udp_ipv6_servers_pool[
                            port].modify_multi_user_table(md5_users)

                if self.is_relay and row['is_multi_user'] != 2:
                    temp_relay_rules = {}
                    for id in self.relay_rule_list:
                        if ((self.relay_rule_list[id]['user_id'] == user_id
                             or self.relay_rule_list[id]['user_id'] == 0)
                                or row['is_multi_user'] != 0) and (
                                    self.relay_rule_list[id]['port'] == 0 or
                                    self.relay_rule_list[id]['port'] == port):
                            has_higher_priority = False
                            for priority_id in self.relay_rule_list:
                                if ((self.relay_rule_list[priority_id]
                                     ['priority'] >
                                     self.relay_rule_list[id]['priority']
                                     and self.relay_rule_list[id]['id'] !=
                                     self.relay_rule_list[priority_id]['id'])
                                        or
                                    (self.relay_rule_list[priority_id]
                                     ['priority']
                                     == self.relay_rule_list[id]['priority']
                                     and self.relay_rule_list[id]['id'] > self.
                                     relay_rule_list[priority_id]['id'])) and (
                                         self.relay_rule_list[priority_id]
                                         ['user_id'] == user_id
                                         or self.relay_rule_list[priority_id]
                                         ['user_id'] == 0) and (
                                             self.relay_rule_list[priority_id]
                                             ['port'] == port or
                                             self.relay_rule_list[priority_id]
                                             ['port'] == 0):
                                    has_higher_priority = True
                                    continue

                            if has_higher_priority:
                                continue

                            if self.relay_rule_list[id][
                                    'dist_ip'] == '0.0.0.0' and row[
                                        'is_multi_user'] == 0:
                                continue

                            temp_relay_rules[id] = self.relay_rule_list[id]

                    if port in ServerPool.get_instance().tcp_servers_pool:
                        ServerPool.get_instance().tcp_servers_pool[
                            port].push_relay_rules(temp_relay_rules)
                    if port in ServerPool.get_instance().tcp_ipv6_servers_pool:
                        ServerPool.get_instance().tcp_ipv6_servers_pool[
                            port].push_relay_rules(temp_relay_rules)
                    if port in ServerPool.get_instance().udp_servers_pool:
                        ServerPool.get_instance().udp_servers_pool[
                            port].push_relay_rules(temp_relay_rules)
                    if port in ServerPool.get_instance().udp_ipv6_servers_pool:
                        ServerPool.get_instance().udp_ipv6_servers_pool[
                            port].push_relay_rules(temp_relay_rules)

                else:
                    temp_relay_rules = {}

                    if port in ServerPool.get_instance().tcp_servers_pool:
                        ServerPool.get_instance().tcp_servers_pool[
                            port].push_relay_rules(temp_relay_rules)
                    if port in ServerPool.get_instance().tcp_ipv6_servers_pool:
                        ServerPool.get_instance().tcp_ipv6_servers_pool[
                            port].push_relay_rules(temp_relay_rules)
                    if port in ServerPool.get_instance().udp_servers_pool:
                        ServerPool.get_instance().udp_servers_pool[
                            port].push_relay_rules(temp_relay_rules)
                    if port in ServerPool.get_instance().udp_ipv6_servers_pool:
                        ServerPool.get_instance().udp_ipv6_servers_pool[
                            port].push_relay_rules(temp_relay_rules)

                if port in ServerPool.get_instance().tcp_servers_pool:
                    relay = ServerPool.get_instance().tcp_servers_pool[port]
                    for name in merge_config_keys:
                        if name in cfg and not self.cmp(
                                cfg[name], relay._config[name]):
                            cfgchange = True
                            break
                if not cfgchange and port in ServerPool.get_instance(
                ).tcp_ipv6_servers_pool:
                    relay = ServerPool.get_instance(
                    ).tcp_ipv6_servers_pool[port]
                    for name in merge_config_keys:
                        if name in cfg and not self.cmp(
                                cfg[name], relay._config[name]):
                            cfgchange = True
                            break
                # config changed
                if cfgchange:
                    self.del_server(port, "config changed")
                    new_servers[port] = (passwd, cfg)
            elif ServerPool.get_instance().server_run_status(port) is False:
                # new_servers[port] = passwd
                self.new_server(port, passwd, cfg)

        for row in last_rows:
            if row['port'] in cur_servers:
                pass
            else:
                self.del_server(row['port'], "port not exist")

        if len(new_servers) > 0:
            from shadowsocks import eventloop
            self.event.wait(eventloop.TIMEOUT_PRECISION +
                            eventloop.TIMEOUT_PRECISION / 2)
            for port in new_servers.keys():
                passwd, cfg = new_servers[port]
                self.new_server(port, passwd, cfg)

        ServerPool.get_instance().push_uid_port_table(self.uid_port_table)
示例#15
0
    def pull_db_all_user(self):
        import cymysql
        # 数据库所有用户信息
        try:
            switchrule = importloader.load('switchrule')
            keys = switchrule.getKeys()
        except Exception as e:
            keys = [
                'id',
                'port',
                'u',
                'd',
                'transfer_enable',
                'passwd',
                'enable',
                'method',
                'protocol',
                'protocol_param',
                'obfs',
                'obfs_param',
                'node_speedlimit',
                'forbidden_ip',
                'forbidden_port',
                'disconnect_ip',
                'is_multi_user']

        if get_config().MYSQL_SSL_ENABLE == 1:
            conn = cymysql.connect(
                host=get_config().MYSQL_HOST,
                port=get_config().MYSQL_PORT,
                user=get_config().MYSQL_USER,
                passwd=get_config().MYSQL_PASS,
                db=get_config().MYSQL_DB,
                charset='utf8',
                ssl={
                    'ca': get_config().MYSQL_SSL_CA,
                    'cert': get_config().MYSQL_SSL_CERT,
                    'key': get_config().MYSQL_SSL_KEY})
        else:
            conn = cymysql.connect(
                host=get_config().MYSQL_HOST,
                port=get_config().MYSQL_PORT,
                user=get_config().MYSQL_USER,
                passwd=get_config().MYSQL_PASS,
                db=get_config().MYSQL_DB,
                charset='utf8')
        conn.autocommit(True)

        cur = conn.cursor()

        cur.execute(
            "SELECT `node_group`,`node_class`,`node_speedlimit`,`traffic_rate`,`mu_only`,`sort` ,name FROM ss_node where `id`='" +
            str(get_config().NODE_ID) + "' AND (`node_bandwidth`<`node_bandwidth_limit` OR `node_bandwidth_limit`=0)")
        nodeinfo = cur.fetchone()

        if nodeinfo is None:
            rows = []
            cur.close()
            conn.commit()
            conn.close()
            return rows

        cur.close()

        self.node_speedlimit = float(nodeinfo[2])
        self.traffic_rate = float(nodeinfo[3])

        self.mu_only = int(nodeinfo[4])

        if nodeinfo[5] == 10:
            self.is_relay = True
        else:
            self.is_relay = False

        if nodeinfo[0] == 0:
            node_group_sql = ""
        else:
            node_group_sql = "AND `node_group`=" + str(nodeinfo[0])

        cur = conn.cursor()
        cur.execute("SELECT " +
                    ','.join(keys) +
                    " FROM user WHERE ((`class`>=" +
                    str(nodeinfo[1]) +
                    " " +
                    node_group_sql +
                    ") OR `is_admin`=1) AND`enable`=1 AND `expire_in`>now() AND `transfer_enable`>`u`+`d`")
        rows = []
        for r in cur.fetchall():
            d = {}
            for column in range(len(keys)):
                d[keys[column]] = r[column]
            rows.append(d)
        cur.close()

        # 读取节点IP
        # SELECT * FROM `ss_node`  where `node_ip` != ''
        self.node_ip_list = []
        cur = conn.cursor()
        cur.execute("SELECT `node_ip` FROM `ss_node`  where `node_ip` != ''")
        for r in cur.fetchall():
            temp_list = str(r[0]).split(',')
            self.node_ip_list.append(temp_list[0])
        cur.close()

        # 读取审计规则,数据包匹配部分
        keys_detect = ['id', 'regex']

        cur = conn.cursor()
        cur.execute("SELECT " + ','.join(keys_detect) +
                    " FROM detect_list where `type` = 1")

        exist_id_list = []

        for r in cur.fetchall():
            id = int(r[0])
            exist_id_list.append(id)
            if id not in self.detect_text_list:
                d = {}
                d['id'] = id
                d['regex'] = str(r[1])
                self.detect_text_list[id] = d
                self.detect_text_ischanged = True
            else:
                if r[1] != self.detect_text_list[id]['regex']:
                    del self.detect_text_list[id]
                    d = {}
                    d['id'] = id
                    d['regex'] = str(r[1])
                    self.detect_text_list[id] = d
                    self.detect_text_ischanged = True

        deleted_id_list = []
        for id in self.detect_text_list:
            if id not in exist_id_list:
                deleted_id_list.append(id)
                self.detect_text_ischanged = True

        for id in deleted_id_list:
            del self.detect_text_list[id]

        cur.close()

        cur = conn.cursor()
        cur.execute("SELECT " + ','.join(keys_detect) +
                    " FROM detect_list where `type` = 2")

        exist_id_list = []

        for r in cur.fetchall():
            id = int(r[0])
            exist_id_list.append(id)
            if r[0] not in self.detect_hex_list:
                d = {}
                d['id'] = id
                d['regex'] = str(r[1])
                self.detect_hex_list[id] = d
                self.detect_hex_ischanged = True
            else:
                if r[1] != self.detect_hex_list[r[0]]['regex']:
                    del self.detect_hex_list[id]
                    d = {}
                    d['id'] = int(r[0])
                    d['regex'] = str(r[1])
                    self.detect_hex_list[id] = d
                    self.detect_hex_ischanged = True

        deleted_id_list = []
        for id in self.detect_hex_list:
            if id not in exist_id_list:
                deleted_id_list.append(id)
                self.detect_hex_ischanged = True

        for id in deleted_id_list:
            del self.detect_hex_list[id]

        cur.close()

        # 读取中转规则,如果是中转节点的话

        if self.is_relay:
            self.relay_rule_list = {}

            keys_detect = ['id', 'user_id', 'dist_ip', 'port', 'priority']

            cur = conn.cursor()
            cur.execute("SELECT " +
                        ','.join(keys_detect) +
                        " FROM relay where `source_node_id` = 0 or `source_node_id` = " +
                        str(get_config().NODE_ID))

            for r in cur.fetchall():
                d = {}
                d['id'] = int(r[0])
                d['user_id'] = int(r[1])
                d['dist_ip'] = str(r[2])
                d['port'] = int(r[3])
                d['priority'] = int(r[4])
                self.relay_rule_list[d['id']] = d

            cur.close()

        conn.close()
        name = nodeinfo[6]
        names = name.split('#')
        portAdd = 0L
        if len(names) > 1:
            portAdd += long(names[1])
        for row in rows:
            if (row['is_multi_user'] == 1L):
                row['port'] += portAdd
        return rows
示例#16
0
    def del_server_out_of_bound_safe(self, last_rows, rows):
        # 停止超流量的服务
        # 启动没超流量的服务
        # 需要动态载入switchrule,以便实时修改规则

        try:
            switchrule = importloader.load("switchrule")
        except Exception as e:
            logging.error("load switchrule.py fail")
        cur_servers = {}
        new_servers = {}

        md5_users = {}

        self.mu_port_list = []

        for row in rows:
            if row["is_multi_user"] != 0:
                self.mu_port_list.append(int(row["port"]))
                continue

            md5_users[row["id"]] = row.copy()
            del md5_users[row["id"]]["u"]
            del md5_users[row["id"]]["d"]
            if md5_users[row["id"]]["disconnect_ip"] is None:
                md5_users[row["id"]]["disconnect_ip"] = ""

            if md5_users[row["id"]]["forbidden_ip"] is None:
                md5_users[row["id"]]["forbidden_ip"] = ""

            if md5_users[row["id"]]["forbidden_port"] is None:
                md5_users[row["id"]]["forbidden_port"] = ""
            md5_users[row["id"]]["md5"] = common.get_md5(
                str(row["id"]) + row["passwd"] + row["method"] + row["obfs"] +
                row["protocol"])

        for row in rows:
            self.port_uid_table[row["port"]] = row["id"]
            self.uid_port_table[row["id"]] = row["port"]

        if self.mu_only == 1:
            i = 0
            while i < len(rows):
                if rows[i]["is_multi_user"] == 0:
                    rows.pop(i)
                    i -= 1
                else:
                    pass
                i += 1

        if self.mu_only == -1:
            i = 0
            while i < len(rows):
                if rows[i]["is_multi_user"] != 0:
                    rows.pop(i)
                    i -= 1
                else:
                    pass
                i += 1

        for row in rows:
            port = row["port"]
            user_id = row["id"]
            passwd = common.to_bytes(row["passwd"])
            cfg = {"password": passwd}

            read_config_keys = [
                "method",
                "obfs",
                "obfs_param",
                "protocol",
                "protocol_param",
                "forbidden_ip",
                "forbidden_port",
                "node_speedlimit",
                "disconnect_ip",
                "is_multi_user",
            ]

            for name in read_config_keys:
                if name in row and row[name]:
                    cfg[name] = row[name]

            merge_config_keys = ["password"] + read_config_keys
            for name in cfg.keys():
                if hasattr(cfg[name], "encode"):
                    try:
                        cfg[name] = cfg[name].encode("utf-8")
                    except Exception as e:
                        logging.warning('encode cfg key "%s" fail, val "%s"' %
                                        (name, cfg[name]))

            if "node_speedlimit" in cfg:
                if float(self.node_speedlimit) > 0.0 or float(
                        cfg["node_speedlimit"]) > 0.0:
                    cfg["node_speedlimit"] = min(
                        float(self.node_speedlimit),
                        float(cfg["node_speedlimit"]),
                    )
            else:
                cfg["node_speedlimit"] = max(float(self.node_speedlimit),
                                             float(0.00))

            if "disconnect_ip" not in cfg:
                cfg["disconnect_ip"] = ""

            if "forbidden_ip" not in cfg:
                cfg["forbidden_ip"] = ""

            if "forbidden_port" not in cfg:
                cfg["forbidden_port"] = ""

            if "protocol_param" not in cfg:
                cfg["protocol_param"] = ""

            if "obfs_param" not in cfg:
                cfg["obfs_param"] = ""

            if "is_multi_user" not in cfg:
                cfg["is_multi_user"] = 0

            if port not in cur_servers:
                cur_servers[port] = passwd
            else:
                logging.error("more than one user use the same port [%s]" %
                              (port, ))
                continue

            if cfg["is_multi_user"] != 0:
                cfg["users_table"] = md5_users.copy()

            cfg["detect_hex_list"] = self.detect_hex_list.copy()
            cfg["detect_text_list"] = self.detect_text_list.copy()

            if self.is_relay and row["is_multi_user"] != 2:
                temp_relay_rules = {}
                for id in self.relay_rule_list:
                    if ((self.relay_rule_list[id]["user_id"] == user_id
                         or self.relay_rule_list[id]["user_id"] == 0)
                            or row["is_multi_user"] != 0) and (
                                self.relay_rule_list[id]["port"] == 0
                                or self.relay_rule_list[id]["port"] == port):
                        has_higher_priority = False
                        for priority_id in self.relay_rule_list:
                            if (((self.relay_rule_list[priority_id]["priority"]
                                  > self.relay_rule_list[id]["priority"]
                                  and self.relay_rule_list[id]["id"] !=
                                  self.relay_rule_list[priority_id]["id"]) or
                                 (self.relay_rule_list[priority_id]["priority"]
                                  == self.relay_rule_list[id]["priority"]
                                  and self.relay_rule_list[id]["id"] >
                                  self.relay_rule_list[priority_id]["id"])) and
                                (self.relay_rule_list[priority_id]["user_id"]
                                 == user_id or
                                 self.relay_rule_list[priority_id]["user_id"]
                                 == 0) and
                                (self.relay_rule_list[priority_id]["port"]
                                 == port
                                 or self.relay_rule_list[priority_id]["port"]
                                 == 0)):
                                has_higher_priority = True
                                continue

                        if has_higher_priority:
                            continue

                        if self.relay_rule_list[id][
                                "dist_ip"] == "0.0.0.0" and row[
                                    "is_multi_user"] == 0:
                            continue

                        temp_relay_rules[id] = self.relay_rule_list[id]

                cfg["relay_rules"] = temp_relay_rules.copy()
            else:
                temp_relay_rules = {}

                cfg["relay_rules"] = temp_relay_rules.copy()

            if ServerPool.get_instance().server_is_run(port) > 0:
                cfgchange = False

                if port in ServerPool.get_instance().tcp_servers_pool:
                    ServerPool.get_instance(
                    ).tcp_servers_pool[port].modify_detect_text_list(
                        self.detect_text_list)
                    ServerPool.get_instance(
                    ).tcp_servers_pool[port].modify_detect_hex_list(
                        self.detect_hex_list)
                if port in ServerPool.get_instance().tcp_ipv6_servers_pool:
                    ServerPool.get_instance(
                    ).tcp_ipv6_servers_pool[port].modify_detect_text_list(
                        self.detect_text_list)
                    ServerPool.get_instance(
                    ).tcp_ipv6_servers_pool[port].modify_detect_hex_list(
                        self.detect_hex_list)
                if port in ServerPool.get_instance().udp_servers_pool:
                    ServerPool.get_instance(
                    ).udp_servers_pool[port].modify_detect_text_list(
                        self.detect_text_list)
                    ServerPool.get_instance(
                    ).udp_servers_pool[port].modify_detect_hex_list(
                        self.detect_hex_list)
                if port in ServerPool.get_instance().udp_ipv6_servers_pool:
                    ServerPool.get_instance(
                    ).udp_ipv6_servers_pool[port].modify_detect_text_list(
                        self.detect_text_list)
                    ServerPool.get_instance(
                    ).udp_ipv6_servers_pool[port].modify_detect_hex_list(
                        self.detect_hex_list)

                if row["is_multi_user"] != 0:
                    if port in ServerPool.get_instance().tcp_servers_pool:
                        ServerPool.get_instance().tcp_servers_pool[
                            port].modify_multi_user_table(md5_users)
                    if port in ServerPool.get_instance().tcp_ipv6_servers_pool:
                        ServerPool.get_instance().tcp_ipv6_servers_pool[
                            port].modify_multi_user_table(md5_users)
                    if port in ServerPool.get_instance().udp_servers_pool:
                        ServerPool.get_instance().udp_servers_pool[
                            port].modify_multi_user_table(md5_users)
                    if port in ServerPool.get_instance().udp_ipv6_servers_pool:
                        ServerPool.get_instance().udp_ipv6_servers_pool[
                            port].modify_multi_user_table(md5_users)

                if self.is_relay and row["is_multi_user"] != 2:
                    temp_relay_rules = {}
                    for id in self.relay_rule_list:
                        if ((self.relay_rule_list[id]["user_id"] == user_id
                             or self.relay_rule_list[id]["user_id"] == 0)
                                or row["is_multi_user"] != 0) and (
                                    self.relay_rule_list[id]["port"] == 0 or
                                    self.relay_rule_list[id]["port"] == port):
                            has_higher_priority = False
                            for priority_id in self.relay_rule_list:
                                if (((self.relay_rule_list[priority_id]
                                      ["priority"] >
                                      self.relay_rule_list[id]["priority"]
                                      and self.relay_rule_list[id]["id"] !=
                                      self.relay_rule_list[priority_id]["id"])
                                     or
                                     (self.relay_rule_list[priority_id]
                                      ["priority"]
                                      == self.relay_rule_list[id]["priority"]
                                      and self.relay_rule_list[id]["id"] >
                                      self.relay_rule_list[priority_id]["id"]))
                                        and
                                    (self.relay_rule_list[priority_id]
                                     ["user_id"] == user_id
                                     or self.relay_rule_list[priority_id]
                                     ["user_id"] == 0) and
                                    (self.relay_rule_list[priority_id]["port"]
                                     == port or
                                     self.relay_rule_list[priority_id]["port"]
                                     == 0)):
                                    has_higher_priority = True
                                    continue

                            if has_higher_priority:
                                continue

                            if self.relay_rule_list[id][
                                    "dist_ip"] == "0.0.0.0" and row[
                                        "is_multi_user"] == 0:
                                continue

                            temp_relay_rules[id] = self.relay_rule_list[id]

                    if port in ServerPool.get_instance().tcp_servers_pool:
                        ServerPool.get_instance().tcp_servers_pool[
                            port].push_relay_rules(temp_relay_rules)
                    if port in ServerPool.get_instance().tcp_ipv6_servers_pool:
                        ServerPool.get_instance().tcp_ipv6_servers_pool[
                            port].push_relay_rules(temp_relay_rules)
                    if port in ServerPool.get_instance().udp_servers_pool:
                        ServerPool.get_instance().udp_servers_pool[
                            port].push_relay_rules(temp_relay_rules)
                    if port in ServerPool.get_instance().udp_ipv6_servers_pool:
                        ServerPool.get_instance().udp_ipv6_servers_pool[
                            port].push_relay_rules(temp_relay_rules)

                else:
                    temp_relay_rules = {}

                    if port in ServerPool.get_instance().tcp_servers_pool:
                        ServerPool.get_instance().tcp_servers_pool[
                            port].push_relay_rules(temp_relay_rules)
                    if port in ServerPool.get_instance().tcp_ipv6_servers_pool:
                        ServerPool.get_instance().tcp_ipv6_servers_pool[
                            port].push_relay_rules(temp_relay_rules)
                    if port in ServerPool.get_instance().udp_servers_pool:
                        ServerPool.get_instance().udp_servers_pool[
                            port].push_relay_rules(temp_relay_rules)
                    if port in ServerPool.get_instance().udp_ipv6_servers_pool:
                        ServerPool.get_instance().udp_ipv6_servers_pool[
                            port].push_relay_rules(temp_relay_rules)

                if port in ServerPool.get_instance().tcp_servers_pool:
                    relay = ServerPool.get_instance().tcp_servers_pool[port]
                    for name in merge_config_keys:
                        if name in cfg and not self.cmp(
                                cfg[name], relay._config[name]):
                            cfgchange = True
                            break
                if not cfgchange and port in ServerPool.get_instance(
                ).tcp_ipv6_servers_pool:
                    relay = ServerPool.get_instance(
                    ).tcp_ipv6_servers_pool[port]
                    for name in merge_config_keys:
                        if name in cfg and not self.cmp(
                                cfg[name], relay._config[name]):
                            cfgchange = True
                            break
                # config changed
                if cfgchange:
                    self.del_server(port, "config changed")
                    new_servers[port] = (passwd, cfg)
            elif ServerPool.get_instance().server_run_status(port) is False:
                # new_servers[port] = passwd
                self.new_server(port, passwd, cfg)

        for row in last_rows:
            if row["port"] in cur_servers:
                pass
            else:
                self.del_server(row["port"], "port not exist")

        if len(new_servers) > 0:
            from shadowsocks import eventloop

            self.event.wait(eventloop.TIMEOUT_PRECISION +
                            eventloop.TIMEOUT_PRECISION / 2)
            for port in new_servers.keys():
                passwd, cfg = new_servers[port]
                self.new_server(port, passwd, cfg)

        ServerPool.get_instance().push_uid_port_table(self.uid_port_table)
示例#17
0
    def pull_db_all_user(self):
        import cymysql

        # 数据库所有用户信息
        try:
            switchrule = importloader.load("switchrule")
            keys = switchrule.getKeys()
        except Exception as e:
            keys = [
                "id",
                "port",
                "u",
                "d",
                "transfer_enable",
                "passwd",
                "enable",
                "method",
                "protocol",
                "protocol_param",
                "obfs",
                "obfs_param",
                "node_speedlimit",
                "forbidden_ip",
                "forbidden_port",
                "disconnect_ip",
                "is_multi_user",
            ]

        if self.api_config.MYSQL_SSL_ENABLE == 1:
            conn = cymysql.connect(
                host=self.api_config.MYSQL_HOST,
                port=self.api_config.MYSQL_PORT,
                user=self.api_config.MYSQL_USER,
                passwd=self.api_config.MYSQL_PASS,
                db=self.api_config.MYSQL_DB,
                charset="utf8",
                ssl={
                    "ca": self.api_config.MYSQL_SSL_CA,
                    "cert": self.api_config.MYSQL_SSL_CERT,
                    "key": self.api_config.MYSQL_SSL_KEY,
                },
            )
        else:
            conn = cymysql.connect(
                host=self.api_config.MYSQL_HOST,
                port=self.api_config.MYSQL_PORT,
                user=self.api_config.MYSQL_USER,
                passwd=self.api_config.MYSQL_PASS,
                db=self.api_config.MYSQL_DB,
                charset="utf8",
            )
        conn.autocommit(True)

        cur = conn.cursor()

        cur.execute(
            "SELECT `node_group`,`node_class`,`node_speedlimit`,`traffic_rate`,`mu_only`,`sort`,`name` FROM ss_node where `id`='"
            + str(self.api_config.NODE_ID)
            + "' AND (`node_bandwidth`<`node_bandwidth_limit` OR `node_bandwidth_limit`=0)"
        )
        nodeinfo = cur.fetchone()

        if nodeinfo is None:
            rows = []
            cur.close()
            conn.commit()
            conn.close()
            return rows

        cur.close()

        self.node_speedlimit = float(nodeinfo[2])
        self.traffic_rate = float(nodeinfo[3])

        self.mu_only = int(nodeinfo[4])

        if nodeinfo[5] == 10:
            self.is_relay = True
        else:
            self.is_relay = False

        try:
            self.port_offset = int(nodeinfo[6].split("#")[1])
        except IndexError:
            self.port_offset = 0

        logging.debug(
            "node_info >> group=%d class=%d speedlimit=%f traffic_rate=%f mu_only=%d sort=%d name=%s port_offset=%d",
            nodeinfo[0], nodeinfo[1], nodeinfo[2],
            nodeinfo[3], nodeinfo[4], nodeinfo[5],
            nodeinfo[6], self.port_offset)

        if nodeinfo[0] == 0:
            node_group_sql = ""
        else:
            node_group_sql = "AND `node_group`=" + str(nodeinfo[0])

        cur = conn.cursor()
        cur.execute(
            "SELECT "
            + ",".join(keys)
            + " FROM user WHERE ((`class`>="
            + str(nodeinfo[1])
            + " "
            + node_group_sql
            + ") OR `is_admin`=1) AND`enable`=1 AND `expire_in`>now() AND `transfer_enable`>`u`+`d`"
        )
        rows = []
        for r in cur.fetchall():
            d = {}
            for column in range(len(keys)):
                d[keys[column]] = r[column]
            d["port"] = self.get_port_by_offset(d["port"])
            rows.append(d)
        cur.close()

        # 读取节点IP
        # SELECT * FROM `ss_node`  where `node_ip` != ''
        self.node_ip_list = []
        cur = conn.cursor()
        cur.execute("SELECT `node_ip` FROM `ss_node`  where `node_ip` != ''")
        for r in cur.fetchall():
            temp_list = str(r[0]).split(",")
            self.node_ip_list.append(temp_list[0])
        cur.close()

        # 读取审计规则,数据包匹配部分
        keys_detect = ["id", "regex"]

        cur = conn.cursor()
        cur.execute("SELECT " + ",".join(keys_detect) + " FROM detect_list where `type` = 1")

        exist_id_list = []

        for r in cur.fetchall():
            id = int(r[0])
            exist_id_list.append(id)
            if id not in self.detect_text_list:
                d = {"id": id, "regex": str(r[1])}
                self.detect_text_list[id] = d
                self.detect_text_ischanged = True
            else:
                if r[1] != self.detect_text_list[id]["regex"]:
                    del self.detect_text_list[id]
                    d = {"id": id, "regex": str(r[1])}
                    self.detect_text_list[id] = d
                    self.detect_text_ischanged = True

        deleted_id_list = []
        for id in self.detect_text_list:
            if id not in exist_id_list:
                deleted_id_list.append(id)
                self.detect_text_ischanged = True

        for id in deleted_id_list:
            del self.detect_text_list[id]

        cur.close()

        cur = conn.cursor()
        cur.execute("SELECT " + ",".join(keys_detect) + " FROM detect_list where `type` = 2")

        exist_id_list = []

        for r in cur.fetchall():
            id = int(r[0])
            exist_id_list.append(id)
            if r[0] not in self.detect_hex_list:
                d = {"id": id, "regex": str(r[1])}
                self.detect_hex_list[id] = d
                self.detect_hex_ischanged = True
            else:
                if r[1] != self.detect_hex_list[r[0]]["regex"]:
                    del self.detect_hex_list[id]
                    d = {"id": int(r[0]), "regex": str(r[1])}
                    self.detect_hex_list[id] = d
                    self.detect_hex_ischanged = True

        deleted_id_list = []
        for id in self.detect_hex_list:
            if id not in exist_id_list:
                deleted_id_list.append(id)
                self.detect_hex_ischanged = True

        for id in deleted_id_list:
            del self.detect_hex_list[id]

        cur.close()

        # 读取中转规则,如果是中转节点的话

        if self.is_relay:
            self.relay_rule_list = {}

            keys_detect = ["id", "user_id", "dist_ip", "port", "priority"]

            cur = conn.cursor()
            cur.execute(
                "SELECT "
                + ",".join(keys_detect)
                + " FROM relay where `source_node_id` = 0 or `source_node_id` = "
                + str(self.api_config.NODE_ID)
            )

            for r in cur.fetchall():
                d = {
                    "id": int(r[0]),
                    "user_id": int(r[1]),
                    "dist_ip": str(r[2]),
                    "port": int(r[3]),
                    "priority": int(r[4]),
                }
                self.relay_rule_list[d["id"]] = d

            cur.close()

        conn.close()
        return rows
示例#18
0
	def del_server_out_of_bound_safe(self, last_rows, rows):
		#停止超流量的服务
		#启动没超流量的服务
		try:
			switchrule = importloader.load('switchrule')
		except Exception as e:
			logging.error('load switchrule.py fail')
		cur_servers = {}
		new_servers = {}
		for row in rows:
			try:
				allow = switchrule.isTurnOn(row) and row['enable'] == 1 and row['u'] + row['d'] < row['transfer_enable']
			except Exception as e:
				allow = False

			port = row['port']
			passwd = common.to_bytes(row['passwd'])
			cfg = {'password': passwd}
			if 'id' in row:
				self.port_uid_table[row['port']] = row['id']

			read_config_keys = ['method', 'obfs', 'obfs_param', 'protocol', 'protocol_param', 'forbidden_ip', 'forbidden_port']
			for name in read_config_keys:
				if name in row and row[name]:
					cfg[name] = row[name]

			merge_config_keys = ['password'] + read_config_keys
			for name in cfg.keys():
				if hasattr(cfg[name], 'encode'):
					cfg[name] = cfg[name].encode('utf-8')

			if port not in cur_servers:
				cur_servers[port] = passwd
			else:
				logging.error('more than one user use the same port [%s]' % (port,))
				continue

			if ServerPool.get_instance().server_is_run(port) > 0:
				if not allow:
					logging.info('db stop server at port [%s]' % (port,))
					ServerPool.get_instance().cb_del_server(port)
					self.force_update_transfer.add(port)
				else:
					cfgchange = False
					if port in ServerPool.get_instance().tcp_servers_pool:
						relay = ServerPool.get_instance().tcp_servers_pool[port]
						for name in merge_config_keys:
							if name in cfg and not self.cmp(cfg[name], relay._config[name]):
								cfgchange = True
								break;
					if not cfgchange and port in ServerPool.get_instance().tcp_ipv6_servers_pool:
						relay = ServerPool.get_instance().tcp_ipv6_servers_pool[port]
						for name in merge_config_keys:
							if name in cfg and not self.cmp(cfg[name], relay._config[name]):
								cfgchange = True
								break;
					#config changed
					if cfgchange:
						logging.info('db stop server at port [%s] reason: config changed: %s' % (port, cfg))
						ServerPool.get_instance().cb_del_server(port)
						self.force_update_transfer.add(port)
						new_servers[port] = (passwd, cfg)

			elif allow and ServerPool.get_instance().server_run_status(port) is False:
				self.new_server(port, passwd, cfg)

		for row in last_rows:
			if row['port'] in cur_servers:
				pass
			else:
				logging.info('db stop server at port [%s] reason: port not exist' % (row['port']))
				ServerPool.get_instance().cb_del_server(row['port'])
				self.clear_cache(row['port'])
				if row['port'] in self.port_uid_table:
					del self.port_uid_table[row['port']]

		if len(new_servers) > 0:
			from shadowsocks import eventloop
			self.event.wait(eventloop.TIMEOUT_PRECISION + eventloop.TIMEOUT_PRECISION / 2)
			for port in new_servers.keys():
				passwd, cfg = new_servers[port]
				self.new_server(port, passwd, cfg)
    def del_server_out_of_bound_safe(self, last_rows, rows):
        #停止超流量的服务
        #启动没超流量的服务
        try:
            switchrule = importloader.load('switchrule')
        except Exception as e:
            logging.error('load switchrule.py fail')
        cur_servers = {}
        new_servers = {}
        for row in rows:
            try:
                allow = switchrule.isTurnOn(
                    row) and row['enable'] == 1 and row['u'] + row['d'] < row[
                        'transfer_enable']
            except Exception as e:
                allow = False

            port = row['port']
            passwd = common.to_bytes(row['passwd'])
            cfg = {'password': passwd}
            if 'id' in row:
                self.port_uid_table[row['port']] = row['id']

            read_config_keys = [
                'method', 'obfs', 'obfs_param', 'protocol', 'protocol_param',
                'forbidden_ip', 'forbidden_port'
            ]
            for name in read_config_keys:
                if name in row and row[name]:
                    cfg[name] = row[name]

            merge_config_keys = ['password'] + read_config_keys
            for name in cfg.keys():
                if hasattr(cfg[name], 'encode'):
                    cfg[name] = cfg[name].encode('utf-8')

            if port not in cur_servers:
                cur_servers[port] = passwd
            else:
                logging.error('more than one user use the same port [%s]' %
                              (port, ))
                continue

            if ServerPool.get_instance().server_is_run(port) > 0:
                if not allow:
                    logging.info('db stop server at port [%s]' % (port, ))
                    ServerPool.get_instance().cb_del_server(port)
                    self.force_update_transfer.add(port)
                else:
                    cfgchange = False
                    if port in ServerPool.get_instance().tcp_servers_pool:
                        relay = ServerPool.get_instance(
                        ).tcp_servers_pool[port]
                        for name in merge_config_keys:
                            if name in cfg and not self.cmp(
                                    cfg[name], relay._config[name]):
                                cfgchange = True
                                break
                    if not cfgchange and port in ServerPool.get_instance(
                    ).tcp_ipv6_servers_pool:
                        relay = ServerPool.get_instance(
                        ).tcp_ipv6_servers_pool[port]
                        for name in merge_config_keys:
                            if name in cfg and not self.cmp(
                                    cfg[name], relay._config[name]):
                                cfgchange = True
                                break
                    #config changed
                    if cfgchange:
                        logging.info(
                            'db stop server at port [%s] reason: config changed: %s'
                            % (port, cfg))
                        ServerPool.get_instance().cb_del_server(port)
                        self.force_update_transfer.add(port)
                        new_servers[port] = (passwd, cfg)

            elif allow and ServerPool.get_instance().server_run_status(
                    port) is False:
                self.new_server(port, passwd, cfg)

        for row in last_rows:
            if row['port'] in cur_servers:
                pass
            else:
                logging.info(
                    'db stop server at port [%s] reason: port not exist' %
                    (row['port']))
                ServerPool.get_instance().cb_del_server(row['port'])
                self.clear_cache(row['port'])
                if row['port'] in self.port_uid_table:
                    del self.port_uid_table[row['port']]

        if len(new_servers) > 0:
            from shadowsocks import eventloop
            self.event.wait(eventloop.TIMEOUT_PRECISION +
                            eventloop.TIMEOUT_PRECISION / 2)
            for port in new_servers.keys():
                passwd, cfg = new_servers[port]
                self.new_server(port, passwd, cfg)
示例#20
0
    def pull_db_all_user(self):
        import cymysql
        # 数据库所有用户信息
        try:
            switchrule = importloader.load('switchrule')
            keys = switchrule.getKeys()
        except Exception as e:
            keys = [
                'accountId id', 'port', 'u', 'd', 'transfer_enable', 'passwd',
                'enable', 'method', 'protocol', 'protocol_param', 'obfs',
                'obfs_param', 'node_speedlimit', 'forbidden_ip',
                'forbidden_port', 'disconnect_ip', 'is_multi_user'
            ]

        if get_config().MYSQL_SSL_ENABLE == 1:
            conn = cymysql.connect(host=get_config().MYSQL_HOST,
                                   port=get_config().MYSQL_PORT,
                                   user=get_config().MYSQL_USER,
                                   passwd=get_config().MYSQL_PASS,
                                   db=get_config().MYSQL_DB,
                                   charset='utf8',
                                   ssl={
                                       'ca': get_config().MYSQL_SSL_CA,
                                       'cert': get_config().MYSQL_SSL_CERT,
                                       'key': get_config().MYSQL_SSL_KEY
                                   })
        else:
            conn = cymysql.connect(host=get_config().MYSQL_HOST,
                                   port=get_config().MYSQL_PORT,
                                   user=get_config().MYSQL_USER,
                                   passwd=get_config().MYSQL_PASS,
                                   db=get_config().MYSQL_DB,
                                   charset='utf8')
        conn.autocommit(True)

        # b 读取节点信息
        cur = conn.cursor()

        cur.execute(
            "SELECT `node_speedlimit`,`singleMode` FROM server where `id`=" +
            str(get_config().NODE_ID) +
            " AND (`node_bandwidth`<`node_bandwidth_limit` OR `node_bandwidth_limit`=0)"
        )
        # b 原代码
        # cur.execute("SELECT `node_group`,`node_class`,`node_speedlimit`,`traffic_rate`,`mu_only`,`sort` FROM ss_node where `id`='" +
        #             str(get_config().NODE_ID) + "' AND (`node_bandwidth`<`node_bandwidth_limit` OR `node_bandwidth_limit`=0)")
        nodeinfo = cur.fetchone()

        if nodeinfo is None:
            rows = []
            cur.close()
            conn.commit()
            conn.close()
            return rows

        cur.close()
        # b 节点限速
        self.node_speedlimit = float(nodeinfo[0])

        # b mu_only -1/只启用普通端口 0/单端口多用户与普通端口并存 1/只启用单端口多用户
        if nodeinfo[1] == "ssr1port":
            self.mu_only = 1
        else:
            self.mu_only = 0

        # self.node_speedlimit = float(nodeinfo[2])
        self.traffic_rate = 1

        # self.mu_only = int(nodeinfo[4])

        # if nodeinfo[5] == 10:
        #     self.is_relay = True
        # else:
        #     self.is_relay = False
        self.is_relay = False

        # if nodeinfo[0] == 0:
        #     node_group_sql = ""
        # else:
        #     node_group_sql = "AND `node_group`=" + str(nodeinfo[0])

        cur = conn.cursor()

        cur.execute("SELECT " + ','.join(keys) +
                    " FROM ssr_user where enable = 1 and serverId=" +
                    str(get_config().NODE_ID))
        # b 下面是原代码
        # cur.execute("SELECT " +
        #             ','.join(keys) +
        #             " FROM user WHERE ((`class`>=" +
        #             str(nodeinfo[1]) +
        #             " " +
        #             node_group_sql +
        #             ") OR `is_admin`=1) AND`enable`=1 AND `expire_in`>now() AND `transfer_enable`>`u`+`d`")
        rows = []
        for r in cur.fetchall():
            d = {}
            for column in range(len(keys)):
                key_temp = keys[column].split(' ')
                d[key_temp[len(key_temp) - 1]] = r[column]
            # for column in range(len(keys)):
            #     d[keys[column]] = r[column]
            rows.append(d)
        cur.close()

        # 读取节点IP
        # SELECT * FROM `ss_node`  where `node_ip` != ''
        self.node_ip_list = []
        cur = conn.cursor()
        # cur.execute("SELECT `node_ip` FROM `ss_node`  where `node_ip` != ''")
        cur.execute(
            "SELECT `host` FROM `server`  where `type` = 'Shadowsocks'")
        for r in cur.fetchall():
            temp_list = str(r[0]).split(':')
            self.node_ip_list.append(temp_list[0])
        cur.close()

        # 读取审计规则,数据包匹配部分  type 1/数据包明文匹配 2/数据包 hex 匹配
        keys_detect = ['id', 'regex']

        cur = conn.cursor()
        cur.execute("SELECT " + ','.join(keys_detect) +
                    " FROM detect_list where `type` = 1")

        exist_id_list = []

        for r in cur.fetchall():
            id = int(r[0])
            exist_id_list.append(id)
            if id not in self.detect_text_list:
                d = {}
                d['id'] = id
                d['regex'] = str(r[1])
                self.detect_text_list[id] = d
                self.detect_text_ischanged = True
            else:
                if r[1] != self.detect_text_list[id]['regex']:
                    del self.detect_text_list[id]
                    d = {}
                    d['id'] = id
                    d['regex'] = str(r[1])
                    self.detect_text_list[id] = d
                    self.detect_text_ischanged = True

        deleted_id_list = []
        for id in self.detect_text_list:
            if id not in exist_id_list:
                deleted_id_list.append(id)
                self.detect_text_ischanged = True

        for id in deleted_id_list:
            del self.detect_text_list[id]

        cur.close()

        cur = conn.cursor()
        cur.execute("SELECT " + ','.join(keys_detect) +
                    " FROM detect_list where `type` = 2")

        exist_id_list = []

        for r in cur.fetchall():
            id = int(r[0])
            exist_id_list.append(id)
            if r[0] not in self.detect_hex_list:
                d = {}
                d['id'] = id
                d['regex'] = str(r[1])
                self.detect_hex_list[id] = d
                self.detect_hex_ischanged = True
            else:
                if r[1] != self.detect_hex_list[r[0]]['regex']:
                    del self.detect_hex_list[id]
                    d = {}
                    d['id'] = int(r[0])
                    d['regex'] = str(r[1])
                    self.detect_hex_list[id] = d
                    self.detect_hex_ischanged = True

        deleted_id_list = []
        for id in self.detect_hex_list:
            if id not in exist_id_list:
                deleted_id_list.append(id)
                self.detect_hex_ischanged = True

        for id in deleted_id_list:
            del self.detect_hex_list[id]

        cur.close()

        # 读取中转规则,如果是中转节点的话

        # if self.is_relay:
        #     self.relay_rule_list = {}

        #     keys_detect = ['id', 'user_id', 'dist_ip', 'port', 'priority']

        #     cur = conn.cursor()
        #     cur.execute("SELECT " +
        #                 ','.join(keys_detect) +
        #                 " FROM relay where `source_node_id` = 0 or `source_node_id` = " +
        #                 str(get_config().NODE_ID))

        #     for r in cur.fetchall():
        #         d = {}
        #         d['id'] = int(r[0])
        #         d['user_id'] = int(r[1])
        #         d['dist_ip'] = str(r[2])
        #         d['port'] = int(r[3])
        #         d['priority'] = int(r[4])
        #         self.relay_rule_list[d['id']] = d

        #     cur.close()

        conn.close()
        return rows
示例#21
0
	def del_server_out_of_bound_safe(self, last_rows, rows):
		#停止超流量的服务
		#启动没超流量的服务
		keymap = {}
		try:
			switchrule = importloader.load('switchrule')
			keymap = switchrule.getRowMap()
		except Exception as e:
			logging.error('load switchrule.py fail')
		cur_servers = {}
		new_servers = {}
		allow_users = {}
		mu_servers  = {}
		config = shell.get_config(False)
		for row in rows:
			try:
				allow = switchrule.isTurnOn(row) and row['enable'] == 1 and row['u'] + row['d'] < row['transfer_enable']
			except Exception as e:
				allow = False

			port = row['port']
			passwd = common.to_bytes(row['passwd'])
			if hasattr(passwd, 'encode'):
				passwd = passwd.encode('utf-8')
			cfg = {'password': passwd}
			if 'id' in row:
				self.port_uid_table[row['port']] = row['id']

			read_config_keys = ['method', 'obfs', 'obfs_param', 'protocol', 'protocol_param', 'forbidden_ip', 'forbidden_port', 'speed_limit_per_con', 'speed_limit_per_user']
			for name in read_config_keys:
				if name in row and row[name]:
					if name in keymap:
						cfg[keymap[name]] = row[name]
					else:
						cfg[name] = row[name]

			merge_config_keys = ['password'] + read_config_keys
			for name in cfg.keys():
				if hasattr(cfg[name], 'encode'):
					try:
						cfg[name] = cfg[name].encode('utf-8')
					except Exception as e:
						logging.warning('encode cfg key "%s" fail, val "%s"' % (name, cfg[name]))

			if port not in cur_servers:
				cur_servers[port] = passwd
			else:
				logging.error('more than one user use the same port [%s]' % (port,))
				continue

			if 'protocol' in cfg and 'protocol_param' in cfg and common.to_str(cfg['protocol']) in obfs.mu_protocol():
				if '#' in common.to_str(cfg['protocol_param']):
					mu_servers[port] = passwd
					allow = True

			if allow:
				if port not in mu_servers:
					allow_users[port] = cfg

				cfgchange = False
				if port in ServerPool.get_instance().tcp_servers_pool:
					relay = ServerPool.get_instance().tcp_servers_pool[port]
					for name in merge_config_keys:
						if name in cfg and not self.cmp(cfg[name], relay._config[name]):
							cfgchange = True
							break
				if not cfgchange and port in ServerPool.get_instance().tcp_ipv6_servers_pool:
					relay = ServerPool.get_instance().tcp_ipv6_servers_pool[port]
					for name in merge_config_keys:
						if (name in cfg) and ((name not in relay._config) or not self.cmp(cfg[name], relay._config[name])):
							cfgchange = True
							break

			if port in mu_servers:
				if ServerPool.get_instance().server_is_run(port) > 0:
					if cfgchange:
						logging.info('db stop server at port [%s] reason: config changed: %s' % (port, cfg))
						ServerPool.get_instance().cb_del_server(port)
						self.force_update_transfer.add(port)
						new_servers[port] = (passwd, cfg)
				else:
					self.new_server(port, passwd, cfg)
			else:
				if ServerPool.get_instance().server_is_run(port) > 0:
					if config['additional_ports_only'] or not allow:
						logging.info('db stop server at port [%s]' % (port,))
						ServerPool.get_instance().cb_del_server(port)
						self.force_update_transfer.add(port)
					else:
						if cfgchange:
							logging.info('db stop server at port [%s] reason: config changed: %s' % (port, cfg))
							ServerPool.get_instance().cb_del_server(port)
							self.force_update_transfer.add(port)
							new_servers[port] = (passwd, cfg)

				elif not config['additional_ports_only'] and allow and port > 0 and port < 65536 and ServerPool.get_instance().server_run_status(port) is False:
					self.new_server(port, passwd, cfg)

		for row in last_rows:
			if row['port'] in cur_servers:
				pass
			else:
				logging.info('db stop server at port [%s] reason: port not exist' % (row['port']))
				ServerPool.get_instance().cb_del_server(row['port'])
				self.clear_cache(row['port'])
				if row['port'] in self.port_uid_table:
					del self.port_uid_table[row['port']]

		if len(new_servers) > 0:
			from shadowsocks import eventloop
			self.event.wait(eventloop.TIMEOUT_PRECISION + eventloop.TIMEOUT_PRECISION / 2)
			for port in new_servers.keys():
				passwd, cfg = new_servers[port]
				self.new_server(port, passwd, cfg)

		logging.debug('db allow users %s \nmu_servers %s' % (allow_users, mu_servers))
		for port in mu_servers:
			ServerPool.get_instance().update_mu_users(port, allow_users)

		self.mu_ports = mu_servers
示例#22
0
	def del_server_out_of_bound_safe(self, last_rows, rows):
		#停止超流量的服务
		#启动没超流量的服务
		try:
			switchrule = importloader.load('switchrule')
		except Exception as e:
			logging.error('load switchrule.py fail')
		cur_servers = {}
		new_servers = {}
		allow_users = {}
		mu_servers  = {}
		config = shell.get_config(False)
		for row in rows:
			try:
				allow = switchrule.isTurnOn(row) and row['enable'] == 1 and row['u'] + row['d'] < row['transfer_enable']
			except Exception as e:
				allow = False

			port = row['port']
			passwd = common.to_bytes(row['passwd'])
			if hasattr(passwd, 'encode'):
				passwd = passwd.encode('utf-8')
			cfg = {'password': passwd}
			if 'id' in row:
				self.port_uid_table[row['port']] = row['id']

			read_config_keys = ['method', 'obfs', 'obfs_param', 'protocol', 'protocol_param', 'forbidden_ip', 'forbidden_port', 'speed_limit_per_con', 'speed_limit_per_user']
			for name in read_config_keys:
				if name in row and row[name]:
					cfg[name] = row[name]

			merge_config_keys = ['password'] + read_config_keys
			for name in cfg.keys():
				if hasattr(cfg[name], 'encode'):
					try:
						cfg[name] = cfg[name].encode('utf-8')
					except Exception as e:
						logging.warning('encode cfg key "%s" fail, val "%s"' % (name, cfg[name]))

			if port not in cur_servers:
				cur_servers[port] = passwd
			else:
				logging.error('more than one user use the same port [%s]' % (port,))
				continue

			if 'protocol' in cfg and 'protocol_param' in cfg and common.to_str(cfg['protocol']) in obfs.mu_protocol():
				if '#' in common.to_str(cfg['protocol_param']):
					mu_servers[port] = passwd
					allow = True

			if allow:
				if port not in mu_servers:
					allow_users[port] = cfg

				cfgchange = False
				if port in ServerPool.get_instance().tcp_servers_pool:
					relay = ServerPool.get_instance().tcp_servers_pool[port]
					for name in merge_config_keys:
						if name in cfg and not self.cmp(cfg[name], relay._config[name]):
							cfgchange = True
							break
				if not cfgchange and port in ServerPool.get_instance().tcp_ipv6_servers_pool:
					relay = ServerPool.get_instance().tcp_ipv6_servers_pool[port]
					for name in merge_config_keys:
						if (name in cfg) and ((name not in relay._config) or not self.cmp(cfg[name], relay._config[name])):
							cfgchange = True
							break

			if port in mu_servers:
				if ServerPool.get_instance().server_is_run(port) > 0:
					if cfgchange:
						logging.info('db stop server at port [%s] reason: config changed: %s' % (port, cfg))
						ServerPool.get_instance().cb_del_server(port)
						self.force_update_transfer.add(port)
						new_servers[port] = (passwd, cfg)
				else:
					self.new_server(port, passwd, cfg)
			else:
				if ServerPool.get_instance().server_is_run(port) > 0:
					if config['additional_ports_only'] or not allow:
						logging.info('db stop server at port [%s]' % (port,))
						ServerPool.get_instance().cb_del_server(port)
						self.force_update_transfer.add(port)
					else:
						if cfgchange:
							logging.info('db stop server at port [%s] reason: config changed: %s' % (port, cfg))
							ServerPool.get_instance().cb_del_server(port)
							self.force_update_transfer.add(port)
							new_servers[port] = (passwd, cfg)

				elif not config['additional_ports_only'] and allow and port > 0 and port < 65536 and ServerPool.get_instance().server_run_status(port) is False:
					self.new_server(port, passwd, cfg)

		for row in last_rows:
			if row['port'] in cur_servers:
				pass
			else:
				logging.info('db stop server at port [%s] reason: port not exist' % (row['port']))
				ServerPool.get_instance().cb_del_server(row['port'])
				self.clear_cache(row['port'])
				if row['port'] in self.port_uid_table:
					del self.port_uid_table[row['port']]

		if len(new_servers) > 0:
			from shadowsocks import eventloop
			self.event.wait(eventloop.TIMEOUT_PRECISION + eventloop.TIMEOUT_PRECISION / 2)
			for port in new_servers.keys():
				passwd, cfg = new_servers[port]
				self.new_server(port, passwd, cfg)

		logging.debug('db allow users %s \nmu_servers %s' % (allow_users, mu_servers))
		for port in mu_servers:
			ServerPool.get_instance().update_mu_users(port, allow_users)

		self.mu_ports = mu_servers