| 77 | } |
| 78 | |
| 79 | func TestSnellV4FirstFrameIncludesInitialPadding(t *testing.T) { |
| 80 | clientRaw, serverRaw := net.Pipe() |
| 81 | defer clientRaw.Close() |
| 82 | defer serverRaw.Close() |
| 83 | |
| 84 | client := newV4Conn(clientRaw, []byte("password")) |
| 85 | writeErr := make(chan error, 1) |
| 86 | go func() { |
| 87 | _, err := client.Write([]byte("x")) |
| 88 | writeErr <- err |
| 89 | }() |
| 90 | |
| 91 | salt := make([]byte, v4SaltSize) |
| 92 | if _, err := io.ReadFull(serverRaw, salt); err != nil { |
| 93 | t.Fatal(err) |
| 94 | } |
| 95 | |
| 96 | headerCipher := make([]byte, v4HeaderCipherSize) |
| 97 | if _, err := io.ReadFull(serverRaw, headerCipher); err != nil { |
| 98 | t.Fatal(err) |
| 99 | } |
| 100 | aead, err := v4AEAD([]byte("password"), salt) |
| 101 | if err != nil { |
| 102 | t.Fatal(err) |
| 103 | } |
| 104 | var nonce [v4NonceSize]byte |
| 105 | header, err := aead.Open(nil, nonce[:], headerCipher, nil) |
| 106 | if err != nil { |
| 107 | t.Fatal(err) |
| 108 | } |
| 109 | paddingLength := int(binary.BigEndian.Uint16(header[3:5])) |
| 110 | payloadLength := int(binary.BigEndian.Uint16(header[5:7])) |
| 111 | if paddingLength < v4InitialPaddingMin || paddingLength >= v4InitialPaddingMin+v4InitialPaddingSpan { |
| 112 | t.Fatalf("unexpected initial padding length: %d", paddingLength) |
| 113 | } |
| 114 | if payloadLength != 1 { |
| 115 | t.Fatalf("unexpected first payload length: %d", payloadLength) |
| 116 | } |
| 117 | |
| 118 | rest := make([]byte, paddingLength+payloadLength+aead.Overhead()) |
| 119 | if _, err := io.ReadFull(serverRaw, rest); err != nil { |
| 120 | t.Fatal(err) |
| 121 | } |
| 122 | if err := <-writeErr; err != nil { |
| 123 | t.Fatal(err) |
| 124 | } |
| 125 | } |
| 126 | |
| 127 | func TestSnellV4PaddedFrame(t *testing.T) { |
| 128 | var raw bytes.Buffer |