| 182 | } |
| 183 | |
| 184 | func (c *TLSFragmentConn) Write(b []byte) (int, error) { |
| 185 | if c.Finished { |
| 186 | return c.Conn.Write(b) |
| 187 | } |
| 188 | b1 := make([]byte, len(c.Buf)+len(b)) |
| 189 | copy(b1, c.Buf) |
| 190 | copy(b1[len(c.Buf):], b) |
| 191 | c.Buf = b1 |
| 192 | if len(c.Buf) < 5 { |
| 193 | return len(b), nil |
| 194 | } |
| 195 | if c.L == 0 { |
| 196 | c.L = int(binary.BigEndian.Uint16(c.Buf[3:5])) |
| 197 | } |
| 198 | if len(c.Buf) < 5+c.L { |
| 199 | return len(b), nil |
| 200 | } |
| 201 | i := 0 |
| 202 | for { |
| 203 | r, err := x.CryptoRandom(c.MinLength, c.MaxLength) |
| 204 | if err != nil { |
| 205 | return 0, err |
| 206 | } |
| 207 | l := int(r) |
| 208 | if i+l > 5+c.L { |
| 209 | l = 5 + c.L - i |
| 210 | } |
| 211 | if _, err := c.Conn.Write(c.Buf[i : i+l]); err != nil { |
| 212 | return 0, err |
| 213 | } |
| 214 | i += l |
| 215 | if i == 5+c.L { |
| 216 | break |
| 217 | } |
| 218 | t, err := x.CryptoRandom(c.MinDelay, c.MaxDelay) |
| 219 | if err != nil { |
| 220 | return 0, err |
| 221 | } |
| 222 | time.Sleep(time.Duration(t) * time.Microsecond) |
| 223 | } |
| 224 | if len(c.Buf) > i { |
| 225 | if _, err := c.Conn.Write(c.Buf[i:]); err != nil { |
| 226 | return 0, err |
| 227 | } |
| 228 | } |
| 229 | c.Finished = true |
| 230 | return len(b), nil |
| 231 | } |