func (s *Server) Serve() error {
	for {
		conn, err := s.ln.Accept()
		if err != nil {
			var noe *net.OpError
			if errors.As(err, &noe) {
				if noe.Err.Error() == "use of closed network connection" {
					break
				}
			}
			log.Error(err)
			continue
		}
		sc := s.wrapConn(conn)
		log.WithFields(log.Fields{
			"id":     sc.id,
			"remote": sc.conn.RemoteAddr(),
			"local":  sc.conn.LocalAddr(),
		}).Info("Client attached")
		s.mu.Lock()
		s.conns = append(s.conns, sc)
		s.mu.Unlock()
		go sc.handleInput()
	}
	return nil
}
Serve listens and spawns a server goroutine for each incoming connection. The
function will return (some time after) shutdown is called.
package server
import (
	"crypto/tls"
	"errors"
	"net"
	"sync"
	"github.com/nicolagi/dino/message"
	"github.com/nicolagi/dino/storage"
	log "github.com/sirupsen/logrus"
)
var ErrPasswordWithoutTLS = errors.New("must use TLS if authorization is required")
type Option func(*options)
type options struct {
	address string
	store   storage.VersionedStore
	tls      bool
	certFile string
	keyFile  string
	authHash string
}
func WithAddress(value string) Option {
	return func(o *options) {
		o.address = value
	}
}
func WithVersionedStore(value storage.VersionedStore) Option {
	return func(o *options) {
		o.store = value
	}
}
func WithKeyPair(certFile, keyFile string) Option {
	return func(o *options) {
		o.tls = true
		o.certFile = certFile
		o.keyFile = keyFile
	}
}
func WithAuthHash(value string) Option {
	return func(o *options) {
		o.authHash = value
	}
}
type Server struct {
	opts    options
	ln      net.Listener
	connIDs *message.MonotoneTags
	mu      sync.Mutex
	conns   []*serverConn
}
func New(opts ...Option) *Server {
	s := &Server{
		connIDs: message.NewMonotoneTags(),
	}
	s.opts.address = ":6660"
	for _, o := range opts {
		o(&s.opts)
	}
	return s
}
func (s *Server) Listen() (addr string, err error) {
	if s.opts.tls {
		var c tls.Certificate
		c, err = tls.LoadX509KeyPair(s.opts.certFile, s.opts.keyFile)
		if err == nil {
			s.ln, err = tls.Listen("tcp", s.opts.address, &tls.Config{
				Certificates: []tls.Certificate{c},
			})
		}
	} else {
		if s.opts.authHash != "" {
			return "", ErrPasswordWithoutTLS
		}
		s.ln, err = net.Listen("tcp", s.opts.address)
	}
	if err != nil {
		return
	}
	addr = s.ln.Addr().String()
	return
}