Search in sources :

Example 1 with InvalidException

use of org.rx.exception.InvalidException in project rxlib by RockyLOMO.

the class Main method main.

@SneakyThrows
public static void main(String[] args) {
    Map<String, String> options = App.argsOptions(args);
    Integer port = Reflects.tryConvert(options.get("port"), Integer.class);
    if (port == null) {
        log.info("Invalid port arg");
        return;
    }
    Main app;
    Integer connectTimeout = Reflects.tryConvert(options.get("connectTimeout"), Integer.class, 60000);
    String mode = options.get("shadowMode");
    boolean udp2raw = false;
    if (eq(mode, "1")) {
        AuthenticEndpoint shadowUser = Reflects.tryConvert(options.get("shadowUser"), AuthenticEndpoint.class);
        if (shadowUser == null) {
            log.info("Invalid shadowUser arg");
            return;
        }
        SocksUser ssUser = new SocksUser(shadowUser.getUsername());
        ssUser.setPassword(shadowUser.getPassword());
        ssUser.setMaxIpCount(-1);
        SocksConfig backConf = new SocksConfig(port);
        backConf.setTransportFlags(TransportFlags.FRONTEND_COMPRESS.flags());
        backConf.setMemoryMode(MemoryMode.MEDIUM);
        backConf.setConnectTimeoutMillis(connectTimeout);
        backConf.setEnableUdp2raw(udp2raw);
        SocksProxyServer backSvr = new SocksProxyServer(backConf, (u, p) -> eq(u, ssUser.getUsername()) && eq(p, ssUser.getPassword()) ? ssUser : SocksUser.ANONYMOUS);
        backSvr.setAesRouter(SocksProxyServer.DNS_AES_ROUTER);
        // server port + 1 = rpc
        RpcServerConfig rpcConf = new RpcServerConfig(port + 1);
        rpcConf.setTransportFlags(TransportFlags.FRONTEND_AES_COMBO.flags());
        Remoting.listen(app = new Main(backSvr), rpcConf);
    } else {
        String[] arg1 = Strings.split(options.get("shadowUsers"), ",");
        if (arg1.length == 0) {
            log.info("Invalid shadowUsers arg");
            return;
        }
        RandomList<UpstreamSupport> shadowServers = new RandomList<>();
        SocksConfig frontConf = new SocksConfig(port);
        YamlConfiguration watcher = new YamlConfiguration("conf.yml").enableWatch();
        watcher.onChanged.combine((s, e) -> {
            SSConf changed = s.readAs(SSConf.class);
            if (changed == null) {
                return;
            }
            conf = changed;
            NQuery<AuthenticEndpoint> svrs = NQuery.of(conf.shadowServer).select(p -> Reflects.tryConvert(p, AuthenticEndpoint.class));
            if (!svrs.any() || svrs.any(Objects::isNull)) {
                throw new InvalidException("Invalid shadowServer arg");
            }
            for (UpstreamSupport support : shadowServers) {
                tryClose(support.getSupport());
            }
            shadowServers.clear();
            for (AuthenticEndpoint shadowServer : svrs) {
                RpcClientConfig rpcConf = RpcClientConfig.poolMode(Sockets.newEndpoint(shadowServer.getEndpoint(), shadowServer.getEndpoint().getPort() + 1), 2, 6);
                rpcConf.setTransportFlags(TransportFlags.BACKEND_AES_COMBO.flags());
                String weight = shadowServer.getParameters().get("w");
                if (Strings.isEmpty(weight)) {
                    continue;
                }
                shadowServers.add(new UpstreamSupport(shadowServer, Remoting.create(SocksSupport.class, rpcConf)), Integer.parseInt(weight));
            }
            log.info("reload svrs {}", toJsonString(svrs));
            if (conf.bypassHosts != null) {
                frontConf.getBypassList().addAll(conf.bypassHosts);
            }
        });
        watcher.raiseChange();
        NQuery<Tuple<ShadowsocksConfig, SocksUser>> shadowUsers = NQuery.of(arg1).select(shadowUser -> {
            String[] sArgs = Strings.split(shadowUser, ":", 4);
            ShadowsocksConfig config = new ShadowsocksConfig(Sockets.anyEndpoint(Integer.parseInt(sArgs[0])), CipherKind.AES_256_GCM.getCipherName(), sArgs[1]);
            SocksUser user = new SocksUser(sArgs[2]);
            user.setPassword(conf.socksPwd);
            user.setMaxIpCount(Integer.parseInt(sArgs[3]));
            return Tuple.of(config, user);
        });
        Integer shadowDnsPort = Reflects.tryConvert(options.get("shadowDnsPort"), Integer.class, 53);
        DnsServer dnsSvr = new DnsServer(shadowDnsPort);
        // 12 hour
        dnsSvr.setTtl(60 * 60 * 10);
        dnsSvr.setShadowServers(shadowServers);
        dnsSvr.addHostsFile("hosts.txt");
        InetSocketAddress shadowDnsEp = Sockets.localEndpoint(shadowDnsPort);
        Sockets.injectNameService(Collections.singletonList(shadowDnsEp));
        frontConf.setTransportFlags(TransportFlags.BACKEND_COMPRESS.flags());
        frontConf.setMemoryMode(MemoryMode.MEDIUM);
        frontConf.setConnectTimeoutMillis(connectTimeout);
        frontConf.setEnableUdp2raw(conf.udp2raw);
        frontConf.setUdp2rawServers(NQuery.of(shadowServers).select(p -> p.getEndpoint().getEndpoint()).toList());
        if (frontConf.isEnableUdp2raw() && conf.udp2rawEndpoint != null) {
            log.info("udp2rawEndpoint: {}", conf.udp2rawEndpoint);
            AuthenticEndpoint udp2rawSvrEp = AuthenticEndpoint.valueOf(conf.udp2rawEndpoint);
            frontConf.getUdp2rawServers().add(udp2rawSvrEp.getEndpoint());
        }
        SocksProxyServer frontSvr = new SocksProxyServer(frontConf, Authenticator.dbAuth(shadowUsers.select(p -> p.right).toList(), port + 1));
        Upstream shadowDnsUpstream = new Upstream(new UnresolvedEndpoint(shadowDnsEp));
        TripleAction<SocksProxyServer, RouteEventArgs> firstRoute = (s, e) -> {
            UnresolvedEndpoint dstEp = e.getDestinationEndpoint();
            // must first
            if (dstEp.getPort() == SocksSupport.DNS_PORT) {
                e.setValue(shadowDnsUpstream);
                return;
            }
            // bypass
            if (frontConf.isBypass(dstEp.getHost())) {
                e.setValue(new Upstream(dstEp));
            }
        };
        frontSvr.onRoute.replace(firstRoute, (s, e) -> {
            if (e.getValue() != null) {
                return;
            }
            e.setValue(new Socks5Upstream(e.getDestinationEndpoint(), frontConf, () -> shadowServers.next(e.getSourceEndpoint(), conf.steeringTTL, true)));
        });
        frontSvr.onUdpRoute.replace(firstRoute, (s, e) -> {
            if (e.getValue() != null) {
                return;
            }
            UnresolvedEndpoint dstEp = e.getDestinationEndpoint();
            if (conf.pcap2socks && e.getSourceEndpoint().getAddress().isLoopbackAddress()) {
                Cache<String, Boolean> cache = Cache.getInstance(Cache.MEMORY_CACHE);
                if (cache.get(hashKey("pcap", e.getSourceEndpoint().getPort()), k -> Sockets.socketInfos(SocketProtocol.UDP).any(p -> p.getSource().getPort() == e.getSourceEndpoint().getPort() && Strings.startsWith(p.getProcessName(), "pcap2socks")))) {
                    log.info("pcap2socks forward");
                    e.setValue(new Upstream(dstEp));
                    return;
                }
            }
            // if (frontConf.isEnableUdp2raw()) {
            // if (udp2rawSvrEp != null) {
            // e.setValue(new Upstream(dstEp, udp2rawSvrEp));
            // } else {
            // e.setValue(new Upstream(dstEp, shadowServers.next().getEndpoint()));
            // }
            // return;
            // }
            e.setValue(new Socks5UdpUpstream(dstEp, frontConf, () -> shadowServers.next(e.getSourceEndpoint(), conf.steeringTTL, true)));
        });
        frontSvr.setAesRouter(SocksProxyServer.DNS_AES_ROUTER);
        app = new Main(frontSvr);
        Action fn = () -> {
            InetAddress addr = InetAddress.getByName(IPSearcher.DEFAULT.current().getIp());
            eachQuietly(shadowServers, p -> p.getSupport().addWhiteList(addr));
        };
        fn.invoke();
        Tasks.schedule(fn, conf.autoWhiteListSeconds * 1000L);
        InetSocketAddress frontSvrEp = Sockets.localEndpoint(port);
        for (Tuple<ShadowsocksConfig, SocksUser> tuple : shadowUsers) {
            ShadowsocksConfig ssConfig = tuple.left;
            SocksUser user = tuple.right;
            AuthenticEndpoint srvEp = new AuthenticEndpoint(frontSvrEp, user.getUsername(), user.getPassword());
            ssConfig.setMemoryMode(MemoryMode.MEDIUM);
            ssConfig.setConnectTimeoutMillis(connectTimeout);
            SocksConfig directConf = new SocksConfig(port);
            frontConf.setMemoryMode(MemoryMode.MEDIUM);
            frontConf.setConnectTimeoutMillis(connectTimeout);
            ShadowsocksServer server = new ShadowsocksServer(ssConfig);
            TripleAction<ShadowsocksServer, RouteEventArgs> ssFirstRoute = (s, e) -> {
                UnresolvedEndpoint dstEp = e.getDestinationEndpoint();
                // must first
                if (dstEp.getPort() == SocksSupport.DNS_PORT) {
                    e.setValue(shadowDnsUpstream);
                    return;
                }
                // bypass
                if (ssConfig.isBypass(dstEp.getHost())) {
                    log.info("ss bypass: {}", dstEp);
                    e.setValue(new Upstream(dstEp));
                }
            };
            server.onRoute.replace(ssFirstRoute, (s, e) -> {
                if (e.getValue() != null) {
                    return;
                }
                // gateway
                IPAddress ipAddress = awaitQuietly(() -> IPSearcher.DEFAULT.search(e.getDestinationEndpoint().getHost()), SocksSupport.ASYNC_TIMEOUT / 2);
                if (ipAddress != null && ipAddress.isChina()) {
                    e.setValue(new Upstream(e.getDestinationEndpoint()));
                    return;
                }
                e.setValue(new Socks5Upstream(e.getDestinationEndpoint(), directConf, () -> new UpstreamSupport(srvEp, null)));
            });
            server.onUdpRoute.replace(ssFirstRoute, (s, e) -> {
                if (e.getValue() != null) {
                    return;
                }
                e.setValue(new Upstream(e.getDestinationEndpoint(), srvEp));
            });
        }
        app.ddns();
    }
    log.info("Server started..");
    app.await();
}
Also used : DnsServer(org.rx.net.dns.DnsServer) Extends(org.rx.core.Extends) SneakyThrows(lombok.SneakyThrows) RequiredArgsConstructor(lombok.RequiredArgsConstructor) Upstream(org.rx.net.socks.upstream.Upstream) InvalidException(org.rx.exception.InvalidException) DnsClient(org.rx.net.dns.DnsClient) CipherKind(org.rx.net.shadowsocks.encryption.CipherKind) HttpClient(org.rx.net.http.HttpClient) InetAddress(java.net.InetAddress) TripleAction(org.rx.util.function.TripleAction) org.rx.net.socks(org.rx.net.socks) Map(java.util.Map) Socks5UdpUpstream(org.rx.net.socks.upstream.Socks5UdpUpstream) App(org.rx.core.App) org.rx.core(org.rx.core) ShadowsocksConfig(org.rx.net.shadowsocks.ShadowsocksConfig) RandomList(org.rx.bean.RandomList) ShadowsocksServer(org.rx.net.shadowsocks.ShadowsocksServer) org.rx.net.support(org.rx.net.support) Tasks.awaitQuietly(org.rx.core.Tasks.awaitQuietly) InetSocketAddress(java.net.InetSocketAddress) Tuple(org.rx.bean.Tuple) Action(org.rx.util.function.Action) Objects(java.util.Objects) Slf4j(lombok.extern.slf4j.Slf4j) List(java.util.List) RpcClientConfig(org.rx.net.rpc.RpcClientConfig) Data(lombok.Data) Remoting(org.rx.net.rpc.Remoting) SUID(org.rx.bean.SUID) org.rx.net(org.rx.net) RpcServerConfig(org.rx.net.rpc.RpcServerConfig) Socks5Upstream(org.rx.net.socks.upstream.Socks5Upstream) Collections(java.util.Collections) TripleAction(org.rx.util.function.TripleAction) Action(org.rx.util.function.Action) RpcServerConfig(org.rx.net.rpc.RpcServerConfig) InetSocketAddress(java.net.InetSocketAddress) InvalidException(org.rx.exception.InvalidException) RandomList(org.rx.bean.RandomList) RpcClientConfig(org.rx.net.rpc.RpcClientConfig) Upstream(org.rx.net.socks.upstream.Upstream) Socks5UdpUpstream(org.rx.net.socks.upstream.Socks5UdpUpstream) Socks5Upstream(org.rx.net.socks.upstream.Socks5Upstream) ShadowsocksConfig(org.rx.net.shadowsocks.ShadowsocksConfig) ShadowsocksServer(org.rx.net.shadowsocks.ShadowsocksServer) DnsServer(org.rx.net.dns.DnsServer) Socks5UdpUpstream(org.rx.net.socks.upstream.Socks5UdpUpstream) Socks5Upstream(org.rx.net.socks.upstream.Socks5Upstream) InetAddress(java.net.InetAddress) Tuple(org.rx.bean.Tuple) SneakyThrows(lombok.SneakyThrows)

