SlideShare a Scribd company logo
SPDYの中身を見てみる


• IIJ 大津繁樹
• ohtsuあっとiij.ad.jp

          2012年5月17日
SPDY フレームの種類と役割
   Data Frames         Control Frames

                 1.   SYN_STREAM
                 2.   SYN_REPLY
                 3.   RST_STREAM
                 4.   SETTINGS
                 5.   NOOP( spdy/3で廃止)
HTTPリクエスト・レスポン   6.   PING
スボディの送受信などで使     7.   GOAWAY
う                8.   HEADERS
                 9.   WINDOW_UPDATE
                 •    CREDENTIAL


                 HTTPリクエスト・レスポンス
                 ヘッダの送受信に使う
                 その他SPDY通信制御情報のやり
                 取りに使う
単純なSPDYのストリームフロー

               SSLハンドシェイク

         NPN (Next Protocol Negotiation) を
         使って SPDY 利用バージョンを交換

                 SYN_STREAM
          HTTPリクエストヘッダ情報を送信

                   SYN_REPLY

          HTTPレスポンスヘッダ情報を送信
クライアント                                       サーバー
                   DATA Frame

          HTTPレスポンスボディを送信

                   GOAWAY

          SPDYストリーム利用停止を通知
spdylayを使ってSPDYの中身を見る
 www.google.com サーバ編 (その1)
 $ ./examples/spdycat -v https://www.google.com

 NPNでプロトコル情報の交換
 [ 0.012] NPN select next protocol: the remote server offers:
       * spdy/3
       * spdy/2
       * http/1.1
       NPN selected the protocol: spdy/3


 google サーバから SDPYの設定情報が送られてくる
 [ 0.018] recv SETTINGS frame <version=3, flags=0, length=20>
       (niv=2)
       [4(1):100]
       [7(0):12288]
4: SETTINGS_MAX_CONCURRENT_STREAMS 最大同時アクティブなストリーム数
7: SETTINGS_INITIAL_WINDOW_SIZE ストリームの初期ウィンドウサイズ(バイト)
spdylayを使ってSPDYの中身を見る
       www.google.com サーバ編 (その2)
SYN_STREAMを使ってHTTPリクエストヘッダ情報をサーバに送信

[ 0.018] send SYN_STREAM frame <version=3, flags=1, length=106>
      (stream_id=1, assoc_stream_id=0, pri=3)
      :host: www.google.com
      :method: GET
      :path: /
      :scheme: https
      :version: HTTP/1.1
      accept: */*
      user-agent: spdylay/0.2.0
spdylayを使ってSPDYの中身を見る
          www.google.com サーバ編 (その3)
SYN_REPLY でHTTPレスポンスヘッダ情報がサーバから送られてくる
[ 0.057] recv SYN_REPLY frame <version=3, flags=0, length=558>
      (stream_id=1)
      :status: 302 Found
      :version: HTTP/1.1
      cache-control: private
      content-length: 222
      content-type: text/html; charset=UTF-8
      date: Thu, 17 May 2012 01:24:23 GMT
      location: https://www.google.co.jp/
      server: gws
     (以下略)
spdylayを使ってSPDYの中身を見る
       www.google.com サーバ編 (その4)
Dataフレーム でHTTPレスポンスボディがサーバから送られてくる

  <HTML><HEAD><meta http-equiv="content-type"
  content="text/html;charset=utf-8">
  <TITLE>302 Moved</TITLE></HEAD><BODY>
  <H1>302 Moved</H1>
  The document has moved
  <A HREF="https://www.google.co.jp/">here</A>.
  </BODY></HTML>
  [ 0.058] recv DATA frame (stream_id=1, flags=1, length=222)


SPDY終了
   [ 0.058] send GOAWAY frame <version=3, flags=0, length=8>
         (last_good_stream_id=0
spdylayを使ってSPDYの中身を見る
              Chrome ブラウザ編 (その1)
      ./examples/spdyd --htdocs=. -v 3000 ./foo-key.pem ./foo-cert.pem

  NPNでプロトコル情報の決定
[id=1] [ 5.046] closed
The negotiated next protocol: spdy/3

SYN_STREAMを使ってHTTPリクエストヘッダ情報がChromeから送られてくる

[id=2] [ 5.051] recv SYN_STREAM frame <version=3, flags=1, length=250>
      (stream_id=1, assoc_stream_id=0, pri=0)
      :host: unixjp:3000
      :method: GET
      :path: /
      :scheme: https
      :version: HTTP/1.1
      accept: text/html,application/xhtml+xml,application/xml;q=0.9,*/*;q=0.8
      accept-charset: Shift_JIS,utf-8;q=0.7,*;q=0.3
      (以下略)
