17899c5ab935cf542069835ec7d3e457db596dbf7Narayan Kamath/* 27899c5ab935cf542069835ec7d3e457db596dbf7Narayan Kamath * Copyright (C) 2012 Square, Inc. 37899c5ab935cf542069835ec7d3e457db596dbf7Narayan Kamath * 47899c5ab935cf542069835ec7d3e457db596dbf7Narayan Kamath * Licensed under the Apache License, Version 2.0 (the "License"); 57899c5ab935cf542069835ec7d3e457db596dbf7Narayan Kamath * you may not use this file except in compliance with the License. 67899c5ab935cf542069835ec7d3e457db596dbf7Narayan Kamath * You may obtain a copy of the License at 77899c5ab935cf542069835ec7d3e457db596dbf7Narayan Kamath * 87899c5ab935cf542069835ec7d3e457db596dbf7Narayan Kamath * http://www.apache.org/licenses/LICENSE-2.0 97899c5ab935cf542069835ec7d3e457db596dbf7Narayan Kamath * 107899c5ab935cf542069835ec7d3e457db596dbf7Narayan Kamath * Unless required by applicable law or agreed to in writing, software 117899c5ab935cf542069835ec7d3e457db596dbf7Narayan Kamath * distributed under the License is distributed on an "AS IS" BASIS, 127899c5ab935cf542069835ec7d3e457db596dbf7Narayan Kamath * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 137899c5ab935cf542069835ec7d3e457db596dbf7Narayan Kamath * See the License for the specific language governing permissions and 147899c5ab935cf542069835ec7d3e457db596dbf7Narayan Kamath * limitations under the License. 157899c5ab935cf542069835ec7d3e457db596dbf7Narayan Kamath */ 162231db3e6bb54447a9b14cf004a6cb03c373651cjwilsonpackage com.squareup.okhttp.internal.spdy; 177899c5ab935cf542069835ec7d3e457db596dbf7Narayan Kamath 187899c5ab935cf542069835ec7d3e457db596dbf7Narayan Kamathfinal class Settings { 1954cf3446000fdcf88a9e62724f7deb0282e98da1jwilson /** 2054cf3446000fdcf88a9e62724f7deb0282e98da1jwilson * From the spdy/3 spec, the default initial window size for all streams is 2154cf3446000fdcf88a9e62724f7deb0282e98da1jwilson * 64 KiB. (Chrome 25 uses 10 MiB). 2254cf3446000fdcf88a9e62724f7deb0282e98da1jwilson */ 2354cf3446000fdcf88a9e62724f7deb0282e98da1jwilson static final int DEFAULT_INITIAL_WINDOW_SIZE = 64 * 1024; 2454cf3446000fdcf88a9e62724f7deb0282e98da1jwilson 2554cf3446000fdcf88a9e62724f7deb0282e98da1jwilson /** Peer request to clear durable settings. */ 2654cf3446000fdcf88a9e62724f7deb0282e98da1jwilson static final int FLAG_CLEAR_PREVIOUSLY_PERSISTED_SETTINGS = 0x1; 2754cf3446000fdcf88a9e62724f7deb0282e98da1jwilson 2854cf3446000fdcf88a9e62724f7deb0282e98da1jwilson /** Sent by servers only. The peer requests this setting persisted for future connections. */ 2954cf3446000fdcf88a9e62724f7deb0282e98da1jwilson static final int PERSIST_VALUE = 0x1; 3054cf3446000fdcf88a9e62724f7deb0282e98da1jwilson /** Sent by clients only. The client is reminding the server of a persisted value. */ 3154cf3446000fdcf88a9e62724f7deb0282e98da1jwilson static final int PERSISTED = 0x2; 3254cf3446000fdcf88a9e62724f7deb0282e98da1jwilson 3354cf3446000fdcf88a9e62724f7deb0282e98da1jwilson /** Sender's estimate of max incoming kbps. */ 3454cf3446000fdcf88a9e62724f7deb0282e98da1jwilson static final int UPLOAD_BANDWIDTH = 0x1; 3554cf3446000fdcf88a9e62724f7deb0282e98da1jwilson /** Sender's estimate of max outgoing kbps. */ 3654cf3446000fdcf88a9e62724f7deb0282e98da1jwilson static final int DOWNLOAD_BANDWIDTH = 0x2; 3754cf3446000fdcf88a9e62724f7deb0282e98da1jwilson /** Sender's estimate of milliseconds between sending a request and receiving a response. */ 3854cf3446000fdcf88a9e62724f7deb0282e98da1jwilson static final int ROUND_TRIP_TIME = 0x3; 3954cf3446000fdcf88a9e62724f7deb0282e98da1jwilson /** Sender's maximum number of concurrent streams. */ 4054cf3446000fdcf88a9e62724f7deb0282e98da1jwilson static final int MAX_CONCURRENT_STREAMS = 0x4; 4154cf3446000fdcf88a9e62724f7deb0282e98da1jwilson /** Current CWND in Packets. */ 4254cf3446000fdcf88a9e62724f7deb0282e98da1jwilson static final int CURRENT_CWND = 0x5; 4354cf3446000fdcf88a9e62724f7deb0282e98da1jwilson /** Retransmission rate. Percentage */ 4454cf3446000fdcf88a9e62724f7deb0282e98da1jwilson static final int DOWNLOAD_RETRANS_RATE = 0x6; 4554cf3446000fdcf88a9e62724f7deb0282e98da1jwilson /** Window size in bytes. */ 4654cf3446000fdcf88a9e62724f7deb0282e98da1jwilson static final int INITIAL_WINDOW_SIZE = 0x7; 4754cf3446000fdcf88a9e62724f7deb0282e98da1jwilson /** Window size in bytes. */ 4854cf3446000fdcf88a9e62724f7deb0282e98da1jwilson static final int CLIENT_CERTIFICATE_VECTOR_SIZE = 0x8; 4954cf3446000fdcf88a9e62724f7deb0282e98da1jwilson /** Total number of settings. */ 5054cf3446000fdcf88a9e62724f7deb0282e98da1jwilson static final int COUNT = 0x9; 5154cf3446000fdcf88a9e62724f7deb0282e98da1jwilson 5254cf3446000fdcf88a9e62724f7deb0282e98da1jwilson /** Bitfield of which flags that values. */ 5354cf3446000fdcf88a9e62724f7deb0282e98da1jwilson private int set; 5454cf3446000fdcf88a9e62724f7deb0282e98da1jwilson 5554cf3446000fdcf88a9e62724f7deb0282e98da1jwilson /** Bitfield of flags that have {@link #PERSIST_VALUE}. */ 5654cf3446000fdcf88a9e62724f7deb0282e98da1jwilson private int persistValue; 5754cf3446000fdcf88a9e62724f7deb0282e98da1jwilson 5854cf3446000fdcf88a9e62724f7deb0282e98da1jwilson /** Bitfield of flags that have {@link #PERSISTED}. */ 5954cf3446000fdcf88a9e62724f7deb0282e98da1jwilson private int persisted; 6054cf3446000fdcf88a9e62724f7deb0282e98da1jwilson 6154cf3446000fdcf88a9e62724f7deb0282e98da1jwilson /** Flag values. */ 6254cf3446000fdcf88a9e62724f7deb0282e98da1jwilson private final int[] values = new int[COUNT]; 6354cf3446000fdcf88a9e62724f7deb0282e98da1jwilson 6454cf3446000fdcf88a9e62724f7deb0282e98da1jwilson void set(int id, int idFlags, int value) { 6554cf3446000fdcf88a9e62724f7deb0282e98da1jwilson if (id >= values.length) { 6654cf3446000fdcf88a9e62724f7deb0282e98da1jwilson return; // Discard unknown settings. 677899c5ab935cf542069835ec7d3e457db596dbf7Narayan Kamath } 687899c5ab935cf542069835ec7d3e457db596dbf7Narayan Kamath 6954cf3446000fdcf88a9e62724f7deb0282e98da1jwilson int bit = 1 << id; 7054cf3446000fdcf88a9e62724f7deb0282e98da1jwilson set |= bit; 7154cf3446000fdcf88a9e62724f7deb0282e98da1jwilson if ((idFlags & PERSIST_VALUE) != 0) { 7254cf3446000fdcf88a9e62724f7deb0282e98da1jwilson persistValue |= bit; 7354cf3446000fdcf88a9e62724f7deb0282e98da1jwilson } else { 7454cf3446000fdcf88a9e62724f7deb0282e98da1jwilson persistValue &= ~bit; 757899c5ab935cf542069835ec7d3e457db596dbf7Narayan Kamath } 7654cf3446000fdcf88a9e62724f7deb0282e98da1jwilson if ((idFlags & PERSISTED) != 0) { 7754cf3446000fdcf88a9e62724f7deb0282e98da1jwilson persisted |= bit; 7854cf3446000fdcf88a9e62724f7deb0282e98da1jwilson } else { 7954cf3446000fdcf88a9e62724f7deb0282e98da1jwilson persisted &= ~bit; 807899c5ab935cf542069835ec7d3e457db596dbf7Narayan Kamath } 817899c5ab935cf542069835ec7d3e457db596dbf7Narayan Kamath 8254cf3446000fdcf88a9e62724f7deb0282e98da1jwilson values[id] = value; 8354cf3446000fdcf88a9e62724f7deb0282e98da1jwilson } 8454cf3446000fdcf88a9e62724f7deb0282e98da1jwilson 8554cf3446000fdcf88a9e62724f7deb0282e98da1jwilson /** Returns true if a value has been assigned for the setting {@code id}. */ 8654cf3446000fdcf88a9e62724f7deb0282e98da1jwilson boolean isSet(int id) { 8754cf3446000fdcf88a9e62724f7deb0282e98da1jwilson int bit = 1 << id; 8854cf3446000fdcf88a9e62724f7deb0282e98da1jwilson return (set & bit) != 0; 8954cf3446000fdcf88a9e62724f7deb0282e98da1jwilson } 9054cf3446000fdcf88a9e62724f7deb0282e98da1jwilson 9154cf3446000fdcf88a9e62724f7deb0282e98da1jwilson /** Returns the value for the setting {@code id}, or 0 if unset. */ 9254cf3446000fdcf88a9e62724f7deb0282e98da1jwilson int get(int id) { 9354cf3446000fdcf88a9e62724f7deb0282e98da1jwilson return values[id]; 9454cf3446000fdcf88a9e62724f7deb0282e98da1jwilson } 9554cf3446000fdcf88a9e62724f7deb0282e98da1jwilson 9654cf3446000fdcf88a9e62724f7deb0282e98da1jwilson /** Returns the flags for the setting {@code id}, or 0 if unset. */ 9754cf3446000fdcf88a9e62724f7deb0282e98da1jwilson int flags(int id) { 9854cf3446000fdcf88a9e62724f7deb0282e98da1jwilson int result = 0; 9954cf3446000fdcf88a9e62724f7deb0282e98da1jwilson if (isPersisted(id)) result |= Settings.PERSISTED; 10054cf3446000fdcf88a9e62724f7deb0282e98da1jwilson if (persistValue(id)) result |= Settings.PERSIST_VALUE; 10154cf3446000fdcf88a9e62724f7deb0282e98da1jwilson return result; 10254cf3446000fdcf88a9e62724f7deb0282e98da1jwilson } 10354cf3446000fdcf88a9e62724f7deb0282e98da1jwilson 10454cf3446000fdcf88a9e62724f7deb0282e98da1jwilson /** Returns the number of settings that have values assigned. */ 10554cf3446000fdcf88a9e62724f7deb0282e98da1jwilson int size() { 10654cf3446000fdcf88a9e62724f7deb0282e98da1jwilson return Integer.bitCount(set); 10754cf3446000fdcf88a9e62724f7deb0282e98da1jwilson } 10854cf3446000fdcf88a9e62724f7deb0282e98da1jwilson 10954cf3446000fdcf88a9e62724f7deb0282e98da1jwilson int getUploadBandwidth(int defaultValue) { 11054cf3446000fdcf88a9e62724f7deb0282e98da1jwilson int bit = 1 << UPLOAD_BANDWIDTH; 11154cf3446000fdcf88a9e62724f7deb0282e98da1jwilson return (bit & set) != 0 ? values[UPLOAD_BANDWIDTH] : defaultValue; 11254cf3446000fdcf88a9e62724f7deb0282e98da1jwilson } 11354cf3446000fdcf88a9e62724f7deb0282e98da1jwilson 11454cf3446000fdcf88a9e62724f7deb0282e98da1jwilson int getDownloadBandwidth(int defaultValue) { 11554cf3446000fdcf88a9e62724f7deb0282e98da1jwilson int bit = 1 << DOWNLOAD_BANDWIDTH; 11654cf3446000fdcf88a9e62724f7deb0282e98da1jwilson return (bit & set) != 0 ? values[DOWNLOAD_BANDWIDTH] : defaultValue; 11754cf3446000fdcf88a9e62724f7deb0282e98da1jwilson } 11854cf3446000fdcf88a9e62724f7deb0282e98da1jwilson 11954cf3446000fdcf88a9e62724f7deb0282e98da1jwilson int getRoundTripTime(int defaultValue) { 12054cf3446000fdcf88a9e62724f7deb0282e98da1jwilson int bit = 1 << ROUND_TRIP_TIME; 12154cf3446000fdcf88a9e62724f7deb0282e98da1jwilson return (bit & set) != 0 ? values[ROUND_TRIP_TIME] : defaultValue; 12254cf3446000fdcf88a9e62724f7deb0282e98da1jwilson } 12354cf3446000fdcf88a9e62724f7deb0282e98da1jwilson 12454cf3446000fdcf88a9e62724f7deb0282e98da1jwilson int getMaxConcurrentStreams(int defaultValue) { 12554cf3446000fdcf88a9e62724f7deb0282e98da1jwilson int bit = 1 << MAX_CONCURRENT_STREAMS; 12654cf3446000fdcf88a9e62724f7deb0282e98da1jwilson return (bit & set) != 0 ? values[MAX_CONCURRENT_STREAMS] : defaultValue; 12754cf3446000fdcf88a9e62724f7deb0282e98da1jwilson } 12854cf3446000fdcf88a9e62724f7deb0282e98da1jwilson 12954cf3446000fdcf88a9e62724f7deb0282e98da1jwilson int getCurrentCwnd(int defaultValue) { 13054cf3446000fdcf88a9e62724f7deb0282e98da1jwilson int bit = 1 << CURRENT_CWND; 13154cf3446000fdcf88a9e62724f7deb0282e98da1jwilson return (bit & set) != 0 ? values[CURRENT_CWND] : defaultValue; 13254cf3446000fdcf88a9e62724f7deb0282e98da1jwilson } 13354cf3446000fdcf88a9e62724f7deb0282e98da1jwilson 13454cf3446000fdcf88a9e62724f7deb0282e98da1jwilson int getDownloadRetransRate(int defaultValue) { 13554cf3446000fdcf88a9e62724f7deb0282e98da1jwilson int bit = 1 << DOWNLOAD_RETRANS_RATE; 13654cf3446000fdcf88a9e62724f7deb0282e98da1jwilson return (bit & set) != 0 ? values[DOWNLOAD_RETRANS_RATE] : defaultValue; 13754cf3446000fdcf88a9e62724f7deb0282e98da1jwilson } 13854cf3446000fdcf88a9e62724f7deb0282e98da1jwilson 13954cf3446000fdcf88a9e62724f7deb0282e98da1jwilson int getInitialWindowSize(int defaultValue) { 14054cf3446000fdcf88a9e62724f7deb0282e98da1jwilson int bit = 1 << INITIAL_WINDOW_SIZE; 14154cf3446000fdcf88a9e62724f7deb0282e98da1jwilson return (bit & set) != 0 ? values[INITIAL_WINDOW_SIZE] : defaultValue; 14254cf3446000fdcf88a9e62724f7deb0282e98da1jwilson } 14354cf3446000fdcf88a9e62724f7deb0282e98da1jwilson 14454cf3446000fdcf88a9e62724f7deb0282e98da1jwilson int getClientCertificateVectorSize(int defaultValue) { 14554cf3446000fdcf88a9e62724f7deb0282e98da1jwilson int bit = 1 << CLIENT_CERTIFICATE_VECTOR_SIZE; 14654cf3446000fdcf88a9e62724f7deb0282e98da1jwilson return (bit & set) != 0 ? values[CLIENT_CERTIFICATE_VECTOR_SIZE] : defaultValue; 14754cf3446000fdcf88a9e62724f7deb0282e98da1jwilson } 14854cf3446000fdcf88a9e62724f7deb0282e98da1jwilson 14954cf3446000fdcf88a9e62724f7deb0282e98da1jwilson /** 15054cf3446000fdcf88a9e62724f7deb0282e98da1jwilson * Returns true if this user agent should use this setting in future SPDY 15154cf3446000fdcf88a9e62724f7deb0282e98da1jwilson * connections to the same host. 15254cf3446000fdcf88a9e62724f7deb0282e98da1jwilson */ 15354cf3446000fdcf88a9e62724f7deb0282e98da1jwilson boolean persistValue(int id) { 15454cf3446000fdcf88a9e62724f7deb0282e98da1jwilson int bit = 1 << id; 15554cf3446000fdcf88a9e62724f7deb0282e98da1jwilson return (persistValue & bit) != 0; 15654cf3446000fdcf88a9e62724f7deb0282e98da1jwilson } 15754cf3446000fdcf88a9e62724f7deb0282e98da1jwilson 15854cf3446000fdcf88a9e62724f7deb0282e98da1jwilson /** Returns true if this setting was persisted. */ 15954cf3446000fdcf88a9e62724f7deb0282e98da1jwilson boolean isPersisted(int id) { 16054cf3446000fdcf88a9e62724f7deb0282e98da1jwilson int bit = 1 << id; 16154cf3446000fdcf88a9e62724f7deb0282e98da1jwilson return (persisted & bit) != 0; 16254cf3446000fdcf88a9e62724f7deb0282e98da1jwilson } 16354cf3446000fdcf88a9e62724f7deb0282e98da1jwilson 16454cf3446000fdcf88a9e62724f7deb0282e98da1jwilson /** 16554cf3446000fdcf88a9e62724f7deb0282e98da1jwilson * Writes {@code other} into this. If any setting is populated by this and 16654cf3446000fdcf88a9e62724f7deb0282e98da1jwilson * {@code other}, the value and flags from {@code other} will be kept. 16754cf3446000fdcf88a9e62724f7deb0282e98da1jwilson */ 16854cf3446000fdcf88a9e62724f7deb0282e98da1jwilson void merge(Settings other) { 16954cf3446000fdcf88a9e62724f7deb0282e98da1jwilson for (int i = 0; i < COUNT; i++) { 17054cf3446000fdcf88a9e62724f7deb0282e98da1jwilson if (!other.isSet(i)) continue; 17154cf3446000fdcf88a9e62724f7deb0282e98da1jwilson set(i, other.flags(i), other.get(i)); 1727899c5ab935cf542069835ec7d3e457db596dbf7Narayan Kamath } 17354cf3446000fdcf88a9e62724f7deb0282e98da1jwilson } 1747899c5ab935cf542069835ec7d3e457db596dbf7Narayan Kamath} 175