diff options
author | Trumeet <17158086+Trumeet@users.noreply.github.com> | 2021-01-16 16:04:50 -0800 |
---|---|---|
committer | Trumeet <17158086+Trumeet@users.noreply.github.com> | 2021-01-16 16:04:50 -0800 |
commit | 8c71583e0633714c01def657228af9b0d47c68df (patch) | |
tree | 480489cdd737af1c4cdc7aee4931063640b5c18f | |
parent | 5dd680f20f286f243427c39d432e4cc67e194445 (diff) | |
download | dn42peering-8c71583e0633714c01def657228af9b0d47c68df.tar dn42peering-8c71583e0633714c01def657228af9b0d47c68df.tar.gz dn42peering-8c71583e0633714c01def657228af9b0d47c68df.tar.bz2 dn42peering-8c71583e0633714c01def657228af9b0d47c68df.zip |
fix(central/agent/rpc): fix non-link local IPv6 support
9 files changed, 70 insertions, 8 deletions
diff --git a/agent/src/main/java/moe/yuuta/dn42peering/agent/grpc/AgentServiceImpl.java b/agent/src/main/java/moe/yuuta/dn42peering/agent/grpc/AgentServiceImpl.java index c1f3971..d9312c1 100644 --- a/agent/src/main/java/moe/yuuta/dn42peering/agent/grpc/AgentServiceImpl.java +++ b/agent/src/main/java/moe/yuuta/dn42peering/agent/grpc/AgentServiceImpl.java @@ -25,6 +25,7 @@ class AgentServiceImpl extends VertxAgentGrpc.AgentVertxImplBase { return Future.<Void>future(f -> provisionService.provisionBGP( request.getNode().getIpv4(), request.getNode().getIpv6(), + request.getNode().getIpv6NonLL(), (int)request.getId(), request.getIpv4(), request.getIpv6().isEmpty() ? null : request.getIpv6(), @@ -42,6 +43,7 @@ class AgentServiceImpl extends VertxAgentGrpc.AgentVertxImplBase { return Future.<Void>future(f -> provisionService.reloadBGP( request.getNode().getIpv4(), request.getNode().getIpv6(), + request.getNode().getIpv6NonLL(), (int)request.getId(), request.getIpv4(), request.getIpv6().isEmpty() ? null : request.getIpv6(), @@ -67,6 +69,7 @@ class AgentServiceImpl extends VertxAgentGrpc.AgentVertxImplBase { return Future.<String>future(f -> provisionService.provisionVPNWireGuard( request.getNode().getIpv4(), request.getNode().getIpv6(), + request.getNode().getIpv6NonLL(), (int)request.getId(), request.getListenPort(), request.getEndpoint().isEmpty() ? "" : request.getEndpoint(), @@ -87,6 +90,7 @@ class AgentServiceImpl extends VertxAgentGrpc.AgentVertxImplBase { return Future.<String>future(f -> provisionService.reloadVPNWireGuard( request.getNode().getIpv4(), request.getNode().getIpv6(), + request.getNode().getIpv6NonLL(), (int)request.getId(), request.getListenPort(), request.getEndpoint().isEmpty() ? "" : request.getEndpoint(), diff --git a/agent/src/main/java/moe/yuuta/dn42peering/agent/provision/IProvisionService.java b/agent/src/main/java/moe/yuuta/dn42peering/agent/provision/IProvisionService.java index c0a9bad..c3d416c 100644 --- a/agent/src/main/java/moe/yuuta/dn42peering/agent/provision/IProvisionService.java +++ b/agent/src/main/java/moe/yuuta/dn42peering/agent/provision/IProvisionService.java @@ -22,6 +22,7 @@ public interface IProvisionService { @Nonnull IProvisionService provisionBGP(@Nonnull String localIP4, @Nonnull String localIP6, + @Nonnull String localIP6NonLL, int id, @Nonnull String ipv4, @Nullable String ipv6, @@ -34,6 +35,7 @@ public interface IProvisionService { @Nonnull IProvisionService reloadBGP(@Nonnull String localIP4, @Nonnull String localIP6, + @Nonnull String localIP6NonLL, int id, @Nonnull String ipv4, @Nullable String ipv6, @@ -50,6 +52,7 @@ public interface IProvisionService { @Nonnull IProvisionService provisionVPNWireGuard(@Nonnull String localIP4, @Nonnull String localIP6, + @Nonnull String localIP6NonLL, int id, int listenPort, @Nullable String endpointWithPort, @@ -64,6 +67,7 @@ public interface IProvisionService { @Nonnull IProvisionService reloadVPNWireGuard(@Nonnull String localIP4, @Nonnull String localIP6, + @Nonnull String localIP6NonLL, int id, int listenPort, @Nullable String endpointWithPort, diff --git a/agent/src/main/java/moe/yuuta/dn42peering/agent/provision/ProvisionServiceImpl.java b/agent/src/main/java/moe/yuuta/dn42peering/agent/provision/ProvisionServiceImpl.java index c72e5b3..733d111 100644 --- a/agent/src/main/java/moe/yuuta/dn42peering/agent/provision/ProvisionServiceImpl.java +++ b/agent/src/main/java/moe/yuuta/dn42peering/agent/provision/ProvisionServiceImpl.java @@ -56,6 +56,7 @@ class ProvisionServiceImpl implements IProvisionService { @Nonnull private Future<Void> writeBGPConfig(@Nonnull String localIP4, @Nonnull String localIP6, + @Nonnull String localIP6NonLL, int id, @Nonnull String ipv4, @Nullable String ipv6, @@ -96,6 +97,7 @@ class ProvisionServiceImpl implements IProvisionService { private Future<Void> writeWGConfig(boolean create, @Nonnull String localIP4, @Nonnull String localIP6, + @Nonnull String localIP6NonLL, @Nonnull String dev, int listenPort, @Nullable String endpointWithPort, @@ -118,12 +120,16 @@ class ProvisionServiceImpl implements IProvisionService { params.put("peer_ipv6", peerIPv6); if (peerIPv6 != null) { try { - params.put("peer_ipv6_ll", Inet6Address.getByName(peerIPv6).isLinkLocalAddress()); + final boolean ll = Inet6Address.getByName(peerIPv6).isLinkLocalAddress(); + params.put("peer_ipv6_ll", ll); + if(ll) + params.put("self_ipv6", localIP6); + else + params.put("self_ipv6", localIP6NonLL); } catch (IOException e) { return Future.failedFuture(e); } } - params.put("self_ipv6", localIP6); params.put("preshared_key", selfPresharedSecret); params.put("endpoint", endpointWithPort); params.put("peer_pub_key", peerPubKey); @@ -153,6 +159,7 @@ class ProvisionServiceImpl implements IProvisionService { @Override public IProvisionService provisionBGP(@Nonnull String localIP4, @Nonnull String localIP6, + @Nonnull String localIP6NonLL, int id, @Nonnull String ipv4, @Nullable String ipv6, @@ -162,7 +169,7 @@ class ProvisionServiceImpl implements IProvisionService { @Nonnull Handler<AsyncResult<Void>> handler) { vertx.sharedData().getLocalLockWithTimeout(getLockNameForBGP(id), 1000) .compose(lock -> - writeBGPConfig(localIP4, localIP6, id, ipv4, ipv6, device, mpbgp, asn, true) + writeBGPConfig(localIP4, localIP6, localIP6NonLL, id, ipv4, ipv6, device, mpbgp, asn, true) .compose(_v -> AsyncShell.execSucc(vertx, "birdc", "configure")) .onComplete(ar -> lock.release()) ) @@ -174,6 +181,7 @@ class ProvisionServiceImpl implements IProvisionService { @Override public IProvisionService reloadBGP(@Nonnull String localIP4, @Nonnull String localIP6, + @Nonnull String localIP6NonLL, int id, @Nonnull String ipv4, @Nullable String ipv6, @@ -183,7 +191,7 @@ class ProvisionServiceImpl implements IProvisionService { @Nonnull Handler<AsyncResult<Void>> handler) { vertx.sharedData().getLocalLockWithTimeout(getLockNameForBGP(id), 1000) .compose(lock -> - writeBGPConfig(localIP4, localIP6, id, ipv4, ipv6, device, mpbgp, asn, false) + writeBGPConfig(localIP4, localIP6, localIP6NonLL, id, ipv4, ipv6, device, mpbgp, asn, false) .compose(_v -> AsyncShell.execSucc(vertx, "birdc", "configure")) .onComplete(ar -> lock.release()) ) @@ -208,6 +216,7 @@ class ProvisionServiceImpl implements IProvisionService { @Override public IProvisionService provisionVPNWireGuard(@Nonnull String localIP4, @Nonnull String localIP6, + @Nonnull String localIP6NonLL, int id, int listenPort, @Nullable String endpointWithPort, @@ -222,6 +231,7 @@ class ProvisionServiceImpl implements IProvisionService { .compose(lock -> writeWGConfig(true, localIP4, localIP6, + localIP6NonLL, generateWireGuardDevName(id), listenPort, endpointWithPort, @@ -242,6 +252,7 @@ class ProvisionServiceImpl implements IProvisionService { @Override public IProvisionService reloadVPNWireGuard(@Nonnull String localIP4, @Nonnull String localIP6, + @Nonnull String localIP6NonLL, int id, int listenPort, @Nullable String endpointWithPort, @@ -256,6 +267,7 @@ class ProvisionServiceImpl implements IProvisionService { .compose(lock -> writeWGConfig(false, localIP4, localIP6, + localIP6NonLL, generateWireGuardDevName(id), listenPort, endpointWithPort, diff --git a/central/src/main/java/moe/yuuta/dn42peering/manage/ManageHandler.java b/central/src/main/java/moe/yuuta/dn42peering/manage/ManageHandler.java index d00ccfa..0c5b6b1 100644 --- a/central/src/main/java/moe/yuuta/dn42peering/manage/ManageHandler.java +++ b/central/src/main/java/moe/yuuta/dn42peering/manage/ManageHandler.java @@ -898,7 +898,15 @@ public class ManageHandler implements ISubRouter { root.put("endpoint", "This node is currently down! Edit the peer to choose another one."); } else { root.put("ipv4", node.getDn42Ip4()); - root.put("ipv6", node.getDn42Ip6()); + try { + if(peer.isIPv6LinkLocal()) { + root.put("ipv6", node.getDn42Ip6()); + } else { + root.put("ipv6", node.getDn42Ip6NonLL()); + } + } catch (IOException e) { + return Future.failedFuture(e); + } root.put("asn", node.getAsn()); root.put("endpoint", node.getPublicIp()); } @@ -915,8 +923,24 @@ public class ManageHandler implements ISubRouter { // Check if we can reload on the fly. // Otherwise, we can only deprovision and provision. // This will cause unnecessary wastes. - final boolean canReload = inPeer.getType() == existingPeer.getType() && + boolean canReload = inPeer.getType() == existingPeer.getType() && inPeer.getNode() == existingPeer.getNode(); + // wg-quick does not support switching local IP addresses. + // However, switch between link local addresses and real IPv6 addresses require the change of + // local v6 address. Therefore, in such cases, we have to do a full re-provision. + if(canReload && // Only check if no other factors prevent us from reloading. + inPeer.getType() == Peer.VPNType.WIREGUARD && + existingPeer.getType() == Peer.VPNType.WIREGUARD) { + try { + final boolean existingLL = existingPeer.isIPv6LinkLocal(); + final boolean newLL = inPeer.isIPv6LinkLocal(); + if(existingLL != newLL) { + canReload = false; + } + } catch (IOException e) { + return Future.failedFuture(e); + } + } Future<Void> future; if (canReload) { future = Future.<Node>future(f -> nodeService.getNode(inPeer.getNode(), f)) diff --git a/central/src/main/java/moe/yuuta/dn42peering/node/Node.java b/central/src/main/java/moe/yuuta/dn42peering/node/Node.java index 31c0be2..5135947 100644 --- a/central/src/main/java/moe/yuuta/dn42peering/node/Node.java +++ b/central/src/main/java/moe/yuuta/dn42peering/node/Node.java @@ -37,6 +37,10 @@ public class Node { @TemplateParameter(name = "dn42_ip6") private String dn42Ip6; + @Column(name = "dn42_ip6_nonll") + @TemplateParameter(name = "dn42_ip6_nonll") + private String dn42Ip6NonLL; + @Column(name = "asn") @TemplateParameter(name = "asn") private String asn; @@ -68,6 +72,7 @@ public class Node { this.publicIp = object.getString("public_ip"); this.dn42Ip4 = object.getString("dn42_ip4"); this.dn42Ip6 = object.getString("dn42_ip6"); + this.dn42Ip6NonLL = object.getString("dn42_ip6_nonll"); this.asn = object.getString("asn"); this.internalIp = object.getString("internal_ip"); this.internalPort = object.getInteger("internal_port"); @@ -83,6 +88,7 @@ public class Node { .put("public_ip", publicIp) .put("dn42_ip4", dn42Ip4) .put("dn42_ip6", dn42Ip6) + .put("dn42_ip6_nonll", dn42Ip6NonLL) .put("asn", asn) .put("internal_ip", internalIp) .put("internal_port", internalPort) @@ -106,6 +112,7 @@ public class Node { .setId(id) .setIpv4(dn42Ip4) .setIpv6(dn42Ip6) + .setIpv6NonLL(dn42Ip6NonLL) .build(); } @@ -151,6 +158,14 @@ public class Node { this.dn42Ip6 = dn42Ip6; } + public String getDn42Ip6NonLL() { + return dn42Ip6NonLL; + } + + public void setDn42Ip6NonLL(String dn42Ip6NonLL) { + this.dn42Ip6NonLL = dn42Ip6NonLL; + } + public String getAsn() { return asn; } diff --git a/central/src/main/java/moe/yuuta/dn42peering/node/NodeServiceImpl.java b/central/src/main/java/moe/yuuta/dn42peering/node/NodeServiceImpl.java index 37d3036..cdcabf3 100644 --- a/central/src/main/java/moe/yuuta/dn42peering/node/NodeServiceImpl.java +++ b/central/src/main/java/moe/yuuta/dn42peering/node/NodeServiceImpl.java @@ -25,7 +25,7 @@ class NodeServiceImpl implements INodeService { @Override public INodeService listNodes(@Nonnull Handler<AsyncResult<List<Node>>> handler) { SqlTemplate - .forQuery(pool, "SELECT id, public_ip, dn42_ip4, dn42_ip6, asn, " + + .forQuery(pool, "SELECT id, public_ip, dn42_ip4, dn42_ip6, dn42_ip6_nonll, asn, " + "internal_ip, internal_port, name, notice, vpn_type_wg " + "FROM node") .mapTo(NodeRowMapper.INSTANCE) @@ -45,7 +45,7 @@ class NodeServiceImpl implements INodeService { public INodeService getNode(int id, @Nonnull Handler<AsyncResult<Node>> handler) { SqlTemplate .forQuery(pool, "SELECT id, public_ip, asn, " + - "dn42_ip4, dn42_ip6, " + + "dn42_ip4, dn42_ip6, dn42_ip6_nonll, " + "internal_ip, internal_port, name, notice, vpn_type_wg " + "FROM node " + "WHERE id = #{id}") diff --git a/docs/central/sql/0-init.sql b/docs/central/sql/0-init.sql index 17ca074..9717efb 100644 --- a/docs/central/sql/0-init.sql +++ b/docs/central/sql/0-init.sql @@ -13,6 +13,7 @@ CREATE TABLE `node` ( `public_ip` varchar(21) COLLATE utf8mb4_unicode_ci NOT NULL, `dn42_ip4` varchar(21) COLLATE utf8mb4_unicode_ci NOT NULL, `dn42_ip6` varchar(39) COLLATE utf8mb4_unicode_ci NOT NULL, + `dn42_ip6_nonll` varchar(39) COLLATE utf8mb4_unicode_ci DEFAULT NULL, `asn` char(20) COLLATE utf8mb4_unicode_ci NOT NULL, `internal_ip` varchar(15) COLLATE utf8mb4_unicode_ci NOT NULL, `internal_port` smallint(5) UNSIGNED NOT NULL, diff --git a/docs/central/sql/1.sql b/docs/central/sql/1.sql new file mode 100644 index 0000000..f4b9aff --- /dev/null +++ b/docs/central/sql/1.sql @@ -0,0 +1 @@ +ALTER TABLE `node` ADD `dn42_ip6_nonll` VARCHAR(39) NULL AFTER `dn42_ip6`;
\ No newline at end of file diff --git a/rpc-common/src/main/proto/agent.proto b/rpc-common/src/main/proto/agent.proto index 126fbd2..585213e 100644 --- a/rpc-common/src/main/proto/agent.proto +++ b/rpc-common/src/main/proto/agent.proto @@ -48,4 +48,5 @@ message Node { uint64 id = 1; string ipv4 = 2; string ipv6 = 3; + string ipv6NonLL = 4; }
\ No newline at end of file |