func (fe *frontend) listenForClients(ln net.Listener, sk *[32]byte) {
	defer fe.waitStop.Done()
	defer ln.Close()
	go func() {
		<-fe.stop
		ln.Close()
	}()
	fe.sk = sk
	curve25519.ScalarBaseMult(&fe.pk, sk)
	for {
		conn, err := ln.Accept()
		if err != nil {
			select {
			case <-fe.stop:
				return
			default:
				log.Printf("accept client: %s", err)
				continue
			}
		}
		fe.waitStop.Add(1)
		go fe.handleClient(conn)
	}
}
caller MUST call fe.waitStop.Add(1) first
package server
import (
	"crypto/hmac"
	"crypto/rand"
	"crypto/sha256"
	"fmt"
	"github.com/andres-erbsen/chatterbox/transport"
	. "github.com/andres-erbsen/dename/protocol"
	"github.com/gogo/protobuf/proto"
	"github.com/syndtr/goleveldb/leveldb"
	"golang.org/x/crypto/curve25519"
	"io"
	"log"
	"net"
	"sync"
	"time"
)
type frontend struct {
	server *server
	sync.Mutex
	hasOperations     chan struct{}
	inviteMacKey      []byte
	inviteMutex       sync.Mutex
	profileOperations []*SignedProfileOperation
	waitOps           map[string]chan struct{}
	pk                [32]byte
	sk                *[32]byte
	isCore            bool
	stop     chan struct{}
	waitStop *sync.WaitGroup
}
func NewFrontend() *frontend {
	fe := &frontend{
		hasOperations: make(chan struct{}, 1),
		waitOps:       make(map[string]chan struct{}),
	}
	return fe
}