package ssh

import (
	
	
	
	
)

type serverConn struct {
	net.Conn

	idleTimeout   time.Duration
	maxDeadline   time.Time
	closeCanceler context.CancelFunc

	// handshakeDeadline is cleared once the handshake completes, which happens
	// after gossh.NewServerConn has started goroutines that read it via
	// updateDeadline. Access it only through the accessors below.
	mu                sync.Mutex
	handshakeDeadline time.Time
}

// setHandshakeDeadline bounds how long the handshake may take.
func ( *serverConn) ( time.Time) {
	.mu.Lock()
	.handshakeDeadline = 
	.mu.Unlock()
	.updateDeadline()
}

// clearHandshakeDeadline drops the handshake deadline once the handshake has
// completed, leaving the idle and max deadlines to govern the connection.
func ( *serverConn) () {
	.mu.Lock()
	.handshakeDeadline = time.Time{}
	.mu.Unlock()
	.updateDeadline()
}

func ( *serverConn) ( []byte) ( int,  error) {
	if .idleTimeout > 0 {
		.updateDeadline()
	}
	,  = .Conn.Write()
	if ,  := .(net.Error);  && .closeCanceler != nil {
		.closeCanceler()
	}
	return
}

func ( *serverConn) ( []byte) ( int,  error) {
	if .idleTimeout > 0 {
		.updateDeadline()
	}
	,  = .Conn.Read()
	if ,  := .(net.Error);  && .closeCanceler != nil {
		.closeCanceler()
	}
	return
}

func ( *serverConn) () ( error) {
	 = .Conn.Close()
	if .closeCanceler != nil {
		.closeCanceler()
	}
	return
}

func ( *serverConn) () {
	.mu.Lock()
	 := .handshakeDeadline
	.mu.Unlock()

	// idleTimeout and maxDeadline are set before the handshake starts and never
	// mutated afterwards, so they need no locking.
	 := .maxDeadline

	if !.IsZero() && (.IsZero() || .Before()) {
		 = 
	}

	if .idleTimeout > 0 {
		 := time.Now().Add(.idleTimeout)
		if .IsZero() || .Before() {
			 = 
		}
	}

	_ = .SetDeadline()
}