Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Pitch black mitigation test #736

Merged
merged 5 commits into from
Oct 17, 2021
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
44 changes: 33 additions & 11 deletions src/freenet/node/LocationManager.java
Original file line number Diff line number Diff line change
Expand Up @@ -17,6 +17,7 @@
import java.nio.file.Files;
import java.security.MessageDigest;
import java.text.DateFormat;
import java.time.Clock;
import java.time.Duration;
import java.time.LocalDateTime;
import java.time.format.DateTimeFormatter;
Expand Down Expand Up @@ -69,6 +70,8 @@
public class LocationManager implements ByteCounter {

public static final String FOIL_PITCH_BLACK_ATTACK_PREFIX = "mitigate-pitch-black-attack-";
public static long PITCH_BLACK_MITIGATION_FREQUENCY_ONE_DAY = DAYS.toMillis(1);
public static long PITCH_BLACK_MITIGATION_STARTUP_DELAY = MINUTES.toMillis(10);

public class MyCallback extends SendMessageOnErrorCallback {

Expand Down Expand Up @@ -117,6 +120,7 @@ public void acknowledged() {
final SwapRequestSender sender;
final Node node;
long timeLastSuccessfullySwapped;
public static Clock clockForTesting = Clock.systemDefaultZone();

public LocationManager(RandomSource r, Node node) {
loc = r.nextDouble();
Expand Down Expand Up @@ -189,18 +193,18 @@ public void run() {

@Override
public void run() {
node.ticker.queueTimedJob(this, DAYS.toMillis(1));
node.ticker.queueTimedJob(this, PITCH_BLACK_MITIGATION_FREQUENCY_ONE_DAY);
if (swappingDisabled()) {
return;
}
LocalDateTime now = LocalDateTime.now();
LocalDateTime now = LocalDateTime.now(clockForTesting);
String isoDateStringToday = DateTimeFormatter.ISO_DATE
.format(now);
String isoDateStringYesterday = DateTimeFormatter.ISO_DATE
.format(now.minus(Duration.ofDays(1)));
.format(now.minusDays(1));
File[] previousInsertFromToday = node.userDir().dir()
.listFiles((file, name) -> name.startsWith(FOIL_PITCH_BLACK_ATTACK_PREFIX
+ isoDateStringToday));
.listFiles((file, name) -> name.startsWith(getPitchBlackPrefix(
isoDateStringToday)));
HighLevelSimpleClient highLevelSimpleClient = node.clientCore.makeClient(
RequestStarter.INTERACTIVE_PRIORITY_CLASS,
true,
Expand All @@ -211,13 +215,12 @@ public void run() {
byte[] randomContentForKSK = new byte[20];
node.secureRandom.nextBytes(randomContentForKSK);
String randomPart = Base64.encode(randomContentForKSK);
String nameForInsert =
FOIL_PITCH_BLACK_ATTACK_PREFIX + isoDateStringToday + "-" + randomPart;
String nameForInsert = getPitchBlackPrefix(isoDateStringToday + "-" + randomPart);
tryToInsertPitchBlackCheck(highLevelSimpleClient, nameForInsert);
}

File[] foilPitchBlackStatusFiles = node.userDir().dir()
.listFiles((file, name) -> name.startsWith(FOIL_PITCH_BLACK_ATTACK_PREFIX));
.listFiles((file, name) -> name.startsWith(getPitchBlackPrefix("")));
if (foilPitchBlackStatusFiles != null) {
File[] successfulInsertFromYesterday = Arrays.stream(foilPitchBlackStatusFiles)
.filter(file -> file.getName().contains(isoDateStringYesterday))
Expand All @@ -243,7 +246,11 @@ public void run() {
}
}
}
}, MINUTES.toMillis(10));
}, PITCH_BLACK_MITIGATION_STARTUP_DELAY);
}

public String getPitchBlackPrefix(String middleSubstring) {
return FOIL_PITCH_BLACK_ATTACK_PREFIX + middleSubstring;
}

private void tryToRequestPitchBlackCheckFromYesterday(
Expand Down Expand Up @@ -271,10 +278,14 @@ private void tryToRequestPitchBlackCheckFromYesterday(
try {
sskFetchResult = highLevelSimpleClient.fetch(insertFromYesterday.getURI());
if (!Arrays.equals(expectedContent, sskFetchResult.asByteArray())) {
// if we received false data, this is definitely an attack: move there to provide a good node in the location
switchLocationToDefendAgainstPitchBlackAttack(insertFromYesterday);
}
} catch (FetchException e) {
if (isRequestExceptionBecauseUriIsNotAvailable(e)) {
if (isRequestExceptionBecauseUriIsNotAvailable(e) && node.fastWeakRandom.nextBoolean()) {
// switch to the attacked location with only 50% probability,
// because it could be caused by the defensive swap of another node
// which made its current content inaccessible.
switchLocationToDefendAgainstPitchBlackAttack(insertFromYesterday);
}
return;
Expand Down Expand Up @@ -303,7 +314,10 @@ private void tryToRequestPitchBlackCheckFromYesterday(
try {
highLevelSimpleClient.fetch(calculatedChkUri);
} catch (FetchException e) {
if (isRequestExceptionBecauseUriIsNotAvailable(e)) {
if (isRequestExceptionBecauseUriIsNotAvailable(e) && node.fastWeakRandom.nextBoolean()) {
// switch to the attacked location with only 50% probability,
// because it could be caused by the defensive swap of another node
// which made its current content inaccessible.
try {
switchLocationToDefendAgainstPitchBlackAttack(new ClientCHK(calculatedChkUri));
} catch (MalformedURLException exception) {
Expand Down Expand Up @@ -1592,6 +1606,14 @@ public Object[] getKnownLocations(long timestamp) {
}
}

public static void setClockForTesting(Clock clock) {
clockForTesting = clock;
}

public static Clock getClockForTesting() {
return clockForTesting;
}

public static double[] extractLocs(PeerNode[] peers, boolean indicateBackoff) {
double[] locs = new double[peers.length];
for(int i=0;i<peers.length;i++) {
Expand Down
Loading