spdylayを使ってSPDYの中身を見る
             Chrome ブラウザ編 (その2)
 サーバからSETTINGSによって同時ストリーム数の設定

 [id=2] [ 5.052] send SETTINGS frame <version=3, flags=0, length=12>
       (niv=1)
       [4(0):100]


SYN_REPLY でHTTPレスポンスヘッダ情報を Chrome に送る

[id=2] [ 5.052] send SYN_REPLY frame <version=3, flags=0, length=109>
      (stream_id=1)
      :status: 200 OK
      :version: HTTP/1.1
      cache-control: max-age=3600
      content-length: 40
      date: Thu, 17 May 2012 02:40:28 GMT
      last-modified: Mon, 14 May 2012 20:34:32 GMT
      server: spdyd spdylay/0.2.0
spdylayを使ってSPDYの中身を見る
            Chrome ブラウザ編 (その3)

データフレームでレスポンスボディを送信
最後のデータフレームは flag 1 (FLAG_FIN) を使ってストリームを
終了させてます。

[id=2] [ 5.052] send DATA frame (stream_id=1, flags=0, length=40)
[id=2] [ 5.053] send DATA frame (stream_id=1, flags=1, length=0)
[id=2] [ 5.053] stream_id=1 closed
spdylayを使ってSPDYの中身を見る
           Chrome ブラウザ編 (その4)
Chrome が favicon.ico を取りに来てるリクエスト

