diff --git a/grpc/grpcclient.go b/grpc/grpcclient.go index 40452e8..d46f62a 100644 --- a/grpc/grpcclient.go +++ b/grpc/grpcclient.go @@ -3,12 +3,12 @@ package grpc import ( "context" "crypto/tls" + "log" + "time" + "github.com/net-byte/vtun/grpc/proto" "google.golang.org/grpc" "google.golang.org/grpc/credentials" - "io" - "log" - "time" "github.com/net-byte/vtun/common/cache" "github.com/net-byte/vtun/common/cipher" @@ -19,6 +19,8 @@ import ( func StartClient(config config.Config) { log.Printf("vtun grpc client started on %v", config.LocalAddr) + iface := tun.CreateTun(config) + go tunToGrpc(config, iface) tlsconfig := &tls.Config{ InsecureSkipVerify: config.TLSInsecureSkipVerify, } @@ -26,22 +28,22 @@ func StartClient(config config.Config) { tlsconfig.ServerName = config.TLSSni } creds := credentials.NewTLS(tlsconfig) - iface := tun.CreateTun(config) - conn, err := grpc.Dial(config.ServerAddr, grpc.WithBlock(), grpc.WithTransportCredentials(creds)) - if err != nil { - log.Panic(err) - } - defer conn.Close() - streamClient := proto.NewGrpcServeClient(conn) - stream, err := streamClient.Tunnel(context.Background()) - if err != nil { - log.Panic(err) - } - go tunToGrpc(config, iface) for { + conn, err := grpc.Dial(config.ServerAddr, grpc.WithBlock(), grpc.WithTransportCredentials(creds)) + if err != nil { + time.Sleep(3 * time.Second) + continue + } + streamClient := proto.NewGrpcServeClient(conn) + stream, err := streamClient.Tunnel(context.Background()) + if err != nil { + conn.Close() + continue + } cache.GetCache().Set("grpcconn", stream, 24*time.Hour) grpcToTun(config, stream, iface) cache.GetCache().Delete("grpcconn") + conn.Close() } } @@ -55,7 +57,7 @@ func tunToGrpc(config config.Config, iface *water.Interface) { if v, ok := cache.GetCache().Get("grpcconn"); ok { b := packet[:n] if config.Obfs { - packet = cipher.XOR(packet) + b = cipher.XOR(b) } grpcconn := v.(proto.GrpcServe_TunnelClient) err = grpcconn.Send(&proto.PacketData{Data: b}) @@ -69,7 +71,7 @@ func tunToGrpc(config config.Config, iface *water.Interface) { func grpcToTun(config config.Config, stream proto.GrpcServe_TunnelClient, iface *water.Interface) { for { packet, err := stream.Recv() - if err != nil || err == io.EOF { + if err != nil { break } b := packet.Data[:] diff --git a/grpc/grpcserver.go b/grpc/grpcserver.go index cfb2ab8..d63d4cd 100644 --- a/grpc/grpcserver.go +++ b/grpc/grpcserver.go @@ -1,14 +1,14 @@ package grpc import ( - "github.com/net-byte/vtun/grpc/proto" - "google.golang.org/grpc" - "google.golang.org/grpc/credentials" - "io" "log" "net" "time" + "github.com/net-byte/vtun/grpc/proto" + "google.golang.org/grpc" + "google.golang.org/grpc/credentials" + "github.com/net-byte/vtun/common/cache" "github.com/net-byte/vtun/common/cipher" "github.com/net-byte/vtun/common/config" @@ -53,7 +53,7 @@ func toClient(config config.Config, iface *water.Interface) { packet := make([]byte, config.MTU) for { n, err := iface.Read(packet) - if err != nil || err == io.EOF || n == 0 { + if err != nil || n == 0 { continue } b := packet[:n] @@ -71,7 +71,7 @@ func toClient(config config.Config, iface *water.Interface) { func toServer(srv proto.GrpcServe_TunnelServer, config config.Config, iface *water.Interface) { for { packet, err := srv.Recv() - if err != nil || err == io.EOF { + if err != nil { break } b := packet.Data[:] diff --git a/quic/quicclient.go b/quic/quicclient.go index 43705c5..63850ee 100644 --- a/quic/quicclient.go +++ b/quic/quicclient.go @@ -3,7 +3,6 @@ package quic import ( "context" "crypto/tls" - "io" "log" "time" @@ -43,11 +42,13 @@ func StartClient(config config.Config) { stream, err := session.OpenStreamSync(context.Background()) if err != nil { log.Println(err) + session.CloseWithError(0, "bye") continue } cache.GetCache().Set("quicconn", stream, 24*time.Hour) quicToTun(config, stream, iface) cache.GetCache().Delete("quicconn") + session.CloseWithError(0, "bye") } } @@ -61,7 +62,7 @@ func tunToQuic(config config.Config, iface *water.Interface) { if v, ok := cache.GetCache().Get("quicconn"); ok { b := packet[:n] if config.Obfs { - packet = cipher.XOR(packet) + b = cipher.XOR(b) } stream := v.(quic.Stream) stream.SetWriteDeadline(time.Now().Add(time.Duration(config.Timeout) * time.Second)) @@ -79,7 +80,7 @@ func quicToTun(config config.Config, stream quic.Stream, iface *water.Interface) for { stream.SetReadDeadline(time.Now().Add(time.Duration(config.Timeout) * time.Second)) n, err := stream.Read(packet) - if err != nil || err == io.EOF { + if err != nil { break } b := packet[:n] diff --git a/quic/quicserver.go b/quic/quicserver.go index e47e7e7..09be2fa 100644 --- a/quic/quicserver.go +++ b/quic/quicserver.go @@ -41,12 +41,8 @@ func StartServer(config config.Config) { log.Println(err) continue } - stream, err := session.AcceptStream(context.Background()) - if err != nil { - log.Println(err) - continue - } - go toServer(config, stream, iface) + go toServer(config, session, iface) + } } @@ -63,14 +59,22 @@ func toClient(config config.Config, iface *water.Interface) { if config.Obfs { b = cipher.XOR(b) } - v.(quic.Stream).Write(b) + _, err := v.(quic.Stream).Write(b) + if err != nil { + cache.GetCache().Delete(key) + } } } } } -func toServer(config config.Config, stream quic.Stream, iface *water.Interface) { - defer stream.Close() +func toServer(config config.Config, session quic.Session, iface *water.Interface) { + stream, err := session.AcceptStream(context.Background()) + if err != nil { + log.Println(err) + return + } + defer session.CloseWithError(0, "bye") packet := make([]byte, config.MTU) for { stream.SetReadDeadline(time.Now().Add(time.Duration(config.Timeout) * time.Second)) @@ -87,4 +91,5 @@ func toServer(config config.Config, stream quic.Stream, iface *water.Interface) iface.Write(b) } } + stream.Close() } diff --git a/tcp/tcpclient.go b/tcp/tcpclient.go index de088b3..8cf4f83 100644 --- a/tcp/tcpclient.go +++ b/tcp/tcpclient.go @@ -41,7 +41,7 @@ func tunToTcp(config config.Config, iface *water.Interface) { if v, ok := cache.GetCache().Get("tcpconn"); ok { b := packet[:n] if config.Obfs { - packet = cipher.XOR(packet) + b = cipher.XOR(b) } tcpconn := v.(net.Conn) tcpconn.SetWriteDeadline(time.Now().Add(time.Duration(config.Timeout) * time.Second)) diff --git a/tls/tlsclient.go b/tls/tlsclient.go index 8162b16..435f308 100644 --- a/tls/tlsclient.go +++ b/tls/tlsclient.go @@ -19,13 +19,13 @@ func StartClient(config config.Config) { log.Printf("vtun tls client started on %v", config.LocalAddr) iface := tun.CreateTun(config) go tunToTLS(config, iface) + tlsconfig := &tls.Config{ + InsecureSkipVerify: config.TLSInsecureSkipVerify, + } + if config.TLSSni != "" { + tlsconfig.ServerName = config.TLSSni + } for { - tlsconfig := &tls.Config{ - InsecureSkipVerify: config.TLSInsecureSkipVerify, - } - if config.TLSSni != "" { - tlsconfig.ServerName = config.TLSSni - } conn, err := tls.Dial("tcp", config.ServerAddr, tlsconfig) if err != nil { time.Sleep(3 * time.Second) @@ -47,7 +47,7 @@ func tunToTLS(config config.Config, iface *water.Interface) { if v, ok := cache.GetCache().Get("tlsconn"); ok { b := packet[:n] if config.Obfs { - packet = cipher.XOR(packet) + b = cipher.XOR(b) } tlsconn := v.(net.Conn) tlsconn.SetWriteDeadline(time.Now().Add(time.Duration(config.Timeout) * time.Second)) diff --git a/ws/wsclient.go b/ws/wsclient.go index 9c5250c..892b9fe 100644 --- a/ws/wsclient.go +++ b/ws/wsclient.go @@ -59,7 +59,7 @@ func tunToWs(config config.Config, iface *water.Interface) { if v, ok := cache.GetCache().Get("wsconn"); ok { b := packet[:n] if config.Obfs { - packet = cipher.XOR(packet) + b = cipher.XOR(b) } wsconn := v.(net.Conn) wsconn.SetWriteDeadline(time.Now().Add(time.Duration(config.Timeout) * time.Second))