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:
@@ -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) {
|
||||||
|
|||||||
@@ -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;
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|||||||
Reference in New Issue
Block a user