mirror of https://gogs.blitter.com/RLabs/xs
-hkexnet.immClose flag to allow client to close first (-x incomplete output bug)
Signed-off-by: Russ Magee <rmagee@gmail.com>
This commit is contained in:
parent
8e02810f0e
commit
1452af3fc8
|
@ -78,6 +78,7 @@ type (
|
||||||
kex KEXAlg // KEX/KEM propsal (client -> server)
|
kex KEXAlg // KEX/KEM propsal (client -> server)
|
||||||
m *sync.Mutex // (internal)
|
m *sync.Mutex // (internal)
|
||||||
c *net.Conn // which also implements io.Reader, io.Writer, ...
|
c *net.Conn // which also implements io.Reader, io.Writer, ...
|
||||||
|
immClose bool
|
||||||
cipheropts uint32 // post-KEx cipher/hmac options
|
cipheropts uint32 // post-KEx cipher/hmac options
|
||||||
opts uint32 // post-KEx protocol options (caller-defined)
|
opts uint32 // post-KEx protocol options (caller-defined)
|
||||||
WinCh chan WinSize
|
WinCh chan WinSize
|
||||||
|
@ -130,6 +131,10 @@ func (hc *Conn) SetStatus(stat CSOType) {
|
||||||
log.Println("closeStat:", *hc.closeStat)
|
log.Println("closeStat:", *hc.closeStat)
|
||||||
}
|
}
|
||||||
|
|
||||||
|
func (hc *Conn) SetImmClose() {
|
||||||
|
hc.immClose = true
|
||||||
|
}
|
||||||
|
|
||||||
// ConnOpts returns the cipher/hmac options value, which is sent to the
|
// ConnOpts returns the cipher/hmac options value, which is sent to the
|
||||||
// peer but is not itself part of the KEx.
|
// peer but is not itself part of the KEx.
|
||||||
//
|
//
|
||||||
|
@ -532,8 +537,15 @@ func (hc *Conn) Close() (err error) {
|
||||||
s := make([]byte, 4)
|
s := make([]byte, 4)
|
||||||
binary.BigEndian.PutUint32(s, uint32(*hc.closeStat))
|
binary.BigEndian.PutUint32(s, uint32(*hc.closeStat))
|
||||||
log.Printf("** Writing closeStat %d at Close()\n", *hc.closeStat)
|
log.Printf("** Writing closeStat %d at Close()\n", *hc.closeStat)
|
||||||
|
(*hc.c).SetWriteDeadline(time.Now().Add(500 * time.Millisecond))
|
||||||
hc.WritePacket(s, CSOExitStatus)
|
hc.WritePacket(s, CSOExitStatus)
|
||||||
err = (*hc.c).Close()
|
// This avoids a bug where server side may not get its last packet of
|
||||||
|
// data through to a client for non-interactive commands which exit
|
||||||
|
// immediately. Avoiding the immediate close lets the client close its
|
||||||
|
// side first.
|
||||||
|
if hc.immClose {
|
||||||
|
err = (*hc.c).Close()
|
||||||
|
}
|
||||||
logger.LogDebug(fmt.Sprintln("[Conn Closing]"))
|
logger.LogDebug(fmt.Sprintln("[Conn Closing]"))
|
||||||
return
|
return
|
||||||
}
|
}
|
||||||
|
@ -811,6 +823,7 @@ func (hc Conn) Read(b []byte) (n int, err error) {
|
||||||
logger.LogDebug(fmt.Sprintln("[truncated payload, cannot determine CSOExitStatus]"))
|
logger.LogDebug(fmt.Sprintln("[truncated payload, cannot determine CSOExitStatus]"))
|
||||||
hc.SetStatus(CSETruncCSO)
|
hc.SetStatus(CSETruncCSO)
|
||||||
}
|
}
|
||||||
|
hc.SetImmClose() // clients can immediately close their end
|
||||||
hc.Close()
|
hc.Close()
|
||||||
} else if ctrlStatOp == CSOTunSetup {
|
} else if ctrlStatOp == CSOTunSetup {
|
||||||
// server side tunnel setup in response to client
|
// server side tunnel setup in response to client
|
||||||
|
|
Loading…
Reference in New Issue