diff --git a/gost/examples/ssh/sshd.go b/gost/examples/ssh/sshd.go index adfd970..0cfc2d2 100644 --- a/gost/examples/ssh/sshd.go +++ b/gost/examples/ssh/sshd.go @@ -41,6 +41,7 @@ func sshTunnelServer() { if err != nil { log.Fatal(err) } + log.Println("server listen on", laddr) log.Fatal(s.Serve(ln)) } diff --git a/gost/socks.go b/gost/socks.go index c4f340a..a44192f 100644 --- a/gost/socks.go +++ b/gost/socks.go @@ -613,10 +613,15 @@ func (h *socks5Handler) handleUDPRelay(conn net.Conn, req *gosocks5.Request) { log.Logf("[socks5-udp] %s -> %s : %s", conn.RemoteAddr(), socksAddr, err) return } - // forward udp local <-> tunnel defer cc.Close() + cc, err = socks5Handshake(cc, h.options.Chain.LastNode().User) + if err != nil { + log.Logf("[socks5-udp] %s -> %s : %s", conn.RemoteAddr(), socksAddr, err) + return + } + cc.SetWriteDeadline(time.Now().Add(WriteTimeout)) r := gosocks5.NewRequest(CmdUDPTun, nil) if err := r.Write(cc); err != nil { diff --git a/gost/ssh.go b/gost/ssh.go index 81cf47c..a5fe1bd 100644 --- a/gost/ssh.go +++ b/gost/ssh.go @@ -147,9 +147,6 @@ func (tr *sshTunnelTransporter) Dial(addr string, options ...DialOption) (conn n session, ok := tr.sessions[addr] if !ok || session.Closed() { - if session != nil { - session.client.Close() - } if opts.Chain == nil { conn, err = net.DialTimeout("tcp", addr, opts.Timeout) } else { @@ -210,11 +207,11 @@ func (tr *sshTunnelTransporter) Handshake(conn net.Conn, options ...HandshakeOpt } tr.sessions[opts.Addr] = session go session.Ping(opts.Interval, 1) - go session.Wait() + go session.waitServer() + go session.waitClose() } if session.Closed() { - session.client.Close() delete(tr.sessions, opts.Addr) return nil, ErrSessionDead } @@ -289,11 +286,20 @@ func (s *sshSession) sendPing() <-chan error { return ch } -func (s *sshSession) Wait() error { +func (s *sshSession) waitServer() error { defer close(s.closed) return s.client.Wait() } +func (s *sshSession) waitClose() { + defer s.client.Close() + + select { + case <-s.deaded: + case <-s.closed: + } +} + func (s *sshSession) Closed() bool { select { case <-s.deaded: