Home | History | Annotate | Download | only in spdy
      1 /*
      2  * Copyright (C) 2012 Square, Inc.
      3  *
      4  * Licensed under the Apache License, Version 2.0 (the "License");
      5  * you may not use this file except in compliance with the License.
      6  * You may obtain a copy of the License at
      7  *
      8  *      http://www.apache.org/licenses/LICENSE-2.0
      9  *
     10  * Unless required by applicable law or agreed to in writing, software
     11  * distributed under the License is distributed on an "AS IS" BASIS,
     12  * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
     13  * See the License for the specific language governing permissions and
     14  * limitations under the License.
     15  */
     16 package com.squareup.okhttp.internal.spdy;
     17 
     18 final class Settings {
     19   /**
     20    * From the spdy/3 spec, the default initial window size for all streams is
     21    * 64 KiB. (Chrome 25 uses 10 MiB).
     22    */
     23   static final int DEFAULT_INITIAL_WINDOW_SIZE = 64 * 1024;
     24 
     25   /** Peer request to clear durable settings. */
     26   static final int FLAG_CLEAR_PREVIOUSLY_PERSISTED_SETTINGS = 0x1;
     27 
     28   /** Sent by servers only. The peer requests this setting persisted for future connections. */
     29   static final int PERSIST_VALUE = 0x1;
     30   /** Sent by clients only. The client is reminding the server of a persisted value. */
     31   static final int PERSISTED = 0x2;
     32 
     33   /** Sender's estimate of max incoming kbps. */
     34   static final int UPLOAD_BANDWIDTH = 0x1;
     35   /** Sender's estimate of max outgoing kbps. */
     36   static final int DOWNLOAD_BANDWIDTH = 0x2;
     37   /** Sender's estimate of milliseconds between sending a request and receiving a response. */
     38   static final int ROUND_TRIP_TIME = 0x3;
     39   /** Sender's maximum number of concurrent streams. */
     40   static final int MAX_CONCURRENT_STREAMS = 0x4;
     41   /** Current CWND in Packets. */
     42   static final int CURRENT_CWND = 0x5;
     43   /** Retransmission rate. Percentage */
     44   static final int DOWNLOAD_RETRANS_RATE = 0x6;
     45   /** Window size in bytes. */
     46   static final int INITIAL_WINDOW_SIZE = 0x7;
     47   /** Window size in bytes. */
     48   static final int CLIENT_CERTIFICATE_VECTOR_SIZE = 0x8;
     49   /** Total number of settings. */
     50   static final int COUNT = 0x9;
     51 
     52   /** Bitfield of which flags that values. */
     53   private int set;
     54 
     55   /** Bitfield of flags that have {@link #PERSIST_VALUE}. */
     56   private int persistValue;
     57 
     58   /** Bitfield of flags that have {@link #PERSISTED}. */
     59   private int persisted;
     60 
     61   /** Flag values. */
     62   private final int[] values = new int[COUNT];
     63 
     64   void set(int id, int idFlags, int value) {
     65     if (id >= values.length) {
     66       return; // Discard unknown settings.
     67     }
     68 
     69     int bit = 1 << id;
     70     set |= bit;
     71     if ((idFlags & PERSIST_VALUE) != 0) {
     72       persistValue |= bit;
     73     } else {
     74       persistValue &= ~bit;
     75     }
     76     if ((idFlags & PERSISTED) != 0) {
     77       persisted |= bit;
     78     } else {
     79       persisted &= ~bit;
     80     }
     81 
     82     values[id] = value;
     83   }
     84 
     85   /** Returns true if a value has been assigned for the setting {@code id}. */
     86   boolean isSet(int id) {
     87     int bit = 1 << id;
     88     return (set & bit) != 0;
     89   }
     90 
     91   /** Returns the value for the setting {@code id}, or 0 if unset. */
     92   int get(int id) {
     93     return values[id];
     94   }
     95 
     96   /** Returns the flags for the setting {@code id}, or 0 if unset. */
     97   int flags(int id) {
     98     int result = 0;
     99     if (isPersisted(id)) result |= Settings.PERSISTED;
    100     if (persistValue(id)) result |= Settings.PERSIST_VALUE;
    101     return result;
    102   }
    103 
    104   /** Returns the number of settings that have values assigned. */
    105   int size() {
    106     return Integer.bitCount(set);
    107   }
    108 
    109   int getUploadBandwidth(int defaultValue) {
    110     int bit = 1 << UPLOAD_BANDWIDTH;
    111     return (bit & set) != 0 ? values[UPLOAD_BANDWIDTH] : defaultValue;
    112   }
    113 
    114   int getDownloadBandwidth(int defaultValue) {
    115     int bit = 1 << DOWNLOAD_BANDWIDTH;
    116     return (bit & set) != 0 ? values[DOWNLOAD_BANDWIDTH] : defaultValue;
    117   }
    118 
    119   int getRoundTripTime(int defaultValue) {
    120     int bit = 1 << ROUND_TRIP_TIME;
    121     return (bit & set) != 0 ? values[ROUND_TRIP_TIME] : defaultValue;
    122   }
    123 
    124   int getMaxConcurrentStreams(int defaultValue) {
    125     int bit = 1 << MAX_CONCURRENT_STREAMS;
    126     return (bit & set) != 0 ? values[MAX_CONCURRENT_STREAMS] : defaultValue;
    127   }
    128 
    129   int getCurrentCwnd(int defaultValue) {
    130     int bit = 1 << CURRENT_CWND;
    131     return (bit & set) != 0 ? values[CURRENT_CWND] : defaultValue;
    132   }
    133 
    134   int getDownloadRetransRate(int defaultValue) {
    135     int bit = 1 << DOWNLOAD_RETRANS_RATE;
    136     return (bit & set) != 0 ? values[DOWNLOAD_RETRANS_RATE] : defaultValue;
    137   }
    138 
    139   int getInitialWindowSize(int defaultValue) {
    140     int bit = 1 << INITIAL_WINDOW_SIZE;
    141     return (bit & set) != 0 ? values[INITIAL_WINDOW_SIZE] : defaultValue;
    142   }
    143 
    144   int getClientCertificateVectorSize(int defaultValue) {
    145     int bit = 1 << CLIENT_CERTIFICATE_VECTOR_SIZE;
    146     return (bit & set) != 0 ? values[CLIENT_CERTIFICATE_VECTOR_SIZE] : defaultValue;
    147   }
    148 
    149   /**
    150    * Returns true if this user agent should use this setting in future SPDY
    151    * connections to the same host.
    152    */
    153   boolean persistValue(int id) {
    154     int bit = 1 << id;
    155     return (persistValue & bit) != 0;
    156   }
    157 
    158   /** Returns true if this setting was persisted. */
    159   boolean isPersisted(int id) {
    160     int bit = 1 << id;
    161     return (persisted & bit) != 0;
    162   }
    163 
    164   /**
    165    * Writes {@code other} into this. If any setting is populated by this and
    166    * {@code other}, the value and flags from {@code other} will be kept.
    167    */
    168   void merge(Settings other) {
    169     for (int i = 0; i < COUNT; i++) {
    170       if (!other.isSet(i)) continue;
    171       set(i, other.flags(i), other.get(i));
    172     }
    173   }
    174 }
    175