func (r *Remote) serveConn(conn net.Conn) { var ( addr proxy.Addr err error remote net.Conn ) defer func() { if remote != nil { remote.Close() } if conn != nil { conn.Close() } }() conn, addr, err = r.tunnel.Server(conn) if err != nil { if err != io.EOF && !isConnClosed(err) { r.log.Error(log.M{"msg": "parse tunnel request failed", "err": err.Error(), "remote": conn.RemoteAddr().String()}) } return } addrStr := addr.String() remote, err = net.Dial("tcp", addrStr) if err != nil { r.log.Error(log.M{"msg": "connect to dst server failed", "err": err.Error(), "addr": addrStr}) return } go PipeCloseDst(remote, conn, r.log) PipeCloseDst(conn, remote, r.log) conn = nil remote = nil }
func (l *Local) dial(addr proxy.Addr) (conn net.Conn, isTunnel bool, err error) { host := string(addr.Host) l.log.Info(log.M{"addr_type": addr.Type, "host": host, "port": addr.Port}) if host := string(addr.Host); l.isDirectConnect(host) { conn, err = net.Dial("tcp", addr.String()) if err == nil { if l.log.IsDebugEnable() { l.log.Debug(log.M{"connect_mode": "direct", "host": host}) } return conn, false, nil } l.log.Error(log.M{"msg": "direct connect failed, try tunnel.", "host": host, "err": err.Error()}) } // tunnel tunnel := l.randTunnel() conn, err = net.Dial("tcp", tunnel.Addr()) if err == nil { conn, err = tunnel.Client(conn, addr) if err != nil { l.log.Error(log.M{"msg": "tunnel handshake failed", "addr": tunnel.Addr(), "err": err.Error()}) } } else { l.log.Error(log.M{"msg": "connect tunnel server failed", "addr": tunnel.Addr(), "err": err.Error()}) } return conn, true, err }