Merge "Add DHCP address lease expiry in IpMemoryStore."

am: 17ea70c6d3

Change-Id: Idb73423aaf875bb77d19f9661e243f152f734fa3
This commit is contained in:
Xiao Ma
2019-04-01 06:16:08 -07:00
committed by android-build-merger
6 changed files with 102 additions and 18 deletions

View File

@@ -72,6 +72,10 @@ public class IpMemoryStoreDatabase {
public static final String COLNAME_ASSIGNEDV4ADDRESS = "assignedV4Address";
public static final String COLTYPE_ASSIGNEDV4ADDRESS = "INTEGER";
public static final String COLNAME_ASSIGNEDV4ADDRESSEXPIRY = "assignedV4AddressExpiry";
// The lease expiry timestamp in uint of milliseconds
public static final String COLTYPE_ASSIGNEDV4ADDRESSEXPIRY = "BIGINT";
// Please note that the group hint is only a *hint*, hence its name. The client can offer
// this information to nudge the grouping in the decision it thinks is right, but it can't
// decide for the memory store what is the same L3 network.
@@ -86,13 +90,14 @@ public class IpMemoryStoreDatabase {
public static final String COLTYPE_MTU = "INTEGER DEFAULT -1";
public static final String CREATE_TABLE = "CREATE TABLE IF NOT EXISTS "
+ TABLENAME + " ("
+ COLNAME_L2KEY + " " + COLTYPE_L2KEY + " PRIMARY KEY NOT NULL, "
+ COLNAME_EXPIRYDATE + " " + COLTYPE_EXPIRYDATE + ", "
+ COLNAME_ASSIGNEDV4ADDRESS + " " + COLTYPE_ASSIGNEDV4ADDRESS + ", "
+ COLNAME_GROUPHINT + " " + COLTYPE_GROUPHINT + ", "
+ COLNAME_DNSADDRESSES + " " + COLTYPE_DNSADDRESSES + ", "
+ COLNAME_MTU + " " + COLTYPE_MTU + ")";
+ TABLENAME + " ("
+ COLNAME_L2KEY + " " + COLTYPE_L2KEY + " PRIMARY KEY NOT NULL, "
+ COLNAME_EXPIRYDATE + " " + COLTYPE_EXPIRYDATE + ", "
+ COLNAME_ASSIGNEDV4ADDRESS + " " + COLTYPE_ASSIGNEDV4ADDRESS + ", "
+ COLNAME_ASSIGNEDV4ADDRESSEXPIRY + " " + COLTYPE_ASSIGNEDV4ADDRESSEXPIRY + ", "
+ COLNAME_GROUPHINT + " " + COLTYPE_GROUPHINT + ", "
+ COLNAME_DNSADDRESSES + " " + COLTYPE_DNSADDRESSES + ", "
+ COLNAME_MTU + " " + COLTYPE_MTU + ")";
public static final String DROP_TABLE = "DROP TABLE IF EXISTS " + TABLENAME;
}
@@ -134,7 +139,7 @@ public class IpMemoryStoreDatabase {
/** The SQLite DB helper */
public static class DbHelper extends SQLiteOpenHelper {
// Update this whenever changing the schema.
private static final int SCHEMA_VERSION = 2;
private static final int SCHEMA_VERSION = 3;
private static final String DATABASE_FILENAME = "IpMemoryStore.db";
public DbHelper(@NonNull final Context context) {
@@ -153,10 +158,27 @@ public class IpMemoryStoreDatabase {
@Override
public void onUpgrade(@NonNull final SQLiteDatabase db, final int oldVersion,
final int newVersion) {
// No upgrade supported yet.
db.execSQL(NetworkAttributesContract.DROP_TABLE);
db.execSQL(PrivateDataContract.DROP_TABLE);
onCreate(db);
try {
if (oldVersion < 2) {
// upgrade from version 1 to version 2
// since we starts from version 2, do nothing here
}
if (oldVersion < 3) {
// upgrade from version 2 to version 3
final String sqlUpgradeAddressExpiry = "alter table"
+ " " + NetworkAttributesContract.TABLENAME + " ADD"
+ " " + NetworkAttributesContract.COLNAME_ASSIGNEDV4ADDRESSEXPIRY
+ " " + NetworkAttributesContract.COLTYPE_ASSIGNEDV4ADDRESSEXPIRY;
db.execSQL(sqlUpgradeAddressExpiry);
}
} catch (SQLiteException e) {
Log.e(TAG, "Could not upgrade to the new version", e);
// create database with new version
db.execSQL(NetworkAttributesContract.DROP_TABLE);
db.execSQL(PrivateDataContract.DROP_TABLE);
onCreate(db);
}
}
/** Called when the database is downgraded */
@@ -204,6 +226,10 @@ public class IpMemoryStoreDatabase {
values.put(NetworkAttributesContract.COLNAME_ASSIGNEDV4ADDRESS,
inet4AddressToIntHTH(attributes.assignedV4Address));
}
if (null != attributes.assignedV4AddressExpiry) {
values.put(NetworkAttributesContract.COLNAME_ASSIGNEDV4ADDRESSEXPIRY,
attributes.assignedV4AddressExpiry);
}
if (null != attributes.groupHint) {
values.put(NetworkAttributesContract.COLNAME_GROUPHINT, attributes.groupHint);
}
@@ -251,6 +277,8 @@ public class IpMemoryStoreDatabase {
final NetworkAttributes.Builder builder = new NetworkAttributes.Builder();
final int assignedV4AddressInt = getInt(cursor,
NetworkAttributesContract.COLNAME_ASSIGNEDV4ADDRESS, 0);
final long assignedV4AddressExpiry = getLong(cursor,
NetworkAttributesContract.COLNAME_ASSIGNEDV4ADDRESSEXPIRY, 0);
final String groupHint = getString(cursor, NetworkAttributesContract.COLNAME_GROUPHINT);
final byte[] dnsAddressesBlob =
getBlob(cursor, NetworkAttributesContract.COLNAME_DNSADDRESSES);
@@ -258,6 +286,9 @@ public class IpMemoryStoreDatabase {
if (0 != assignedV4AddressInt) {
builder.setAssignedV4Address(intToInet4AddressHTH(assignedV4AddressInt));
}
if (0 != assignedV4AddressExpiry) {
builder.setAssignedV4AddressExpiry(assignedV4AddressExpiry);
}
builder.setGroupHint(groupHint);
if (null != dnsAddressesBlob) {
builder.setDnsAddresses(decodeAddressList(dnsAddressesBlob));

View File

@@ -228,6 +228,7 @@ public class IpMemoryStoreServiceTest {
public void testNetworkAttributes() throws UnknownHostException {
final NetworkAttributes.Builder na = new NetworkAttributes.Builder();
na.setAssignedV4Address((Inet4Address) Inet4Address.getByName("1.2.3.4"));
na.setAssignedV4AddressExpiry(System.currentTimeMillis() + 7_200_000);
na.setGroupHint("hint1");
na.setMtu(219);
final String l2Key = FAKE_KEYS[0];
@@ -257,6 +258,8 @@ public class IpMemoryStoreServiceTest {
+ status.resultCode, status.isSuccess());
assertEquals(l2Key, key);
assertEquals(attributes.assignedV4Address, attr.assignedV4Address);
assertEquals(attributes.assignedV4AddressExpiry,
attr.assignedV4AddressExpiry);
assertEquals(attributes.groupHint, attr.groupHint);
assertEquals(attributes.mtu, attr.mtu);
assertEquals(attributes2.dnsAddresses, attr.dnsAddresses);
@@ -278,7 +281,7 @@ public class IpMemoryStoreServiceTest {
// Verify that this test does not miss any new field added later.
// If any field is added to NetworkAttributes it must be tested here for storing
// and retrieving.
assertEquals(4, Arrays.stream(NetworkAttributes.class.getDeclaredFields())
assertEquals(5, Arrays.stream(NetworkAttributes.class.getDeclaredFields())
.filter(f -> !Modifier.isStatic(f.getModifiers())).count());
}

View File

@@ -60,6 +60,13 @@ public class NetworkAttributes {
public final Inet4Address assignedV4Address;
private static final float WEIGHT_ASSIGNEDV4ADDR = 300.0f;
// The lease expiry timestamp of v4 address allocated from DHCP server, in milliseconds.
@Nullable
public final Long assignedV4AddressExpiry;
// lease expiry doesn't imply any correlation between "the same lease expiry value" and "the
// same L3 network".
private static final float WEIGHT_ASSIGNEDV4ADDREXPIRY = 0.0f;
// Optionally supplied by the client if it has an opinion on L3 network. For example, this
// could be a hash of the SSID + security type on WiFi.
@Nullable
@@ -81,6 +88,7 @@ public class NetworkAttributes {
/** @hide */
@VisibleForTesting
public static final float TOTAL_WEIGHT = WEIGHT_ASSIGNEDV4ADDR
+ WEIGHT_ASSIGNEDV4ADDREXPIRY
+ WEIGHT_GROUPHINT
+ WEIGHT_DNSADDRESSES
+ WEIGHT_MTU;
@@ -89,11 +97,16 @@ public class NetworkAttributes {
@VisibleForTesting
public NetworkAttributes(
@Nullable final Inet4Address assignedV4Address,
@Nullable final Long assignedV4AddressExpiry,
@Nullable final String groupHint,
@Nullable final List<InetAddress> dnsAddresses,
@Nullable final Integer mtu) {
if (mtu != null && mtu < 0) throw new IllegalArgumentException("MTU can't be negative");
if (assignedV4AddressExpiry != null && assignedV4AddressExpiry <= 0) {
throw new IllegalArgumentException("lease expiry can't be negative or zero");
}
this.assignedV4Address = assignedV4Address;
this.assignedV4AddressExpiry = assignedV4AddressExpiry;
this.groupHint = groupHint;
this.dnsAddresses = null == dnsAddresses ? null :
Collections.unmodifiableList(new ArrayList<>(dnsAddresses));
@@ -105,6 +118,8 @@ public class NetworkAttributes {
// The call to the other constructor must be the first statement of this constructor,
// so everything has to be inline
this((Inet4Address) getByAddressOrNull(parcelable.assignedV4Address),
parcelable.assignedV4AddressExpiry > 0
? parcelable.assignedV4AddressExpiry : null,
parcelable.groupHint,
blobArrayToInetAddressList(parcelable.dnsAddresses),
parcelable.mtu >= 0 ? parcelable.mtu : null);
@@ -150,6 +165,8 @@ public class NetworkAttributes {
final NetworkAttributesParcelable parcelable = new NetworkAttributesParcelable();
parcelable.assignedV4Address =
(null == assignedV4Address) ? null : assignedV4Address.getAddress();
parcelable.assignedV4AddressExpiry =
(null == assignedV4AddressExpiry) ? 0 : assignedV4AddressExpiry;
parcelable.groupHint = groupHint;
parcelable.dnsAddresses = inetAddressListToBlobArray(dnsAddresses);
parcelable.mtu = (null == mtu) ? -1 : mtu;
@@ -168,6 +185,8 @@ public class NetworkAttributes {
public float getNetworkGroupSamenessConfidence(@NonNull final NetworkAttributes o) {
final float samenessScore =
samenessContribution(WEIGHT_ASSIGNEDV4ADDR, assignedV4Address, o.assignedV4Address)
+ samenessContribution(WEIGHT_ASSIGNEDV4ADDREXPIRY, assignedV4AddressExpiry,
o.assignedV4AddressExpiry)
+ samenessContribution(WEIGHT_GROUPHINT, groupHint, o.groupHint)
+ samenessContribution(WEIGHT_DNSADDRESSES, dnsAddresses, o.dnsAddresses)
+ samenessContribution(WEIGHT_MTU, mtu, o.mtu);
@@ -189,6 +208,8 @@ public class NetworkAttributes {
@Nullable
private Inet4Address mAssignedAddress;
@Nullable
private Long mAssignedAddressExpiry;
@Nullable
private String mGroupHint;
@Nullable
private List<InetAddress> mDnsAddresses;
@@ -205,6 +226,20 @@ public class NetworkAttributes {
return this;
}
/**
* Set the lease expiry timestamp of assigned v4 address.
* @param assignedV4AddressExpiry The lease expiry timestamp of assigned v4 address.
* @return This builder.
*/
public Builder setAssignedV4AddressExpiry(
@Nullable final Long assignedV4AddressExpiry) {
if (null != assignedV4AddressExpiry && assignedV4AddressExpiry <= 0) {
throw new IllegalArgumentException("lease expiry can't be negative or zero");
}
mAssignedAddressExpiry = assignedV4AddressExpiry;
return this;
}
/**
* Set the group hint.
* @param groupHint The group hint.
@@ -248,14 +283,15 @@ public class NetworkAttributes {
* @return The built NetworkAttributes object.
*/
public NetworkAttributes build() {
return new NetworkAttributes(mAssignedAddress, mGroupHint, mDnsAddresses, mMtu);
return new NetworkAttributes(mAssignedAddress, mAssignedAddressExpiry,
mGroupHint, mDnsAddresses, mMtu);
}
}
/** @hide */
public boolean isEmpty() {
return (null == assignedV4Address) && (null == groupHint)
&& (null == dnsAddresses) && (null == mtu);
return (null == assignedV4Address) && (null == assignedV4AddressExpiry)
&& (null == groupHint) && (null == dnsAddresses) && (null == mtu);
}
@Override
@@ -263,6 +299,7 @@ public class NetworkAttributes {
if (!(o instanceof NetworkAttributes)) return false;
final NetworkAttributes other = (NetworkAttributes) o;
return Objects.equals(assignedV4Address, other.assignedV4Address)
&& Objects.equals(assignedV4AddressExpiry, other.assignedV4AddressExpiry)
&& Objects.equals(groupHint, other.groupHint)
&& Objects.equals(dnsAddresses, other.dnsAddresses)
&& Objects.equals(mtu, other.mtu);
@@ -270,7 +307,8 @@ public class NetworkAttributes {
@Override
public int hashCode() {
return Objects.hash(assignedV4Address, groupHint, dnsAddresses, mtu);
return Objects.hash(assignedV4Address, assignedV4AddressExpiry,
groupHint, dnsAddresses, mtu);
}
/** Pretty print */
@@ -286,6 +324,13 @@ public class NetworkAttributes {
nullFields.add("assignedV4Addr");
}
if (null != assignedV4AddressExpiry) {
resultJoiner.add("assignedV4AddressExpiry :");
resultJoiner.add(assignedV4AddressExpiry.toString());
} else {
nullFields.add("assignedV4AddressExpiry");
}
if (null != groupHint) {
resultJoiner.add("groupHint :");
resultJoiner.add(groupHint);

View File

@@ -30,6 +30,7 @@ import android.net.ipmemorystore.Blob;
*/
parcelable NetworkAttributesParcelable {
byte[] assignedV4Address;
long assignedV4AddressExpiry;
String groupHint;
Blob[] dnsAddresses;
int mtu;

View File

@@ -44,6 +44,8 @@ public class ParcelableTests {
assertEquals(in, new NetworkAttributes(parcelingRoundTrip(in.toParcelable())));
builder.setAssignedV4Address((Inet4Address) Inet4Address.getByName("1.2.3.4"));
// lease will expire in two hours
builder.setAssignedV4AddressExpiry(System.currentTimeMillis() + 7_200_000);
// groupHint stays null this time around
builder.setDnsAddresses(Collections.emptyList());
builder.setMtu(18);
@@ -51,6 +53,7 @@ public class ParcelableTests {
assertEquals(in, new NetworkAttributes(parcelingRoundTrip(in.toParcelable())));
builder.setAssignedV4Address((Inet4Address) Inet4Address.getByName("6.7.8.9"));
builder.setAssignedV4AddressExpiry(System.currentTimeMillis() + 3_600_000);
builder.setGroupHint("groupHint");
builder.setDnsAddresses(Arrays.asList(
InetAddress.getByName("ACA1:652B:0911:DE8F:1200:115E:913B:AA2A"),
@@ -66,7 +69,7 @@ public class ParcelableTests {
// Verify that this test does not miss any new field added later.
// If any field is added to NetworkAttributes it must be tested here for parceling
// roundtrip.
assertEquals(4, Arrays.stream(NetworkAttributes.class.getDeclaredFields())
assertEquals(5, Arrays.stream(NetworkAttributes.class.getDeclaredFields())
.filter(f -> !Modifier.isStatic(f.getModifiers())).count());
}

View File

@@ -57,6 +57,7 @@ public class NetworkAttributesTest {
final NetworkAttributes na =
new NetworkAttributes(
(Inet4Address) Inet4Address.getByAddress(new byte[] {1, 2, 3, 4}),
System.currentTimeMillis() + 7_200_000,
"some hint",
Arrays.asList(Inet4Address.getByAddress(new byte[] {5, 6, 7, 8}),
Inet4Address.getByAddress(new byte[] {9, 0, 1, 2})),