github.com/sagernet/sing-box@v1.9.0-rc.20/transport/v2raygrpc/server.go (about) 1 package v2raygrpc 2 3 import ( 4 "context" 5 "net" 6 "os" 7 "strings" 8 "time" 9 10 "github.com/sagernet/sing-box/adapter" 11 "github.com/sagernet/sing-box/common/tls" 12 "github.com/sagernet/sing-box/option" 13 "github.com/sagernet/sing/common" 14 M "github.com/sagernet/sing/common/metadata" 15 N "github.com/sagernet/sing/common/network" 16 17 "golang.org/x/net/http2" 18 "google.golang.org/grpc" 19 "google.golang.org/grpc/keepalive" 20 gM "google.golang.org/grpc/metadata" 21 "google.golang.org/grpc/peer" 22 ) 23 24 var _ adapter.V2RayServerTransport = (*Server)(nil) 25 26 type Server struct { 27 ctx context.Context 28 handler N.TCPConnectionHandler 29 server *grpc.Server 30 } 31 32 func NewServer(ctx context.Context, options option.V2RayGRPCOptions, tlsConfig tls.ServerConfig, handler N.TCPConnectionHandler) (*Server, error) { 33 var serverOptions []grpc.ServerOption 34 if tlsConfig != nil { 35 if !common.Contains(tlsConfig.NextProtos(), http2.NextProtoTLS) { 36 tlsConfig.SetNextProtos(append([]string{"h2"}, tlsConfig.NextProtos()...)) 37 } 38 serverOptions = append(serverOptions, grpc.Creds(NewTLSTransportCredentials(tlsConfig))) 39 } 40 if options.IdleTimeout > 0 { 41 serverOptions = append(serverOptions, grpc.KeepaliveParams(keepalive.ServerParameters{ 42 Time: time.Duration(options.IdleTimeout), 43 Timeout: time.Duration(options.PingTimeout), 44 })) 45 } 46 server := &Server{ctx, handler, grpc.NewServer(serverOptions...)} 47 RegisterGunServiceCustomNameServer(server.server, server, options.ServiceName) 48 return server, nil 49 } 50 51 func (s *Server) Tun(server GunService_TunServer) error { 52 ctx, cancel := common.ContextWithCancelCause(s.ctx) 53 conn := NewGRPCConn(server, cancel) 54 var metadata M.Metadata 55 if remotePeer, loaded := peer.FromContext(server.Context()); loaded { 56 metadata.Source = M.SocksaddrFromNet(remotePeer.Addr) 57 } 58 if grpcMetadata, loaded := gM.FromIncomingContext(server.Context()); loaded { 59 forwardFrom := strings.Join(grpcMetadata.Get("X-Forwarded-For"), ",") 60 if forwardFrom != "" { 61 for _, from := range strings.Split(forwardFrom, ",") { 62 originAddr := M.ParseSocksaddr(from) 63 if originAddr.IsValid() { 64 metadata.Source = originAddr.Unwrap() 65 } 66 } 67 } 68 } 69 go s.handler.NewConnection(ctx, conn, metadata) 70 <-ctx.Done() 71 return nil 72 } 73 74 func (s *Server) mustEmbedUnimplementedGunServiceServer() { 75 } 76 77 func (s *Server) Network() []string { 78 return []string{N.NetworkTCP} 79 } 80 81 func (s *Server) Serve(listener net.Listener) error { 82 return s.server.Serve(listener) 83 } 84 85 func (s *Server) ServePacket(listener net.PacketConn) error { 86 return os.ErrInvalid 87 } 88 89 func (s *Server) Close() error { 90 s.server.Stop() 91 return nil 92 }