code: func (p *Provider) clientSetup() (*Client, error) {
  	defer metrics.MeasureSince([]string{"scada", "setup"}, time.Now())
  
  	// Reset the previous backoff
  	p.backoffLock.Lock()
  	p.noRetry = false
  	p.backoff = 0
  	p.backoffLock.Unlock()
  
  	// Dial a new connection
  	opts := Opts{
  		Addr:      p.config.Endpoint,
  		TLS:       true,
  		TLSConfig: p.config.TLSConfig,
  		LogOutput: p.config.LogOutput,
  	}
  	client, err := DialOpts(&opts)
  	if err != nil {
  		p.logger.Printf("[ERR] scada-client: failed to dial: %v", err)
  		return nil, err
  	}
  
  	// Perform a handshake
  	resp, err := p.handshake(client)
  	if err != nil {
  		p.logger.Printf("[ERR] scada-client: failed to handshake: %v", err)
  		client.Close()
  		return nil, err
  	}
  	if resp != nil && resp.SessionID != "" {
  		p.logger.Printf("[DEBUG] scada-client: assigned session '%s'", resp.SessionID)
  	}
  	if resp != nil && !resp.Authenticated {
  		p.logger.Printf("[WARN] scada-client: authentication failed: %v", resp.Reason)
  	}
  
  	// Set the new client
  	p.clientLock.Lock()
  	if p.client != nil {
  		p.client.Close()
  	}
  	p.client = client
  	p.clientLock.Unlock()
  
  	p.sessionLock.Lock()
  	p.sessionID = resp.SessionID
  	p.sessionAuth = resp.Authenticated
  	p.sessionLock.Unlock()
  
  	return client, nil
  }
docs: // clientSetup is used to setup a new connection