18dc1fd0237992e1d693376b4f6eea45e7447e9dbNathan Harold/*
28dc1fd0237992e1d693376b4f6eea45e7447e9dbNathan Harold * Copyright (C) 2017 The Android Open Source Project
38dc1fd0237992e1d693376b4f6eea45e7447e9dbNathan Harold *
48dc1fd0237992e1d693376b4f6eea45e7447e9dbNathan Harold * Licensed under the Apache License, Version 2.0 (the "License");
58dc1fd0237992e1d693376b4f6eea45e7447e9dbNathan Harold * you may not use this file except in compliance with the License.
68dc1fd0237992e1d693376b4f6eea45e7447e9dbNathan Harold * You may obtain a copy of the License at
78dc1fd0237992e1d693376b4f6eea45e7447e9dbNathan Harold *
88dc1fd0237992e1d693376b4f6eea45e7447e9dbNathan Harold *      http://www.apache.org/licenses/LICENSE-2.0
98dc1fd0237992e1d693376b4f6eea45e7447e9dbNathan Harold *
108dc1fd0237992e1d693376b4f6eea45e7447e9dbNathan Harold * Unless required by applicable law or agreed to in writing, software
118dc1fd0237992e1d693376b4f6eea45e7447e9dbNathan Harold * distributed under the License is distributed on an "AS IS" BASIS,
128dc1fd0237992e1d693376b4f6eea45e7447e9dbNathan Harold * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
138dc1fd0237992e1d693376b4f6eea45e7447e9dbNathan Harold * See the License for the specific language governing permissions and
148dc1fd0237992e1d693376b4f6eea45e7447e9dbNathan Harold * limitations under the License.
158dc1fd0237992e1d693376b4f6eea45e7447e9dbNathan Harold */
168dc1fd0237992e1d693376b4f6eea45e7447e9dbNathan Haroldpackage android.net;
178dc1fd0237992e1d693376b4f6eea45e7447e9dbNathan Harold
188dc1fd0237992e1d693376b4f6eea45e7447e9dbNathan Haroldimport android.os.Parcel;
198dc1fd0237992e1d693376b4f6eea45e7447e9dbNathan Haroldimport android.os.ParcelFileDescriptor;
208dc1fd0237992e1d693376b4f6eea45e7447e9dbNathan Haroldimport android.os.Parcelable;
218dc1fd0237992e1d693376b4f6eea45e7447e9dbNathan Haroldimport java.io.FileDescriptor;
228dc1fd0237992e1d693376b4f6eea45e7447e9dbNathan Haroldimport java.io.IOException;
238dc1fd0237992e1d693376b4f6eea45e7447e9dbNathan Harold
248dc1fd0237992e1d693376b4f6eea45e7447e9dbNathan Harold/**
258dc1fd0237992e1d693376b4f6eea45e7447e9dbNathan Harold * This class is used to return a UDP Socket and corresponding status from the IpSecService to an
268dc1fd0237992e1d693376b4f6eea45e7447e9dbNathan Harold * IpSecManager.UdpEncapsulationSocket.
278dc1fd0237992e1d693376b4f6eea45e7447e9dbNathan Harold *
288dc1fd0237992e1d693376b4f6eea45e7447e9dbNathan Harold * @hide
298dc1fd0237992e1d693376b4f6eea45e7447e9dbNathan Harold */
308dc1fd0237992e1d693376b4f6eea45e7447e9dbNathan Haroldpublic final class IpSecUdpEncapResponse implements Parcelable {
318dc1fd0237992e1d693376b4f6eea45e7447e9dbNathan Harold    private static final String TAG = "IpSecUdpEncapResponse";
328dc1fd0237992e1d693376b4f6eea45e7447e9dbNathan Harold
338dc1fd0237992e1d693376b4f6eea45e7447e9dbNathan Harold    public final int resourceId;
348dc1fd0237992e1d693376b4f6eea45e7447e9dbNathan Harold    public final int port;
358dc1fd0237992e1d693376b4f6eea45e7447e9dbNathan Harold    public final int status;
368dc1fd0237992e1d693376b4f6eea45e7447e9dbNathan Harold    // There is a weird asymmetry with FileDescriptor: you can write a FileDescriptor
378dc1fd0237992e1d693376b4f6eea45e7447e9dbNathan Harold    // but you read a ParcelFileDescriptor. To circumvent this, when we receive a FD
388dc1fd0237992e1d693376b4f6eea45e7447e9dbNathan Harold    // from the user, we immediately create a ParcelFileDescriptor DUP, which we invalidate
398dc1fd0237992e1d693376b4f6eea45e7447e9dbNathan Harold    // on writeParcel() by setting the flag to do close-on-write.
408dc1fd0237992e1d693376b4f6eea45e7447e9dbNathan Harold    // TODO: tests to ensure this doesn't leak
418dc1fd0237992e1d693376b4f6eea45e7447e9dbNathan Harold    public final ParcelFileDescriptor fileDescriptor;
428dc1fd0237992e1d693376b4f6eea45e7447e9dbNathan Harold
438dc1fd0237992e1d693376b4f6eea45e7447e9dbNathan Harold    // Parcelable Methods
448dc1fd0237992e1d693376b4f6eea45e7447e9dbNathan Harold
458dc1fd0237992e1d693376b4f6eea45e7447e9dbNathan Harold    @Override
468dc1fd0237992e1d693376b4f6eea45e7447e9dbNathan Harold    public int describeContents() {
478dc1fd0237992e1d693376b4f6eea45e7447e9dbNathan Harold        return (fileDescriptor != null) ? Parcelable.CONTENTS_FILE_DESCRIPTOR : 0;
488dc1fd0237992e1d693376b4f6eea45e7447e9dbNathan Harold    }
498dc1fd0237992e1d693376b4f6eea45e7447e9dbNathan Harold
508dc1fd0237992e1d693376b4f6eea45e7447e9dbNathan Harold    @Override
518dc1fd0237992e1d693376b4f6eea45e7447e9dbNathan Harold    public void writeToParcel(Parcel out, int flags) {
528dc1fd0237992e1d693376b4f6eea45e7447e9dbNathan Harold        out.writeInt(status);
538dc1fd0237992e1d693376b4f6eea45e7447e9dbNathan Harold        out.writeInt(resourceId);
548dc1fd0237992e1d693376b4f6eea45e7447e9dbNathan Harold        out.writeInt(port);
558dc1fd0237992e1d693376b4f6eea45e7447e9dbNathan Harold        out.writeParcelable(fileDescriptor, Parcelable.PARCELABLE_WRITE_RETURN_VALUE);
568dc1fd0237992e1d693376b4f6eea45e7447e9dbNathan Harold    }
578dc1fd0237992e1d693376b4f6eea45e7447e9dbNathan Harold
588dc1fd0237992e1d693376b4f6eea45e7447e9dbNathan Harold    public IpSecUdpEncapResponse(int inStatus) {
598dc1fd0237992e1d693376b4f6eea45e7447e9dbNathan Harold        if (inStatus == IpSecManager.Status.OK) {
608dc1fd0237992e1d693376b4f6eea45e7447e9dbNathan Harold            throw new IllegalArgumentException("Valid status implies other args must be provided");
618dc1fd0237992e1d693376b4f6eea45e7447e9dbNathan Harold        }
628dc1fd0237992e1d693376b4f6eea45e7447e9dbNathan Harold        status = inStatus;
638dc1fd0237992e1d693376b4f6eea45e7447e9dbNathan Harold        resourceId = IpSecManager.INVALID_RESOURCE_ID;
648dc1fd0237992e1d693376b4f6eea45e7447e9dbNathan Harold        port = -1;
658dc1fd0237992e1d693376b4f6eea45e7447e9dbNathan Harold        fileDescriptor = null; // yes I know it's redundant, but readability
668dc1fd0237992e1d693376b4f6eea45e7447e9dbNathan Harold    }
678dc1fd0237992e1d693376b4f6eea45e7447e9dbNathan Harold
688dc1fd0237992e1d693376b4f6eea45e7447e9dbNathan Harold    public IpSecUdpEncapResponse(int inStatus, int inResourceId, int inPort, FileDescriptor inFd)
698dc1fd0237992e1d693376b4f6eea45e7447e9dbNathan Harold            throws IOException {
708dc1fd0237992e1d693376b4f6eea45e7447e9dbNathan Harold        if (inStatus == IpSecManager.Status.OK && inFd == null) {
718dc1fd0237992e1d693376b4f6eea45e7447e9dbNathan Harold            throw new IllegalArgumentException("Valid status implies FD must be non-null");
728dc1fd0237992e1d693376b4f6eea45e7447e9dbNathan Harold        }
738dc1fd0237992e1d693376b4f6eea45e7447e9dbNathan Harold        status = inStatus;
748dc1fd0237992e1d693376b4f6eea45e7447e9dbNathan Harold        resourceId = inResourceId;
758dc1fd0237992e1d693376b4f6eea45e7447e9dbNathan Harold        port = inPort;
768dc1fd0237992e1d693376b4f6eea45e7447e9dbNathan Harold        fileDescriptor = (status == IpSecManager.Status.OK) ? ParcelFileDescriptor.dup(inFd) : null;
778dc1fd0237992e1d693376b4f6eea45e7447e9dbNathan Harold    }
788dc1fd0237992e1d693376b4f6eea45e7447e9dbNathan Harold
798dc1fd0237992e1d693376b4f6eea45e7447e9dbNathan Harold    private IpSecUdpEncapResponse(Parcel in) {
808dc1fd0237992e1d693376b4f6eea45e7447e9dbNathan Harold        status = in.readInt();
818dc1fd0237992e1d693376b4f6eea45e7447e9dbNathan Harold        resourceId = in.readInt();
828dc1fd0237992e1d693376b4f6eea45e7447e9dbNathan Harold        port = in.readInt();
838dc1fd0237992e1d693376b4f6eea45e7447e9dbNathan Harold        fileDescriptor = in.readParcelable(ParcelFileDescriptor.class.getClassLoader());
848dc1fd0237992e1d693376b4f6eea45e7447e9dbNathan Harold    }
858dc1fd0237992e1d693376b4f6eea45e7447e9dbNathan Harold
868dc1fd0237992e1d693376b4f6eea45e7447e9dbNathan Harold    public static final Parcelable.Creator<IpSecUdpEncapResponse> CREATOR =
878dc1fd0237992e1d693376b4f6eea45e7447e9dbNathan Harold            new Parcelable.Creator<IpSecUdpEncapResponse>() {
888dc1fd0237992e1d693376b4f6eea45e7447e9dbNathan Harold                public IpSecUdpEncapResponse createFromParcel(Parcel in) {
898dc1fd0237992e1d693376b4f6eea45e7447e9dbNathan Harold                    return new IpSecUdpEncapResponse(in);
908dc1fd0237992e1d693376b4f6eea45e7447e9dbNathan Harold                }
918dc1fd0237992e1d693376b4f6eea45e7447e9dbNathan Harold
928dc1fd0237992e1d693376b4f6eea45e7447e9dbNathan Harold                public IpSecUdpEncapResponse[] newArray(int size) {
938dc1fd0237992e1d693376b4f6eea45e7447e9dbNathan Harold                    return new IpSecUdpEncapResponse[size];
948dc1fd0237992e1d693376b4f6eea45e7447e9dbNathan Harold                }
958dc1fd0237992e1d693376b4f6eea45e7447e9dbNathan Harold            };
968dc1fd0237992e1d693376b4f6eea45e7447e9dbNathan Harold}
97