Example 2 with InvalidException

use of org.rx.exception.InvalidException in project rxlib by RockyLOMO.

the class Reflects method changeType.

@SuppressWarnings(NON_RAW_TYPES)
@ErrorCode("enumError")
@ErrorCode(cause = NoSuchMethodException.class)
@ErrorCode(cause = ReflectiveOperationException.class)
public static <T> T changeType(Object value, @NonNull Class<T> toType) {
    if (value == null) {
        if (!toType.isPrimitive()) {
            if (List.class.equals(toType)) {
                return (T) Collections.emptyList();
            }
            if (Map.class.equals(toType)) {
                return (T) Collections.emptyMap();
            }
            return null;
        }
        if (boolean.class.equals(toType)) {
            return (T) Boolean.FALSE;
        } else {
            value = 0;
        }
    }
    Class<?> fromType = value.getClass();
    Object fValue = value;
    if (toType.equals(String.class)) {
        value = value.toString();
    } else if (toType.equals(UUID.class)) {
        value = UUID.fromString(value.toString());
    } else if (toType.equals(BigDecimal.class)) {
        value = new BigDecimal(value.toString());
    } else if (toType.isEnum()) {
        boolean failBack = true;
        if (NEnum.class.isAssignableFrom(toType)) {
            if (value instanceof String) {
                try {
                    value = Integer.valueOf((String) value);
                } catch (NumberFormatException e) {
                // ignore
                }
            }
            if (value instanceof Number) {
                int val = ((Number) value).intValue();
                value = NEnum.valueOf((Class) toType, val);
                failBack = false;
            }
        }
        if (failBack) {
            String val = value.toString();
            value = NQuery.of(toType.getEnumConstants()).singleOrDefault(p -> ((Enum) p).name().equals(val));
        }
        if (value == null) {
            throw new ApplicationException("enumError", values(fValue, toType.getSimpleName()));
        }
    } else if ((!toType.isPrimitive() && TypeUtils.isInstance(value, toType))) {
    // isInstance int to long/all to object ok, do nothing
    } else {
        try {
            toType = (Class) primitiveToWrapper(toType);
            if (toType.equals(Boolean.class) && isAssignable(fromType, Number.class)) {
                int val = ((Number) value).intValue();
                if (val == 0) {
                    value = Boolean.FALSE;
                } else if (val == 1) {
                    value = Boolean.TRUE;
                } else {
                    throw new InvalidException("Value should be 0 or 1");
                }
            } else {
                NQuery<Method> methods = getMethodMap(toType).get(CHANGE_TYPE_METHOD);
                if (methods == null || fromType.isEnum()) {
                    Class<T> fType = toType;
                    ConvertBean convertBean = NQuery.of(CONVERT_BEANS).firstOrDefault(p -> TypeUtils.isInstance(fValue, p.baseFromType) && p.toType.isAssignableFrom(fType));
                    if (convertBean != null) {
                        return (T) convertBean.converter.apply(value, convertBean.toType);
                    }
                    throw new NoSuchMethodException(CHANGE_TYPE_METHOD);
                }
                if (isAssignable(toType, Number.class) && primitiveToWrapper(fromType).equals(Boolean.class)) {
                    boolean val = (boolean) value;
                    if (!val) {
                        value = "0";
                    } else {
                        value = "1";
                    }
                }
                Method m = null;
                for (Method p : methods) {
                    if (!(p.getParameterCount() == 1 && p.getParameterTypes()[0].equals(String.class))) {
                        continue;
                    }
                    m = p;
                    break;
                }
                if (m == null) {
                    m = toType.getDeclaredMethod(CHANGE_TYPE_METHOD, String.class);
                }
                value = m.invoke(null, value.toString());
            }
        } catch (NoSuchMethodException e) {
            throw new ApplicationException(values(toType), e);
        } catch (ReflectiveOperationException e) {
            throw new ApplicationException(values(fromType, toType, value), e);
        }
    }
    return (T) value;
}
Also used : InvalidException(org.rx.exception.InvalidException) BigDecimal(java.math.BigDecimal) ApplicationException(org.rx.exception.ApplicationException) ErrorCode(org.rx.annotation.ErrorCode)

