← back to drwoodard72__ssh-ping

Function bodies 28 total

All specs Real LLM only Function bodies
main function · go · L22-L95 (74 LOC)
main.go
func main() {
	// Define flags
	versionFlag := flag.Bool("V", false, "print version and exit")
	countFlag := flag.Int("c", 100, "number of echo characters to send")
	timeFlag := flag.Duration("t", 0, "time limit for echo test")
	echoTimeoutFlag := flag.Duration("w", 10*time.Second, "per-echo timeout")
	sizeFlag := flag.Int("s", 8, "size in MB for speed test")
	remoteFlag := flag.String("r", "/tmp/sshping-test", "remote test file path")
	identFlag := flag.String("i", "", "identity/key file")
	portFlag := flag.Int("p", 22, "SSH port")
	userFlag := flag.String("u", "", "SSH user")
	proxyFlag := flag.String("proxy", "", "SOCKS5 proxy address (e.g. 127.0.0.1:9050 for Tor)")
	insecureFlag := flag.Bool("insecure", false, "skip host key verification")
	echoOnlyFlag := flag.Bool("e", false, "echo test only")
	speedOnlyFlag := flag.Bool("b", false, "speed test only")
	humanFlag := flag.Bool("H", false, "human-readable output")
	delimFlag := flag.Bool("d", false, "delimited numbers")
	verboseFlag
parseTarget function · go · L97-L120 (24 LOC)
main.go
func parseTarget(target, userFlag string, portFlag int) (string, int, string) {
	var host string
	var port int = portFlag
	var user string = userFlag

	// Check for user@host
	if strings.Contains(target, "@") {
		parts := strings.SplitN(target, "@", 2)
		user = parts[0]
		target = parts[1]
	}

	// Check for host:port (handles IPv6 bracket notation via net.SplitHostPort)
	if h, p, err := net.SplitHostPort(target); err == nil {
		host = h
		if pn, err := strconv.Atoi(p); err == nil {
			port = pn
		}
	} else {
		host = target
	}

	return host, port, user
}
runEchoTest function · go · L122-L150 (29 LOC)
main.go
func runEchoTest(sess *ssh.Session, count int, limit, echoTimeout time.Duration, verbosity int, human, delim bool) {
	shell, err := sess.OpenShell()
	if err != nil {
		log.Fatalf("failed to open shell: %v", err)
	}

	result, err := ssh.RunEchoTest(shell, count, limit, echoTimeout, verbosity)
	if err != nil {
		log.Fatalf("echo test failed: %v", err)
	}

	fmt.Println("\nEcho results:")
	fmt.Printf("  Sent:     %d\n", result.Sent)
	fmt.Printf("  Received: %d\n", result.Received)

	if len(result.Latencies) > 0 {
		min := stats.Min(result.Latencies)
		max := stats.Max(result.Latencies)
		mean := stats.Mean(result.Latencies)
		median := stats.Median(result.Latencies)
		stddev := stats.StdDev(result.Latencies)

		fmt.Printf("  Min:      %s\n", fmtDuration(min, human, delim))
		fmt.Printf("  Max:      %s\n", fmtDuration(max, human, delim))
		fmt.Printf("  Mean:     %s\n", fmtDuration(mean, human, delim))
		fmt.Printf("  Median:   %s\n", fmtDuration(median, human, delim))
		fmt.Printf("  StdDe
runSpeedTest function · go · L152-L168 (17 LOC)
main.go
func runSpeedTest(client *gossh.Client, remotePath string, sizeMB int, human, delim bool) {
	fmt.Println("\nSpeed test:")

	upload, err := ssh.RunUploadTest(client, remotePath, sizeMB)
	if err != nil {
		log.Printf("upload test failed: %v", err)
	} else {
		fmt.Printf("  Upload:   %s\n", fmtThroughput(upload, human, delim))
	}

	download, err := ssh.RunDownloadTest(client, remotePath, sizeMB)
	if err != nil {
		log.Printf("download test failed: %v", err)
	} else {
		fmt.Printf("  Download: %s\n", fmtThroughput(download, human, delim))
	}
}
fmtDuration function · go · L170-L187 (18 LOC)
main.go
func fmtDuration(d time.Duration, human, delim bool) string {
	if delim {
		return fmt.Sprintf("%d", d.Nanoseconds())
	}
	if human {
		ns := d.Nanoseconds()
		if ns < 1000 {
			return fmt.Sprintf("%d ns", ns)
		} else if ns < 1000000 {
			return fmt.Sprintf("%.2f µs", float64(ns)/1000)
		} else if ns < 1000000000 {
			return fmt.Sprintf("%.2f ms", float64(ns)/1000000)
		} else {
			return fmt.Sprintf("%.2f s", float64(ns)/1000000000)
		}
	}
	return d.String()
}
fmtThroughput function · go · L189-L202 (14 LOC)
main.go
func fmtThroughput(mbps float64, human, delim bool) string {
	if delim {
		return fmt.Sprintf("%.6f", mbps)
	}
	if human {
		if mbps >= 1024 {
			return fmt.Sprintf("%.2f GB/s", mbps/1024)
		} else if mbps >= 1 {
			return fmt.Sprintf("%.2f MB/s", mbps)
		}
		return fmt.Sprintf("%.2f KB/s", mbps*1024)
	}
	return fmt.Sprintf("%.2f MB/s", mbps)
}
RunEchoTest function · go · L21-L151 (131 LOC)
ssh/echo.go
func RunEchoTest(shell io.ReadWriter, count int, limit, echoTimeout time.Duration, verbose int) (EchoResult, error) {
	result := EchoResult{
		Latencies: make([]time.Duration, 0, count),
	}

	// Set up raw mode on remote (no buffering, no echo), print a sentinel
	// byte, then start cat. The sentinel (0x06 ACK) is printed by printf
	// as part of the command chain, so it appears on stdout only after stty
	// has run. Cat starts immediately after, so any stdin we send after
	// seeing the sentinel is guaranteed to be read by cat.
	const sentinel = 0x06
	fmt.Fprintf(shell, "stty raw -echo && printf '\\006' && cat\n")

	// Single persistent reader goroutine. The done channel lets it exit once
	// ReadByte unblocks (which happens when the SSH session is closed by the
	// caller). Between RunEchoTest returning and session close, the goroutine
	// remains blocked in ReadByte — this is expected and harmless.
	done := make(chan struct{})
	defer close(done)
	byteCh := make(chan readResult, 1)
	
About: code-quality intelligence by Repobility · https://repobility.com
Connect function · go · L40-L95 (56 LOC)
ssh/session.go
func Connect(cfg Config) (*connectResult, error) {
	addr := net.JoinHostPort(cfg.Host, fmt.Sprintf("%d", cfg.Port))

	hostKeyCb, err := hostKeyCallback(cfg.Insecure)
	if err != nil {
		return nil, err
	}

	// Build auth methods in order: pubkey, keyboard-interactive, password
	var authMethods []ssh.AuthMethod
	var agentConn net.Conn

	// Try public key authentication
	if methods, conn, err := publicKeyAuth(cfg.IdentFile); err == nil {
		authMethods = append(authMethods, methods...)
		agentConn = conn
	}

	if cfg.Password != "" {
		authMethods = append(authMethods, ssh.Password(cfg.Password))
	}

	clientConfig := &ssh.ClientConfig{
		User:            cfg.User,
		Auth:            authMethods,
		HostKeyCallback: hostKeyCb,
		Timeout:         cfg.Timeout,
	}

	result, err := dial(addr, cfg.SOCKS5Proxy, cfg.Timeout, clientConfig)
	if err == nil {
		result.agentConn = agentConn
		return result, nil
	}

	// If auth failed and we skipped a passphrase-protected -i key because
	// the agent was 
dial function · go · L97-L120 (24 LOC)
ssh/session.go
func dial(addr, socks5Proxy string, timeout time.Duration, clientConfig *ssh.ClientConfig) (*connectResult, error) {
	if socks5Proxy != "" {
		dialer, err := proxy.SOCKS5("tcp", socks5Proxy, nil, &net.Dialer{Timeout: timeout})
		if err != nil {
			return nil, fmt.Errorf("socks5 dialer: %w", err)
		}
		conn, err := dialer.Dial("tcp", addr)
		if err != nil {
			return nil, fmt.Errorf("socks5 dial failed: %w", err)
		}
		c, chans, reqs, err := ssh.NewClientConn(conn, addr, clientConfig)
		if err != nil {
			conn.Close()
			return nil, fmt.Errorf("ssh handshake failed: %w", err)
		}
		return &connectResult{client: ssh.NewClient(c, chans, reqs)}, nil
	}

	client, err := ssh.Dial("tcp", addr, clientConfig)
	if err != nil {
		return nil, fmt.Errorf("dial failed: %w", err)
	}
	return &connectResult{client: client}, nil
}
isAuthError function · go · L122-L126 (5 LOC)
ssh/session.go
func isAuthError(err error) bool {
	msg := err.Error()
	return strings.Contains(msg, "unable to authenticate") ||
		strings.Contains(msg, "no supported methods remain")
}
publicKeyAuth function · go · L130-L172 (43 LOC)
ssh/session.go
func publicKeyAuth(identFile string) ([]ssh.AuthMethod, net.Conn, error) {
	var methods []ssh.AuthMethod
	var agentConn net.Conn

	// Try SSH agent
	if agentSock := os.Getenv("SSH_AUTH_SOCK"); agentSock != "" {
		conn, err := net.Dial("unix", agentSock)
		if err == nil {
			ag := agent.NewClient(conn)
			methods = append(methods, ssh.PublicKeysCallback(ag.Signers))
			agentConn = conn
		}
	}

	// If a specific identity file is provided, try loading it.
	// Only prompt for passphrase if no agent is available to fall back on.
	if identFile != "" {
		if method, err := loadPrivateKey(identFile, agentConn == nil); err == nil {
			methods = append(methods, method)
		}
	}

	// Try default SSH keys only if no agent and no explicit identity file
	if len(methods) == 0 {
		homeDir, err := os.UserHomeDir()
		if err == nil {
			for _, name := range []string{"id_rsa", "id_ecdsa", "id_ed25519"} {
				keyPath := filepath.Join(homeDir, ".ssh", name)
				method, err := loadPrivateKey(keyPath, true)
				
loadPrivateKey function · go · L174-L200 (27 LOC)
ssh/session.go
func loadPrivateKey(path string, promptForPassphrase bool) (ssh.AuthMethod, error) {
	keyBytes, err := os.ReadFile(path)
	if err != nil {
		return nil, err
	}

	signer, err := ssh.ParsePrivateKey(keyBytes)
	if err == nil {
		return ssh.PublicKeys(signer), nil
	}

	if !promptForPassphrase {
		return nil, fmt.Errorf("key %s is passphrase-protected, skipping (agent available)", path)
	}

	passphrase, err := promptPassphrase(path)
	if err != nil {
		return nil, err
	}

	signer, err = ssh.ParsePrivateKeyWithPassphrase(keyBytes, []byte(passphrase))
	if err != nil {
		return nil, fmt.Errorf("failed to unlock key %s: %w", path, err)
	}

	return ssh.PublicKeys(signer), nil
}
promptPassphrase function · go · L202-L237 (36 LOC)
ssh/session.go
func promptPassphrase(keyPath string) (string, error) {
	fmt.Fprintf(os.Stderr, "Enter passphrase for %s: ", keyPath)

	// Read password without echo
	fd := int(syscall.Stdin)
	oldState, err := term.GetState(fd)
	if err != nil {
		// Fall back to unbuffered line reading if terminal mode unavailable.
		// Avoid bufio.NewReader here — it would consume extra bytes from
		// stdin that the TOFU host key prompt needs later.
		var passphrase []byte
		buf := make([]byte, 1)
		for {
			n, err := os.Stdin.Read(buf)
			if n > 0 && buf[0] == '\n' {
				break
			}
			if n > 0 {
				passphrase = append(passphrase, buf[0])
			}
			if err != nil {
				break
			}
		}
		return string(passphrase), nil
	}
	defer term.Restore(fd, oldState)

	password, err := term.ReadPassword(fd)
	if err != nil {
		return "", err
	}

	fmt.Fprintf(os.Stderr, "\n")
	return string(password), nil
}
hostKeyCallback function · go · L240-L339 (100 LOC)
ssh/session.go
func hostKeyCallback(insecure bool) (ssh.HostKeyCallback, error) {
	if insecure {
		return ssh.InsecureIgnoreHostKey(), nil
	}
	homeDir, err := os.UserHomeDir()
	if err != nil {
		return nil, fmt.Errorf("cannot find home directory: %w", err)
	}
	knownHostsFile := filepath.Join(homeDir, ".ssh", "known_hosts")

	// Create known_hosts if it doesn't exist.
	if _, err := os.Stat(knownHostsFile); os.IsNotExist(err) {
		if err := os.MkdirAll(filepath.Dir(knownHostsFile), 0700); err != nil {
			return nil, fmt.Errorf("cannot create .ssh directory: %w", err)
		}
		f, err := os.OpenFile(knownHostsFile, os.O_CREATE|os.O_WRONLY, 0600)
		if err != nil {
			return nil, fmt.Errorf("cannot create known_hosts: %w", err)
		}
		f.Close()
	}

	cb, err := knownhosts.New(knownHostsFile)
	if err != nil {
		return nil, fmt.Errorf("cannot read known_hosts (%s): %w", knownHostsFile, err)
	}

	// TOFU wrapper: prompt to accept unknown keys, reject changed keys.
	return func(hostname string, remote net.Addr, key 
keyTypeName function · go · L341-L354 (14 LOC)
ssh/session.go
func keyTypeName(keyType string) string {
	switch keyType {
	case "ssh-rsa":
		return "RSA"
	case "ssh-ed25519":
		return "ED25519"
	case "ecdsa-sha2-nistp256", "ecdsa-sha2-nistp384", "ecdsa-sha2-nistp521":
		return "ECDSA"
	case "ssh-dss":
		return "DSA"
	default:
		return strings.ToUpper(keyType)
	}
}
Want this analysis on your repo? https://repobility.com/scan/
NewSession function · go · L362-L394 (33 LOC)
ssh/session.go
func NewSession(cfg Config) (*Session, error) {
	if cfg.User == "" {
		currentUser, err := user.Current()
		if err != nil {
			return nil, fmt.Errorf("failed to get current user: %w", err)
		}
		cfg.User = currentUser.Username
	}

	if cfg.Timeout == 0 {
		cfg.Timeout = 10 * time.Second
	}

	cr, err := Connect(cfg)
	if err != nil {
		return nil, err
	}

	sess, err := cr.client.NewSession()
	if err != nil {
		cr.client.Close()
		if cr.agentConn != nil {
			cr.agentConn.Close()
		}
		return nil, fmt.Errorf("new session failed: %w", err)
	}

	return &Session{
		Client:    cr.client,
		Sess:      sess,
		agentConn: cr.agentConn,
	}, nil
}
OpenShell method · go · L396-L426 (31 LOC)
ssh/session.go
func (s *Session) OpenShell() (io.ReadWriter, error) {
	in, err := s.Sess.StdinPipe()
	if err != nil {
		return nil, fmt.Errorf("stdin pipe failed: %w", err)
	}

	out, err := s.Sess.StdoutPipe()
	if err != nil {
		in.Close()
		return nil, fmt.Errorf("stdout pipe failed: %w", err)
	}

	// Request PTY for interactive shell
	modes := ssh.TerminalModes{
		ssh.ECHO:          1,
		ssh.TTY_OP_ISPEED: 14400,
		ssh.TTY_OP_OSPEED: 14400,
	}

	if err := s.Sess.RequestPty("xterm", 24, 80, modes); err != nil {
		in.Close()
		return nil, fmt.Errorf("pty request failed: %w", err)
	}

	if err := s.Sess.Shell(); err != nil {
		in.Close()
		return nil, fmt.Errorf("shell start failed: %w", err)
	}

	return &readWriter{in: in, out: out}, nil
}
Close method · go · L428-L443 (16 LOC)
ssh/session.go
func (s *Session) Close() error {
	var err1, err2 error
	if s.Sess != nil {
		err1 = s.Sess.Close()
	}
	if s.Client != nil {
		err2 = s.Client.Close()
	}
	if s.agentConn != nil {
		s.agentConn.Close()
	}
	if err1 != nil {
		return err1
	}
	return err2
}
Read method · go · L450-L452 (3 LOC)
ssh/session.go
func (rw *readWriter) Read(b []byte) (int, error) {
	return rw.out.Read(b)
}
Write method · go · L454-L456 (3 LOC)
ssh/session.go
func (rw *readWriter) Write(b []byte) (int, error) {
	return rw.in.Write(b)
}
Close method · go · L458-L460 (3 LOC)
ssh/session.go
func (rw *readWriter) Close() error {
	return rw.in.Close()
}
RunUploadTest function · go · L13-L65 (53 LOC)
ssh/speed.go
func RunUploadTest(client *ssh.Client, remotePath string, sizeMB int) (float64, error) {
	if sizeMB <= 0 {
		return 0, fmt.Errorf("size must be > 0, got %d", sizeMB)
	}
	sfTPClient, err := sftp.NewClient(client)
	if err != nil {
		return 0, fmt.Errorf("sftp client creation failed: %w", err)
	}
	defer sfTPClient.Close()

	// Create remote file
	remoteFile, err := sfTPClient.Create(remotePath)
	if err != nil {
		return 0, fmt.Errorf("remote file creation failed: %w", err)
	}

	// Generate random data and write
	bufSize := 1024 * 1024 // 1 MB chunks
	totalBytes := int64(sizeMB) * 1024 * 1024
	buf := make([]byte, bufSize)

	// Fill with random data
	rand.Read(buf)

	written := int64(0)
	start := time.Now()

	for written < totalBytes {
		remaining := totalBytes - written
		if int64(bufSize) > remaining {
			buf = make([]byte, remaining)
			rand.Read(buf)
		}

		n, err := remoteFile.Write(buf)
		if err != nil {
			remoteFile.Close()
			sfTPClient.Remove(remotePath)
			return 0, fmt.Errorf("w
RunDownloadTest function · go · L67-L137 (71 LOC)
ssh/speed.go
func RunDownloadTest(client *ssh.Client, remotePath string, sizeMB int) (float64, error) {
	if sizeMB <= 0 {
		return 0, fmt.Errorf("size must be > 0, got %d", sizeMB)
	}
	sfTPClient, err := sftp.NewClient(client)
	if err != nil {
		return 0, fmt.Errorf("sftp client creation failed: %w", err)
	}
	defer sfTPClient.Close()

	// First, create a file to download by uploading test data
	remoteFile, err := sfTPClient.Create(remotePath)
	if err != nil {
		return 0, fmt.Errorf("remote file creation failed: %w", err)
	}

	bufSize := 1024 * 1024
	totalBytes := int64(sizeMB) * 1024 * 1024
	buf := make([]byte, bufSize)
	rand.Read(buf)

	written := int64(0)
	for written < totalBytes {
		remaining := totalBytes - written
		if int64(bufSize) > remaining {
			buf = make([]byte, remaining)
			rand.Read(buf)
		}
		n, err := remoteFile.Write(buf)
		if err != nil {
			remoteFile.Close()
			sfTPClient.Remove(remotePath)
			return 0, fmt.Errorf("setup write failed: %w", err)
		}
		written += int64(n)
	}
	if
Repobility — the code-quality scanner for AI-generated software · https://repobility.com
Min function · go · L9-L20 (12 LOC)
stats/stats.go
func Min(d []time.Duration) time.Duration {
	if len(d) == 0 {
		return 0
	}
	min := d[0]
	for _, v := range d[1:] {
		if v < min {
			min = v
		}
	}
	return min
}
Max function · go · L22-L33 (12 LOC)
stats/stats.go
func Max(d []time.Duration) time.Duration {
	if len(d) == 0 {
		return 0
	}
	max := d[0]
	for _, v := range d[1:] {
		if v > max {
			max = v
		}
	}
	return max
}
Mean function · go · L35-L44 (10 LOC)
stats/stats.go
func Mean(d []time.Duration) time.Duration {
	if len(d) == 0 {
		return 0
	}
	sum := int64(0)
	for _, v := range d {
		sum += v.Nanoseconds()
	}
	return time.Duration(sum / int64(len(d)))
}
Median function · go · L46-L59 (14 LOC)
stats/stats.go
func Median(d []time.Duration) time.Duration {
	if len(d) == 0 {
		return 0
	}
	sorted := make([]time.Duration, len(d))
	copy(sorted, d)
	sort.Slice(sorted, func(i, j int) bool { return sorted[i] < sorted[j] })

	mid := len(sorted) / 2
	if len(sorted)%2 == 1 {
		return sorted[mid]
	}
	return (sorted[mid-1] + sorted[mid]) / 2
}
StdDev function · go · L61-L73 (13 LOC)
stats/stats.go
func StdDev(d []time.Duration) time.Duration {
	if len(d) < 2 {
		return 0
	}
	mean := Mean(d)
	sumSq := 0.0
	for _, v := range d {
		diff := float64(v.Nanoseconds() - mean.Nanoseconds())
		sumSq += diff * diff
	}
	variance := sumSq / float64(len(d)-1)
	return time.Duration(math.Sqrt(variance))
}