1 /* 2 * Copyright (c) 2014, Oracle and/or its affiliates. All rights reserved. 3 * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. 4 * 5 * This code is free software; you can redistribute it and/or modify it 6 * under the terms of the GNU General Public License version 2 only, as 7 * published by the Free Software Foundation. Oracle designates this 8 * particular file as subject to the "Classpath" exception as provided 9 * by Oracle in the LICENSE file that accompanied this code. 10 * 11 * This code is distributed in the hope that it will be useful, but WITHOUT 12 * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or 13 * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License 14 * version 2 for more details (a copy is included in the LICENSE file that 15 * accompanied this code). 16 * 17 * You should have received a copy of the GNU General Public License version 18 * 2 along with this work; if not, write to the Free Software Foundation, 19 * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA. 20 * 21 * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA 22 * or visit www.oracle.com if you need additional information or have any 23 * questions. 24 */ 25 26 package jdk.net; 27 28 import java.lang.annotation.Native; 29 30 /** 31 * Represents the service level properties for the platform specific socket 32 * option {@link ExtendedSocketOptions#SO_FLOW_SLA}. 33 * <p> 34 * The priority and bandwidth parameters must be set before 35 * setting the socket option. 36 * <p> 37 * When the {@code SO_FLOW_SLA} option is set then it may not take effect 38 * immediately. If the value of the socket option is obtained with 39 * {@code getOption()} then the status may be returned as {@code INPROGRESS} 40 * until it takes effect. The priority and bandwidth values are only valid when 41 * the status is returned as OK. 42 * <p> 43 * When a security manager is installed, a {@link NetworkPermission} 44 * is required to set or get this option. 45 * 46 * @since 1.8 47 */ 48 // Android-removed: @jdk.Exported, not present on Android. 49 // @jdk.Exported 50 public class SocketFlow { 51 52 @Native public static final int UNSET = -1; 53 @Native public static final int NORMAL_PRIORITY = 1; 54 @Native public static final int HIGH_PRIORITY = 2; 55 56 @Native private static final int NO_STATUS_VALUE = 0; 57 @Native private static final int OK_VALUE = 1; 58 @Native private static final int NO_PERMISSION_VALUE = 2; 59 @Native private static final int NOT_CONNECTED_VALUE = 3; 60 @Native private static final int NOT_SUPPORTED_VALUE = 4; 61 @Native private static final int ALREADY_CREATED_VALUE = 5; 62 @Native private static final int IN_PROGRESS_VALUE = 6; 63 @Native private static final int OTHER_VALUE = 7; 64 65 /** 66 * Enumeration of the return values from the SO_FLOW_SLA 67 * socket option. Both setting and getting the option return 68 * one of these statuses, which reflect the state of socket's 69 * flow. 70 * 71 * @since 1.8 72 */ 73 // Android-removed: @jdk.Exported, not present on Android. 74 // @jdk.Exported 75 public enum Status { 76 /** 77 * Set or get socket option has not been called yet. Status 78 * values can only be retrieved after calling set or get. 79 */ 80 NO_STATUS(NO_STATUS_VALUE), 81 /** 82 * Flow successfully created. 83 */ 84 OK(OK_VALUE), 85 /** 86 * Caller has no permission to create flow. 87 */ 88 NO_PERMISSION(NO_PERMISSION_VALUE), 89 /** 90 * Flow can not be created because socket is not connected. 91 */ 92 NOT_CONNECTED(NOT_CONNECTED_VALUE), 93 /** 94 * Flow creation not supported for this socket. 95 */ 96 NOT_SUPPORTED(NOT_SUPPORTED_VALUE), 97 /** 98 * A flow already exists with identical attributes. 99 */ 100 ALREADY_CREATED(ALREADY_CREATED_VALUE), 101 /** 102 * A flow is being created. 103 */ 104 IN_PROGRESS(IN_PROGRESS_VALUE), 105 /** 106 * Some other unspecified error. 107 */ 108 OTHER(OTHER_VALUE); 109 110 private final int value; Status(int value)111 Status(int value) { this.value = value; } 112 from(int value)113 static Status from(int value) { 114 if (value == NO_STATUS.value) return NO_STATUS; 115 else if (value == OK.value) return OK; 116 else if (value == NO_PERMISSION.value) return NO_PERMISSION; 117 else if (value == NOT_CONNECTED.value) return NOT_CONNECTED; 118 else if (value == NOT_SUPPORTED.value) return NOT_SUPPORTED; 119 else if (value == ALREADY_CREATED.value) return ALREADY_CREATED; 120 else if (value == IN_PROGRESS.value) return IN_PROGRESS; 121 else if (value == OTHER.value) return OTHER; 122 else throw new InternalError("Unknown value: " + value); 123 } 124 } 125 126 private int priority = NORMAL_PRIORITY; 127 private long bandwidth = UNSET; 128 private Status status = Status.NO_STATUS; 129 130 /** 131 * Creates a new SocketFlow that can be used to set the SO_FLOW_SLA 132 * socket option and create a socket flow. 133 */ create()134 public static SocketFlow create() { 135 return new SocketFlow(); 136 } 137 SocketFlow()138 private SocketFlow() { } 139 140 /** 141 * Sets this SocketFlow's priority. Must be either NORMAL_PRIORITY 142 * HIGH_PRIORITY. If not set, a flow's priority is normal. 143 * 144 * @throws IllegalArgumentException if priority is not NORMAL_PRIORITY or 145 * HIGH_PRIORITY. 146 */ priority(int priority)147 public SocketFlow priority(int priority) { 148 if (priority != NORMAL_PRIORITY && priority != HIGH_PRIORITY) 149 throw new IllegalArgumentException("invalid priority :" + priority); 150 this.priority = priority; 151 return this; 152 } 153 154 /** 155 * Sets this SocketFlow's bandwidth. Must be greater than or equal to zero. 156 * A value of zero drops all packets for the socket. 157 * 158 * @throws IllegalArgumentException if bandwidth is less than zero. 159 */ bandwidth(long bandwidth)160 public SocketFlow bandwidth(long bandwidth) { 161 if (bandwidth < 0) 162 throw new IllegalArgumentException("invalid bandwidth: " + bandwidth); 163 this.bandwidth = bandwidth; 164 return this; 165 } 166 167 /** 168 * Returns this SocketFlow's priority. 169 */ priority()170 public int priority() { 171 return priority; 172 } 173 174 /** 175 * Returns this SocketFlow's bandwidth. 176 * 177 * @return this SocketFlow's bandwidth, or {@code -1} if status is not OK. 178 */ bandwidth()179 public long bandwidth() { 180 return bandwidth; 181 } 182 183 /** 184 * Returns the Status value of this SocketFlow. NO_STATUS is returned 185 * if the object was not used in a call to set or get the option. 186 */ status()187 public Status status() { 188 return status; 189 } 190 status(int status)191 void status(int status) { 192 this.status = Status.from(status); 193 } 194 195 @Override toString()196 public String toString() { 197 StringBuilder sb = new StringBuilder(super.toString()); 198 sb.append(" [ priority=").append(priority()) 199 .append(", bandwidth=").append(bandwidth()) 200 .append(", status=").append(status()) 201 .append(" ]"); 202 return sb.toString(); 203 } 204 } 205