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