func (l *Listener) doHandshake(prologue []byte, conn net.Conn) {
	defer func() { l.handshakeSema <- struct{}{} }()
	select {
	case <-l.quit:
		return
	default:
	}
	cxnoiseConn := &Conn{
		conn:  conn,
		noise: NewNoiseMachine(false, prologue, l.localStatic),
	}
	conn.SetReadDeadline(time.Now().Add(handshakeReadTimeout))
	var actOne [ActOneSize]byte
	if _, err := io.ReadFull(conn, actOne[:]); err != nil {
		cxnoiseConn.conn.Close()
		l.rejectConn(err)
		return
	}
	if err := cxnoiseConn.noise.RecvActOne(actOne); err != nil {
		cxnoiseConn.conn.Close()
		l.rejectConn(err)
		return
	}
	actTwo, err := cxnoiseConn.noise.GenActTwo()
	if err != nil {
		cxnoiseConn.conn.Close()
		l.rejectConn(err)
		return
	}
	if _, err := conn.Write(actTwo[:]); err != nil {
		cxnoiseConn.conn.Close()
		l.rejectConn(err)
		return
	}
	select {
	case <-l.quit:
		return
	default:
	}
	conn.SetReadDeadline(time.Now().Add(handshakeReadTimeout))
	var actThree [ActThreeSize]byte
	if _, err := io.ReadFull(conn, actThree[:]); err != nil {
		cxnoiseConn.conn.Close()
		l.rejectConn(err)
		return
	}
	if err := cxnoiseConn.noise.RecvActThree(actThree); err != nil {
		cxnoiseConn.conn.Close()
		l.rejectConn(err)
		return
	}
	conn.SetReadDeadline(time.Time{})
	l.acceptConn(cxnoiseConn)
}
doHandshake asynchronously performs the cxnoise handshake, so that it does
not block the main accept loop. This prevents peers that delay writing to the
connection from block other connection attempts.
package cxnoise
import (
	"errors"
	"io"
	"net"
	"strconv"
	"time"
	"github.com/mit-dci/lit/crypto/koblitz"
)
const defaultHandshakes = 1000
type Listener struct {
	localStatic *koblitz.PrivateKey
	tcp *net.TCPListener
	handshakeSema chan struct{}
	conns         chan maybeConn
	quit          chan struct{}
}
var _ net.Listener = (*Listener)(nil)
func NewListener(localStatic *koblitz.PrivateKey, port int) (*Listener,
	error) {
	str := ":" + strconv.Itoa(port)  
	addr, err := net.ResolveTCPAddr("tcp", str)
	if err != nil {
		return nil, err
	}
	l, err := net.ListenTCP("tcp", addr)
	if err != nil {
		return nil, err
	}
	cxnoiseListener := &Listener{
		localStatic:   localStatic,
		tcp:           l,
		handshakeSema: make(chan struct{}, defaultHandshakes),
		conns:         make(chan maybeConn),
		quit:          make(chan struct{}),
	}
	for i := 0; i < defaultHandshakes; i++ {
		cxnoiseListener.handshakeSema <- struct{}{}
	}
	go cxnoiseListener.listen()
	return cxnoiseListener, nil
}
func (l *Listener) listen() {
	for {
		select {
		case <-l.handshakeSema:
		case <-l.quit:
			return
		}
		conn, err := l.tcp.Accept()
		if err != nil {
			l.rejectConn(err)
			l.handshakeSema <- struct{}{}
			continue
		}
		go l.doHandshake([]byte("opencx"), conn)
	}
}