You can not select more than 25 topics Topics must start with a letter or number, can include dashes ('-') and can be up to 35 characters long.
 
 
 
 
 
 

810 lines
21 KiB

  1. // Copyright 2012 The Go Authors. All rights reserved.
  2. // Use of this source code is governed by a BSD-style
  3. // license that can be found in the LICENSE file.
  4. package tls
  5. import (
  6. "bytes"
  7. "crypto/x509"
  8. "errors"
  9. "fmt"
  10. "internal/testenv"
  11. "io"
  12. "io/ioutil"
  13. "math"
  14. "math/rand"
  15. "net"
  16. "os"
  17. "reflect"
  18. "strings"
  19. "testing"
  20. "testing/quick"
  21. "time"
  22. )
  23. var rsaCertPEM = `-----BEGIN CERTIFICATE-----
  24. MIIB0zCCAX2gAwIBAgIJAI/M7BYjwB+uMA0GCSqGSIb3DQEBBQUAMEUxCzAJBgNV
  25. BAYTAkFVMRMwEQYDVQQIDApTb21lLVN0YXRlMSEwHwYDVQQKDBhJbnRlcm5ldCBX
  26. aWRnaXRzIFB0eSBMdGQwHhcNMTIwOTEyMjE1MjAyWhcNMTUwOTEyMjE1MjAyWjBF
  27. MQswCQYDVQQGEwJBVTETMBEGA1UECAwKU29tZS1TdGF0ZTEhMB8GA1UECgwYSW50
  28. ZXJuZXQgV2lkZ2l0cyBQdHkgTHRkMFwwDQYJKoZIhvcNAQEBBQADSwAwSAJBANLJ
  29. hPHhITqQbPklG3ibCVxwGMRfp/v4XqhfdQHdcVfHap6NQ5Wok/4xIA+ui35/MmNa
  30. rtNuC+BdZ1tMuVCPFZcCAwEAAaNQME4wHQYDVR0OBBYEFJvKs8RfJaXTH08W+SGv
  31. zQyKn0H8MB8GA1UdIwQYMBaAFJvKs8RfJaXTH08W+SGvzQyKn0H8MAwGA1UdEwQF
  32. MAMBAf8wDQYJKoZIhvcNAQEFBQADQQBJlffJHybjDGxRMqaRmDhX0+6v02TUKZsW
  33. r5QuVbpQhH6u+0UgcW0jp9QwpxoPTLTWGXEWBBBurxFwiCBhkQ+V
  34. -----END CERTIFICATE-----
  35. `
  36. var rsaKeyPEM = `-----BEGIN RSA PRIVATE KEY-----
  37. MIIBOwIBAAJBANLJhPHhITqQbPklG3ibCVxwGMRfp/v4XqhfdQHdcVfHap6NQ5Wo
  38. k/4xIA+ui35/MmNartNuC+BdZ1tMuVCPFZcCAwEAAQJAEJ2N+zsR0Xn8/Q6twa4G
  39. 6OB1M1WO+k+ztnX/1SvNeWu8D6GImtupLTYgjZcHufykj09jiHmjHx8u8ZZB/o1N
  40. MQIhAPW+eyZo7ay3lMz1V01WVjNKK9QSn1MJlb06h/LuYv9FAiEA25WPedKgVyCW
  41. SmUwbPw8fnTcpqDWE3yTO3vKcebqMSsCIBF3UmVue8YU3jybC3NxuXq3wNm34R8T
  42. xVLHwDXh/6NJAiEAl2oHGGLz64BuAfjKrqwz7qMYr9HCLIe/YsoWq/olzScCIQDi
  43. D2lWusoe2/nEqfDVVWGWlyJ7yOmqaVm/iNUN9B2N2g==
  44. -----END RSA PRIVATE KEY-----
  45. `
  46. // keyPEM is the same as rsaKeyPEM, but declares itself as just
  47. // "PRIVATE KEY", not "RSA PRIVATE KEY". https://golang.org/issue/4477
  48. var keyPEM = `-----BEGIN PRIVATE KEY-----
  49. MIIBOwIBAAJBANLJhPHhITqQbPklG3ibCVxwGMRfp/v4XqhfdQHdcVfHap6NQ5Wo
  50. k/4xIA+ui35/MmNartNuC+BdZ1tMuVCPFZcCAwEAAQJAEJ2N+zsR0Xn8/Q6twa4G
  51. 6OB1M1WO+k+ztnX/1SvNeWu8D6GImtupLTYgjZcHufykj09jiHmjHx8u8ZZB/o1N
  52. MQIhAPW+eyZo7ay3lMz1V01WVjNKK9QSn1MJlb06h/LuYv9FAiEA25WPedKgVyCW
  53. SmUwbPw8fnTcpqDWE3yTO3vKcebqMSsCIBF3UmVue8YU3jybC3NxuXq3wNm34R8T
  54. xVLHwDXh/6NJAiEAl2oHGGLz64BuAfjKrqwz7qMYr9HCLIe/YsoWq/olzScCIQDi
  55. D2lWusoe2/nEqfDVVWGWlyJ7yOmqaVm/iNUN9B2N2g==
  56. -----END PRIVATE KEY-----
  57. `
  58. var ecdsaCertPEM = `-----BEGIN CERTIFICATE-----
  59. MIIB/jCCAWICCQDscdUxw16XFDAJBgcqhkjOPQQBMEUxCzAJBgNVBAYTAkFVMRMw
  60. EQYDVQQIEwpTb21lLVN0YXRlMSEwHwYDVQQKExhJbnRlcm5ldCBXaWRnaXRzIFB0
  61. eSBMdGQwHhcNMTIxMTE0MTI0MDQ4WhcNMTUxMTE0MTI0MDQ4WjBFMQswCQYDVQQG
  62. EwJBVTETMBEGA1UECBMKU29tZS1TdGF0ZTEhMB8GA1UEChMYSW50ZXJuZXQgV2lk
  63. Z2l0cyBQdHkgTHRkMIGbMBAGByqGSM49AgEGBSuBBAAjA4GGAAQBY9+my9OoeSUR
  64. lDQdV/x8LsOuLilthhiS1Tz4aGDHIPwC1mlvnf7fg5lecYpMCrLLhauAc1UJXcgl
  65. 01xoLuzgtAEAgv2P/jgytzRSpUYvgLBt1UA0leLYBy6mQQbrNEuqT3INapKIcUv8
  66. XxYP0xMEUksLPq6Ca+CRSqTtrd/23uTnapkwCQYHKoZIzj0EAQOBigAwgYYCQXJo
  67. A7Sl2nLVf+4Iu/tAX/IF4MavARKC4PPHK3zfuGfPR3oCCcsAoz3kAzOeijvd0iXb
  68. H5jBImIxPL4WxQNiBTexAkF8D1EtpYuWdlVQ80/h/f4pBcGiXPqX5h2PQSQY7hP1
  69. +jwM1FGS4fREIOvlBYr/SzzQRtwrvrzGYxDEDbsC0ZGRnA==
  70. -----END CERTIFICATE-----
  71. `
  72. var ecdsaKeyPEM = `-----BEGIN EC PARAMETERS-----
  73. BgUrgQQAIw==
  74. -----END EC PARAMETERS-----
  75. -----BEGIN EC PRIVATE KEY-----
  76. MIHcAgEBBEIBrsoKp0oqcv6/JovJJDoDVSGWdirrkgCWxrprGlzB9o0X8fV675X0
  77. NwuBenXFfeZvVcwluO7/Q9wkYoPd/t3jGImgBwYFK4EEACOhgYkDgYYABAFj36bL
  78. 06h5JRGUNB1X/Hwuw64uKW2GGJLVPPhoYMcg/ALWaW+d/t+DmV5xikwKssuFq4Bz
  79. VQldyCXTXGgu7OC0AQCC/Y/+ODK3NFKlRi+AsG3VQDSV4tgHLqZBBus0S6pPcg1q
  80. kohxS/xfFg/TEwRSSws+roJr4JFKpO2t3/be5OdqmQ==
  81. -----END EC PRIVATE KEY-----
  82. `
  83. var keyPairTests = []struct {
  84. algo string
  85. cert string
  86. key string
  87. }{
  88. {"ECDSA", ecdsaCertPEM, ecdsaKeyPEM},
  89. {"RSA", rsaCertPEM, rsaKeyPEM},
  90. {"RSA-untyped", rsaCertPEM, keyPEM}, // golang.org/issue/4477
  91. }
  92. func TestX509KeyPair(t *testing.T) {
  93. t.Parallel()
  94. var pem []byte
  95. for _, test := range keyPairTests {
  96. pem = []byte(test.cert + test.key)
  97. if _, err := X509KeyPair(pem, pem); err != nil {
  98. t.Errorf("Failed to load %s cert followed by %s key: %s", test.algo, test.algo, err)
  99. }
  100. pem = []byte(test.key + test.cert)
  101. if _, err := X509KeyPair(pem, pem); err != nil {
  102. t.Errorf("Failed to load %s key followed by %s cert: %s", test.algo, test.algo, err)
  103. }
  104. }
  105. }
  106. func TestX509KeyPairErrors(t *testing.T) {
  107. _, err := X509KeyPair([]byte(rsaKeyPEM), []byte(rsaCertPEM))
  108. if err == nil {
  109. t.Fatalf("X509KeyPair didn't return an error when arguments were switched")
  110. }
  111. if subStr := "been switched"; !strings.Contains(err.Error(), subStr) {
  112. t.Fatalf("Expected %q in the error when switching arguments to X509KeyPair, but the error was %q", subStr, err)
  113. }
  114. _, err = X509KeyPair([]byte(rsaCertPEM), []byte(rsaCertPEM))
  115. if err == nil {
  116. t.Fatalf("X509KeyPair didn't return an error when both arguments were certificates")
  117. }
  118. if subStr := "certificate"; !strings.Contains(err.Error(), subStr) {
  119. t.Fatalf("Expected %q in the error when both arguments to X509KeyPair were certificates, but the error was %q", subStr, err)
  120. }
  121. const nonsensePEM = `
  122. -----BEGIN NONSENSE-----
  123. Zm9vZm9vZm9v
  124. -----END NONSENSE-----
  125. `
  126. _, err = X509KeyPair([]byte(nonsensePEM), []byte(nonsensePEM))
  127. if err == nil {
  128. t.Fatalf("X509KeyPair didn't return an error when both arguments were nonsense")
  129. }
  130. if subStr := "NONSENSE"; !strings.Contains(err.Error(), subStr) {
  131. t.Fatalf("Expected %q in the error when both arguments to X509KeyPair were nonsense, but the error was %q", subStr, err)
  132. }
  133. }
  134. func TestX509MixedKeyPair(t *testing.T) {
  135. if _, err := X509KeyPair([]byte(rsaCertPEM), []byte(ecdsaKeyPEM)); err == nil {
  136. t.Error("Load of RSA certificate succeeded with ECDSA private key")
  137. }
  138. if _, err := X509KeyPair([]byte(ecdsaCertPEM), []byte(rsaKeyPEM)); err == nil {
  139. t.Error("Load of ECDSA certificate succeeded with RSA private key")
  140. }
  141. }
  142. func newLocalListener(t testing.TB) net.Listener {
  143. ln, err := net.Listen("tcp", "127.0.0.1:0")
  144. if err != nil {
  145. ln, err = net.Listen("tcp6", "[::1]:0")
  146. }
  147. if err != nil {
  148. t.Fatal(err)
  149. }
  150. return ln
  151. }
  152. func TestDialTimeout(t *testing.T) {
  153. if testing.Short() {
  154. t.Skip("skipping in short mode")
  155. }
  156. listener := newLocalListener(t)
  157. addr := listener.Addr().String()
  158. defer listener.Close()
  159. complete := make(chan bool)
  160. defer close(complete)
  161. go func() {
  162. conn, err := listener.Accept()
  163. if err != nil {
  164. t.Error(err)
  165. return
  166. }
  167. <-complete
  168. conn.Close()
  169. }()
  170. dialer := &net.Dialer{
  171. Timeout: 10 * time.Millisecond,
  172. }
  173. var err error
  174. if _, err = DialWithDialer(dialer, "tcp", addr, nil); err == nil {
  175. t.Fatal("DialWithTimeout completed successfully")
  176. }
  177. if !isTimeoutError(err) {
  178. t.Errorf("resulting error not a timeout: %v\nType %T: %#v", err, err, err)
  179. }
  180. }
  181. func isTimeoutError(err error) bool {
  182. if ne, ok := err.(net.Error); ok {
  183. return ne.Timeout()
  184. }
  185. return false
  186. }
  187. // tests that Conn.Read returns (non-zero, io.EOF) instead of
  188. // (non-zero, nil) when a Close (alertCloseNotify) is sitting right
  189. // behind the application data in the buffer.
  190. func TestConnReadNonzeroAndEOF(t *testing.T) {
  191. // This test is racy: it assumes that after a write to a
  192. // localhost TCP connection, the peer TCP connection can
  193. // immediately read it. Because it's racy, we skip this test
  194. // in short mode, and then retry it several times with an
  195. // increasing sleep in between our final write (via srv.Close
  196. // below) and the following read.
  197. if testing.Short() {
  198. t.Skip("skipping in short mode")
  199. }
  200. var err error
  201. for delay := time.Millisecond; delay <= 64*time.Millisecond; delay *= 2 {
  202. if err = testConnReadNonzeroAndEOF(t, delay); err == nil {
  203. return
  204. }
  205. }
  206. t.Error(err)
  207. }
  208. func testConnReadNonzeroAndEOF(t *testing.T, delay time.Duration) error {
  209. ln := newLocalListener(t)
  210. defer ln.Close()
  211. srvCh := make(chan *Conn, 1)
  212. var serr error
  213. go func() {
  214. sconn, err := ln.Accept()
  215. if err != nil {
  216. serr = err
  217. srvCh <- nil
  218. return
  219. }
  220. serverConfig := testConfig.Clone()
  221. srv := Server(sconn, serverConfig)
  222. if err := srv.Handshake(); err != nil {
  223. serr = fmt.Errorf("handshake: %v", err)
  224. srvCh <- nil
  225. return
  226. }
  227. srvCh <- srv
  228. }()
  229. clientConfig := testConfig.Clone()
  230. conn, err := Dial("tcp", ln.Addr().String(), clientConfig)
  231. if err != nil {
  232. t.Fatal(err)
  233. }
  234. defer conn.Close()
  235. srv := <-srvCh
  236. if srv == nil {
  237. return serr
  238. }
  239. buf := make([]byte, 6)
  240. srv.Write([]byte("foobar"))
  241. n, err := conn.Read(buf)
  242. if n != 6 || err != nil || string(buf) != "foobar" {
  243. return fmt.Errorf("Read = %d, %v, data %q; want 6, nil, foobar", n, err, buf)
  244. }
  245. srv.Write([]byte("abcdef"))
  246. srv.Close()
  247. time.Sleep(delay)
  248. n, err = conn.Read(buf)
  249. if n != 6 || string(buf) != "abcdef" {
  250. return fmt.Errorf("Read = %d, buf= %q; want 6, abcdef", n, buf)
  251. }
  252. if err != io.EOF {
  253. return fmt.Errorf("Second Read error = %v; want io.EOF", err)
  254. }
  255. return nil
  256. }
  257. func TestTLSUniqueMatches(t *testing.T) {
  258. ln := newLocalListener(t)
  259. defer ln.Close()
  260. serverTLSUniques := make(chan []byte)
  261. go func() {
  262. for i := 0; i < 2; i++ {
  263. sconn, err := ln.Accept()
  264. if err != nil {
  265. t.Fatal(err)
  266. }
  267. serverConfig := testConfig.Clone()
  268. srv := Server(sconn, serverConfig)
  269. if err := srv.Handshake(); err != nil {
  270. t.Fatal(err)
  271. }
  272. serverTLSUniques <- srv.ConnectionState().TLSUnique
  273. }
  274. }()
  275. clientConfig := testConfig.Clone()
  276. clientConfig.ClientSessionCache = NewLRUClientSessionCache(1)
  277. conn, err := Dial("tcp", ln.Addr().String(), clientConfig)
  278. if err != nil {
  279. t.Fatal(err)
  280. }
  281. if !bytes.Equal(conn.ConnectionState().TLSUnique, <-serverTLSUniques) {
  282. t.Error("client and server channel bindings differ")
  283. }
  284. conn.Close()
  285. conn, err = Dial("tcp", ln.Addr().String(), clientConfig)
  286. if err != nil {
  287. t.Fatal(err)
  288. }
  289. defer conn.Close()
  290. if !conn.ConnectionState().DidResume {
  291. t.Error("second session did not use resumption")
  292. }
  293. if !bytes.Equal(conn.ConnectionState().TLSUnique, <-serverTLSUniques) {
  294. t.Error("client and server channel bindings differ when session resumption is used")
  295. }
  296. }
  297. func TestVerifyHostname(t *testing.T) {
  298. testenv.MustHaveExternalNetwork(t)
  299. c, err := Dial("tcp", "www.google.com:https", nil)
  300. if err != nil {
  301. t.Fatal(err)
  302. }
  303. if err := c.VerifyHostname("www.google.com"); err != nil {
  304. t.Fatalf("verify www.google.com: %v", err)
  305. }
  306. if err := c.VerifyHostname("www.yahoo.com"); err == nil {
  307. t.Fatalf("verify www.yahoo.com succeeded")
  308. }
  309. c, err = Dial("tcp", "www.google.com:https", &Config{InsecureSkipVerify: true})
  310. if err != nil {
  311. t.Fatal(err)
  312. }
  313. if err := c.VerifyHostname("www.google.com"); err == nil {
  314. t.Fatalf("verify www.google.com succeeded with InsecureSkipVerify=true")
  315. }
  316. if err := c.VerifyHostname("www.yahoo.com"); err == nil {
  317. t.Fatalf("verify www.google.com succeeded with InsecureSkipVerify=true")
  318. }
  319. }
  320. func TestVerifyHostnameResumed(t *testing.T) {
  321. testenv.MustHaveExternalNetwork(t)
  322. config := &Config{
  323. ClientSessionCache: NewLRUClientSessionCache(32),
  324. }
  325. for i := 0; i < 2; i++ {
  326. c, err := Dial("tcp", "www.google.com:https", config)
  327. if err != nil {
  328. t.Fatalf("Dial #%d: %v", i, err)
  329. }
  330. cs := c.ConnectionState()
  331. if i > 0 && !cs.DidResume {
  332. t.Fatalf("Subsequent connection unexpectedly didn't resume")
  333. }
  334. if cs.VerifiedChains == nil {
  335. t.Fatalf("Dial #%d: cs.VerifiedChains == nil", i)
  336. }
  337. if err := c.VerifyHostname("www.google.com"); err != nil {
  338. t.Fatalf("verify www.google.com #%d: %v", i, err)
  339. }
  340. c.Close()
  341. }
  342. }
  343. func TestConnCloseBreakingWrite(t *testing.T) {
  344. ln := newLocalListener(t)
  345. defer ln.Close()
  346. srvCh := make(chan *Conn, 1)
  347. var serr error
  348. var sconn net.Conn
  349. go func() {
  350. var err error
  351. sconn, err = ln.Accept()
  352. if err != nil {
  353. serr = err
  354. srvCh <- nil
  355. return
  356. }
  357. serverConfig := testConfig.Clone()
  358. srv := Server(sconn, serverConfig)
  359. if err := srv.Handshake(); err != nil {
  360. serr = fmt.Errorf("handshake: %v", err)
  361. srvCh <- nil
  362. return
  363. }
  364. srvCh <- srv
  365. }()
  366. cconn, err := net.Dial("tcp", ln.Addr().String())
  367. if err != nil {
  368. t.Fatal(err)
  369. }
  370. defer cconn.Close()
  371. conn := &changeImplConn{
  372. Conn: cconn,
  373. }
  374. clientConfig := testConfig.Clone()
  375. tconn := Client(conn, clientConfig)
  376. if err := tconn.Handshake(); err != nil {
  377. t.Fatal(err)
  378. }
  379. srv := <-srvCh
  380. if srv == nil {
  381. t.Fatal(serr)
  382. }
  383. defer sconn.Close()
  384. connClosed := make(chan struct{})
  385. conn.closeFunc = func() error {
  386. close(connClosed)
  387. return nil
  388. }
  389. inWrite := make(chan bool, 1)
  390. var errConnClosed = errors.New("conn closed for test")
  391. conn.writeFunc = func(p []byte) (n int, err error) {
  392. inWrite <- true
  393. <-connClosed
  394. return 0, errConnClosed
  395. }
  396. closeReturned := make(chan bool, 1)
  397. go func() {
  398. <-inWrite
  399. tconn.Close() // test that this doesn't block forever.
  400. closeReturned <- true
  401. }()
  402. _, err = tconn.Write([]byte("foo"))
  403. if err != errConnClosed {
  404. t.Errorf("Write error = %v; want errConnClosed", err)
  405. }
  406. <-closeReturned
  407. if err := tconn.Close(); err != errClosed {
  408. t.Errorf("Close error = %v; want errClosed", err)
  409. }
  410. }
  411. func TestConnCloseWrite(t *testing.T) {
  412. ln := newLocalListener(t)
  413. defer ln.Close()
  414. clientDoneChan := make(chan struct{})
  415. serverCloseWrite := func() error {
  416. sconn, err := ln.Accept()
  417. if err != nil {
  418. return fmt.Errorf("accept: %v", err)
  419. }
  420. defer sconn.Close()
  421. serverConfig := testConfig.Clone()
  422. srv := Server(sconn, serverConfig)
  423. if err := srv.Handshake(); err != nil {
  424. return fmt.Errorf("handshake: %v", err)
  425. }
  426. defer srv.Close()
  427. data, err := ioutil.ReadAll(srv)
  428. if err != nil {
  429. return err
  430. }
  431. if len(data) > 0 {
  432. return fmt.Errorf("Read data = %q; want nothing", data)
  433. }
  434. if err := srv.CloseWrite(); err != nil {
  435. return fmt.Errorf("server CloseWrite: %v", err)
  436. }
  437. // Wait for clientCloseWrite to finish, so we know we
  438. // tested the CloseWrite before we defer the
  439. // sconn.Close above, which would also cause the
  440. // client to unblock like CloseWrite.
  441. <-clientDoneChan
  442. return nil
  443. }
  444. clientCloseWrite := func() error {
  445. defer close(clientDoneChan)
  446. clientConfig := testConfig.Clone()
  447. conn, err := Dial("tcp", ln.Addr().String(), clientConfig)
  448. if err != nil {
  449. return err
  450. }
  451. if err := conn.Handshake(); err != nil {
  452. return err
  453. }
  454. defer conn.Close()
  455. if err := conn.CloseWrite(); err != nil {
  456. return fmt.Errorf("client CloseWrite: %v", err)
  457. }
  458. if _, err := conn.Write([]byte{0}); err != errShutdown {
  459. return fmt.Errorf("CloseWrite error = %v; want errShutdown", err)
  460. }
  461. data, err := ioutil.ReadAll(conn)
  462. if err != nil {
  463. return err
  464. }
  465. if len(data) > 0 {
  466. return fmt.Errorf("Read data = %q; want nothing", data)
  467. }
  468. return nil
  469. }
  470. errChan := make(chan error, 2)
  471. go func() { errChan <- serverCloseWrite() }()
  472. go func() { errChan <- clientCloseWrite() }()
  473. for i := 0; i < 2; i++ {
  474. select {
  475. case err := <-errChan:
  476. if err != nil {
  477. t.Fatal(err)
  478. }
  479. case <-time.After(10 * time.Second):
  480. t.Fatal("deadlock")
  481. }
  482. }
  483. // Also test CloseWrite being called before the handshake is
  484. // finished:
  485. {
  486. ln2 := newLocalListener(t)
  487. defer ln2.Close()
  488. netConn, err := net.Dial("tcp", ln2.Addr().String())
  489. if err != nil {
  490. t.Fatal(err)
  491. }
  492. defer netConn.Close()
  493. conn := Client(netConn, testConfig.Clone())
  494. if err := conn.CloseWrite(); err != errEarlyCloseWrite {
  495. t.Errorf("CloseWrite error = %v; want errEarlyCloseWrite", err)
  496. }
  497. }
  498. }
  499. func TestClone(t *testing.T) {
  500. var c1 Config
  501. v := reflect.ValueOf(&c1).Elem()
  502. rnd := rand.New(rand.NewSource(time.Now().Unix()))
  503. typ := v.Type()
  504. for i := 0; i < typ.NumField(); i++ {
  505. f := v.Field(i)
  506. if !f.CanSet() {
  507. // unexported field; not cloned.
  508. continue
  509. }
  510. // testing/quick can't handle functions or interfaces.
  511. fn := typ.Field(i).Name
  512. switch fn {
  513. case "Rand":
  514. f.Set(reflect.ValueOf(io.Reader(os.Stdin)))
  515. continue
  516. case "Time", "GetCertificate", "GetConfigForClient", "VerifyPeerCertificate", "GetClientCertificate":
  517. // DeepEqual can't compare functions.
  518. continue
  519. case "Certificates":
  520. f.Set(reflect.ValueOf([]Certificate{
  521. {Certificate: [][]byte{{'b'}}},
  522. }))
  523. continue
  524. case "NameToCertificate":
  525. f.Set(reflect.ValueOf(map[string]*Certificate{"a": nil}))
  526. continue
  527. case "RootCAs", "ClientCAs":
  528. f.Set(reflect.ValueOf(x509.NewCertPool()))
  529. continue
  530. case "ClientSessionCache":
  531. f.Set(reflect.ValueOf(NewLRUClientSessionCache(10)))
  532. continue
  533. case "KeyLogWriter":
  534. f.Set(reflect.ValueOf(io.Writer(os.Stdout)))
  535. continue
  536. }
  537. q, ok := quick.Value(f.Type(), rnd)
  538. if !ok {
  539. t.Fatalf("quick.Value failed on field %s", fn)
  540. }
  541. f.Set(q)
  542. }
  543. c2 := c1.Clone()
  544. // DeepEqual also compares unexported fields, thus c2 needs to have run
  545. // serverInit in order to be DeepEqual to c1. Cloning it and discarding
  546. // the result is sufficient.
  547. c2.Clone()
  548. if !reflect.DeepEqual(&c1, c2) {
  549. t.Errorf("clone failed to copy a field")
  550. }
  551. }
  552. // changeImplConn is a net.Conn which can change its Write and Close
  553. // methods.
  554. type changeImplConn struct {
  555. net.Conn
  556. writeFunc func([]byte) (int, error)
  557. closeFunc func() error
  558. }
  559. func (w *changeImplConn) Write(p []byte) (n int, err error) {
  560. if w.writeFunc != nil {
  561. return w.writeFunc(p)
  562. }
  563. return w.Conn.Write(p)
  564. }
  565. func (w *changeImplConn) Close() error {
  566. if w.closeFunc != nil {
  567. return w.closeFunc()
  568. }
  569. return w.Conn.Close()
  570. }
  571. func throughput(b *testing.B, totalBytes int64, dynamicRecordSizingDisabled bool) {
  572. ln := newLocalListener(b)
  573. defer ln.Close()
  574. N := b.N
  575. // Less than 64KB because Windows appears to use a TCP rwin < 64KB.
  576. // See Issue #15899.
  577. const bufsize = 32 << 10
  578. go func() {
  579. buf := make([]byte, bufsize)
  580. for i := 0; i < N; i++ {
  581. sconn, err := ln.Accept()
  582. if err != nil {
  583. // panic rather than synchronize to avoid benchmark overhead
  584. // (cannot call b.Fatal in goroutine)
  585. panic(fmt.Errorf("accept: %v", err))
  586. }
  587. serverConfig := testConfig.Clone()
  588. serverConfig.CipherSuites = nil // the defaults may prefer faster ciphers
  589. serverConfig.DynamicRecordSizingDisabled = dynamicRecordSizingDisabled
  590. srv := Server(sconn, serverConfig)
  591. if err := srv.Handshake(); err != nil {
  592. panic(fmt.Errorf("handshake: %v", err))
  593. }
  594. if _, err := io.CopyBuffer(srv, srv, buf); err != nil {
  595. panic(fmt.Errorf("copy buffer: %v", err))
  596. }
  597. }
  598. }()
  599. b.SetBytes(totalBytes)
  600. clientConfig := testConfig.Clone()
  601. clientConfig.CipherSuites = nil // the defaults may prefer faster ciphers
  602. clientConfig.DynamicRecordSizingDisabled = dynamicRecordSizingDisabled
  603. buf := make([]byte, bufsize)
  604. chunks := int(math.Ceil(float64(totalBytes) / float64(len(buf))))
  605. for i := 0; i < N; i++ {
  606. conn, err := Dial("tcp", ln.Addr().String(), clientConfig)
  607. if err != nil {
  608. b.Fatal(err)
  609. }
  610. for j := 0; j < chunks; j++ {
  611. _, err := conn.Write(buf)
  612. if err != nil {
  613. b.Fatal(err)
  614. }
  615. _, err = io.ReadFull(conn, buf)
  616. if err != nil {
  617. b.Fatal(err)
  618. }
  619. }
  620. conn.Close()
  621. }
  622. }
  623. func BenchmarkThroughput(b *testing.B) {
  624. for _, mode := range []string{"Max", "Dynamic"} {
  625. for size := 1; size <= 64; size <<= 1 {
  626. name := fmt.Sprintf("%sPacket/%dMB", mode, size)
  627. b.Run(name, func(b *testing.B) {
  628. throughput(b, int64(size<<20), mode == "Max")
  629. })
  630. }
  631. }
  632. }
  633. type slowConn struct {
  634. net.Conn
  635. bps int
  636. }
  637. func (c *slowConn) Write(p []byte) (int, error) {
  638. if c.bps == 0 {
  639. panic("too slow")
  640. }
  641. t0 := time.Now()
  642. wrote := 0
  643. for wrote < len(p) {
  644. time.Sleep(100 * time.Microsecond)
  645. allowed := int(time.Since(t0).Seconds()*float64(c.bps)) / 8
  646. if allowed > len(p) {
  647. allowed = len(p)
  648. }
  649. if wrote < allowed {
  650. n, err := c.Conn.Write(p[wrote:allowed])
  651. wrote += n
  652. if err != nil {
  653. return wrote, err
  654. }
  655. }
  656. }
  657. return len(p), nil
  658. }
  659. func latency(b *testing.B, bps int, dynamicRecordSizingDisabled bool) {
  660. ln := newLocalListener(b)
  661. defer ln.Close()
  662. N := b.N
  663. go func() {
  664. for i := 0; i < N; i++ {
  665. sconn, err := ln.Accept()
  666. if err != nil {
  667. // panic rather than synchronize to avoid benchmark overhead
  668. // (cannot call b.Fatal in goroutine)
  669. panic(fmt.Errorf("accept: %v", err))
  670. }
  671. serverConfig := testConfig.Clone()
  672. serverConfig.DynamicRecordSizingDisabled = dynamicRecordSizingDisabled
  673. srv := Server(&slowConn{sconn, bps}, serverConfig)
  674. if err := srv.Handshake(); err != nil {
  675. panic(fmt.Errorf("handshake: %v", err))
  676. }
  677. io.Copy(srv, srv)
  678. }
  679. }()
  680. clientConfig := testConfig.Clone()
  681. clientConfig.DynamicRecordSizingDisabled = dynamicRecordSizingDisabled
  682. buf := make([]byte, 16384)
  683. peek := make([]byte, 1)
  684. for i := 0; i < N; i++ {
  685. conn, err := Dial("tcp", ln.Addr().String(), clientConfig)
  686. if err != nil {
  687. b.Fatal(err)
  688. }
  689. // make sure we're connected and previous connection has stopped
  690. if _, err := conn.Write(buf[:1]); err != nil {
  691. b.Fatal(err)
  692. }
  693. if _, err := io.ReadFull(conn, peek); err != nil {
  694. b.Fatal(err)
  695. }
  696. if _, err := conn.Write(buf); err != nil {
  697. b.Fatal(err)
  698. }
  699. if _, err = io.ReadFull(conn, peek); err != nil {
  700. b.Fatal(err)
  701. }
  702. conn.Close()
  703. }
  704. }
  705. func BenchmarkLatency(b *testing.B) {
  706. for _, mode := range []string{"Max", "Dynamic"} {
  707. for _, kbps := range []int{200, 500, 1000, 2000, 5000} {
  708. name := fmt.Sprintf("%sPacket/%dkbps", mode, kbps)
  709. b.Run(name, func(b *testing.B) {
  710. latency(b, kbps*1000, mode == "Max")
  711. })
  712. }
  713. }
  714. }