aboutsummaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorTrumeet <17158086+Trumeet@users.noreply.github.com>2021-01-16 16:04:50 -0800
committerTrumeet <17158086+Trumeet@users.noreply.github.com>2021-01-16 16:04:50 -0800
commit8c71583e0633714c01def657228af9b0d47c68df (patch)
tree480489cdd737af1c4cdc7aee4931063640b5c18f
parent5dd680f20f286f243427c39d432e4cc67e194445 (diff)
downloaddn42peering-8c71583e0633714c01def657228af9b0d47c68df.tar
dn42peering-8c71583e0633714c01def657228af9b0d47c68df.tar.gz
dn42peering-8c71583e0633714c01def657228af9b0d47c68df.tar.bz2
dn42peering-8c71583e0633714c01def657228af9b0d47c68df.zip
fix(central/agent/rpc): fix non-link local IPv6 support
-rw-r--r--agent/src/main/java/moe/yuuta/dn42peering/agent/grpc/AgentServiceImpl.java4
-rw-r--r--agent/src/main/java/moe/yuuta/dn42peering/agent/provision/IProvisionService.java4
-rw-r--r--agent/src/main/java/moe/yuuta/dn42peering/agent/provision/ProvisionServiceImpl.java20
-rw-r--r--central/src/main/java/moe/yuuta/dn42peering/manage/ManageHandler.java28
-rw-r--r--central/src/main/java/moe/yuuta/dn42peering/node/Node.java15
-rw-r--r--central/src/main/java/moe/yuuta/dn42peering/node/NodeServiceImpl.java4
-rw-r--r--docs/central/sql/0-init.sql1
-rw-r--r--docs/central/sql/1.sql1
-rw-r--r--rpc-common/src/main/proto/agent.proto1
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