[id=2] [ 5.094] recv SYN_STREAM frame <version=3, flags=1, length=39>
      (stream_id=3, assoc_stream_id=0, pri=1)
      :host: unixjp:3000
      :method: GET
      :path: /favicon.ico
      :scheme: https
      :version: HTTP/1.1
      accept: */*
      accept-charset: Shift_JIS,utf-8;q=0.7,*;q=0.3
      accept-encoding: gzip,deflate,sdch
      accept-language: en-US,en;q=0.8
      user-agent: Mozilla/5.0 (Windows NT 6.1; WOW64) AppleWebKit/536.5
(KHTML, like Gecko) Chrome/19.0.1084.46 Safari/536.5
spdylayを使ってSPDYの中身を見る
            Chrome ブラウザ編 (その5)
favicon なんて用意していないので404を返す SYN_REPLY
[id=2] [ 5.095] send SYN_REPLY frame <version=3, flags=0, length=33>
      (stream_id=3)
      :status: 404 Not Found
      :version: HTTP/1.1
      content-encoding: gzip
      date: Thu, 17 May 2012 02:40:28 GMT
      server: spdyd spdylay/0.2.0

最後に Chrome から PING で SPDY の生存確認をしています。
[id=2] [ 6.048] recv PING frame <version=3, flags=0, length=4>
      (unique_id=1)
[id=2] [ 6.048] send PING frame <version=3, flags=0, length=4>
      (unique_id=1)
Control frames
0 1 2 3 4 5 6 7 8 9 0 1 2 3 4 5 6 7 8 9 0 1 2 3 4 5 6 7 8 9 0 1
1            version                          Type
     Flags                           Length
                             Data
Data frames
0 1 2 3 4 5 6 7 8 9 0 1 2 3 4 5 6 7 8 9 0 1 2 3 4 5 6 7 8 9 0 1
0                            Stream-ID
     Flags                               Length
                              Data

                              Flags
                    0x01 FLAG_FIN
                    0x02 FLAG_COMPRESS
SYN_STREAM
0 1 2 3 4 5 6 7 8 9 0 1 2 3 4 5 6 7 8 9 0 1 2 3 4 5 6 7 8 9 0 1
1                     version                                        1
          Flags                                           Length
X                                           Stream-ID
X                                   Associated-To-Stream-ID
    Pri      Unused               Slot               Number of Name/Value pairs (32bit)
                                 Number of Name/Value pairs
                                    Length of name (32bit)
                                         Name (string)
                                    Length of value (32bit)
                                         Value (string)

                                             Flags
                                0x01 FLAG_FIN
                                                                            圧縮データ
                                0x02 FLAG_UNIDIRECTIONAL
SYN_REPLY
0 1 2 3 4 5 6 7 8 9 0 1 2 3 4 5 6 7 8 9 0 1 2 3 4 5 6 7 8 9 0 1
1            version                                     2
     Flags                                      Length
X                                 Stream-ID
                        Number of Name/Value pairs
                              Length of name
                                  Name
                              Length of value
                                  Value


                                  Flags
                       0x01 FLAG_FIN


                                                             圧縮データ
RST_STREAM
0 1 2 3 4 5 6 7 8 9 0 1 2 3 4 5 6 7 8 9 0 1 2 3 4 5 6 7 8 9 0 1
1               version                                    3
    0 (flags)                                 8 (length)
X                                Stream-ID
                              Status Code



                                 Satus code
         1 PROTOCOL_ERROR             7     FLOW_CONTROL_ERROR
         2 INVALID_STREAM             8     STREAM_ALREADY_CLOSED
         3 REFUSED_STREAM             9     STREAM_IN_USE
         4 UNSUPPORTED_VERSION        10 INVALID_CREDENTIALS
         5 CANCEL                     11 FRAME_TOO_LARGE
         6 INTERNAL_ERROR
SETTINGS
0 1 2 3 4 5 6 7 8 9 0 1 2 3 4 5 6 7 8 9 0 1 2 3 4 5 6 7 8 9 0 1
1                    version                                              4
         Flags                                           Length

                                      Number of entries
        ID.flags                                            ID
                                            Value


                     Flags                                             ID.flags
              FLAG_SETTING_CLEAR_SETTINGS              0x01      FLAG_SETTINGS_PERSIST_VALUE
    0x01
                                                       0x02      FLAG_SETTINGS_PERSISTED

                                              ID
    1   SETTINGS_UPLOAD_BANDWIDTH                  5   SETTINGS_CURRENT_CWND

    2   SETTINGS_DOWNLOAD_BANDWIDTH                6   SETTINGS_DOWNLOAD_RETRANS_RATE

    3   SETTINGS_ROUND_TRIP_TIME                   7   SETTINGS_INITAL_WINDOW_SIZE

    4   SETTINGS_MAX_CONCURRENT_STREAM             8   SETTINGS_CLIENT_CERTIFICATE_VECTOR_SIZE
PING
0 1 2 3 4 5 6 7 8 9 0 1 2 3 4 5 6 7 8 9 0 1 2 3 4 5 6 7 8 9 0 1
1               version                              6
    0 (flags)                           4 (length)

                            32-bit ID
GOAWAY
0 1 2 3 4 5 6 7 8 9 0 1 2 3 4 5 6 7 8 9 0 1 2 3 4 5 6 7 8 9 0 1
1               version                                    7
    0 (flags)                                 8 (length)

X                             Last-good-stream-ID
                                Status code

                                Status code
                          0   OK
                          1   PROTOCOL_ERROR
                          11 INTERNAL_ERRRO
HEADERS
0 1 2 3 4 5 6 7 8 9 0 1 2 3 4 5 6 7 8 9 0 1 2 3 4 5 6 7 8 9 0 1
1            version                                     8
     Flags                                      Length
X                                 Stream-ID
                        Number of Name/Value pairs
                              Length of name
                                  Name
                              Length of value
                                  Value


                                  Flags
                       0x01 FLAG_FIN


                                                             圧縮データ
WINDOW_UPDATE
0 1 2 3 4 5 6 7 8 9 0 1 2 3 4 5 6 7 8 9 0 1 2 3 4 5 6 7 8 9 0 1
1               version                                   9
    0 (flags)                                8 (length)
X                                Stream-ID
X                            Delta-Window-Size

More Related Content

SPDYの中身を見てみよう

  • 1. SPDYの中身を見てみる • IIJ 大津繁樹 • ohtsuあっとiij.ad.jp 2012年5月17日
  • 2. SPDY フレームの種類と役割 Data Frames Control Frames 1. SYN_STREAM 2. SYN_REPLY 3. RST_STREAM 4. SETTINGS 5. NOOP( spdy/3で廃止) HTTPリクエスト・レスポン 6. PING スボディの送受信などで使 7. GOAWAY う 8. HEADERS 9. WINDOW_UPDATE • CREDENTIAL HTTPリクエスト・レスポンス ヘッダの送受信に使う その他SPDY通信制御情報のやり 取りに使う
  • 3. 単純なSPDYのストリームフロー SSLハンドシェイク NPN (Next Protocol Negotiation) を 使って SPDY 利用バージョンを交換 SYN_STREAM HTTPリクエストヘッダ情報を送信 SYN_REPLY HTTPレスポンスヘッダ情報を送信 クライアント サーバー DATA Frame HTTPレスポンスボディを送信 GOAWAY SPDYストリーム利用停止を通知
  • 4. spdylayを使ってSPDYの中身を見る www.google.com サーバ編 (その1) $ ./examples/spdycat -v https://www.google.com NPNでプロトコル情報の交換 [ 0.012] NPN select next protocol: the remote server offers: * spdy/3 * spdy/2 * http/1.1 NPN selected the protocol: spdy/3 google サーバから SDPYの設定情報が送られてくる [ 0.018] recv SETTINGS frame <version=3, flags=0, length=20> (niv=2) [4(1):100] [7(0):12288] 4: SETTINGS_MAX_CONCURRENT_STREAMS 最大同時アクティブなストリーム数 7: SETTINGS_INITIAL_WINDOW_SIZE ストリームの初期ウィンドウサイズ(バイト)
  • 5. spdylayを使ってSPDYの中身を見る www.google.com サーバ編 (その2) SYN_STREAMを使ってHTTPリクエストヘッダ情報をサーバに送信 [ 0.018] send SYN_STREAM frame <version=3, flags=1, length=106> (stream_id=1, assoc_stream_id=0, pri=3) :host: www.google.com :method: GET :path: / :scheme: https :version: HTTP/1.1 accept: */* user-agent: spdylay/0.2.0
  • 6. spdylayを使ってSPDYの中身を見る www.google.com サーバ編 (その3) SYN_REPLY でHTTPレスポンスヘッダ情報がサーバから送られてくる [ 0.057] recv SYN_REPLY frame <version=3, flags=0, length=558> (stream_id=1) :status: 302 Found :version: HTTP/1.1 cache-control: private content-length: 222 content-type: text/html; charset=UTF-8 date: Thu, 17 May 2012 01:24:23 GMT location: https://www.google.co.jp/ server: gws (以下略)
  • 7. spdylayを使ってSPDYの中身を見る www.google.com サーバ編 (その4) Dataフレーム でHTTPレスポンスボディがサーバから送られてくる <HTML><HEAD><meta http-equiv="content-type" content="text/html;charset=utf-8"> <TITLE>302 Moved</TITLE></HEAD><BODY> <H1>302 Moved</H1> The document has moved <A HREF="https://www.google.co.jp/">here</A>. </BODY></HTML> [ 0.058] recv DATA frame (stream_id=1, flags=1, length=222) SPDY終了 [ 0.058] send GOAWAY frame <version=3, flags=0, length=8> (last_good_stream_id=0
  • 8. spdylayを使ってSPDYの中身を見る Chrome ブラウザ編 (その1) ./examples/spdyd --htdocs=. -v 3000 ./foo-key.pem ./foo-cert.pem NPNでプロトコル情報の決定 [id=1] [ 5.046] closed The negotiated next protocol: spdy/3 SYN_STREAMを使ってHTTPリクエストヘッダ情報がChromeから送られてくる [id=2] [ 5.051] recv SYN_STREAM frame <version=3, flags=1, length=250> (stream_id=1, assoc_stream_id=0, pri=0) :host: unixjp:3000 :method: GET :path: / :scheme: https :version: HTTP/1.1 accept: text/html,application/xhtml+xml,application/xml;q=0.9,*/*;q=0.8 accept-charset: Shift_JIS,utf-8;q=0.7,*;q=0.3 (以下略)
  • 9. spdylayを使ってSPDYの中身を見る Chrome ブラウザ編 (その2) サーバからSETTINGSによって同時ストリーム数の設定 [id=2] [ 5.052] send SETTINGS frame <version=3, flags=0, length=12> (niv=1) [4(0):100] SYN_REPLY でHTTPレスポンスヘッダ情報を Chrome に送る [id=2] [ 5.052] send SYN_REPLY frame <version=3, flags=0, length=109> (stream_id=1) :status: 200 OK :version: HTTP/1.1 cache-control: max-age=3600 content-length: 40 date: Thu, 17 May 2012 02:40:28 GMT last-modified: Mon, 14 May 2012 20:34:32 GMT server: spdyd spdylay/0.2.0
  • 10. spdylayを使ってSPDYの中身を見る Chrome ブラウザ編 (その3) データフレームでレスポンスボディを送信 最後のデータフレームは flag 1 (FLAG_FIN) を使ってストリームを 終了させてます。 [id=2] [ 5.052] send DATA frame (stream_id=1, flags=0, length=40) [id=2] [ 5.053] send DATA frame (stream_id=1, flags=1, length=0) [id=2] [ 5.053] stream_id=1 closed
  • 11. spdylayを使ってSPDYの中身を見る Chrome ブラウザ編 (その4) Chrome が favicon.ico を取りに来てるリクエスト [id=2] [ 5.094] recv SYN_STREAM frame <version=3, flags=1, length=39> (stream_id=3, assoc_stream_id=0, pri=1) :host: unixjp:3000 :method: GET :path: /favicon.ico :scheme: https :version: HTTP/1.1 accept: */* accept-charset: Shift_JIS,utf-8;q=0.7,*;q=0.3 accept-encoding: gzip,deflate,sdch accept-language: en-US,en;q=0.8 user-agent: Mozilla/5.0 (Windows NT 6.1; WOW64) AppleWebKit/536.5 (KHTML, like Gecko) Chrome/19.0.1084.46 Safari/536.5
  • 12. spdylayを使ってSPDYの中身を見る Chrome ブラウザ編 (その5) favicon なんて用意していないので404を返す SYN_REPLY [id=2] [ 5.095] send SYN_REPLY frame <version=3, flags=0, length=33> (stream_id=3) :status: 404 Not Found :version: HTTP/1.1 content-encoding: gzip date: Thu, 17 May 2012 02:40:28 GMT server: spdyd spdylay/0.2.0 最後に Chrome から PING で SPDY の生存確認をしています。 [id=2] [ 6.048] recv PING frame <version=3, flags=0, length=4> (unique_id=1) [id=2] [ 6.048] send PING frame <version=3, flags=0, length=4> (unique_id=1)
  • 13. Control frames 0 1 2 3 4 5 6 7 8 9 0 1 2 3 4 5 6 7 8 9 0 1 2 3 4 5 6 7 8 9 0 1 1 version Type Flags Length Data
  • 14. Data frames 0 1 2 3 4 5 6 7 8 9 0 1 2 3 4 5 6 7 8 9 0 1 2 3 4 5 6 7 8 9 0 1 0 Stream-ID Flags Length Data Flags 0x01 FLAG_FIN 0x02 FLAG_COMPRESS
  • 15. SYN_STREAM 0 1 2 3 4 5 6 7 8 9 0 1 2 3 4 5 6 7 8 9 0 1 2 3 4 5 6 7 8 9 0 1 1 version 1 Flags Length X Stream-ID X Associated-To-Stream-ID Pri Unused Slot Number of Name/Value pairs (32bit) Number of Name/Value pairs Length of name (32bit) Name (string) Length of value (32bit) Value (string) Flags 0x01 FLAG_FIN 圧縮データ 0x02 FLAG_UNIDIRECTIONAL
  • 16. SYN_REPLY 0 1 2 3 4 5 6 7 8 9 0 1 2 3 4 5 6 7 8 9 0 1 2 3 4 5 6 7 8 9 0 1 1 version 2 Flags Length X Stream-ID Number of Name/Value pairs Length of name Name Length of value Value Flags 0x01 FLAG_FIN 圧縮データ
  • 17. RST_STREAM 0 1 2 3 4 5 6 7 8 9 0 1 2 3 4 5 6 7 8 9 0 1 2 3 4 5 6 7 8 9 0 1 1 version 3 0 (flags) 8 (length) X Stream-ID Status Code Satus code 1 PROTOCOL_ERROR 7 FLOW_CONTROL_ERROR 2 INVALID_STREAM 8 STREAM_ALREADY_CLOSED 3 REFUSED_STREAM 9 STREAM_IN_USE 4 UNSUPPORTED_VERSION 10 INVALID_CREDENTIALS 5 CANCEL 11 FRAME_TOO_LARGE 6 INTERNAL_ERROR
  • 18. SETTINGS 0 1 2 3 4 5 6 7 8 9 0 1 2 3 4 5 6 7 8 9 0 1 2 3 4 5 6 7 8 9 0 1 1 version 4 Flags Length Number of entries ID.flags ID Value Flags ID.flags FLAG_SETTING_CLEAR_SETTINGS 0x01 FLAG_SETTINGS_PERSIST_VALUE 0x01 0x02 FLAG_SETTINGS_PERSISTED ID 1 SETTINGS_UPLOAD_BANDWIDTH 5 SETTINGS_CURRENT_CWND 2 SETTINGS_DOWNLOAD_BANDWIDTH 6 SETTINGS_DOWNLOAD_RETRANS_RATE 3 SETTINGS_ROUND_TRIP_TIME 7 SETTINGS_INITAL_WINDOW_SIZE 4 SETTINGS_MAX_CONCURRENT_STREAM 8 SETTINGS_CLIENT_CERTIFICATE_VECTOR_SIZE
  • 19. PING 0 1 2 3 4 5 6 7 8 9 0 1 2 3 4 5 6 7 8 9 0 1 2 3 4 5 6 7 8 9 0 1 1 version 6 0 (flags) 4 (length) 32-bit ID
  • 20. GOAWAY 0 1 2 3 4 5 6 7 8 9 0 1 2 3 4 5 6 7 8 9 0 1 2 3 4 5 6 7 8 9 0 1 1 version 7 0 (flags) 8 (length) X Last-good-stream-ID Status code Status code 0 OK 1 PROTOCOL_ERROR 11 INTERNAL_ERRRO
  • 21. HEADERS 0 1 2 3 4 5 6 7 8 9 0 1 2 3 4 5 6 7 8 9 0 1 2 3 4 5 6 7 8 9 0 1 1 version 8 Flags Length X Stream-ID Number of Name/Value pairs Length of name Name Length of value Value Flags 0x01 FLAG_FIN 圧縮データ
  • 22. WINDOW_UPDATE 0 1 2 3 4 5 6 7 8 9 0 1 2 3 4 5 6 7 8 9 0 1 2 3 4 5 6 7 8 9 0 1 1 version 9 0 (flags) 8 (length) X Stream-ID X Delta-Window-Size