Example 3 with InvalidException

use of org.rx.exception.InvalidException in project rxlib by RockyLOMO.

the class Reflects method getResource.

public static InputStream getResource(String namePattern) {
    InputStream stream = getClassLoader().getResourceAsStream(namePattern);
    if (stream != null) {
        return stream;
    }
    InputStream in = getResources(namePattern).firstOrDefault();
    if (in == null) {
        throw new InvalidException("Resource %s not found", namePattern);
    }
    return in;
}
Also used : InputStream(java.io.InputStream) InvalidException(org.rx.exception.InvalidException)

Example 4 with InvalidException

use of org.rx.exception.InvalidException in project rxlib by RockyLOMO.

the class ShellCommander method start.

@SneakyThrows
public synchronized ShellCommander start() {
    if (isRunning()) {
        throw new InvalidException("already started");
    }
    // Runtime.getRuntime().exec(shell, null, workspace)
    StringTokenizer st = new StringTokenizer(shell);
    String[] cmdarray = new String[st.countTokens()];
    for (int i = 0; st.hasMoreTokens(); i++) {
        cmdarray[i] = st.nextToken();
    }
    Process tmp = process = new ProcessBuilder(cmdarray).directory(workspace).redirectErrorStream(// 合并getInputStream和getErrorStream
    true).start();
    log.debug("start {}", shell);
    if (daemonFuture != null) {
        daemonFuture.cancel(true);
    }
    daemonFuture = Tasks.run(() -> {
        LineNumberReader reader = null;
        try {
            if (!onOutPrint.isEmpty()) {
                reader = new LineNumberReader(new InputStreamReader(tmp.getInputStream(), StandardCharsets.UTF_8));
            }
            while (tmp.isAlive()) {
                try {
                    if (reader != null) {
                        String line;
                        while ((line = reader.readLine()) != null) {
                            raiseEvent(onOutPrint, new OutPrintEventArgs(reader.getLineNumber(), line));
                        }
                    }
                } catch (Throwable e) {
                    ExceptionHandler.INSTANCE.log("onOutPrint", e);
                }
                Thread.sleep(intervalPeriod);
            }
        } finally {
            tryClose(reader);
            int exitValue = tmp.exitValue();
            log.debug("exit={} {}", exitValue, shell);
            raiseEvent(onExited, new ExitedEventArgs(exitValue));
        }
    });
    return this;
}
Also used : StringTokenizer(java.util.StringTokenizer) InvalidException(org.rx.exception.InvalidException)

