2021-03-14 15:02:07 +00:00
package grpc
import (
"context"
2021-07-05 21:25:03 +08:00
"time"
2021-03-14 15:02:07 +00:00
2023-02-27 19:52:01 +00:00
goreality "github.com/xtls/reality"
2021-03-14 15:02:07 +00:00
"github.com/xtls/xray-core/common"
2024-06-29 14:32:57 -04:00
"github.com/xtls/xray-core/common/errors"
2021-03-14 15:02:07 +00:00
"github.com/xtls/xray-core/common/net"
"github.com/xtls/xray-core/transport/internet"
"github.com/xtls/xray-core/transport/internet/grpc/encoding"
2023-02-27 19:52:01 +00:00
"github.com/xtls/xray-core/transport/internet/reality"
2021-03-14 15:02:07 +00:00
"github.com/xtls/xray-core/transport/internet/tls"
2022-05-18 15:29:01 +08:00
"google.golang.org/grpc"
"google.golang.org/grpc/credentials"
"google.golang.org/grpc/keepalive"
2021-03-14 15:02:07 +00:00
)
type Listener struct {
encoding . UnimplementedGRPCServiceServer
2026-06-19 06:31:21 +08:00
ctx context . Context
handler internet . ConnHandler
local net . Addr
config * Config
trustedXForwardedFor [] string
2021-03-14 15:02:07 +00:00
s * grpc . Server
}
func ( l Listener ) Tun ( server encoding . GRPCService_TunServer ) error {
tunCtx , cancel := context . WithCancel ( l . ctx )
2026-06-19 06:31:21 +08:00
l . handler ( encoding . NewHunkConn ( server , cancel , l . trustedXForwardedFor ))
2021-03-14 15:02:07 +00:00
<- tunCtx . Done ()
return nil
}
func ( l Listener ) TunMulti ( server encoding . GRPCService_TunMultiServer ) error {
tunCtx , cancel := context . WithCancel ( l . ctx )
2026-06-19 06:31:21 +08:00
l . handler ( encoding . NewMultiHunkConn ( server , cancel , l . trustedXForwardedFor ))
2021-03-14 15:02:07 +00:00
<- tunCtx . Done ()
return nil
}
func ( l Listener ) Close () error {
l . s . Stop ()
return nil
}
func ( l Listener ) Addr () net . Addr {
return l . local
}
func Listen ( ctx context . Context , address net . Address , port net . Port , settings * internet . MemoryStreamConfig , handler internet . ConnHandler ) ( internet . Listener , error ) {
grpcSettings := settings . ProtocolSettings .( * Config )
var listener * Listener
if port == net . Port ( 0 ) { // unix
listener = & Listener {
handler : handler ,
local : & net . UnixAddr {
Name : address . Domain (),
Net : "unix" ,
},
config : grpcSettings ,
}
} else { // tcp
listener = & Listener {
handler : handler ,
local : & net . TCPAddr {
IP : address . IP (),
Port : int ( port ),
},
config : grpcSettings ,
}
}
listener . ctx = ctx
2026-06-19 06:31:21 +08:00
if settings . SocketSettings != nil {
listener . trustedXForwardedFor = settings . SocketSettings . TrustedXForwardedFor
}
2021-03-14 15:02:07 +00:00
config := tls . ConfigFromStreamSettings ( settings )
2021-07-05 21:25:03 +08:00
var options [] grpc . ServerOption
2021-03-14 15:02:07 +00:00
var s * grpc . Server
2021-07-05 21:25:03 +08:00
if config != nil {
2021-10-22 00:01:51 -04:00
// gRPC server may silently ignore TLS errors
2021-07-05 21:25:03 +08:00
options = append ( options , grpc . Creds ( credentials . NewTLS ( config . GetTLSConfig ( tls . WithNextProto ( "h2" )))))
2021-03-14 15:02:07 +00:00
}
2021-07-05 21:25:03 +08:00
if grpcSettings . IdleTimeout > 0 || grpcSettings . HealthCheckTimeout > 0 {
options = append ( options , grpc . KeepaliveParams ( keepalive . ServerParameters {
Time : time . Second * time . Duration ( grpcSettings . IdleTimeout ),
Timeout : time . Second * time . Duration ( grpcSettings . HealthCheckTimeout ),
}))
}
s = grpc . NewServer ( options ... )
2021-03-14 15:02:07 +00:00
listener . s = s
if settings . SocketSettings != nil && settings . SocketSettings . AcceptProxyProtocol {
2024-06-29 14:32:57 -04:00
errors . LogWarning ( ctx , "accepting PROXY protocol" )
2021-03-14 15:02:07 +00:00
}
go func () {
var streamListener net . Listener
var err error
2026-09-21 02:12:50 +08:00
var addr net . Addr
2021-03-14 15:02:07 +00:00
if port == net . Port ( 0 ) { // unix
2026-09-21 02:12:50 +08:00
addr = & net . UnixAddr { Name : address . Domain (), Net : "unix" }
2021-03-14 15:02:07 +00:00
} else { // tcp
2026-09-21 02:12:50 +08:00
addr = & net . TCPAddr { IP : address . IP (), Port : int ( port )}
2021-03-14 15:02:07 +00:00
}
2026-09-21 02:12:50 +08:00
if settings . FinalMask != nil {
streamListener , err = settings . FinalMask . Listen ( ctx , addr )
} else {
streamListener , err = internet . ListenSystem ( ctx , addr , settings . SocketSettings )
}
if err != nil {
errors . LogErrorInner ( ctx , err , "failed to listen on " , address , ":" , port )
return
2026-03-07 23:42:18 +08:00
}
2024-11-09 14:16:11 +03:00
errors . LogDebug ( ctx , "gRPC listen for service name `" + grpcSettings . getServiceName () + "` tun `" + grpcSettings . getTunStreamName () + "` multi tun `" + grpcSettings . getTunMultiStreamName () + "`" )
2023-03-26 09:28:19 +03:30
encoding . RegisterGRPCServiceServerX ( s , listener , grpcSettings . getServiceName (), grpcSettings . getTunStreamName (), grpcSettings . getTunMultiStreamName ())
2021-03-14 15:02:07 +00:00
2023-02-27 19:52:01 +00:00
if config := reality . ConfigFromStreamSettings ( settings ); config != nil {
streamListener = goreality . NewListener ( streamListener , config . GetREALITYConfig ())
}
2021-03-14 15:02:07 +00:00
if err = s . Serve ( streamListener ); err != nil {
2024-06-29 14:32:57 -04:00
errors . LogInfoInner ( ctx , err , "Listener for gRPC ended" )
2021-03-14 15:02:07 +00:00
}
}()
return listener , nil
}
func init () {
common . Must ( internet . RegisterTransportListener ( protocolName , Listen ))
}