Commit 0f79ef2d authored by Hiro's avatar Hiro 🏄 Committed by Iain Learmonth
Browse files

Add logic to report overload descriptor line information on relay search.

relay-search#40005

Update readme with development section with quick instructions to start developing on
metrics-lib
parent 955832fe
......@@ -106,3 +106,30 @@ The examples explained in the tutorials are available as source code in
src/main/resources/examples/
```
Development
-----------
To contribute to metrics-lib, check out the Java survival guide first:
https://gitlab.torproject.org/tpo/network-health/team/-/wikis/metrics/Java
Start by checking out the project from Git.
The source code from gitlab.torproject.org and can be cloned via HTTPS or SSH
depending on the access you have. If you are doing this manually, ensure you
perform a recursive clone as metrics-base is included in the repository as a
submodule.
The tests, builds and other common development tasks are primarily
performed through calling Ant targets. Ant is also used to fetch dependencies.
Run:
```
$ ant resolve
```
To fetch needed dependencies. Make sure you have [ivy](https://ant.apache.org/ivy/)
configured and installed under:
```
-/usr/share/ant/lib
-/home/hiro/.ant/lib
```
......@@ -37,7 +37,7 @@ import java.util.SortedMap;
* verifying their correctness. The (bridge) directory authorities may
* decide to exclude dishonest servers from the network statuses they
* produce, but that wouldn't be reflected in extra-info descriptors.</p>
*
*
* @since 1.0.0
*/
public interface ExtraInfoDescriptor extends Descriptor {
......@@ -122,6 +122,43 @@ public interface ExtraInfoDescriptor extends Descriptor {
*/
BandwidthHistory getIpv6ReadHistory();
/**
* Return the server's history exhausted bandwidth as a timestamp of the
* last time this happened, or -1 if the descriptor does not
* contain a bandwidth overload rate limit.
*
* @since 2.18.0
*/
long getOverloadRatelimitsTimestamp();
/**
* Return the server's read-overload-count, or -1 if the descriptor does not
* contain a bandwidth overload rate limit.
*
* @since 2.18.0
*/
int getOverloadRatelimitsReadCount();
/**
* Return the server's write-overload-count, or -1 if the descriptor does not
* contain a bandwidth overload rate limit.
*
* @since 2.18.0
*/
int getOverloadRatelimitsWriteCount();
/**
* Return the server's descriptor exhaustion as a timestamp.
* The timestamp indicates that the maximum was reached between the
* timestamp and the "published" timestamp of the document.
*
* -1 is returned if the descriptor does not contain a file descriptor
* exhaustion.
*
* @since 2.18.0
*/
long getOverloadFdExhaustedTimestamp();
/**
* Return a SHA-1 digest of the GeoIP database file used by this server
* to resolve client IP addresses to country codes, encoded as 40
......@@ -794,4 +831,3 @@ public interface ExtraInfoDescriptor extends Descriptor {
*/
String getRouterSignatureEd25519();
}
......@@ -97,6 +97,12 @@ public abstract class ExtraInfoDescriptorImpl extends DescriptorImpl
case WRITE_HISTORY:
this.parseWriteHistoryLine(line, partsNoOpt);
break;
case OVERLOAD_RATELIMITS:
this.parseOverloadRatelimits(line, partsNoOpt);
break;
case OVERLOAD_FD_EXHAUSTED:
this.parseOverloadFdExhausted(line, partsNoOpt);
break;
case IPV6_READ_HISTORY:
this.parseIpv6ReadHistoryLine(line, partsNoOpt);
break;
......@@ -332,6 +338,30 @@ public abstract class ExtraInfoDescriptorImpl extends DescriptorImpl
partsNoOpt);
}
private void parseOverloadRatelimits(String line,
String[] partsNoOpt) throws DescriptorParseException {
int version = Integer.parseInt(partsNoOpt[1]);
if (version != 1) {
throw new DescriptorParseException("Illegal version number for line '"
+ line + "' in extra-info descriptor.");
}
this.overloadRatelimitsTimestamp = ParseHelper.parseTimestampAtIndex(line,
partsNoOpt, 2, 3);
this.overloadRatelimitsReadCount = Integer.parseInt(partsNoOpt[6]);
this.overloadRatelimitsWriteCount = Integer.parseInt(partsNoOpt[7]);
}
private void parseOverloadFdExhausted(String line,
String[] partsNoOpt) throws DescriptorParseException {
int version = Integer.parseInt(partsNoOpt[1]);
if (version != 1) {
throw new DescriptorParseException("Illegal version number for line '"
+ line + "' in extra-info descriptor.");
}
this.overloadFdExhaustedTimestamp = ParseHelper.parseTimestampAtIndex(line,
partsNoOpt, 2, 3);
}
private void parseIpv6ReadHistoryLine(String line,
String[] partsNoOpt) throws DescriptorParseException {
this.ipv6ReadHistory = new BandwidthHistoryImpl(line,
......@@ -953,6 +983,34 @@ public abstract class ExtraInfoDescriptorImpl extends DescriptorImpl
return this.geoip6DbDigest;
}
private long overloadRatelimitsTimestamp = -1L;
@Override
public long getOverloadRatelimitsTimestamp() {
return this.overloadRatelimitsTimestamp;
}
private int overloadRatelimitsReadCount = -1;
@Override
public int getOverloadRatelimitsReadCount() {
return this.overloadRatelimitsReadCount;
}
private int overloadRatelimitsWriteCount = -1;
@Override
public int getOverloadRatelimitsWriteCount() {
return this.overloadRatelimitsWriteCount;
}
private long overloadFdExhaustedTimestamp = -1L;
@Override
public long getOverloadFdExhaustedTimestamp() {
return this.overloadFdExhaustedTimestamp;
}
private long dirreqStatsEndMillis = -1L;
@Override
......@@ -1462,4 +1520,3 @@ public abstract class ExtraInfoDescriptorImpl extends DescriptorImpl
return this.routerSignatureEd25519;
}
}
......@@ -7,7 +7,7 @@ public enum Key {
EMPTY("the-empty-key"),
INVALID("the-invalid-key"),
/* crypto keys */
CRYPTO_BEGIN("-----BEGIN"),
CRYPTO_END("-----END"),
......@@ -118,6 +118,8 @@ public enum Key {
ONION_KEY_CROSSCERT("onion-key-crosscert"),
OPT("opt"),
OR_ADDRESS("or-address"),
OVERLOAD_RATELIMITS("overload-ratelimits"),
OVERLOAD_FD_EXHAUSTED("overload-fd-exhausted"),
P("p"),
P6("p6"),
PACKAGE("package"),
......
......@@ -22,6 +22,7 @@ import org.junit.rules.ExpectedException;
import java.io.ByteArrayOutputStream;
import java.io.IOException;
import java.util.ArrayList;
import java.util.Date;
import java.util.List;
import java.util.Map;
import java.util.SortedMap;
......@@ -75,6 +76,16 @@ public class ExtraInfoDescriptorImplTest {
return db.buildDescriptor();
}
private String overloadRatelimitsLine = "overload-ratelimits 1 "
+ "2021-07-24 03:00:00 1048576 3145728 824 650";
private static ExtraInfoDescriptor createWithOverloadRateLimitsLine(
String line) throws DescriptorParseException {
DescriptorBuilder db = new DescriptorBuilder();
db.overloadRatelimitsLine = line;
return db.buildDescriptor();
}
private String ipv6WriteHistoryLine = null;
private static ExtraInfoDescriptor createWithIpv6WriteHistoryLine(
......@@ -293,6 +304,9 @@ public class ExtraInfoDescriptorImplTest {
if (this.readHistoryLine != null) {
sb.append(this.readHistoryLine).append("\n");
}
if (this.overloadRatelimitsLine != null) {
sb.append(this.overloadRatelimitsLine).append("\n");
}
if (this.ipv6WriteHistoryLine != null) {
sb.append(this.ipv6WriteHistoryLine).append("\n");
}
......@@ -1215,6 +1229,32 @@ public class ExtraInfoDescriptorImplTest {
descriptor.getIpv6ReadHistory().getBandwidthValues().size());
}
@Test
public void testOverloadRatelimits()
throws DescriptorParseException {
ExtraInfoDescriptor descriptor = DescriptorBuilder
.createWithOverloadRateLimitsLine("overload-ratelimits 1 "
+ "2021-07-24 03:00:00 1048576 3145728 824 650");
String expectedDate = "Sat Jul 24 03:00:00 UTC 2021";
assertEquals(expectedDate,
new Date(descriptor.getOverloadRatelimitsTimestamp()).toString());
assertEquals(824,
descriptor.getOverloadRatelimitsReadCount());
assertEquals(650,
descriptor.getOverloadRatelimitsWriteCount());
}
@Test
public void testOverloadFdExhausted()
throws DescriptorParseException {
ExtraInfoDescriptor descriptor = DescriptorBuilder
.createWithOverloadRateLimitsLine("overload-fd-exhausted "
+ "1 2021-07-23 10:00:00");
String expectedDate = "Fri Jul 23 10:00:00 UTC 2021";
assertEquals(expectedDate,
new Date(descriptor.getOverloadFdExhaustedTimestamp()).toString());
}
@Test
public void testDirreqWriteHistoryMissingBytesBegin()
throws DescriptorParseException {
......@@ -2493,4 +2533,3 @@ public class ExtraInfoDescriptorImplTest {
assertNull(descriptor.getDigestSha256Base64());
}
}
Supports Markdown
0% or .
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment