def init_func(self, creator_fd, gw_configs, enable_ipv6=False): """ :param creator_fd: :param tunnel_ip: 隧道IPV4或者IPV6地址 :param gw_configs: :param enable_ipv6:是否开启ipv6支持 :return: """ dgram_proxy_subnet, prefix = utils.extract_subnet_info( gw_configs["dgram_proxy_subnet"]) dgram_proxy_subnet6, prefix6 = utils.extract_subnet_info( gw_configs["dgram_proxy_subnet6"]) dev_path = "/dev/%s" % fdsl_ctl.FDSL_DEV_NAME fileno = os.open(dev_path, os.O_RDONLY) subnet = utils.calc_subnet(dgram_proxy_subnet, prefix, is_ipv6=False) subnet6 = utils.calc_subnet(dgram_proxy_subnet6, prefix6, is_ipv6=True) byte_subnet = socket.inet_aton(subnet) byte_subnet6 = socket.inet_pton(socket.AF_INET6, subnet6) r = fdsl_ctl.set_udp_proxy_subnet(fileno, byte_subnet, prefix, False) if enable_ipv6: r = fdsl_ctl.set_udp_proxy_subnet(fileno, byte_subnet6, prefix, True) self.__tunnel_fd = creator_fd self.set_fileno(fileno) self.register(self.fileno) self.add_evt_read(self.fileno) return self.fileno
def init_func(self, creator_fd, gw_configs, enable_ipv6=False): """ :param creator_fd: :param tunnel_ip: 隧道IPV4或者IPV6地址 :param gw_configs: :param enable_ipv6:是否开启ipv6支持 :return: """ dgram_proxy_subnet, prefix = utils.extract_subnet_info(gw_configs["dgram_proxy_subnet"]) dgram_proxy_subnet6, prefix6 = utils.extract_subnet_info(gw_configs["dgram_proxy_subnet6"]) dev_path = "/dev/%s" % fdsl_ctl.FDSL_DEV_NAME fileno = os.open(dev_path, os.O_RDONLY) subnet = utils.calc_subnet(dgram_proxy_subnet, prefix, is_ipv6=False) subnet6 = utils.calc_subnet(dgram_proxy_subnet6, prefix6, is_ipv6=True) byte_subnet = socket.inet_aton(subnet) byte_subnet6 = socket.inet_pton(socket.AF_INET6, subnet6) r = fdsl_ctl.set_udp_proxy_subnet(fileno, byte_subnet, prefix, False) if enable_ipv6: r = fdsl_ctl.set_udp_proxy_subnet(fileno, byte_subnet6, prefix, True) self.__tunnel_fd = creator_fd self.set_fileno(fileno) self.register(self.fileno) self.add_evt_read(self.fileno) return self.fileno
def add_rule(self, subnet, prefix): check_rs = self.__check_format(subnet, prefix) if not check_rs: return False is_ipv6 = False if utils.is_ipv6_address(subnet): is_ipv6 = True if not utils.check_subnet_fmt(subnet, prefix, is_ipv6=is_ipv6): return False if is_ipv6: subnet = utils.calc_subnet(subnet, prefix, is_ipv6=True) else: subnet = utils.calc_subnet(subnet, prefix, is_ipv6=False) name = "%s/%s" % ( subnet, prefix, ) if is_ipv6: self.__ipv6_rules[name] = ( subnet, prefix, ) else: self.__ip_rules[name] = ( subnet, prefix, ) return True
def __init__(self, subnet, prefix, is_ipv6=False): self.__emptys = {} if is_ipv6: fa = socket.AF_INET6 else: fa = socket.AF_INET subnet = utils.calc_subnet(subnet, prefix, is_ipv6=is_ipv6) self.__byte_subnet = socket.inet_pton(fa, subnet) s = utils.get_ip_addr_max(subnet, prefix, is_ipv6=is_ipv6) # 最后一个IP地址是广播地址,保留 self.__byte_subnet_max = utils.ip_addr_minus(socket.inet_pton(fa, s)) # 子网为基地址,需要加1 self.__byte_subnet_cur = utils.ip_addr_plus(self.__byte_subnet)
def __set_static_ip_rules(self, rules): nameserver = self.__configs["public"]["remote_dns"] ns_is_ipv6 = utils.is_ipv6_address(nameserver) # 查看新的规则 kv_pairs_new = {} for subnet, prefix in rules: if not utils.is_ipv6_address(subnet) and not utils.is_ipv4_address(subnet): logging.print_error("wrong pre ip rule %s/%s" % (subnet, prefix,)) continue is_ipv6 = utils.is_ipv6_address(subnet) # 找到和nameserver冲突的路由那么跳过 t = utils.calc_subnet(nameserver, prefix, is_ipv6=ns_is_ipv6) if t == subnet: logging.print_error( "conflict preload ip rules %s/%s with nameserver %s" % (subnet, prefix, nameserver,) ) continue name = "%s/%s" % (subnet, prefix,) kv_pairs_new[name] = (subnet, prefix, is_ipv6,) # 需要删除的列表 need_dels = [] # 需要增加的路由 need_adds = [] for name in kv_pairs_new: # 新的规则旧的没有那么就需要添加 if name not in self.__static_routes: need_adds.append(kv_pairs_new[name]) for name in self.__static_routes: # 旧的规则新的没有,那么就是需要删除 if name not in kv_pairs_new: need_dels.append(self.__static_routes[name]) # 删除需要删除的路由 for subnet, prefix, is_ipv6 in need_dels: self.__del_route(subnet, prefix=prefix, is_ipv6=is_ipv6, is_dynamic=False) # 增加需要增加的路由 for subnet, prefix, is_ipv6 in need_adds: self.set_route(subnet, prefix=prefix, is_ipv6=is_ipv6, is_dynamic=False)
def set_route(self, host, prefix=None, timeout=None, is_ipv6=False, is_dynamic=True): if host in self.__routes: return # 如果是服务器的地址,那么不设置路由,避免使用ip_rules规则的时候进入死循环,因为服务器地址可能不在ip_rules文件中 if host == self.__server_ip: return # 检查路由是否和nameserver冲突,如果冲突那么不添加路由 nameserver = self.__configs["public"]["remote_dns"] if nameserver == host: return # 如果禁止了IPV6流量,那么不设置IPV6路由 if not self.__enable_ipv6_traffic and is_ipv6: return if is_ipv6: s = "-6" if not prefix: prefix = 128 else: s = "" if not prefix: prefix = 32 if is_ipv6: n = 128 else: n = 32 # 首先查看是否已经加了永久路由 while n > 0: subnet = utils.calc_subnet(host, n, is_ipv6=is_ipv6) name = "%s/%s" % (subnet, n) n -= 1 # 找到永久路由的记录就直接返回,避免冲突 if name not in self.__static_routes: continue return cmd = "ip %s route add %s/%s dev %s" % (s, host, prefix, self.__DEVNAME) os.system(cmd) if not is_dynamic: name = "%s/%s" % (host, prefix,) self.__static_routes[name] = (host, prefix, is_ipv6,) return if not timeout: timeout = self.__ROUTE_TIMEOUT self.__route_timer.set_timeout(host, timeout) self.__routes[host] = is_ipv6
def __get_conflict_from_static_route(self, ipaddr, is_ipv6=False): """获取与static冲突的结果 :param ipaddr: :param is_ipv6: :return: """ if is_ipv6: n = 128 else: n = 32 rs = None while n > 0: sub = utils.calc_subnet(ipaddr, n, is_ipv6=is_ipv6) name = "%s/%s" % (sub, n,) if name in self.__static_routes: rs = self.__static_routes[name] break n -= 1 return rs
def match(self, ipaddr, is_ipv6=False): if is_ipv6: rules = self.__ipv6_rules else: rules = self.__ip_rules result = False if is_ipv6: n = 128 else: n = 32 while n > 0: subnet = utils.calc_subnet(ipaddr, n, is_ipv6=is_ipv6) name = "%s/%s" % (subnet, n) n -= 1 if name not in rules: continue result = True break return result