forked from KNEMC/KLALB
自动获得节点地址功能
This commit is contained in:
+14
@@ -0,0 +1,14 @@
|
|||||||
|
4569
|
||||||
|
HTTP$127.0.0.1:8081
|
||||||
|
>
|
||||||
|
NULL-宿迁联通$153.36.240.12:65529
|
||||||
|
Openfrp-杭州多线-1$cn-hz-bgp-1.openfrp.top:65529
|
||||||
|
Openfrp-北京多线-3$cn-bj-bgp-3.openfrp.top:65529
|
||||||
|
Openfrp-北京多线-7$180.76.147.250:65529
|
||||||
|
Openfrp-西安电信-1$cn-sx-xa-bgp-1.openfrp.top:65529
|
||||||
|
XYZ-韩国首尔$frp.104300.xyz:49965
|
||||||
|
aFrps-美国洛杉矶$la.afrps.cn:49966
|
||||||
|
aFrps-新加坡$sg.afrps.cn:49966
|
||||||
|
aFrps-美国芝加哥$ch.afrps.cn:49966
|
||||||
|
aFrps-美国圣何塞$sj.afrps.cn:49966
|
||||||
|
|
||||||
@@ -0,0 +1,52 @@
|
|||||||
|
package org.kne.cloud.network.klalb;
|
||||||
|
|
||||||
|
import java.io.Serializable;
|
||||||
|
import java.net.Inet6Address;
|
||||||
|
import java.net.InetAddress;
|
||||||
|
import java.net.InetSocketAddress;
|
||||||
|
import java.net.UnknownHostException;
|
||||||
|
import java.util.Objects;
|
||||||
|
|
||||||
|
public class IPPort implements Serializable{
|
||||||
|
private InetAddress ip;
|
||||||
|
private int port;
|
||||||
|
public IPPort(String ipport) throws UnknownHostException {
|
||||||
|
int index =ipport.lastIndexOf(":");
|
||||||
|
ip=InetAddress.getByName( ipport.substring(0,index));
|
||||||
|
port=Integer.parseInt(ipport.substring(index+1));
|
||||||
|
|
||||||
|
}
|
||||||
|
@Override
|
||||||
|
public int hashCode() {
|
||||||
|
return Objects.hash(ip, port);
|
||||||
|
}
|
||||||
|
@Override
|
||||||
|
public boolean equals(Object obj) {
|
||||||
|
if (this == obj)
|
||||||
|
return true;
|
||||||
|
if (obj == null)
|
||||||
|
return false;
|
||||||
|
if (getClass() != obj.getClass())
|
||||||
|
return false;
|
||||||
|
IPPort other = (IPPort) obj;
|
||||||
|
return Objects.equals(ip, other.ip) && port == other.port;
|
||||||
|
}
|
||||||
|
public IPPort(String ip2, int port2) throws UnknownHostException {
|
||||||
|
ip=InetAddress.getByName(ip2);
|
||||||
|
port=port2;
|
||||||
|
}
|
||||||
|
public InetAddress getIp() {
|
||||||
|
return ip;
|
||||||
|
}
|
||||||
|
public int getPort() {
|
||||||
|
return port;
|
||||||
|
}
|
||||||
|
@Override
|
||||||
|
public String toString() {
|
||||||
|
if(ip instanceof Inet6Address) {
|
||||||
|
return "["+ip.getHostAddress()+"]:"+port;
|
||||||
|
}
|
||||||
|
return ip.getHostAddress()+":"+port;
|
||||||
|
}
|
||||||
|
|
||||||
|
}
|
||||||
@@ -3,6 +3,11 @@ package org.kne.cloud.network.klalb;
|
|||||||
import java.io.BufferedInputStream;
|
import java.io.BufferedInputStream;
|
||||||
import java.io.BufferedOutputStream;
|
import java.io.BufferedOutputStream;
|
||||||
import java.io.IOException;
|
import java.io.IOException;
|
||||||
|
import java.net.MalformedURLException;
|
||||||
|
import java.net.Socket;
|
||||||
|
import java.net.URI;
|
||||||
|
import java.net.URL;
|
||||||
|
import java.net.UnknownHostException;
|
||||||
import java.util.ArrayList;
|
import java.util.ArrayList;
|
||||||
import java.util.List;
|
import java.util.List;
|
||||||
import java.util.UUID;
|
import java.util.UUID;
|
||||||
@@ -37,6 +42,10 @@ public class KLALBClient {
|
|||||||
try {
|
try {
|
||||||
TCPConnection tc=new TCPConnection(tll);
|
TCPConnection tc=new TCPConnection(tll);
|
||||||
tc.getDout().writeShort(59649);
|
tc.getDout().writeShort(59649);
|
||||||
|
tc.getDout().write(1);
|
||||||
|
tc.getDout().writeUTF(tll.getName());
|
||||||
|
tc.getDout().writeUTF(tll.getIp());
|
||||||
|
tc.getDout().writeInt(tll.getPort());
|
||||||
tc.getDout().writeLong(uid.getMostSignificantBits());
|
tc.getDout().writeLong(uid.getMostSignificantBits());
|
||||||
tc.getDout().writeLong(uid.getLeastSignificantBits());
|
tc.getDout().writeLong(uid.getLeastSignificantBits());
|
||||||
tc.getDout().flush();
|
tc.getDout().flush();
|
||||||
@@ -83,8 +92,35 @@ public class KLALBClient {
|
|||||||
public List<Tunnel> getTls() {
|
public List<Tunnel> getTls() {
|
||||||
return tls;
|
return tls;
|
||||||
}
|
}
|
||||||
|
public static List<ServiceElement> services=new ArrayList<ServiceElement>();
|
||||||
|
|
||||||
|
public void searchTunnels(String ipport) throws IOException {
|
||||||
|
IPPort u=new IPPort(ipport);
|
||||||
|
TCPConnection tcpc=null;
|
||||||
|
try {
|
||||||
|
tcpc=new TCPConnection(null, new Socket(u.getIp(),u.getPort()));
|
||||||
|
tcpc.getDout().writeShort(59649);
|
||||||
|
tcpc.getDout().write(0);
|
||||||
|
tcpc.getDout().flush();
|
||||||
|
int s=tcpc.getDin().readInt();
|
||||||
|
for (int i = 0; i < s; i++) {
|
||||||
|
services.add(new ServiceElement(tcpc.getDin().readUTF()));
|
||||||
|
}
|
||||||
|
int s2=tcpc.getDin().readInt();
|
||||||
|
for (int i = 0; i < s2; i++) {
|
||||||
|
tls.add(new Tunnel(tcpc.getDin().readUTF()));
|
||||||
|
}
|
||||||
|
System.out.println(services);
|
||||||
|
System.out.println(tls);
|
||||||
|
}finally {
|
||||||
|
if(tcpc!=null) {
|
||||||
|
tcpc.close();
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
public static void main(String[] args) throws IOException {
|
public static void main(String[] args) throws IOException {
|
||||||
KLALBClient kc=new KLALBClient(4568);
|
KLALBClient kc=new KLALBClient(4568);
|
||||||
|
kc.searchTunnels("153.36.240.12:65529");
|
||||||
//Tunnel t= new Tunnel("Test1", "127.0.0.1", 4569);
|
//Tunnel t= new Tunnel("Test1", "127.0.0.1", 4569);
|
||||||
/*Tunnel t= new Tunnel("Test1", "cn-hz-bgp-1.openfrp.top", 65529);
|
/*Tunnel t= new Tunnel("Test1", "cn-hz-bgp-1.openfrp.top", 65529);
|
||||||
tls.add(t);
|
tls.add(t);
|
||||||
@@ -95,7 +131,7 @@ public class KLALBClient {
|
|||||||
Tunnel t4=new Tunnel("Test4","cn-sx-xa-bgp-1.openfrp.top",65529);
|
Tunnel t4=new Tunnel("Test4","cn-sx-xa-bgp-1.openfrp.top",65529);
|
||||||
tls.add(t4);
|
tls.add(t4);
|
||||||
*/
|
*/
|
||||||
List<Tunnel> tls=kc.getTls();
|
/* List<Tunnel> tls=kc.getTls();
|
||||||
Tunnel t5=new Tunnel("Test5","la.afrps.cn",49966);
|
Tunnel t5=new Tunnel("Test5","la.afrps.cn",49966);
|
||||||
tls.add(t5);
|
tls.add(t5);
|
||||||
Tunnel t6=new Tunnel("Test6","sg.afrps.cn",49966);
|
Tunnel t6=new Tunnel("Test6","sg.afrps.cn",49966);
|
||||||
@@ -110,7 +146,7 @@ public class KLALBClient {
|
|||||||
Tunnel t11=new Tunnel("Test11","153.36.240.12",65529);
|
Tunnel t11=new Tunnel("Test11","153.36.240.12",65529);
|
||||||
tls.add(t11);
|
tls.add(t11);
|
||||||
Tunnel t12=new Tunnel("Test12","frp.freefrps.com",49965);
|
Tunnel t12=new Tunnel("Test12","frp.freefrps.com",49965);
|
||||||
tls.add(t12);
|
tls.add(t12);*/
|
||||||
kc.open();
|
kc.open();
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|||||||
@@ -0,0 +1,114 @@
|
|||||||
|
package org.kne.cloud.network.klalb;
|
||||||
|
|
||||||
|
import java.io.File;
|
||||||
|
import java.io.IOException;
|
||||||
|
import java.util.ArrayList;
|
||||||
|
import java.util.List;
|
||||||
|
import java.util.Properties;
|
||||||
|
import java.util.Scanner;
|
||||||
|
|
||||||
|
public class KLALBSM {
|
||||||
|
public static List<ServiceElement> services=new ArrayList<ServiceElement>();
|
||||||
|
|
||||||
|
public static List<Tunnel> tunnels=new ArrayList<Tunnel>();
|
||||||
|
public static void main(String[] args) throws IOException {
|
||||||
|
File f=new File("klalbs.ini");
|
||||||
|
if(!f.exists()) {
|
||||||
|
f.createNewFile();
|
||||||
|
ept();
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
if(f.length()<=0) {
|
||||||
|
ept();
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
Scanner scn=new Scanner(f);
|
||||||
|
int remp=scn.nextInt();
|
||||||
|
System.out.println("KNE云负载均衡调度软件服务端V0.1");
|
||||||
|
System.out.println("开放端口:"+remp);
|
||||||
|
int x=0;
|
||||||
|
System.out.println("服务列表:");
|
||||||
|
while(scn.hasNext() ) {
|
||||||
|
String s=scn.next();
|
||||||
|
if(">".equals(s)) {
|
||||||
|
x++;
|
||||||
|
System.out.println("隧道列表:");
|
||||||
|
continue;
|
||||||
|
}
|
||||||
|
switch(x) {
|
||||||
|
case 0:
|
||||||
|
ServiceElement se=new ServiceElement(s);
|
||||||
|
System.out.println(se);
|
||||||
|
services.add(se);
|
||||||
|
break;
|
||||||
|
case 1:
|
||||||
|
Tunnel t=new Tunnel(s);
|
||||||
|
System.out.println(t);
|
||||||
|
tunnels.add(t);
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
|
||||||
|
}
|
||||||
|
scn.close();
|
||||||
|
new KLALBServer(remp,services,tunnels);
|
||||||
|
System.out.println("提示:运行时输入reload可以重新加载配置文件,已经建立的TCP连接不受影响(暂不支持修改开放端口)");
|
||||||
|
Scanner scn2=new Scanner(System.in);
|
||||||
|
while(true) {
|
||||||
|
String command=scn2.next();
|
||||||
|
switch(command) {
|
||||||
|
case "reload":
|
||||||
|
synchronized (services) {
|
||||||
|
synchronized(tunnels) {
|
||||||
|
scn=new Scanner(f);
|
||||||
|
services.clear();
|
||||||
|
tunnels.clear();
|
||||||
|
remp=scn.nextInt();
|
||||||
|
x=0;
|
||||||
|
System.out.println("服务列表:");
|
||||||
|
while(scn.hasNext() ) {
|
||||||
|
String s=scn.next();
|
||||||
|
if(">".equals(s)) {
|
||||||
|
x++;
|
||||||
|
System.out.println("隧道列表:");
|
||||||
|
continue;
|
||||||
|
}
|
||||||
|
switch(x) {
|
||||||
|
case 0:
|
||||||
|
ServiceElement se=new ServiceElement(s);
|
||||||
|
System.out.println(se);
|
||||||
|
services.add(se);
|
||||||
|
break;
|
||||||
|
case 1:
|
||||||
|
Tunnel t=new Tunnel(s);
|
||||||
|
System.out.println(t);
|
||||||
|
tunnels.add(t);
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
|
||||||
|
}
|
||||||
|
scn.close();
|
||||||
|
}
|
||||||
|
}
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
private static void ept() {
|
||||||
|
System.out.println("请填写配置文件后再启动程序!");
|
||||||
|
System.out.println("格式:");
|
||||||
|
System.out.println("开放端口");
|
||||||
|
System.out.println("服务协议1$服务地址1$服务端口1");
|
||||||
|
System.out.println("服务协议2$服务地址2$服务端口2");
|
||||||
|
System.out.println("......");
|
||||||
|
System.out.println("服务协议n$服务地址n$服务端口n");
|
||||||
|
System.out.println(">");
|
||||||
|
System.out.println("隧道名称1$隧道地址1$隧道端口1");
|
||||||
|
System.out.println("隧道名称2$隧道地址2$隧道端口2");
|
||||||
|
System.out.println("......");
|
||||||
|
System.out.println("隧道名称n$隧道地址n$隧道端口n");
|
||||||
|
System.out.println("");
|
||||||
|
System.out.println("按照顺序从上向下匹配,若都不是则匹配最后一个");
|
||||||
|
}
|
||||||
|
|
||||||
|
}
|
||||||
@@ -5,23 +5,51 @@ import java.io.IOException;
|
|||||||
import java.net.ConnectException;
|
import java.net.ConnectException;
|
||||||
import java.net.Socket;
|
import java.net.Socket;
|
||||||
import java.util.HashMap;
|
import java.util.HashMap;
|
||||||
|
import java.util.List;
|
||||||
import java.util.UUID;
|
import java.util.UUID;
|
||||||
import java.util.WeakHashMap;
|
import java.util.WeakHashMap;
|
||||||
|
|
||||||
public class KLALBServer {
|
public class KLALBServer {
|
||||||
WeakHashMap<UUID, IOThreadManager> whm=new WeakHashMap<>();
|
WeakHashMap<UUID, IOThreadManager> whm=new WeakHashMap<>();
|
||||||
public KLALBServer(int port) throws IOException {
|
public KLALBServer(int port, List<ServiceElement> services,List<Tunnel> tunnels) throws IOException {
|
||||||
TCPListener tcpl=new TCPListener(port);
|
TCPListener tcpl=new TCPListener(port);
|
||||||
tcpl.setCon((s)->{
|
tcpl.setCon((s)->{
|
||||||
try {
|
try {
|
||||||
//s.setSoTimeout(10000);
|
//s.setSoTimeout(10000);
|
||||||
DataInputStream din=new DataInputStream(s.getInputStream());
|
TCPConnection tcc=new TCPConnection(null,s);
|
||||||
|
DataInputStream din=tcc.getDin();
|
||||||
int val=din.readShort()&0xffff;
|
int val=din.readShort()&0xffff;
|
||||||
if(val!=59649) {
|
if(val!=59649) {
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
int x=din.read();
|
||||||
|
if(x==0) {
|
||||||
|
synchronized (services) {
|
||||||
|
int counts=services.size();
|
||||||
|
tcc.getDout().writeInt(counts);
|
||||||
|
for (int i = 0; i < counts; i++) {
|
||||||
|
tcc.getDout().writeUTF(services.get(i).toString());
|
||||||
|
}
|
||||||
|
}
|
||||||
|
synchronized (tunnels) {
|
||||||
|
int counts=tunnels.size();
|
||||||
|
tcc.getDout().writeInt(counts);
|
||||||
|
for (int i = 0; i < counts; i++) {
|
||||||
|
tcc.getDout().writeUTF(tunnels.get(i).toString());
|
||||||
|
}
|
||||||
|
}
|
||||||
|
tcc.getDout().flush();
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
String name = din.readUTF();
|
||||||
|
String ip = din.readUTF();
|
||||||
|
int portx=din.readInt();
|
||||||
|
Tunnel tll=new Tunnel(name, ip, portx);
|
||||||
|
tcc.setTunnel(tll);
|
||||||
|
|
||||||
UUID uid=new UUID(din.readLong(),din.readLong());
|
UUID uid=new UUID(din.readLong(),din.readLong());
|
||||||
System.out.println(uid);
|
|
||||||
|
System.out.println("隧道连接:"+tll);
|
||||||
IOThreadManager nx = null;
|
IOThreadManager nx = null;
|
||||||
if(whm.containsKey(uid)) {
|
if(whm.containsKey(uid)) {
|
||||||
nx=whm.get(uid);
|
nx=whm.get(uid);
|
||||||
@@ -33,7 +61,7 @@ public class KLALBServer {
|
|||||||
whm.put(uid, nx);
|
whm.put(uid, nx);
|
||||||
|
|
||||||
}
|
}
|
||||||
nx.handleSocket(new TCPConnection(null,s));
|
nx.handleSocket(tcc);
|
||||||
int n=nx.getTcps().size();
|
int n=nx.getTcps().size();
|
||||||
if(n<=0) {
|
if(n<=0) {
|
||||||
nx.closeLocal();
|
nx.closeLocal();
|
||||||
@@ -55,7 +83,7 @@ public class KLALBServer {
|
|||||||
|
|
||||||
}
|
}
|
||||||
|
|
||||||
public static void main(String[] args) throws IOException {
|
/*public static void main(String[] args) throws IOException {
|
||||||
KLALBServer kc=new KLALBServer(4569);
|
KLALBServer kc=new KLALBServer(4569);
|
||||||
}
|
}*/
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -0,0 +1,59 @@
|
|||||||
|
package org.kne.cloud.network.klalb;
|
||||||
|
|
||||||
|
import java.net.UnknownHostException;
|
||||||
|
import java.util.HashMap;
|
||||||
|
import java.util.Iterator;
|
||||||
|
import java.util.List;
|
||||||
|
import java.util.Map;
|
||||||
|
|
||||||
|
public class ServiceElement {
|
||||||
|
public static final Map<Integer,String> procs=new HashMap<Integer,String>();
|
||||||
|
static {
|
||||||
|
procs.put(768,"RDP");
|
||||||
|
procs.put(5635,"HTTPS");
|
||||||
|
procs.put(59649, "KLALB");
|
||||||
|
procs.put(21331, "SSH");
|
||||||
|
|
||||||
|
procs.put(18245, "HTTP");
|
||||||
|
procs.put(20559, "HTTP");
|
||||||
|
procs.put(18501, "HTTP");
|
||||||
|
procs.put(20565, "HTTP");
|
||||||
|
procs.put(17477, "HTTP");
|
||||||
|
procs.put(17231, "HTTP");
|
||||||
|
procs.put(20304, "HTTP");
|
||||||
|
procs.put(21586, "HTTP");
|
||||||
|
procs.put(20545, "HTTP");
|
||||||
|
}
|
||||||
|
public String proc;
|
||||||
|
public IPPort ipport;
|
||||||
|
public ServiceElement(String ini) throws UnknownHostException {
|
||||||
|
String[]t=ini.split("\\$");
|
||||||
|
if(t.length==1) {
|
||||||
|
proc="";
|
||||||
|
ipport=new IPPort(t[0]);
|
||||||
|
}else {
|
||||||
|
proc=t[0];
|
||||||
|
ipport=new IPPort(t[1]);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
@Override
|
||||||
|
public String toString() {
|
||||||
|
if(proc.isEmpty())
|
||||||
|
return ipport.toString();
|
||||||
|
return proc+"$"+ipport;
|
||||||
|
}
|
||||||
|
public static ServiceElement getbyproc(List<ServiceElement> services, int n) {
|
||||||
|
String proc=procs.get(n);
|
||||||
|
synchronized (services) {
|
||||||
|
|
||||||
|
Iterator<ServiceElement>sei=services.iterator();
|
||||||
|
while (sei.hasNext()) {
|
||||||
|
ServiceElement serviceElement = (ServiceElement) sei.next();
|
||||||
|
if(serviceElement.proc.isEmpty()||serviceElement.proc.equals(proc))
|
||||||
|
return serviceElement;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
return null;
|
||||||
|
}
|
||||||
|
|
||||||
|
}
|
||||||
@@ -74,6 +74,10 @@ public class TCPConnection {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
public void setTunnel(Tunnel tunnel) {
|
||||||
|
this.tunnel = tunnel;
|
||||||
|
}
|
||||||
|
|
||||||
public TCPConnection(Tunnel t) throws UnknownHostException, IOException {
|
public TCPConnection(Tunnel t) throws UnknownHostException, IOException {
|
||||||
this(t, t.connectClientSocket());
|
this(t, t.connectClientSocket());
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -7,17 +7,21 @@ import java.io.DataOutputStream;
|
|||||||
import java.io.IOException;
|
import java.io.IOException;
|
||||||
import java.net.Socket;
|
import java.net.Socket;
|
||||||
import java.net.UnknownHostException;
|
import java.net.UnknownHostException;
|
||||||
|
import java.util.Objects;
|
||||||
|
|
||||||
public class Tunnel {
|
public class Tunnel {
|
||||||
private String name;
|
private String name;
|
||||||
private String ip;
|
private IPPort ipport;
|
||||||
private int port;
|
|
||||||
|
|
||||||
public Tunnel(String name, String ip, int port) {
|
public Tunnel(String name, String ip, int port) throws UnknownHostException {
|
||||||
super();
|
super();
|
||||||
this.name = name;
|
this.name = name;
|
||||||
this.ip = ip;
|
this.ipport=new IPPort(ip,port);
|
||||||
this.port = port;
|
}
|
||||||
|
public Tunnel(String s) throws UnknownHostException {
|
||||||
|
String[]t=s.split("\\$");
|
||||||
|
name=t[0];
|
||||||
|
ipport=new IPPort(t[1]);
|
||||||
}
|
}
|
||||||
public String getName() {
|
public String getName() {
|
||||||
return name;
|
return name;
|
||||||
@@ -26,24 +30,34 @@ public class Tunnel {
|
|||||||
this.name = name;
|
this.name = name;
|
||||||
}
|
}
|
||||||
public String getIp() {
|
public String getIp() {
|
||||||
return ip;
|
return ipport.getIp().getHostAddress();
|
||||||
}
|
|
||||||
public void setIp(String ip) {
|
|
||||||
this.ip = ip;
|
|
||||||
}
|
}
|
||||||
public int getPort() {
|
public int getPort() {
|
||||||
return port;
|
return ipport.getPort();
|
||||||
}
|
|
||||||
public void setPort(int port) {
|
|
||||||
this.port = port;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
public String toString() {
|
public String toString() {
|
||||||
return name+"$"+ip+"$"+port;
|
return name+"$"+ipport;
|
||||||
}
|
}
|
||||||
public Socket connectClientSocket() throws UnknownHostException, IOException {
|
public Socket connectClientSocket() throws UnknownHostException, IOException {
|
||||||
return new Socket(ip, port);
|
return new Socket(ipport.getIp(), ipport.getPort());
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public int hashCode() {
|
||||||
|
return Objects.hash(ipport, name);
|
||||||
|
}
|
||||||
|
@Override
|
||||||
|
public boolean equals(Object obj) {
|
||||||
|
if (this == obj)
|
||||||
|
return true;
|
||||||
|
if (obj == null)
|
||||||
|
return false;
|
||||||
|
if (getClass() != obj.getClass())
|
||||||
|
return false;
|
||||||
|
Tunnel other = (Tunnel) obj;
|
||||||
|
return Objects.equals(ipport, other.ipport) && Objects.equals(name, other.name);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
|
|||||||
Reference in New Issue
Block a user