Connection keepalive/disconnect

This commit is contained in:
Russ Magee 2023-11-05 14:58:24 -08:00
parent 74be6173b6
commit bcea6d713f
4 changed files with 135 additions and 29 deletions

View file

@ -64,7 +64,6 @@ type (
// see: https://en.wikipedia.org/wiki/chaff_(countermeasure)
ChaffConfig struct {
shutdown bool //set to inform chaffHelper to shut down
enabled bool
msecsMin uint //msecs min interval
msecsMax uint //msecs max interval
szMax uint // max size in bytes
@ -87,8 +86,9 @@ type (
Rows uint16
Cols uint16
chaff ChaffConfig
tuns *map[uint16](*TunEndpoint)
keepalive uint // if this reaches zero, conn is considered dead
chaff ChaffConfig
tuns *map[uint16](*TunEndpoint)
closeStat *CSOType // close status (CSOExitStatus)
r cipher.Stream //read cipherStream
@ -971,7 +971,7 @@ func Dial(protocol string, ipport string, extensions ...string) (hc Conn, err er
// Close a hkex.Conn
func (hc *Conn) Close() (err error) {
hc.DisableChaff()
hc.ShutdownChaff()
s := make([]byte, 4)
binary.BigEndian.PutUint32(s, uint32(*hc.closeStat))
log.Printf("** Writing closeStat %d at Close()\n", *hc.closeStat)
@ -1337,6 +1337,9 @@ func (hc Conn) Read(b []byte) (n int, err error) {
case CSOChaff:
// Throw away pkt if it's chaff (ie., caller to Read() won't see this data)
log.Printf("[Chaff pkt, discarded (len %d)]\n", decryptN)
case CSOKeepAlive:
//log.Printf("[KeepAlive pkt, discarded (len %d)]\n", decryptN)
hc.ResetKeepAlive()
case CSOTermSize:
fmt.Sscanf(string(payloadBytes), "%d %d", &hc.Rows, &hc.Cols)
log.Printf("[TermSize pkt: rows %v cols %v]\n", hc.Rows, hc.Cols)
@ -1568,18 +1571,12 @@ func (hc *Conn) WritePacket(b []byte, ctrlStatOp byte) (n int, err error) {
return retN, err
}
func (hc *Conn) EnableChaff() {
func (hc *Conn) StartupChaff() {
hc.chaff.shutdown = false
hc.chaff.enabled = true
log.Println("Chaffing ENABLED")
hc.chaffHelper()
}
func (hc *Conn) DisableChaff() {
hc.chaff.enabled = false
log.Println("Chaffing DISABLED")
}
func (hc *Conn) ShutdownChaff() {
hc.chaff.shutdown = true
log.Println("Chaffing SHUTDOWN")
@ -1594,9 +1591,10 @@ func (hc *Conn) SetupChaff(msecsMin uint, msecsMax uint, szMax uint) {
// Helper routine to spawn a chaffing goroutine for each Conn
func (hc *Conn) chaffHelper() {
go func() {
var nextDuration int
for {
var nextDuration int
if hc.chaff.enabled {
//logger.LogDebug(fmt.Sprintf("[chaffHelper Loop]\n"))
if !hc.chaff.shutdown {
var bufTmp []byte
bufTmp = make([]byte, rand.Intn(int(hc.chaff.szMax)))
min := int(hc.chaff.msecsMin)
@ -1604,17 +1602,60 @@ func (hc *Conn) chaffHelper() {
_, _ = rand.Read(bufTmp)
_, err := hc.WritePacket(bufTmp, CSOChaff)
if err != nil {
log.Println("[ *** error - chaffHelper quitting *** ]")
hc.chaff.enabled = false
log.Println("[ *** error - chaffHelper shutting down *** ]")
hc.chaff.shutdown = true
break
}
}
time.Sleep(time.Duration(nextDuration) * time.Millisecond)
if hc.chaff.shutdown {
log.Println("*** chaffHelper shutting down")
} else {
log.Println("[ *** chaffHelper shutting down *** ]")
break
}
time.Sleep(time.Duration(nextDuration) * time.Millisecond)
}
}()
}
func (hc *Conn) StartupKeepAlive() {
hc.ResetKeepAlive()
log.Println("KeepAlive ENABLED")
hc.keepaliveHelper()
}
func (hc *Conn) ShutdownKeepAlive() {
log.Println("Conn SHUTDOWN")
hc.SetStatus(CSEConnDead)
hc.Close()
}
func (hc *Conn) ResetKeepAlive() {
hc.keepalive = 3
log.Println("KeepAlive RESET")
}
// Helper routine to spawn a keepalive goroutine for each Conn
func (hc *Conn) keepaliveHelper() {
go func() {
for {
nextDuration := 10000
bufTmp := []byte{0x55, 0xaa}
_, err := hc.WritePacket(bufTmp, CSOKeepAlive)
//logger.LogDebug(fmt.Sprintf("[keepalive]\n"))
if err != nil {
logger.LogDebug(fmt.Sprintf("[ *** error - keepaliveHelper quitting *** ]\n"))
break
}
time.Sleep(time.Duration(nextDuration) * time.Millisecond)
hc.keepalive -= 1
//if rand.Intn(32) == 0 {
// hc.keepalive = 0
//}
if hc.keepalive == 0 {
logger.LogDebug(fmt.Sprintf("*** keepaliveHelper shutting down\n"))
hc.ShutdownKeepAlive()
break
}
}
}()
}