func (s *slowStartState) msgIsInSequence(msg controlMessage) bool {
	s.lock.Lock()
	defer s.lock.Unlock()
	return seqCompare(s.nr, msg.ns()) == 0
}
A message with ns value equal to our nr is the next packet in sequence.
package l2tp
import (
	"errors"
	"fmt"
	"strings"
	"sync"
	"time"
	"github.com/go-kit/kit/log"
	"github.com/go-kit/kit/log/level"
	"golang.org/x/sys/unix"
)
type slowStartState struct {
	lock                             sync.Mutex
	ns, nr, cwnd, thresh, nacks, ntx uint16
}
type xmitMsg struct {
	xport *transport
	msg controlMessage
	nretries uint
	completeChan chan error
	isComplete bool
	retryTimer *time.Timer
	onComplete func(m *xmitMsg, err error)
}
type rawMsg struct {
	b  []byte
	sa unix.Sockaddr
}
type recvMsg struct {
	msg  controlMessage
	from unix.Sockaddr
}
type nrInd struct {
	msgType avpMsgType
	nr      uint16
}
type transportConfig struct {
	HelloTimeout time.Duration
	TxWindowSize uint16
	MaxRetries uint
	RetryTimeout time.Duration
	AckTimeout time.Duration
	Version ProtocolVersion
	PeerControlConnID ControlConnID
}
type transport struct {
	logger               log.Logger
	slowStart            slowStartState
	config               transportConfig
	cp                   *controlPlane
	helloTimer, ackTimer *time.Timer
	helloInFlight        bool
	sendChan             chan *xmitMsg
	retryChan            chan *xmitMsg
	recvChan             chan *recvMsg
	nrChan               chan []nrInd
	rxQueue              []*recvMsg
	txQueue, ackQueue    []*xmitMsg
	senderWg             sync.WaitGroup
	receiverWg           sync.WaitGroup
}
func seqIncrement(seqNum uint16) uint16 {
	next := uint32(seqNum)
	next = (next + 1) % 0x10000
	return uint16(next)
}
func seqCompare(seq1, seq2 uint16) int {
	var delta uint16
	if seq2 <= seq1 {
		delta = seq1 - seq2
	} else {
		delta = (0xffff - seq2 + 1) + seq1
	}
	if delta == 0 {
		return 0
	} else if delta < 0x8000 {
		return 1
	}
	return -1
}
func (s *slowStartState) canSend() bool {
	s.lock.Lock()
	defer s.lock.Unlock()
	return s.ntx < s.cwnd
}
func (s *slowStartState) onSend() {
	s.lock.Lock()
	defer s.lock.Unlock()
	s.ntx++
}
func (s *slowStartState) onAck(maxTxWindow uint16) {
	s.lock.Lock()
	defer s.lock.Unlock()
	if s.ntx > 0 {
		if s.cwnd < maxTxWindow {
			if s.cwnd < s.thresh {
				s.cwnd++
			} else {
				s.nacks++
				if s.nacks >= s.cwnd {
					s.nacks = 0
					s.cwnd++
				}
			}
		}
		s.ntx--
	}
}
func (s *slowStartState) onRetransmit() {
	s.lock.Lock()
	defer s.lock.Unlock()
	s.thresh = s.cwnd / 2
	s.cwnd = 1
}
func (s *slowStartState) incrementNr() {
	s.lock.Lock()
	defer s.lock.Unlock()
	s.nr = seqIncrement(s.nr)
}
func (s *slowStartState) incrementNs() {
	s.lock.Lock()
	defer s.lock.Unlock()
	s.ns = seqIncrement(s.ns)
}