Example 5 with InvalidException

use of org.rx.exception.InvalidException in project rxlib by RockyLOMO.

the class YamlConfiguration method enableWatch.

public synchronized YamlConfiguration enableWatch(@NonNull String outputFile) {
    if (watcher != null) {
        throw new InvalidException("Already watched");
    }
    if (!yaml.isEmpty()) {
        try (FileStream fs = new FileStream(outputFile)) {
            fs.setPosition(0);
            fs.writeString(new Yaml().dumpAsMap(yaml));
            fs.flip();
        }
    }
    watcher = new FileWatcher(Files.getFullPath(this.outputFile = outputFile), p -> p.toString().equals(this.outputFile));
    watcher.onChanged.combine((s, e) -> {
        String filePath = e.getPath().toString();
        log.info("Config changing {} {} -> {}", e.isCreate(), filePath, yaml);
        synchronized (this) {
            yaml.clear();
            if (!e.isDelete()) {
                write(filePath);
            }
        }
        log.info("Config changed {} {} -> {}", e.isCreate(), filePath, yaml);
        raiseEvent(onChanged, new ChangedEventArgs(filePath));
    });
    return this;
}
Also used : java.util(java.util) Getter(lombok.Getter) ApplicationException(org.rx.exception.ApplicationException) NonNull(lombok.NonNull) RequiredArgsConstructor(lombok.RequiredArgsConstructor) Extends.values(org.rx.core.Extends.values) InvalidException(org.rx.exception.InvalidException) Extends.as(org.rx.core.Extends.as) CollectionUtils(org.apache.commons.collections4.CollectionUtils) File(java.io.File) Yaml(org.yaml.snakeyaml.Yaml) Slf4j(lombok.extern.slf4j.Slf4j) FileWatcher(org.rx.io.FileWatcher) Files(org.rx.io.Files) JSONObject(com.alibaba.fastjson.JSONObject) FileStream(org.rx.io.FileStream) ErrorCode(org.rx.annotation.ErrorCode) InputStream(java.io.InputStream) FileWatcher(org.rx.io.FileWatcher) InvalidException(org.rx.exception.InvalidException) FileStream(org.rx.io.FileStream) Yaml(org.yaml.snakeyaml.Yaml)

Aggregations

InvalidException (org.rx.exception.InvalidException)23 SneakyThrows (lombok.SneakyThrows)10 Slf4j (lombok.extern.slf4j.Slf4j)5 InetSocketAddress (java.net.InetSocketAddress)4 Map (java.util.Map)4 Getter (lombok.Getter)4 NonNull (lombok.NonNull)4 Test (org.junit.jupiter.api.Test)4 org.rx.core (org.rx.core)4 Extends (org.rx.core.Extends)4 ExceptionHandler (org.rx.exception.ExceptionHandler)4 List (java.util.List)3 RequiredArgsConstructor (lombok.RequiredArgsConstructor)3 ErrorCode (org.rx.annotation.ErrorCode)3 App (org.rx.core.App)3 Constants (org.rx.core.Constants)3 StringBuilder (org.rx.core.StringBuilder)3 ApplicationException (org.rx.exception.ApplicationException)3 Sockets (org.rx.net.Sockets)3 JSONObject (com.alibaba.fastjson.JSONObject)2