github.com/tumi8/quic-go@v0.37.4-tum/integrationtests/self/handshake_test.go (about)

     1  package self_test
     2  
     3  import (
     4  	"context"
     5  	"crypto/tls"
     6  	"errors"
     7  	"fmt"
     8  	"io"
     9  	"net"
    10  	"time"
    11  
    12  	"github.com/tumi8/quic-go"
    13  	"github.com/tumi8/quic-go/noninternal/protocol"
    14  	"github.com/tumi8/quic-go/noninternal/qerr"
    15  	"github.com/tumi8/quic-go/noninternal/qtls"
    16  
    17  	. "github.com/onsi/ginkgo/v2"
    18  	. "github.com/onsi/gomega"
    19  )
    20  
    21  type tokenStore struct {
    22  	store quic.TokenStore
    23  	gets  chan<- string
    24  	puts  chan<- string
    25  }
    26  
    27  var _ quic.TokenStore = &tokenStore{}
    28  
    29  func newTokenStore(gets, puts chan<- string) quic.TokenStore {
    30  	return &tokenStore{
    31  		store: quic.NewLRUTokenStore(10, 4),
    32  		gets:  gets,
    33  		puts:  puts,
    34  	}
    35  }
    36  
    37  func (c *tokenStore) Put(key string, token *quic.ClientToken) {
    38  	c.puts <- key
    39  	c.store.Put(key, token)
    40  }
    41  
    42  func (c *tokenStore) Pop(key string) *quic.ClientToken {
    43  	c.gets <- key
    44  	return c.store.Pop(key)
    45  }
    46  
    47  var _ = Describe("Handshake tests", func() {
    48  	var (
    49  		server        *quic.Listener
    50  		serverConfig  *quic.Config
    51  		acceptStopped chan struct{}
    52  	)
    53  
    54  	BeforeEach(func() {
    55  		server = nil
    56  		acceptStopped = make(chan struct{})
    57  		serverConfig = getQuicConfig(nil)
    58  	})
    59  
    60  	AfterEach(func() {
    61  		if server != nil {
    62  			server.Close()
    63  			<-acceptStopped
    64  		}
    65  	})
    66  
    67  	runServer := func(tlsConf *tls.Config) {
    68  		var err error
    69  		// start the server
    70  		server, err = quic.ListenAddr("localhost:0", tlsConf, serverConfig)
    71  		Expect(err).ToNot(HaveOccurred())
    72  
    73  		go func() {
    74  			defer GinkgoRecover()
    75  			defer close(acceptStopped)
    76  			for {
    77  				if _, err := server.Accept(context.Background()); err != nil {
    78  					return
    79  				}
    80  			}
    81  		}()
    82  	}
    83  
    84  	Context("using different cipher suites", func() {
    85  		for n, id := range map[string]uint16{
    86  			"TLS_AES_128_GCM_SHA256":       tls.TLS_AES_128_GCM_SHA256,
    87  			"TLS_AES_256_GCM_SHA384":       tls.TLS_AES_256_GCM_SHA384,
    88  			"TLS_CHACHA20_POLY1305_SHA256": tls.TLS_CHACHA20_POLY1305_SHA256,
    89  		} {
    90  			name := n
    91  			suiteID := id
    92  
    93  			It(fmt.Sprintf("using %s", name), func() {
    94  				reset := qtls.SetCipherSuite(suiteID)
    95  				defer reset()
    96  
    97  				tlsConf := getTLSConfig()
    98  				ln, err := quic.ListenAddr("localhost:0", tlsConf, serverConfig)
    99  				Expect(err).ToNot(HaveOccurred())
   100  				defer ln.Close()
   101  
   102  				go func() {
   103  					defer GinkgoRecover()
   104  					conn, err := ln.Accept(context.Background())
   105  					Expect(err).ToNot(HaveOccurred())
   106  					str, err := conn.OpenStream()
   107  					Expect(err).ToNot(HaveOccurred())
   108  					defer str.Close()
   109  					_, err = str.Write(PRData)
   110  					Expect(err).ToNot(HaveOccurred())
   111  				}()
   112  
   113  				conn, err := quic.DialAddr(
   114  					context.Background(),
   115  					fmt.Sprintf("localhost:%d", ln.Addr().(*net.UDPAddr).Port),
   116  					getTLSClientConfig(),
   117  					getQuicConfig(nil),
   118  				)
   119  				Expect(err).ToNot(HaveOccurred())
   120  				str, err := conn.AcceptStream(context.Background())
   121  				Expect(err).ToNot(HaveOccurred())
   122  				data, err := io.ReadAll(str)
   123  				Expect(err).ToNot(HaveOccurred())
   124  				Expect(data).To(Equal(PRData))
   125  				Expect(conn.ConnectionState().TLS.CipherSuite).To(Equal(suiteID))
   126  				Expect(conn.CloseWithError(0, "")).To(Succeed())
   127  			})
   128  		}
   129  	})
   130  
   131  	Context("Certificate validation", func() {
   132  		It("accepts the certificate", func() {
   133  			runServer(getTLSConfig())
   134  			_, err := quic.DialAddr(
   135  				context.Background(),
   136  				fmt.Sprintf("localhost:%d", server.Addr().(*net.UDPAddr).Port),
   137  				getTLSClientConfig(),
   138  				getQuicConfig(nil),
   139  			)
   140  			Expect(err).ToNot(HaveOccurred())
   141  		})
   142  
   143  		It("has the right local and remote address on the tls.Config.GetConfigForClient ClientHelloInfo.Conn", func() {
   144  			var local, remote net.Addr
   145  			var local2, remote2 net.Addr
   146  			done := make(chan struct{})
   147  			tlsConf := &tls.Config{
   148  				GetConfigForClient: func(info *tls.ClientHelloInfo) (*tls.Config, error) {
   149  					local = info.Conn.LocalAddr()
   150  					remote = info.Conn.RemoteAddr()
   151  					conf := getTLSConfig()
   152  					conf.GetCertificate = func(info *tls.ClientHelloInfo) (*tls.Certificate, error) {
   153  						defer close(done)
   154  						local2 = info.Conn.LocalAddr()
   155  						remote2 = info.Conn.RemoteAddr()
   156  						return &(conf.Certificates[0]), nil
   157  					}
   158  					return conf, nil
   159  				},
   160  			}
   161  			runServer(tlsConf)
   162  			conn, err := quic.DialAddr(
   163  				context.Background(),
   164  				fmt.Sprintf("localhost:%d", server.Addr().(*net.UDPAddr).Port),
   165  				getTLSClientConfig(),
   166  				getQuicConfig(nil),
   167  			)
   168  			Expect(err).ToNot(HaveOccurred())
   169  			Eventually(done).Should(BeClosed())
   170  			Expect(server.Addr()).To(Equal(local))
   171  			Expect(conn.LocalAddr().(*net.UDPAddr).Port).To(Equal(remote.(*net.UDPAddr).Port))
   172  			Expect(local).To(Equal(local2))
   173  			Expect(remote).To(Equal(remote2))
   174  		})
   175  
   176  		It("works with a long certificate chain", func() {
   177  			runServer(getTLSConfigWithLongCertChain())
   178  			_, err := quic.DialAddr(
   179  				context.Background(),
   180  				fmt.Sprintf("localhost:%d", server.Addr().(*net.UDPAddr).Port),
   181  				getTLSClientConfig(),
   182  				getQuicConfig(nil),
   183  			)
   184  			Expect(err).ToNot(HaveOccurred())
   185  		})
   186  
   187  		It("errors if the server name doesn't match", func() {
   188  			runServer(getTLSConfig())
   189  			conn, err := net.ListenUDP("udp", nil)
   190  			Expect(err).ToNot(HaveOccurred())
   191  			conf := getTLSClientConfig()
   192  			conf.ServerName = "foo.bar"
   193  			_, err = quic.Dial(
   194  				context.Background(),
   195  				conn,
   196  				server.Addr(),
   197  				conf,
   198  				getQuicConfig(nil),
   199  			)
   200  			Expect(err).To(HaveOccurred())
   201  			var transportErr *quic.TransportError
   202  			Expect(errors.As(err, &transportErr)).To(BeTrue())
   203  			Expect(transportErr.ErrorCode.IsCryptoError()).To(BeTrue())
   204  			Expect(transportErr.Error()).To(ContainSubstring("x509: certificate is valid for localhost, not foo.bar"))
   205  		})
   206  
   207  		It("fails the handshake if the client fails to provide the requested client cert", func() {
   208  			tlsConf := getTLSConfig()
   209  			tlsConf.ClientAuth = tls.RequireAndVerifyClientCert
   210  			runServer(tlsConf)
   211  
   212  			conn, err := quic.DialAddr(
   213  				context.Background(),
   214  				fmt.Sprintf("localhost:%d", server.Addr().(*net.UDPAddr).Port),
   215  				getTLSClientConfig(),
   216  				getQuicConfig(nil),
   217  			)
   218  			// Usually, the error will occur after the client already finished the handshake.
   219  			// However, there's a race condition here. The server's CONNECTION_CLOSE might be
   220  			// received before the connection is returned, so we might already get the error while dialing.
   221  			if err == nil {
   222  				errChan := make(chan error)
   223  				go func() {
   224  					defer GinkgoRecover()
   225  					_, err := conn.AcceptStream(context.Background())
   226  					errChan <- err
   227  				}()
   228  				Eventually(errChan).Should(Receive(&err))
   229  			}
   230  			Expect(err).To(HaveOccurred())
   231  			var transportErr *quic.TransportError
   232  			Expect(errors.As(err, &transportErr)).To(BeTrue())
   233  			Expect(transportErr.ErrorCode.IsCryptoError()).To(BeTrue())
   234  			Expect(transportErr.Error()).To(Or(
   235  				ContainSubstring("tls: certificate required"),
   236  				ContainSubstring("tls: bad certificate"),
   237  			))
   238  		})
   239  
   240  		It("uses the ServerName in the tls.Config", func() {
   241  			runServer(getTLSConfig())
   242  			tlsConf := getTLSClientConfig()
   243  			tlsConf.ServerName = "foo.bar"
   244  			_, err := quic.DialAddr(
   245  				context.Background(),
   246  				fmt.Sprintf("localhost:%d", server.Addr().(*net.UDPAddr).Port),
   247  				tlsConf,
   248  				getQuicConfig(nil),
   249  			)
   250  			Expect(err).To(HaveOccurred())
   251  			var transportErr *quic.TransportError
   252  			Expect(errors.As(err, &transportErr)).To(BeTrue())
   253  			Expect(transportErr.ErrorCode.IsCryptoError()).To(BeTrue())
   254  			Expect(transportErr.Error()).To(ContainSubstring("x509: certificate is valid for localhost, not foo.bar"))
   255  		})
   256  	})
   257  
   258  	Context("rate limiting", func() {
   259  		var (
   260  			server *quic.Listener
   261  			pconn  net.PacketConn
   262  			dialer *quic.Transport
   263  		)
   264  
   265  		dial := func() (quic.Connection, error) {
   266  			remoteAddr := fmt.Sprintf("localhost:%d", server.Addr().(*net.UDPAddr).Port)
   267  			raddr, err := net.ResolveUDPAddr("udp", remoteAddr)
   268  			Expect(err).ToNot(HaveOccurred())
   269  			return dialer.Dial(context.Background(), raddr, getTLSClientConfig(), getQuicConfig(nil))
   270  		}
   271  
   272  		BeforeEach(func() {
   273  			var err error
   274  			// start the server, but don't call Accept
   275  			server, err = quic.ListenAddr("localhost:0", getTLSConfig(), serverConfig)
   276  			Expect(err).ToNot(HaveOccurred())
   277  
   278  			// prepare a (single) packet conn for dialing to the server
   279  			laddr, err := net.ResolveUDPAddr("udp", "localhost:0")
   280  			Expect(err).ToNot(HaveOccurred())
   281  			pconn, err = net.ListenUDP("udp", laddr)
   282  			Expect(err).ToNot(HaveOccurred())
   283  			dialer = &quic.Transport{Conn: pconn, ConnectionIDLength: 4}
   284  		})
   285  
   286  		AfterEach(func() {
   287  			Expect(server.Close()).To(Succeed())
   288  			Expect(pconn.Close()).To(Succeed())
   289  			Expect(dialer.Close()).To(Succeed())
   290  		})
   291  
   292  		It("rejects new connection attempts if connections don't get accepted", func() {
   293  			for i := 0; i < protocol.MaxAcceptQueueSize; i++ {
   294  				conn, err := dial()
   295  				Expect(err).ToNot(HaveOccurred())
   296  				defer conn.CloseWithError(0, "")
   297  			}
   298  			time.Sleep(25 * time.Millisecond) // wait a bit for the connection to be queued
   299  
   300  			_, err := dial()
   301  			Expect(err).To(HaveOccurred())
   302  			var transportErr *quic.TransportError
   303  			Expect(errors.As(err, &transportErr)).To(BeTrue())
   304  			Expect(transportErr.ErrorCode).To(Equal(quic.ConnectionRefused))
   305  
   306  			// now accept one connection, freeing one spot in the queue
   307  			_, err = server.Accept(context.Background())
   308  			Expect(err).ToNot(HaveOccurred())
   309  			// dial again, and expect that this dial succeeds
   310  			conn, err := dial()
   311  			Expect(err).ToNot(HaveOccurred())
   312  			defer conn.CloseWithError(0, "")
   313  			time.Sleep(25 * time.Millisecond) // wait a bit for the connection to be queued
   314  
   315  			_, err = dial()
   316  			Expect(err).To(HaveOccurred())
   317  			Expect(errors.As(err, &transportErr)).To(BeTrue())
   318  			Expect(transportErr.ErrorCode).To(Equal(quic.ConnectionRefused))
   319  		})
   320  
   321  		It("removes closed connections from the accept queue", func() {
   322  			firstConn, err := dial()
   323  			Expect(err).ToNot(HaveOccurred())
   324  
   325  			for i := 1; i < protocol.MaxAcceptQueueSize; i++ {
   326  				conn, err := dial()
   327  				Expect(err).ToNot(HaveOccurred())
   328  				defer conn.CloseWithError(0, "")
   329  			}
   330  			time.Sleep(scaleDuration(20 * time.Millisecond)) // wait a bit for the connection to be queued
   331  
   332  			_, err = dial()
   333  			Expect(err).To(HaveOccurred())
   334  			var transportErr *quic.TransportError
   335  			Expect(errors.As(err, &transportErr)).To(BeTrue())
   336  			Expect(transportErr.ErrorCode).To(Equal(quic.ConnectionRefused))
   337  
   338  			// Now close the one of the connection that are waiting to be accepted.
   339  			// This should free one spot in the queue.
   340  			Expect(firstConn.CloseWithError(0, ""))
   341  			Eventually(firstConn.Context().Done()).Should(BeClosed())
   342  			time.Sleep(scaleDuration(200 * time.Millisecond))
   343  
   344  			// dial again, and expect that this dial succeeds
   345  			_, err = dial()
   346  			Expect(err).ToNot(HaveOccurred())
   347  			time.Sleep(scaleDuration(20 * time.Millisecond)) // wait a bit for the connection to be queued
   348  
   349  			_, err = dial()
   350  			Expect(err).To(HaveOccurred())
   351  			Expect(errors.As(err, &transportErr)).To(BeTrue())
   352  			Expect(transportErr.ErrorCode).To(Equal(quic.ConnectionRefused))
   353  		})
   354  	})
   355  
   356  	Context("ALPN", func() {
   357  		It("negotiates an application protocol", func() {
   358  			ln, err := quic.ListenAddr("localhost:0", getTLSConfig(), serverConfig)
   359  			Expect(err).ToNot(HaveOccurred())
   360  
   361  			done := make(chan struct{})
   362  			go func() {
   363  				defer GinkgoRecover()
   364  				conn, err := ln.Accept(context.Background())
   365  				Expect(err).ToNot(HaveOccurred())
   366  				cs := conn.ConnectionState()
   367  				Expect(cs.TLS.NegotiatedProtocol).To(Equal(alpn))
   368  				close(done)
   369  			}()
   370  
   371  			conn, err := quic.DialAddr(
   372  				context.Background(),
   373  				fmt.Sprintf("localhost:%d", ln.Addr().(*net.UDPAddr).Port),
   374  				getTLSClientConfig(),
   375  				nil,
   376  			)
   377  			Expect(err).ToNot(HaveOccurred())
   378  			defer conn.CloseWithError(0, "")
   379  			cs := conn.ConnectionState()
   380  			Expect(cs.TLS.NegotiatedProtocol).To(Equal(alpn))
   381  			Eventually(done).Should(BeClosed())
   382  			Expect(ln.Close()).To(Succeed())
   383  		})
   384  
   385  		It("errors if application protocol negotiation fails", func() {
   386  			runServer(getTLSConfig())
   387  
   388  			tlsConf := getTLSClientConfig()
   389  			tlsConf.NextProtos = []string{"foobar"}
   390  			_, err := quic.DialAddr(
   391  				context.Background(),
   392  				fmt.Sprintf("localhost:%d", server.Addr().(*net.UDPAddr).Port),
   393  				tlsConf,
   394  				nil,
   395  			)
   396  			Expect(err).To(HaveOccurred())
   397  			var transportErr *quic.TransportError
   398  			Expect(errors.As(err, &transportErr)).To(BeTrue())
   399  			Expect(transportErr.ErrorCode.IsCryptoError()).To(BeTrue())
   400  			Expect(transportErr.Error()).To(ContainSubstring("no application protocol"))
   401  		})
   402  	})
   403  
   404  	Context("using tokens", func() {
   405  		It("uses tokens provided in NEW_TOKEN frames", func() {
   406  			server, err := quic.ListenAddr("localhost:0", getTLSConfig(), serverConfig)
   407  			Expect(err).ToNot(HaveOccurred())
   408  			defer server.Close()
   409  
   410  			// dial the first connection and receive the token
   411  			go func() {
   412  				defer GinkgoRecover()
   413  				_, err := server.Accept(context.Background())
   414  				Expect(err).ToNot(HaveOccurred())
   415  			}()
   416  
   417  			gets := make(chan string, 100)
   418  			puts := make(chan string, 100)
   419  			tokenStore := newTokenStore(gets, puts)
   420  			quicConf := getQuicConfig(&quic.Config{TokenStore: tokenStore})
   421  			conn, err := quic.DialAddr(
   422  				context.Background(),
   423  				fmt.Sprintf("localhost:%d", server.Addr().(*net.UDPAddr).Port),
   424  				getTLSClientConfig(),
   425  				quicConf,
   426  			)
   427  			Expect(err).ToNot(HaveOccurred())
   428  			Expect(gets).To(Receive())
   429  			Eventually(puts).Should(Receive())
   430  			// received a token. Close this connection.
   431  			Expect(conn.CloseWithError(0, "")).To(Succeed())
   432  
   433  			// dial the second connection and verify that the token was used
   434  			done := make(chan struct{})
   435  			go func() {
   436  				defer GinkgoRecover()
   437  				defer close(done)
   438  				_, err := server.Accept(context.Background())
   439  				Expect(err).ToNot(HaveOccurred())
   440  			}()
   441  			conn, err = quic.DialAddr(
   442  				context.Background(),
   443  				fmt.Sprintf("localhost:%d", server.Addr().(*net.UDPAddr).Port),
   444  				getTLSClientConfig(),
   445  				quicConf,
   446  			)
   447  			Expect(err).ToNot(HaveOccurred())
   448  			defer conn.CloseWithError(0, "")
   449  			Expect(gets).To(Receive())
   450  
   451  			Eventually(done).Should(BeClosed())
   452  		})
   453  
   454  		It("rejects invalid Retry token with the INVALID_TOKEN error", func() {
   455  			serverConfig.RequireAddressValidation = func(net.Addr) bool { return true }
   456  			serverConfig.MaxRetryTokenAge = time.Nanosecond
   457  
   458  			server, err := quic.ListenAddr("localhost:0", getTLSConfig(), serverConfig)
   459  			Expect(err).ToNot(HaveOccurred())
   460  			defer server.Close()
   461  
   462  			_, err = quic.DialAddr(
   463  				context.Background(),
   464  				fmt.Sprintf("localhost:%d", server.Addr().(*net.UDPAddr).Port),
   465  				getTLSClientConfig(),
   466  				nil,
   467  			)
   468  			Expect(err).To(HaveOccurred())
   469  			var transportErr *quic.TransportError
   470  			Expect(errors.As(err, &transportErr)).To(BeTrue())
   471  			Expect(transportErr.ErrorCode).To(Equal(quic.InvalidToken))
   472  		})
   473  	})
   474  
   475  	Context("GetConfigForClient", func() {
   476  		It("uses the quic.Config returned by GetConfigForClient", func() {
   477  			serverConfig.EnableDatagrams = false
   478  			var calledFrom net.Addr
   479  			serverConfig.GetConfigForClient = func(info *quic.ClientHelloInfo) (*quic.Config, error) {
   480  				conf := serverConfig.Clone()
   481  				conf.EnableDatagrams = true
   482  				calledFrom = info.RemoteAddr
   483  				return getQuicConfig(conf), nil
   484  			}
   485  			ln, err := quic.ListenAddr("localhost:0", getTLSConfig(), serverConfig)
   486  			Expect(err).ToNot(HaveOccurred())
   487  
   488  			done := make(chan struct{})
   489  			go func() {
   490  				defer GinkgoRecover()
   491  				_, err := ln.Accept(context.Background())
   492  				Expect(err).ToNot(HaveOccurred())
   493  				close(done)
   494  			}()
   495  
   496  			conn, err := quic.DialAddr(
   497  				context.Background(),
   498  				fmt.Sprintf("localhost:%d", ln.Addr().(*net.UDPAddr).Port),
   499  				getTLSClientConfig(),
   500  				getQuicConfig(&quic.Config{EnableDatagrams: true}),
   501  			)
   502  			Expect(err).ToNot(HaveOccurred())
   503  			defer conn.CloseWithError(0, "")
   504  			cs := conn.ConnectionState()
   505  			Expect(cs.SupportsDatagrams).To(BeTrue())
   506  			Eventually(done).Should(BeClosed())
   507  			Expect(ln.Close()).To(Succeed())
   508  			Expect(calledFrom.(*net.UDPAddr).Port).To(Equal(conn.LocalAddr().(*net.UDPAddr).Port))
   509  		})
   510  
   511  		It("rejects the connection attempt if GetConfigForClient errors", func() {
   512  			serverConfig.EnableDatagrams = false
   513  			serverConfig.GetConfigForClient = func(info *quic.ClientHelloInfo) (*quic.Config, error) {
   514  				return nil, errors.New("rejected")
   515  			}
   516  			ln, err := quic.ListenAddr("localhost:0", getTLSConfig(), serverConfig)
   517  			Expect(err).ToNot(HaveOccurred())
   518  			defer ln.Close()
   519  
   520  			done := make(chan struct{})
   521  			go func() {
   522  				defer GinkgoRecover()
   523  				_, err := ln.Accept(context.Background())
   524  				Expect(err).To(HaveOccurred()) // we don't expect to accept any connection
   525  				close(done)
   526  			}()
   527  
   528  			_, err = quic.DialAddr(
   529  				context.Background(),
   530  				fmt.Sprintf("localhost:%d", ln.Addr().(*net.UDPAddr).Port),
   531  				getTLSClientConfig(),
   532  				getQuicConfig(&quic.Config{EnableDatagrams: true}),
   533  			)
   534  			Expect(err).To(HaveOccurred())
   535  			var transportErr *quic.TransportError
   536  			Expect(errors.As(err, &transportErr)).To(BeTrue())
   537  			Expect(transportErr.ErrorCode).To(Equal(qerr.ConnectionRefused))
   538  		})
   539  	})
   540  
   541  	It("doesn't send any packets when generating the ClientHello fails", func() {
   542  		ln, err := net.ListenUDP("udp", nil)
   543  		Expect(err).ToNot(HaveOccurred())
   544  		done := make(chan struct{})
   545  		packetChan := make(chan struct{})
   546  		go func() {
   547  			defer GinkgoRecover()
   548  			defer close(done)
   549  			for {
   550  				_, _, err := ln.ReadFromUDP(make([]byte, protocol.MaxPacketBufferSize))
   551  				if err != nil {
   552  					return
   553  				}
   554  				packetChan <- struct{}{}
   555  			}
   556  		}()
   557  
   558  		tlsConf := getTLSClientConfig()
   559  		tlsConf.NextProtos = []string{""}
   560  		_, err = quic.DialAddr(
   561  			context.Background(),
   562  			fmt.Sprintf("localhost:%d", ln.LocalAddr().(*net.UDPAddr).Port),
   563  			tlsConf,
   564  			nil,
   565  		)
   566  		Expect(err).To(MatchError(&qerr.TransportError{
   567  			ErrorCode:    qerr.InternalError,
   568  			ErrorMessage: "tls: invalid NextProtos value",
   569  		}))
   570  		Consistently(packetChan).ShouldNot(Receive())
   571  		ln.Close()
   572  		Eventually(done).Should(BeClosed())
   573  	})
   574  })