code: func (c *client) establishSecureConnection(ctx context.Context) error {
  	errorChan := make(chan error, 1)
  
  	go func() {
  		err := c.session.run() // returns as soon as the session is closed
  		if err != errCloseForRecreating && c.createdPacketConn {
  			c.packetHandlers.Close()
  		}
  		errorChan <- err
  	}()
  
  	select {
  	case <-ctx.Done():
  		// The session will send a PeerGoingAway error to the server.
  		c.session.Close()
  		return ctx.Err()
  	case err := <-errorChan:
  		return err
  	case <-c.handshakeChan:
  		// handshake successfully completed
  		return nil
  	}
  }
docs: // establishSecureConnection runs the session, and tries to establish a secure connection
  // It returns:
  // - errCloseForRecreating when the server sends a version negotiation packet
  // - any other error that might occur
  // - when the connection is forward-secure