From f87199c59e61978828e1393d864067c40caf7d63 Mon Sep 17 00:00:00 2001 From: mo Date: Sun, 19 Apr 2020 17:57:30 +0800 Subject: [PATCH] Fix panic when target.LocalAddr() is not *net.TCPAddr This happens when you use custom dialer that returns custom net.Conn that returns a non-*net.TCPAddr net.Addr for LocalAddr() calls. For example, if you dial through an SSH connection, it might be difficult to figure out remote local address, so you return a stub instead. --- request.go | 11 ++++++++--- 1 file changed, 8 insertions(+), 3 deletions(-) diff --git a/request.go b/request.go index 8b40ffe..4f753e1 100644 --- a/request.go +++ b/request.go @@ -190,9 +190,7 @@ func (s *Server) handleConnect(ctx context.Context, conn conn, req *Request) err defer target.Close() // Send success - local := target.LocalAddr().(*net.TCPAddr) - bind := AddrSpec{IP: local.IP, Port: local.Port} - if err := sendReply(conn, successReply, &bind); err != nil { + if err := sendReply(conn, successReply, addrSpecFromNetAddr(target.LocalAddr())); err != nil { return fmt.Errorf("Failed to send reply: %v", err) } @@ -302,6 +300,13 @@ func readAddrSpec(r io.Reader) (*AddrSpec, error) { return d, nil } +func addrSpecFromNetAddr(addr net.Addr) *AddrSpec { + if tcpAddr, ok := addr.(*net.TCPAddr); ok { + return &AddrSpec{IP: tcpAddr.IP, Port: tcpAddr.Port} + } + return nil +} + // sendReply is used to send a reply message func sendReply(w io.Writer, resp uint8, addr *AddrSpec) error { // Format the address