func (l *Conn) isClosing() bool {
	return atomic.LoadUint32(&l.closeCount) > 0
}
isClosing returns whether or not we're currently closing.
package ldap
import (
	"crypto/tls"
	"errors"
	"fmt"
	"log"
	"net"
	"sync"
	"sync/atomic"
	"time"
	"gopkg.in/asn1-ber.v1"
)
const (
	MessageQuit = 0
	MessageRequest = 1
	MessageResponse = 2
	MessageFinish = 3
	MessageTimeout = 4
)
type PacketResponse struct {
	Packet *ber.Packet
	Error error
}
func (pr *PacketResponse) ReadPacket() (*ber.Packet, error) {
	if (pr == nil) || (pr.Packet == nil && pr.Error == nil) {
		return nil, NewError(ErrorNetwork, errors.New("ldap: could not retrieve response"))
	}
	return pr.Packet, pr.Error
}
type messageContext struct {
	id int64
	done chan struct{}
	responses chan *PacketResponse
}
func (msgCtx *messageContext) sendResponse(packet *PacketResponse) {
	select {
	case msgCtx.responses <- packet:
	case <-msgCtx.done:
	}
}
type messagePacket struct {
	Op        int
	MessageID int64
	Packet    *ber.Packet
	Context   *messageContext
}
type sendMessageFlags uint
const (
	startTLS sendMessageFlags = 1 << iota
)
type Conn struct {
	conn                net.Conn
	isTLS               bool
	closeCount          uint32
	closeErr            atomicValue
	isStartingTLS       bool
	Debug               debugging
	chanConfirm         chan bool
	messageContexts     map[int64]*messageContext
	chanMessage         chan *messagePacket
	chanMessageID       chan int64
	wgSender            sync.WaitGroup
	wgClose             sync.WaitGroup
	once                sync.Once
	outstandingRequests uint
	messageMutex        sync.Mutex
	requestTimeout      time.Duration
}
var _ Client = &Conn{}
var DefaultTimeout = 60 * time.Second
func Dial(network, addr string, timeout time.Duration) (*Conn, error) {
	c, err := net.DialTimeout(network, addr, timeout)
	if err != nil {
		return nil, NewError(ErrorNetwork, err)
	}
	conn := NewConn(c, false)
	conn.Start()
	return conn, nil
}
func DialTLS(network, addr string, config *tls.Config) (*Conn, error) {
	dc, err := net.DialTimeout(network, addr, DefaultTimeout)
	if err != nil {
		return nil, NewError(ErrorNetwork, err)
	}
	c := tls.Client(dc, config)
	err = c.Handshake()
	if err != nil {
		dc.Close()
		return nil, NewError(ErrorNetwork, err)
	}
	conn := NewConn(c, true)
	conn.Start()
	return conn, nil
}
func NewConn(conn net.Conn, isTLS bool) *Conn {
	return &Conn{
		conn:            conn,
		chanConfirm:     make(chan bool),
		chanMessageID:   make(chan int64),
		chanMessage:     make(chan *messagePacket, 10),
		messageContexts: map[int64]*messageContext{},
		requestTimeout:  0,
		isTLS:           isTLS,
	}
}
func (l *Conn) Start() {
	go l.reader()
	go l.processMessages()
	l.wgClose.Add(1)
}