diff --git a/src/MultiAddressBlackList.cs b/src/MultiAddressBlackList.cs
new file mode 100644
index 0000000..782ddab
--- /dev/null
+++ b/src/MultiAddressBlackList.cs
@@ -0,0 +1,39 @@
+using Ipfs;
+using System;
+using System.Collections.Concurrent;
+using System.Collections.Generic;
+using System.Linq;
+using System.Text;
+using System.Threading;
+using System.Threading.Tasks;
+
+namespace PeerTalk
+{
+ ///
+ /// A sequence of filters that are not approved.
+ ///
+ ///
+ /// Only targets that do match a filter will pass.
+ ///
+ public class MultiAddressBlackList : ConcurrentBag, IPolicy
+ {
+ ///
+ public Task IsAllowedAsync(MultiAddress target, CancellationToken cancel = default(CancellationToken))
+ {
+ return Task.FromResult(!this.Any(filter => Matches(filter, target)));
+ }
+
+ bool Matches(MultiAddress filter, MultiAddress target)
+ {
+ return filter
+ .Protocols
+ .All(fp => target.Protocols.Any(tp => tp.Code == fp.Code && tp.Value == fp.Value));
+ }
+
+ ///
+ public async Task IsNotAllowedAsync(MultiAddress target, CancellationToken cancel = default(CancellationToken))
+ {
+ return !await IsAllowedAsync(target, cancel).ConfigureAwait(false);
+ }
+ }
+}
diff --git a/src/MultiAddressWhiteList.cs b/src/MultiAddressWhiteList.cs
new file mode 100644
index 0000000..e37c61f
--- /dev/null
+++ b/src/MultiAddressWhiteList.cs
@@ -0,0 +1,43 @@
+using Ipfs;
+using System;
+using System.Collections.Concurrent;
+using System.Collections.Generic;
+using System.Linq;
+using System.Text;
+using System.Threading;
+using System.Threading.Tasks;
+
+namespace PeerTalk
+{
+ ///
+ /// A sequence of filters that are approved.
+ ///
+ ///
+ /// Only targets that are a subset of any filters will pass. If no filters are defined, then anything
+ /// passes.
+ ///
+ public class MultiAddressWhiteList : ConcurrentBag, IPolicy
+ {
+ ///
+ public Task IsAllowedAsync(MultiAddress target, CancellationToken cancel = default(CancellationToken))
+ {
+ if (IsEmpty)
+ return Task.FromResult(true);
+
+ return Task.FromResult(this.Any(filter => Matches(filter, target)));
+ }
+
+ bool Matches(MultiAddress filter, MultiAddress target)
+ {
+ return filter
+ .Protocols
+ .All(fp => target.Protocols.Any(tp => tp.Code == fp.Code && tp.Value == fp.Value));
+ }
+
+ ///
+ public async Task IsNotAllowedAsync(MultiAddress target, CancellationToken cancel = default(CancellationToken))
+ {
+ return !await IsAllowedAsync(target, cancel).ConfigureAwait(false);
+ }
+ }
+}
diff --git a/src/Swarm.cs b/src/Swarm.cs
index 370ec3b..618478f 100644
--- a/src/Swarm.cs
+++ b/src/Swarm.cs
@@ -363,12 +363,12 @@ public bool HasPendingConnection(Peer peer)
///
/// The addresses that cannot be used.
///
- public BlackList BlackList { get; set; } = new BlackList();
+ public MultiAddressBlackList BlackList { get; set; } = new MultiAddressBlackList();
///
/// The addresses that can be used.
///
- public WhiteList WhiteList { get; set; } = new WhiteList();
+ public MultiAddressWhiteList WhiteList { get; set; } = new MultiAddressWhiteList();
///
public Task StartAsync()
@@ -434,8 +434,8 @@ public async Task StopAsync()
listeners.Clear();
pendingConnections.Clear();
pendingRemoteConnections.Clear();
- BlackList = new BlackList();
- WhiteList = new WhiteList();
+ BlackList = new MultiAddressBlackList();
+ WhiteList = new MultiAddressWhiteList();
log.Debug($"Stopped {LocalPeer}");
}
diff --git a/test/MultiAdressBlackListTest.cs b/test/MultiAdressBlackListTest.cs
new file mode 100644
index 0000000..165677f
--- /dev/null
+++ b/test/MultiAdressBlackListTest.cs
@@ -0,0 +1,65 @@
+using Ipfs;
+using Microsoft.VisualStudio.TestTools.UnitTesting;
+using System;
+using System.Linq;
+using System.Threading;
+using System.Threading.Tasks;
+
+namespace PeerTalk
+{
+ [TestClass]
+ public class MultiAddressBlackListTest
+ {
+ MultiAddress a = "/ipfs/QmSoLMeWqB7YGVLJN3pNLQpmmEk35v6wYtsMGLzSr5QBU3";
+ MultiAddress a1 = "/ip4/127.0.0.1/ipfs/QmSoLMeWqB7YGVLJN3pNLQpmmEk35v6wYtsMGLzSr5QBU3";
+ MultiAddress b = "/p2p/QmSoLMeWqB7YGVLJN3pNLQpmmEk35v6wYtsMGLzSr5QBU3";
+ MultiAddress c = "/ipfs/QmSoLV4Bbm51jM9C4gDYZQ9Cy3U6aXMJDAbzgu2fzaDs64";
+ MultiAddress d = "/p2p/QmSoLV4Bbm51jM9C4gDYZQ9Cy3U6aXMJDAbzgu2fzaDs64";
+
+ [TestMethod]
+ public async Task Allowed()
+ {
+ var policy = new MultiAddressBlackList();
+ policy.Add(a);
+ policy.Add(b);
+ Assert.IsFalse(await policy.IsAllowedAsync(a));
+ Assert.IsFalse(await policy.IsAllowedAsync(a1));
+ Assert.IsFalse(await policy.IsAllowedAsync(b));
+ Assert.IsTrue(await policy.IsAllowedAsync(c));
+ Assert.IsTrue(await policy.IsAllowedAsync(d));
+ }
+
+ [TestMethod]
+ public async Task Allowed_Alias()
+ {
+ var policy = new MultiAddressBlackList();
+ policy.Add(a);
+ Assert.IsFalse(await policy.IsAllowedAsync(a));
+ Assert.IsFalse(await policy.IsAllowedAsync(a1));
+ Assert.IsFalse(await policy.IsAllowedAsync(b));
+ Assert.IsTrue(await policy.IsAllowedAsync(c));
+ Assert.IsTrue(await policy.IsAllowedAsync(d));
+ }
+
+ [TestMethod]
+ public async Task NotAllowed()
+ {
+ var policy = new MultiAddressBlackList();
+ policy.Add(a);
+ policy.Add(b);
+ Assert.IsTrue(await policy.IsNotAllowedAsync(a));
+ Assert.IsTrue(await policy.IsNotAllowedAsync(a1));
+ Assert.IsTrue(await policy.IsNotAllowedAsync(b));
+ Assert.IsFalse(await policy.IsNotAllowedAsync(c));
+ Assert.IsFalse(await policy.IsNotAllowedAsync(d));
+ }
+
+ [TestMethod]
+ public async Task Empty()
+ {
+ var policy = new MultiAddressBlackList();
+ Assert.IsTrue(await policy.IsAllowedAsync(a));
+ Assert.IsFalse(await policy.IsNotAllowedAsync(a));
+ }
+ }
+}
diff --git a/test/MultiAdressWhiteListTest.cs b/test/MultiAdressWhiteListTest.cs
new file mode 100644
index 0000000..e832617
--- /dev/null
+++ b/test/MultiAdressWhiteListTest.cs
@@ -0,0 +1,65 @@
+using Ipfs;
+using Microsoft.VisualStudio.TestTools.UnitTesting;
+using System;
+using System.Linq;
+using System.Threading;
+using System.Threading.Tasks;
+
+namespace PeerTalk
+{
+ [TestClass]
+ public class MultiAddressWhiteListTest
+ {
+ MultiAddress a = "/ipfs/QmSoLMeWqB7YGVLJN3pNLQpmmEk35v6wYtsMGLzSr5QBU3";
+ MultiAddress a1 = "/ip4/127.0.0.1/ipfs/QmSoLMeWqB7YGVLJN3pNLQpmmEk35v6wYtsMGLzSr5QBU3";
+ MultiAddress b = "/p2p/QmSoLMeWqB7YGVLJN3pNLQpmmEk35v6wYtsMGLzSr5QBU3";
+ MultiAddress c = "/ipfs/QmSoLV4Bbm51jM9C4gDYZQ9Cy3U6aXMJDAbzgu2fzaDs64";
+ MultiAddress d = "/p2p/QmSoLV4Bbm51jM9C4gDYZQ9Cy3U6aXMJDAbzgu2fzaDs64";
+
+ [TestMethod]
+ public async Task Allowed()
+ {
+ var policy = new MultiAddressWhiteList();
+ policy.Add(a);
+ policy.Add(b);
+ Assert.IsTrue(await policy.IsAllowedAsync(a));
+ Assert.IsTrue(await policy.IsAllowedAsync(a1));
+ Assert.IsTrue(await policy.IsAllowedAsync(b));
+ Assert.IsFalse(await policy.IsAllowedAsync(c));
+ Assert.IsFalse(await policy.IsAllowedAsync(d));
+ }
+
+ [TestMethod]
+ public async Task Allowed_Alias()
+ {
+ var policy = new MultiAddressWhiteList();
+ policy.Add(a);
+ Assert.IsTrue(await policy.IsAllowedAsync(a));
+ Assert.IsTrue(await policy.IsAllowedAsync(a1));
+ Assert.IsTrue(await policy.IsAllowedAsync(b));
+ Assert.IsFalse(await policy.IsAllowedAsync(c));
+ Assert.IsFalse(await policy.IsAllowedAsync(d));
+ }
+
+ [TestMethod]
+ public async Task NotAllowed()
+ {
+ var policy = new MultiAddressWhiteList();
+ policy.Add(a);
+ policy.Add(b);
+ Assert.IsFalse(await policy.IsNotAllowedAsync(a));
+ Assert.IsFalse(await policy.IsNotAllowedAsync(a1));
+ Assert.IsFalse(await policy.IsNotAllowedAsync(b));
+ Assert.IsTrue(await policy.IsNotAllowedAsync(c));
+ Assert.IsTrue(await policy.IsNotAllowedAsync(d));
+ }
+
+ [TestMethod]
+ public async Task Empty()
+ {
+ var policy = new MultiAddressWhiteList();
+ Assert.IsTrue(await policy.IsAllowedAsync(a));
+ Assert.IsFalse(await policy.IsNotAllowedAsync(a));
+ }
+ }
+}