354 lines
11 KiB
Java
354 lines
11 KiB
Java
/*
|
|
* Copyright (C) 2021 The Android Open Source Project
|
|
*
|
|
* Licensed under the Apache License, Version 2.0 (the "License");
|
|
* you may not use this file except in compliance with the License.
|
|
* You may obtain a copy of the License at
|
|
*
|
|
* http://www.apache.org/licenses/LICENSE-2.0
|
|
*
|
|
* Unless required by applicable law or agreed to in writing, software
|
|
* distributed under the License is distributed on an "AS IS" BASIS,
|
|
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
|
* See the License for the specific language governing permissions and
|
|
* limitations under the License.
|
|
*/
|
|
|
|
package android.net;
|
|
|
|
import android.annotation.NonNull;
|
|
import android.annotation.Nullable;
|
|
import android.annotation.SystemApi;
|
|
import android.os.Parcel;
|
|
import android.os.Parcelable;
|
|
import android.util.Range;
|
|
|
|
import com.android.net.module.util.InetAddressUtils;
|
|
|
|
import java.net.Inet6Address;
|
|
import java.net.InetAddress;
|
|
import java.util.Objects;
|
|
|
|
|
|
/**
|
|
* DSCP policy to be set on the requesting NetworkAgent.
|
|
* @hide
|
|
*/
|
|
@SystemApi
|
|
public final class DscpPolicy implements Parcelable {
|
|
/**
|
|
* Indicates that the policy does not specify a protocol.
|
|
*/
|
|
public static final int PROTOCOL_ANY = -1;
|
|
|
|
/**
|
|
* Indicates that the policy does not specify a port.
|
|
*/
|
|
public static final int SOURCE_PORT_ANY = -1;
|
|
|
|
/** The unique policy ID. Each requesting network is responsible for maintaining policy IDs
|
|
* unique within that network. In the case where a policy with an existing ID is created, the
|
|
* new policy will update the existing policy with the same ID.
|
|
*/
|
|
private final int mPolicyId;
|
|
|
|
/** The QoS DSCP marking to be added to packets matching the policy. */
|
|
private final int mDscp;
|
|
|
|
/** The source IP address. */
|
|
private final @Nullable InetAddress mSrcAddr;
|
|
|
|
/** The destination IP address. */
|
|
private final @Nullable InetAddress mDstAddr;
|
|
|
|
/** The source port. */
|
|
private final int mSrcPort;
|
|
|
|
/** The IP protocol that the policy requires. */
|
|
private final int mProtocol;
|
|
|
|
/** Destination port range. Inclusive range. */
|
|
private final @Nullable Range<Integer> mDstPortRange;
|
|
|
|
/**
|
|
* Implement the Parcelable interface
|
|
*
|
|
* @hide
|
|
*/
|
|
public int describeContents() {
|
|
return 0;
|
|
}
|
|
|
|
/* package */ DscpPolicy(
|
|
int policyId,
|
|
int dscp,
|
|
@Nullable InetAddress srcAddr,
|
|
@Nullable InetAddress dstAddr,
|
|
int srcPort,
|
|
int protocol,
|
|
Range<Integer> dstPortRange) {
|
|
this.mPolicyId = policyId;
|
|
this.mDscp = dscp;
|
|
this.mSrcAddr = srcAddr;
|
|
this.mDstAddr = dstAddr;
|
|
this.mSrcPort = srcPort;
|
|
this.mProtocol = protocol;
|
|
this.mDstPortRange = dstPortRange;
|
|
|
|
if (mPolicyId < 1 || mPolicyId > 255) {
|
|
throw new IllegalArgumentException("Policy ID not in valid range: " + mPolicyId);
|
|
}
|
|
if (mDscp < 0 || mDscp > 63) {
|
|
throw new IllegalArgumentException("DSCP value not in valid range: " + mDscp);
|
|
}
|
|
// Since SOURCE_PORT_ANY is the default source port value need to allow it as well.
|
|
// TODO: Move the default value into this constructor or throw an error from the
|
|
// instead.
|
|
if (mSrcPort < -1 || mSrcPort > 65535) {
|
|
throw new IllegalArgumentException("Source port not in valid range: " + mSrcPort);
|
|
}
|
|
if (mDstPortRange != null
|
|
&& (dstPortRange.getLower() < 0 || mDstPortRange.getLower() > 65535)
|
|
&& (mDstPortRange.getUpper() < 0 || mDstPortRange.getUpper() > 65535)) {
|
|
throw new IllegalArgumentException("Destination port not in valid range");
|
|
}
|
|
if (mSrcAddr != null && mDstAddr != null && (mSrcAddr instanceof Inet6Address)
|
|
!= (mDstAddr instanceof Inet6Address)) {
|
|
throw new IllegalArgumentException("Source/destination address of different family");
|
|
}
|
|
}
|
|
|
|
/**
|
|
* The unique policy ID.
|
|
*
|
|
* Each requesting network is responsible for maintaining unique
|
|
* policy IDs. In the case where a policy with an existing ID is created, the new
|
|
* policy will update the existing policy with the same ID
|
|
*
|
|
* @return Policy ID set in Builder.
|
|
*/
|
|
public int getPolicyId() {
|
|
return mPolicyId;
|
|
}
|
|
|
|
/**
|
|
* The QoS DSCP marking to be added to packets matching the policy.
|
|
*
|
|
* @return DSCP value set in Builder.
|
|
*/
|
|
public int getDscpValue() {
|
|
return mDscp;
|
|
}
|
|
|
|
/**
|
|
* The source IP address.
|
|
*
|
|
* @return Source IP address set in Builder or {@code null} if none was set.
|
|
*/
|
|
public @Nullable InetAddress getSourceAddress() {
|
|
return mSrcAddr;
|
|
}
|
|
|
|
/**
|
|
* The destination IP address.
|
|
*
|
|
* @return Destination IP address set in Builder or {@code null} if none was set.
|
|
*/
|
|
public @Nullable InetAddress getDestinationAddress() {
|
|
return mDstAddr;
|
|
}
|
|
|
|
/**
|
|
* The source port.
|
|
*
|
|
* @return Source port set in Builder or {@link #SOURCE_PORT_ANY} if no port was set.
|
|
*/
|
|
public int getSourcePort() {
|
|
return mSrcPort;
|
|
}
|
|
|
|
/**
|
|
* The IP protocol that the policy requires.
|
|
*
|
|
* @return Protocol set in Builder or {@link #PROTOCOL_ANY} if no protocol was set.
|
|
* {@link #PROTOCOL_ANY} indicates that any protocol will be matched.
|
|
*/
|
|
public int getProtocol() {
|
|
return mProtocol;
|
|
}
|
|
|
|
/**
|
|
* Destination port range. Inclusive range.
|
|
*
|
|
* @return Range<Integer> set in Builder or {@code null} if none was set.
|
|
*/
|
|
public @Nullable Range<Integer> getDestinationPortRange() {
|
|
return mDstPortRange;
|
|
}
|
|
|
|
@Override
|
|
public String toString() {
|
|
return "DscpPolicy { "
|
|
+ "policyId = " + mPolicyId + ", "
|
|
+ "dscp = " + mDscp + ", "
|
|
+ "srcAddr = " + mSrcAddr + ", "
|
|
+ "dstAddr = " + mDstAddr + ", "
|
|
+ "srcPort = " + mSrcPort + ", "
|
|
+ "protocol = " + mProtocol + ", "
|
|
+ "dstPortRange = "
|
|
+ (mDstPortRange == null ? "none" : mDstPortRange.toString())
|
|
+ " }";
|
|
}
|
|
|
|
@Override
|
|
public boolean equals(@Nullable Object o) {
|
|
if (this == o) return true;
|
|
if (!(o instanceof DscpPolicy)) return false;
|
|
DscpPolicy that = (DscpPolicy) o;
|
|
return true
|
|
&& mPolicyId == that.mPolicyId
|
|
&& mDscp == that.mDscp
|
|
&& Objects.equals(mSrcAddr, that.mSrcAddr)
|
|
&& Objects.equals(mDstAddr, that.mDstAddr)
|
|
&& mSrcPort == that.mSrcPort
|
|
&& mProtocol == that.mProtocol
|
|
&& Objects.equals(mDstPortRange, that.mDstPortRange);
|
|
}
|
|
|
|
@Override
|
|
public int hashCode() {
|
|
return Objects.hash(mPolicyId, mDscp, mSrcAddr.hashCode(),
|
|
mDstAddr.hashCode(), mSrcPort, mProtocol, mDstPortRange.hashCode());
|
|
}
|
|
|
|
/** @hide */
|
|
@Override
|
|
public void writeToParcel(@NonNull Parcel dest, int flags) {
|
|
dest.writeInt(mPolicyId);
|
|
dest.writeInt(mDscp);
|
|
InetAddressUtils.parcelInetAddress(dest, mSrcAddr, flags);
|
|
InetAddressUtils.parcelInetAddress(dest, mDstAddr, flags);
|
|
dest.writeInt(mSrcPort);
|
|
dest.writeInt(mProtocol);
|
|
dest.writeBoolean(mDstPortRange != null ? true : false);
|
|
if (mDstPortRange != null) {
|
|
dest.writeInt(mDstPortRange.getLower());
|
|
dest.writeInt(mDstPortRange.getUpper());
|
|
}
|
|
}
|
|
|
|
/** @hide */
|
|
DscpPolicy(@NonNull Parcel in) {
|
|
this.mPolicyId = in.readInt();
|
|
this.mDscp = in.readInt();
|
|
this.mSrcAddr = InetAddressUtils.unparcelInetAddress(in);
|
|
this.mDstAddr = InetAddressUtils.unparcelInetAddress(in);
|
|
this.mSrcPort = in.readInt();
|
|
this.mProtocol = in.readInt();
|
|
if (in.readBoolean()) {
|
|
this.mDstPortRange = new Range<Integer>(in.readInt(), in.readInt());
|
|
} else {
|
|
this.mDstPortRange = null;
|
|
}
|
|
}
|
|
|
|
/** @hide */
|
|
public @SystemApi static final @NonNull Parcelable.Creator<DscpPolicy> CREATOR =
|
|
new Parcelable.Creator<DscpPolicy>() {
|
|
@Override
|
|
public DscpPolicy[] newArray(int size) {
|
|
return new DscpPolicy[size];
|
|
}
|
|
|
|
@Override
|
|
public DscpPolicy createFromParcel(@NonNull android.os.Parcel in) {
|
|
return new DscpPolicy(in);
|
|
}
|
|
};
|
|
|
|
/**
|
|
* A builder for {@link DscpPolicy}
|
|
*
|
|
*/
|
|
public static final class Builder {
|
|
|
|
private final int mPolicyId;
|
|
private final int mDscp;
|
|
private @Nullable InetAddress mSrcAddr;
|
|
private @Nullable InetAddress mDstAddr;
|
|
private int mSrcPort = SOURCE_PORT_ANY;
|
|
private int mProtocol = PROTOCOL_ANY;
|
|
private @Nullable Range<Integer> mDstPortRange;
|
|
|
|
private long mBuilderFieldsSet = 0L;
|
|
|
|
/**
|
|
* Creates a new Builder.
|
|
*
|
|
* @param policyId The unique policy ID. Each requesting network is responsible for
|
|
* maintaining unique policy IDs. In the case where a policy with an
|
|
* existing ID is created, the new policy will update the existing
|
|
* policy with the same ID
|
|
* @param dscpValue The DSCP value to set.
|
|
*/
|
|
public Builder(int policyId, int dscpValue) {
|
|
mPolicyId = policyId;
|
|
mDscp = dscpValue;
|
|
}
|
|
|
|
/**
|
|
* Specifies that this policy matches packets with the specified source IP address.
|
|
*/
|
|
public @NonNull Builder setSourceAddress(@NonNull InetAddress value) {
|
|
mSrcAddr = value;
|
|
return this;
|
|
}
|
|
|
|
/**
|
|
* Specifies that this policy matches packets with the specified destination IP address.
|
|
*/
|
|
public @NonNull Builder setDestinationAddress(@NonNull InetAddress value) {
|
|
mDstAddr = value;
|
|
return this;
|
|
}
|
|
|
|
/**
|
|
* Specifies that this policy matches packets with the specified source port.
|
|
*/
|
|
public @NonNull Builder setSourcePort(int value) {
|
|
mSrcPort = value;
|
|
return this;
|
|
}
|
|
|
|
/**
|
|
* Specifies that this policy matches packets with the specified protocol.
|
|
*/
|
|
public @NonNull Builder setProtocol(int value) {
|
|
mProtocol = value;
|
|
return this;
|
|
}
|
|
|
|
/**
|
|
* Specifies that this policy matches packets with the specified destination port range.
|
|
*/
|
|
public @NonNull Builder setDestinationPortRange(@NonNull Range<Integer> range) {
|
|
mDstPortRange = range;
|
|
return this;
|
|
}
|
|
|
|
/**
|
|
* Constructs a DscpPolicy with the specified parameters.
|
|
*/
|
|
public @NonNull DscpPolicy build() {
|
|
return new DscpPolicy(
|
|
mPolicyId,
|
|
mDscp,
|
|
mSrcAddr,
|
|
mDstAddr,
|
|
mSrcPort,
|
|
mProtocol,
|
|
mDstPortRange);
|
|
}
|
|
}
|
|
}
|