Merge changes Idce2024f,I7e009073,I29fe506c,I37b2a0b8,Iccb4e3ec into main

* changes:
  Add toString for more consistent logging to IaPrefixOption
  Create IpPrefix in IaPrefixOption constructor
  Add @Computed annotation to Struct
  Remove check that preferred lifetime >= t2
  Remove IA prefix option option-code from public constructor
This commit is contained in:
Patrick Rohr
2023-10-25 02:14:30 +00:00
committed by Gerrit Code Review
2 changed files with 52 additions and 15 deletions

View File

@@ -146,6 +146,14 @@ public class Struct {
int arraysize() default 0; int arraysize() default 0;
} }
/**
* Indicates that this field contains a computed value and is ignored for the purposes of Struct
* parsing.
*/
@Retention(RetentionPolicy.RUNTIME)
@Target(ElementType.FIELD)
public @interface Computed {}
private static class FieldInfo { private static class FieldInfo {
@NonNull @NonNull
public final Field annotation; public final Field annotation;
@@ -533,6 +541,7 @@ public class Struct {
final FieldInfo[] annotationFields = new FieldInfo[getAnnotationFieldCount(clazz)]; final FieldInfo[] annotationFields = new FieldInfo[getAnnotationFieldCount(clazz)];
for (java.lang.reflect.Field field : clazz.getDeclaredFields()) { for (java.lang.reflect.Field field : clazz.getDeclaredFields()) {
if (Modifier.isStatic(field.getModifiers())) continue; if (Modifier.isStatic(field.getModifiers())) continue;
if (field.getAnnotation(Computed.class) != null) continue;
final Field annotation = field.getAnnotation(Field.class); final Field annotation = field.getAnnotation(Field.class);
if (annotation == null) { if (annotation == null) {

View File

@@ -18,12 +18,17 @@ package com.android.net.module.util.structs;
import static com.android.net.module.util.NetworkStackConstants.DHCP6_OPTION_IAPREFIX; import static com.android.net.module.util.NetworkStackConstants.DHCP6_OPTION_IAPREFIX;
import android.net.IpPrefix;
import android.util.Log; import android.util.Log;
import com.android.net.module.util.Struct; import com.android.net.module.util.Struct;
import com.android.net.module.util.Struct.Computed;
import com.android.net.module.util.Struct.Field; import com.android.net.module.util.Struct.Field;
import com.android.net.module.util.Struct.Type; import com.android.net.module.util.Struct.Type;
import java.net.Inet6Address;
import java.net.InetAddress;
import java.net.UnknownHostException;
import java.nio.ByteBuffer; import java.nio.ByteBuffer;
import java.nio.ByteOrder; import java.nio.ByteOrder;
@@ -70,7 +75,11 @@ public class IaPrefixOption extends Struct {
@Field(order = 5, type = Type.ByteArray, arraysize = 16) @Field(order = 5, type = Type.ByteArray, arraysize = 16)
public final byte[] prefix; public final byte[] prefix;
public IaPrefixOption(final short code, final short length, final long preferred, @Computed
private final IpPrefix mIpPrefix;
// Constructor used by Struct.parse()
protected IaPrefixOption(final short code, final short length, final long preferred,
final long valid, final byte prefixLen, final byte[] prefix) { final long valid, final byte prefixLen, final byte[] prefix) {
this.code = code; this.code = code;
this.length = length; this.length = length;
@@ -78,30 +87,43 @@ public class IaPrefixOption extends Struct {
this.valid = valid; this.valid = valid;
this.prefixLen = prefixLen; this.prefixLen = prefixLen;
this.prefix = prefix.clone(); this.prefix = prefix.clone();
try {
final Inet6Address addr = (Inet6Address) InetAddress.getByAddress(prefix);
mIpPrefix = new IpPrefix(addr, prefixLen);
} catch (UnknownHostException | ClassCastException e) {
// UnknownHostException should never happen unless prefix is null.
// ClassCastException can occur when prefix is an IPv6 mapped IPv4 address.
// Both scenarios should throw an exception in the context of Struct#parse().
throw new IllegalArgumentException(e);
}
}
public IaPrefixOption(final short length, final long preferred, final long valid,
final byte prefixLen, final byte[] prefix) {
this((byte) DHCP6_OPTION_IAPREFIX, length, preferred, valid, prefixLen, prefix);
} }
/** /**
* Check whether or not IA Prefix option in IA_PD option is valid per RFC8415#section-21.22. * Check whether or not IA Prefix option in IA_PD option is valid per RFC8415#section-21.22.
*
* Note: an expired prefix can still be valid.
*/ */
public boolean isValid(int t2) { public boolean isValid() {
if (preferred < 0 || valid < 0) { if (preferred < 0) {
Log.w(TAG, "IA_PD option with invalid lifetime, preferred lifetime " + preferred Log.w(TAG, "Invalid preferred lifetime: " + this);
+ ", valid lifetime " + valid); return false;
}
if (valid < 0) {
Log.w(TAG, "Invalid valid lifetime: " + this);
return false; return false;
} }
if (preferred > valid) { if (preferred > valid) {
Log.w(TAG, "IA_PD option with preferred lifetime " + preferred Log.w(TAG, "Invalid lifetime. Preferred lifetime > valid lifetime: " + this);
+ " greater than valid lifetime " + valid);
return false; return false;
} }
if (prefixLen > 64) { if (prefixLen > 64) {
Log.w(TAG, "IA_PD option with prefix length " + prefixLen Log.w(TAG, "Invalid prefix length: " + this);
+ " longer than 64");
return false;
}
// Either preferred lifetime or t2 might be 0 which is valid, then ignore it.
if (preferred != 0 && t2 != 0 && preferred < t2) {
Log.w(TAG, "preferred lifetime " + preferred + " is smaller than T2 " + t2);
return false; return false;
} }
return true; return true;
@@ -119,8 +141,14 @@ public class IaPrefixOption extends Struct {
*/ */
public static ByteBuffer build(final short length, final long preferred, final long valid, public static ByteBuffer build(final short length, final long preferred, final long valid,
final byte prefixLen, final byte[] prefix) { final byte prefixLen, final byte[] prefix) {
final IaPrefixOption option = new IaPrefixOption((byte) DHCP6_OPTION_IAPREFIX, final IaPrefixOption option = new IaPrefixOption(
length /* 25 + IAPrefix options length */, preferred, valid, prefixLen, prefix); length /* 25 + IAPrefix options length */, preferred, valid, prefixLen, prefix);
return ByteBuffer.wrap(option.writeToBytes(ByteOrder.BIG_ENDIAN)); return ByteBuffer.wrap(option.writeToBytes(ByteOrder.BIG_ENDIAN));
} }
@Override
public String toString() {
return "IA Prefix, length " + length + ": " + mIpPrefix + ", pref " + preferred + ", valid "
+ valid;
}
} }