2020-11-25 14:01:53 +03:00
package inbound
import (
2023-01-06 08:37:16 +03:00
"bytes"
2020-11-25 14:01:53 +03:00
"context"
2023-01-27 06:43:58 +03:00
gotls "crypto/tls"
2020-11-25 14:01:53 +03:00
"io"
2023-01-06 08:37:16 +03:00
"reflect"
2020-11-25 14:01:53 +03:00
"strconv"
2021-01-13 18:13:51 +03:00
"strings"
2020-11-25 14:01:53 +03:00
"time"
2023-01-06 08:37:16 +03:00
"unsafe"
2020-11-25 14:01:53 +03:00
2020-12-04 04:36:16 +03:00
"github.com/xtls/xray-core/common"
"github.com/xtls/xray-core/common/buf"
"github.com/xtls/xray-core/common/errors"
"github.com/xtls/xray-core/common/log"
"github.com/xtls/xray-core/common/net"
"github.com/xtls/xray-core/common/protocol"
"github.com/xtls/xray-core/common/retry"
"github.com/xtls/xray-core/common/session"
"github.com/xtls/xray-core/common/signal"
"github.com/xtls/xray-core/common/task"
2023-02-15 19:07:12 +03:00
"github.com/xtls/xray-core/core"
2020-12-04 04:36:16 +03:00
"github.com/xtls/xray-core/features/dns"
feature_inbound "github.com/xtls/xray-core/features/inbound"
"github.com/xtls/xray-core/features/policy"
"github.com/xtls/xray-core/features/routing"
2023-09-02 18:37:50 +03:00
"github.com/xtls/xray-core/proxy"
2020-12-04 04:36:16 +03:00
"github.com/xtls/xray-core/proxy/vless"
"github.com/xtls/xray-core/proxy/vless/encoding"
2023-02-15 19:07:12 +03:00
"github.com/xtls/xray-core/transport/internet/reality"
2021-12-15 03:28:47 +03:00
"github.com/xtls/xray-core/transport/internet/stat"
2020-12-04 04:36:16 +03:00
"github.com/xtls/xray-core/transport/internet/tls"
2020-11-25 14:01:53 +03:00
)
func init ( ) {
common . Must ( common . RegisterConfig ( ( * Config ) ( nil ) , func ( ctx context . Context , config interface { } ) ( interface { } , error ) {
var dc dns . Client
if err := core . RequireFeatures ( ctx , func ( d dns . Client ) error {
dc = d
return nil
} ) ; err != nil {
return nil , err
}
2024-09-13 17:51:26 +03:00
c := config . ( * Config )
validator := new ( vless . MemoryValidator )
for _ , user := range c . Clients {
u , err := user . ToMemoryUser ( )
if err != nil {
return nil , errors . New ( "failed to get VLESS user" ) . Base ( err ) . AtError ( )
}
if err := validator . Add ( u ) ; err != nil {
return nil , errors . New ( "failed to initiate user" ) . Base ( err ) . AtError ( )
}
}
return New ( ctx , c , dc , validator )
2020-11-25 14:01:53 +03:00
} ) )
}
// Handler is an inbound connection handler that handles messages in VLess protocol.
type Handler struct {
inboundHandlerManager feature_inbound . Manager
policyManager policy . Manager
2024-09-13 17:51:26 +03:00
validator vless . Validator
2020-11-25 14:01:53 +03:00
dns dns . Client
2021-01-13 18:13:51 +03:00
fallbacks map [ string ] map [ string ] map [ string ] * Fallback // or nil
2020-11-25 14:01:53 +03:00
// regexps map[string]*regexp.Regexp // or nil
}
// New creates a new VLess inbound handler.
2024-09-13 17:51:26 +03:00
func New ( ctx context . Context , config * Config , dc dns . Client , validator vless . Validator ) ( * Handler , error ) {
2020-11-25 14:01:53 +03:00
v := core . MustFromContext ( ctx )
handler := & Handler {
inboundHandlerManager : v . GetFeature ( feature_inbound . ManagerType ( ) ) . ( feature_inbound . Manager ) ,
policyManager : v . GetFeature ( policy . ManagerType ( ) ) . ( policy . Manager ) ,
dns : dc ,
2024-09-13 17:51:26 +03:00
validator : validator ,
2020-11-25 14:01:53 +03:00
}
if config . Fallbacks != nil {
2021-01-13 18:13:51 +03:00
handler . fallbacks = make ( map [ string ] map [ string ] map [ string ] * Fallback )
2020-11-25 14:01:53 +03:00
// handler.regexps = make(map[string]*regexp.Regexp)
for _ , fb := range config . Fallbacks {
2021-01-13 18:13:51 +03:00
if handler . fallbacks [ fb . Name ] == nil {
handler . fallbacks [ fb . Name ] = make ( map [ string ] map [ string ] * Fallback )
2020-11-25 14:01:53 +03:00
}
2021-01-13 18:13:51 +03:00
if handler . fallbacks [ fb . Name ] [ fb . Alpn ] == nil {
handler . fallbacks [ fb . Name ] [ fb . Alpn ] = make ( map [ string ] * Fallback )
}
handler . fallbacks [ fb . Name ] [ fb . Alpn ] [ fb . Path ] = fb
2020-11-25 14:01:53 +03:00
/ *
if fb . Path != "" {
if r , err := regexp . Compile ( fb . Path ) ; err != nil {
2024-06-29 21:32:57 +03:00
return nil , errors . New ( "invalid path regexp" ) . Base ( err ) . AtError ( )
2020-11-25 14:01:53 +03:00
} else {
handler . regexps [ fb . Path ] = r
}
}
* /
}
2021-01-15 14:36:31 +03:00
if handler . fallbacks [ "" ] != nil {
for name , apfb := range handler . fallbacks {
if name != "" {
for alpn := range handler . fallbacks [ "" ] {
if apfb [ alpn ] == nil {
apfb [ alpn ] = make ( map [ string ] * Fallback )
}
}
}
}
}
2021-01-15 00:55:52 +03:00
for _ , apfb := range handler . fallbacks {
if apfb [ "" ] != nil {
for alpn , pfb := range apfb {
if alpn != "" { // && alpn != "h2" {
for path , fb := range apfb [ "" ] {
if pfb [ path ] == nil {
pfb [ path ] = fb
}
}
}
}
}
}
2020-11-25 14:01:53 +03:00
if handler . fallbacks [ "" ] != nil {
2021-01-15 00:55:52 +03:00
for name , apfb := range handler . fallbacks {
if name != "" {
for alpn , pfb := range handler . fallbacks [ "" ] {
for path , fb := range pfb {
if apfb [ alpn ] [ path ] == nil {
apfb [ alpn ] [ path ] = fb
}
2020-11-25 14:01:53 +03:00
}
}
}
}
}
}
return handler , nil
}
2023-01-28 08:39:36 +03:00
func isMuxAndNotXUDP ( request * protocol . RequestHeader , first * buf . Buffer ) bool {
if request . Command != protocol . RequestCommandMux {
return false
}
if first . Len ( ) < 7 {
return true
}
firstBytes := first . Bytes ( )
return ! ( firstBytes [ 2 ] == 0 && // ID high
firstBytes [ 3 ] == 0 && // ID low
firstBytes [ 6 ] == 2 ) // Network type: UDP
}
2020-11-25 14:01:53 +03:00
// Close implements common.Closable.Close().
func ( h * Handler ) Close ( ) error {
return errors . Combine ( common . Close ( h . validator ) )
}
// AddUser implements proxy.UserManager.AddUser().
func ( h * Handler ) AddUser ( ctx context . Context , u * protocol . MemoryUser ) error {
return h . validator . Add ( u )
}
// RemoveUser implements proxy.UserManager.RemoveUser().
func ( h * Handler ) RemoveUser ( ctx context . Context , e string ) error {
return h . validator . Del ( e )
}
2024-11-03 07:25:23 +03:00
// GetUser implements proxy.UserManager.GetUser().
func ( h * Handler ) GetUser ( ctx context . Context , email string ) * protocol . MemoryUser {
return h . validator . GetByEmail ( email )
}
// GetUsers implements proxy.UserManager.GetUsers().
func ( h * Handler ) GetUsers ( ctx context . Context ) [ ] * protocol . MemoryUser {
return h . validator . GetAll ( )
}
// GetUsersCount implements proxy.UserManager.GetUsersCount().
func ( h * Handler ) GetUsersCount ( context . Context ) int64 {
return h . validator . GetCount ( )
}
2020-11-25 14:01:53 +03:00
// Network implements proxy.Inbound.Network().
func ( * Handler ) Network ( ) [ ] net . Network {
return [ ] net . Network { net . Network_TCP , net . Network_UNIX }
}
// Process implements proxy.Inbound.Process().
2021-09-20 15:11:21 +03:00
func ( h * Handler ) Process ( ctx context . Context , network net . Network , connection stat . Connection , dispatcher routing . Dispatcher ) error {
2020-11-25 14:01:53 +03:00
iConn := connection
2023-05-04 05:21:45 +03:00
if statConn , ok := iConn . ( * stat . CounterConnection ) ; ok {
2020-11-25 14:01:53 +03:00
iConn = statConn . Connection
}
sessionPolicy := h . policyManager . ForLevel ( 0 )
if err := connection . SetReadDeadline ( time . Now ( ) . Add ( sessionPolicy . Timeouts . Handshake ) ) ; err != nil {
2024-06-29 21:32:57 +03:00
return errors . New ( "unable to set read deadline" ) . Base ( err ) . AtWarning ( )
2020-11-25 14:01:53 +03:00
}
2023-01-17 06:18:58 +03:00
first := buf . FromBytes ( make ( [ ] byte , buf . Size ) )
first . Clear ( )
2020-11-25 14:01:53 +03:00
firstLen , _ := first . ReadFrom ( connection )
2024-06-29 21:32:57 +03:00
errors . LogInfo ( ctx , "firstLen = " , firstLen )
2020-11-25 14:01:53 +03:00
reader := & buf . BufferedReader {
Reader : buf . NewReader ( connection ) ,
Buffer : buf . MultiBuffer { first } ,
}
var request * protocol . RequestHeader
var requestAddons * encoding . Addons
var err error
2021-01-15 00:55:52 +03:00
napfb := h . fallbacks
isfb := napfb != nil
2020-11-25 14:01:53 +03:00
if isfb && firstLen < 18 {
2024-06-29 21:32:57 +03:00
err = errors . New ( "fallback directly" )
2020-11-25 14:01:53 +03:00
} else {
request , requestAddons , isfb , err = encoding . DecodeRequestHeader ( isfb , first , reader , h . validator )
}
if err != nil {
if isfb {
if err := connection . SetReadDeadline ( time . Time { } ) ; err != nil {
2024-06-29 21:32:57 +03:00
errors . LogWarningInner ( ctx , err , "unable to set back read deadline" )
2020-11-25 14:01:53 +03:00
}
2024-06-29 21:32:57 +03:00
errors . LogInfoInner ( ctx , err , "fallback starts" )
2020-11-25 14:01:53 +03:00
2021-01-13 18:13:51 +03:00
name := ""
2020-11-25 14:01:53 +03:00
alpn := ""
2021-01-15 00:55:52 +03:00
if tlsConn , ok := iConn . ( * tls . Conn ) ; ok {
cs := tlsConn . ConnectionState ( )
name = cs . ServerName
alpn = cs . NegotiatedProtocol
2024-07-12 01:20:06 +03:00
errors . LogInfo ( ctx , "realName = " + name )
errors . LogInfo ( ctx , "realAlpn = " + alpn )
2023-02-15 19:07:12 +03:00
} else if realityConn , ok := iConn . ( * reality . Conn ) ; ok {
cs := realityConn . ConnectionState ( )
name = cs . ServerName
alpn = cs . NegotiatedProtocol
2024-07-12 01:20:06 +03:00
errors . LogInfo ( ctx , "realName = " + name )
errors . LogInfo ( ctx , "realAlpn = " + alpn )
2021-01-15 00:55:52 +03:00
}
2021-01-22 02:37:55 +03:00
name = strings . ToLower ( name )
alpn = strings . ToLower ( alpn )
2021-01-15 00:55:52 +03:00
if len ( napfb ) > 1 || napfb [ "" ] == nil {
2021-01-15 12:43:39 +03:00
if name != "" && napfb [ name ] == nil {
match := ""
for n := range napfb {
if n != "" && strings . Contains ( name , n ) && len ( n ) > len ( match ) {
match = n
}
2021-01-13 18:13:51 +03:00
}
2021-01-15 12:43:39 +03:00
name = match
2021-01-13 18:13:51 +03:00
}
2021-01-15 00:55:52 +03:00
}
if napfb [ name ] == nil {
name = ""
}
apfb := napfb [ name ]
if apfb == nil {
2024-06-29 21:32:57 +03:00
return errors . New ( ` failed to find the default "name" config ` ) . AtWarning ( )
2021-01-15 00:55:52 +03:00
}
2021-01-13 18:13:51 +03:00
2021-01-15 00:55:52 +03:00
if apfb [ alpn ] == nil {
alpn = ""
2020-11-25 14:01:53 +03:00
}
2021-01-15 00:55:52 +03:00
pfb := apfb [ alpn ]
2020-11-25 14:01:53 +03:00
if pfb == nil {
2024-06-29 21:32:57 +03:00
return errors . New ( ` failed to find the default "alpn" config ` ) . AtWarning ( )
2020-11-25 14:01:53 +03:00
}
path := ""
if len ( pfb ) > 1 || pfb [ "" ] == nil {
/ *
if lines := bytes . Split ( firstBytes , [ ] byte { '\r' , '\n' } ) ; len ( lines ) > 1 {
if s := bytes . Split ( lines [ 0 ] , [ ] byte { ' ' } ) ; len ( s ) == 3 {
if len ( s [ 0 ] ) < 8 && len ( s [ 1 ] ) > 0 && len ( s [ 2 ] ) == 8 {
2024-06-29 21:32:57 +03:00
errors . New ( "realPath = " + string ( s [ 1 ] ) ) . AtInfo ( ) . WriteToLog ( sid )
2020-11-25 14:01:53 +03:00
for _ , fb := range pfb {
if fb . Path != "" && h . regexps [ fb . Path ] . Match ( s [ 1 ] ) {
path = fb . Path
break
}
}
}
}
}
* /
if firstLen >= 18 && first . Byte ( 4 ) != '*' { // not h2c
firstBytes := first . Bytes ( )
for i := 4 ; i <= 8 ; i ++ { // 5 -> 9
if firstBytes [ i ] == '/' && firstBytes [ i - 1 ] == ' ' {
search := len ( firstBytes )
if search > 64 {
search = 64 // up to about 60
}
for j := i + 1 ; j < search ; j ++ {
k := firstBytes [ j ]
if k == '\r' || k == '\n' { // avoid logging \r or \n
break
}
2021-03-12 14:50:59 +03:00
if k == '?' || k == ' ' {
2020-11-25 14:01:53 +03:00
path = string ( firstBytes [ i : j ] )
2024-07-12 01:20:06 +03:00
errors . LogInfo ( ctx , "realPath = " + path )
2020-11-25 14:01:53 +03:00
if pfb [ path ] == nil {
path = ""
}
break
}
}
break
}
}
}
}
fb := pfb [ path ]
if fb == nil {
2024-06-29 21:32:57 +03:00
return errors . New ( ` failed to find the default "path" config ` ) . AtWarning ( )
2020-11-25 14:01:53 +03:00
}
ctx , cancel := context . WithCancel ( ctx )
timer := signal . CancelAfterInactivity ( ctx , cancel , sessionPolicy . Timeouts . ConnectionIdle )
ctx = policy . ContextWithBufferPolicy ( ctx , sessionPolicy . Buffer )
var conn net . Conn
if err := retry . ExponentialBackoff ( 5 , 100 ) . On ( func ( ) error {
var dialer net . Dialer
conn , err = dialer . DialContext ( ctx , fb . Type , fb . Dest )
if err != nil {
return err
}
return nil
} ) ; err != nil {
2024-06-29 21:32:57 +03:00
return errors . New ( "failed to dial to " + fb . Dest ) . Base ( err ) . AtWarning ( )
2020-11-25 14:01:53 +03:00
}
defer conn . Close ( )
serverReader := buf . NewReader ( conn )
serverWriter := buf . NewWriter ( conn )
postRequest := func ( ) error {
defer timer . SetTimeout ( sessionPolicy . Timeouts . DownlinkOnly )
if fb . Xver != 0 {
2021-01-24 00:06:15 +03:00
ipType := 4
remoteAddr , remotePort , err := net . SplitHostPort ( connection . RemoteAddr ( ) . String ( ) )
if err != nil {
ipType = 0
}
localAddr , localPort , err := net . SplitHostPort ( connection . LocalAddr ( ) . String ( ) )
if err != nil {
ipType = 0
}
if ipType == 4 {
2021-01-22 06:26:57 +03:00
for i := 0 ; i < len ( remoteAddr ) ; i ++ {
if remoteAddr [ i ] == ':' {
ipType = 6
break
}
2020-11-25 14:01:53 +03:00
}
}
pro := buf . New ( )
defer pro . Release ( )
switch fb . Xver {
case 1 :
2021-01-22 06:26:57 +03:00
if ipType == 0 {
pro . Write ( [ ] byte ( "PROXY UNKNOWN\r\n" ) )
break
}
if ipType == 4 {
2020-11-25 14:01:53 +03:00
pro . Write ( [ ] byte ( "PROXY TCP4 " + remoteAddr + " " + localAddr + " " + remotePort + " " + localPort + "\r\n" ) )
} else {
pro . Write ( [ ] byte ( "PROXY TCP6 " + remoteAddr + " " + localAddr + " " + remotePort + " " + localPort + "\r\n" ) )
}
case 2 :
2021-01-22 06:26:57 +03:00
pro . Write ( [ ] byte ( "\x0D\x0A\x0D\x0A\x00\x0D\x0A\x51\x55\x49\x54\x0A" ) ) // signature
if ipType == 0 {
pro . Write ( [ ] byte ( "\x20\x00\x00\x00" ) ) // v2 + LOCAL + UNSPEC + UNSPEC + 0 bytes
break
}
if ipType == 4 {
pro . Write ( [ ] byte ( "\x21\x11\x00\x0C" ) ) // v2 + PROXY + AF_INET + STREAM + 12 bytes
2020-11-25 14:01:53 +03:00
pro . Write ( net . ParseIP ( remoteAddr ) . To4 ( ) )
pro . Write ( net . ParseIP ( localAddr ) . To4 ( ) )
} else {
2021-01-22 06:26:57 +03:00
pro . Write ( [ ] byte ( "\x21\x21\x00\x24" ) ) // v2 + PROXY + AF_INET6 + STREAM + 36 bytes
2020-11-25 14:01:53 +03:00
pro . Write ( net . ParseIP ( remoteAddr ) . To16 ( ) )
pro . Write ( net . ParseIP ( localAddr ) . To16 ( ) )
}
p1 , _ := strconv . ParseUint ( remotePort , 10 , 16 )
p2 , _ := strconv . ParseUint ( localPort , 10 , 16 )
pro . Write ( [ ] byte { byte ( p1 >> 8 ) , byte ( p1 ) , byte ( p2 >> 8 ) , byte ( p2 ) } )
}
if err := serverWriter . WriteMultiBuffer ( buf . MultiBuffer { pro } ) ; err != nil {
2024-06-29 21:32:57 +03:00
return errors . New ( "failed to set PROXY protocol v" , fb . Xver ) . Base ( err ) . AtWarning ( )
2020-11-25 14:01:53 +03:00
}
}
if err := buf . Copy ( reader , serverWriter , buf . UpdateActivity ( timer ) ) ; err != nil {
2024-06-29 21:32:57 +03:00
return errors . New ( "failed to fallback request payload" ) . Base ( err ) . AtInfo ( )
2020-11-25 14:01:53 +03:00
}
return nil
}
writer := buf . NewWriter ( connection )
getResponse := func ( ) error {
defer timer . SetTimeout ( sessionPolicy . Timeouts . UplinkOnly )
if err := buf . Copy ( serverReader , writer , buf . UpdateActivity ( timer ) ) ; err != nil {
2024-06-29 21:32:57 +03:00
return errors . New ( "failed to deliver response payload" ) . Base ( err ) . AtInfo ( )
2020-11-25 14:01:53 +03:00
}
return nil
}
if err := task . Run ( ctx , task . OnSuccess ( postRequest , task . Close ( serverWriter ) ) , task . OnSuccess ( getResponse , task . Close ( writer ) ) ) ; err != nil {
common . Interrupt ( serverReader )
common . Interrupt ( serverWriter )
2024-06-29 21:32:57 +03:00
return errors . New ( "fallback ends" ) . Base ( err ) . AtInfo ( )
2020-11-25 14:01:53 +03:00
}
return nil
}
if errors . Cause ( err ) != io . EOF {
log . Record ( & log . AccessMessage {
From : connection . RemoteAddr ( ) ,
To : "" ,
Status : log . AccessRejected ,
Reason : err ,
} )
2024-06-29 21:32:57 +03:00
err = errors . New ( "invalid request from " , connection . RemoteAddr ( ) ) . Base ( err ) . AtInfo ( )
2020-11-25 14:01:53 +03:00
}
return err
}
if err := connection . SetReadDeadline ( time . Time { } ) ; err != nil {
2024-06-29 21:32:57 +03:00
errors . LogWarningInner ( ctx , err , "unable to set back read deadline" )
2020-11-25 14:01:53 +03:00
}
2024-06-29 21:32:57 +03:00
errors . LogInfo ( ctx , "received request for " , request . Destination ( ) )
2020-11-25 14:01:53 +03:00
inbound := session . InboundFromContext ( ctx )
if inbound == nil {
panic ( "no inbound metadata" )
}
2023-04-06 13:21:35 +03:00
inbound . Name = "vless"
2020-11-25 14:01:53 +03:00
inbound . User = request . User
account := request . User . Account . ( * vless . MemoryAccount )
responseAddons := & encoding . Addons {
// Flow: requestAddons.Flow,
}
2023-01-06 08:37:16 +03:00
var input * bytes . Reader
var rawInput * bytes . Buffer
2020-11-25 14:01:53 +03:00
switch requestAddons . Flow {
2023-03-04 13:39:26 +03:00
case vless . XRV :
2023-03-04 18:39:27 +03:00
if account . Flow == requestAddons . Flow {
2024-05-14 04:52:24 +03:00
inbound . CanSpliceCopy = 2
2020-11-25 14:01:53 +03:00
switch request . Command {
case protocol . RequestCommandUDP :
2024-06-29 21:32:57 +03:00
return errors . New ( requestAddons . Flow + " doesn't support UDP" ) . AtWarning ( )
2023-04-17 00:15:36 +03:00
case protocol . RequestCommandMux :
fallthrough // we will break Mux connections that contain TCP requests
2020-11-25 14:01:53 +03:00
case protocol . RequestCommandTCP :
2023-03-04 13:39:26 +03:00
var t reflect . Type
var p uintptr
if tlsConn , ok := iConn . ( * tls . Conn ) ; ok {
if tlsConn . ConnectionState ( ) . Version != gotls . VersionTLS13 {
2024-06-29 21:32:57 +03:00
return errors . New ( ` failed to use ` + requestAddons . Flow + ` , found outer tls version ` , tlsConn . ConnectionState ( ) . Version ) . AtWarning ( )
2020-11-25 14:01:53 +03:00
}
2023-03-04 13:39:26 +03:00
t = reflect . TypeOf ( tlsConn . Conn ) . Elem ( )
p = uintptr ( unsafe . Pointer ( tlsConn . Conn ) )
} else if realityConn , ok := iConn . ( * reality . Conn ) ; ok {
t = reflect . TypeOf ( realityConn . Conn ) . Elem ( )
p = uintptr ( unsafe . Pointer ( realityConn . Conn ) )
2020-11-25 14:01:53 +03:00
} else {
2024-06-29 21:32:57 +03:00
return errors . New ( "XTLS only supports TLS and REALITY directly for now." ) . AtWarning ( )
2023-03-04 13:39:26 +03:00
}
i , _ := t . FieldByName ( "input" )
r , _ := t . FieldByName ( "rawInput" )
input = ( * bytes . Reader ) ( unsafe . Pointer ( p + i . Offset ) )
rawInput = ( * bytes . Buffer ) ( unsafe . Pointer ( p + r . Offset ) )
2020-11-25 14:01:53 +03:00
}
} else {
2024-11-25 19:16:29 +03:00
return errors . New ( "account " + account . ID . String ( ) + " is not able to use the flow " + requestAddons . Flow ) . AtWarning ( )
2020-11-25 14:01:53 +03:00
}
2023-03-04 18:39:27 +03:00
case "" :
2024-05-14 04:52:24 +03:00
inbound . CanSpliceCopy = 3
2023-04-17 00:15:36 +03:00
if account . Flow == vless . XRV && ( request . Command == protocol . RequestCommandTCP || isMuxAndNotXUDP ( request , first ) ) {
2024-11-25 19:16:29 +03:00
return errors . New ( "account " + account . ID . String ( ) + " is rejected since the client flow is empty. Note that the pure TLS proxy has certain TLS in TLS characters." ) . AtWarning ( )
2022-12-05 02:24:46 +03:00
}
2020-11-25 14:01:53 +03:00
default :
2024-06-29 21:32:57 +03:00
return errors . New ( "unknown request flow " + requestAddons . Flow ) . AtWarning ( )
2020-11-25 14:01:53 +03:00
}
if request . Command != protocol . RequestCommandMux {
ctx = log . ContextWithAccessMessage ( ctx , & log . AccessMessage {
From : connection . RemoteAddr ( ) ,
To : request . Destination ( ) ,
Status : log . AccessAccepted ,
Reason : "" ,
Email : request . User . Email ,
} )
2023-04-12 18:20:38 +03:00
} else if account . Flow == vless . XRV {
ctx = session . ContextWithAllowedNetwork ( ctx , net . Network_UDP )
2020-11-25 14:01:53 +03:00
}
sessionPolicy = h . policyManager . ForLevel ( request . User . Level )
ctx , cancel := context . WithCancel ( ctx )
timer := signal . CancelAfterInactivity ( ctx , cancel , sessionPolicy . Timeouts . ConnectionIdle )
2024-05-20 06:54:36 +03:00
inbound . Timer = timer
2020-11-25 14:01:53 +03:00
ctx = policy . ContextWithBufferPolicy ( ctx , sessionPolicy . Buffer )
link , err := dispatcher . Dispatch ( ctx , request . Destination ( ) )
if err != nil {
2024-06-29 21:32:57 +03:00
return errors . New ( "failed to dispatch request to " , request . Destination ( ) ) . Base ( err ) . AtWarning ( )
2020-11-25 14:01:53 +03:00
}
serverReader := link . Reader // .(*pipe.Reader)
serverWriter := link . Writer // .(*pipe.Writer)
2023-09-02 18:37:50 +03:00
trafficState := proxy . NewTrafficState ( account . ID . Bytes ( ) )
2020-11-25 14:01:53 +03:00
postRequest := func ( ) error {
defer timer . SetTimeout ( sessionPolicy . Timeouts . DownlinkOnly )
// default: clientReader := reader
clientReader := encoding . DecodeBodyAddons ( reader , request , requestAddons )
var err error
2023-06-22 09:43:22 +03:00
if requestAddons . Flow == vless . XRV {
2023-05-04 05:21:45 +03:00
ctx1 := session . ContextWithInbound ( ctx , nil ) // TODO enable splice
2024-02-02 23:32:46 +03:00
clientReader = proxy . NewVisionReader ( clientReader , trafficState , ctx1 )
2024-05-14 04:52:24 +03:00
err = encoding . XtlsRead ( clientReader , serverWriter , timer , connection , input , rawInput , trafficState , nil , ctx1 )
2020-11-25 14:01:53 +03:00
} else {
2024-07-12 01:20:06 +03:00
// from clientReader.ReadMultiBuffer to serverWriter.WriteMultiBuffer
2020-11-25 14:01:53 +03:00
err = buf . Copy ( clientReader , serverWriter , buf . UpdateActivity ( timer ) )
}
if err != nil {
2024-06-29 21:32:57 +03:00
return errors . New ( "failed to transfer request payload" ) . Base ( err ) . AtInfo ( )
2020-11-25 14:01:53 +03:00
}
return nil
}
getResponse := func ( ) error {
defer timer . SetTimeout ( sessionPolicy . Timeouts . UplinkOnly )
bufferWriter := buf . NewBufferedWriter ( buf . NewWriter ( connection ) )
if err := encoding . EncodeResponseHeader ( bufferWriter , request , responseAddons ) ; err != nil {
2024-06-29 21:32:57 +03:00
return errors . New ( "failed to encode response header" ) . Base ( err ) . AtWarning ( )
2020-11-25 14:01:53 +03:00
}
// default: clientWriter := bufferWriter
2023-09-02 18:37:50 +03:00
clientWriter := encoding . EncodeBodyAddons ( bufferWriter , request , requestAddons , trafficState , ctx )
2022-10-29 07:51:59 +03:00
multiBuffer , err1 := serverReader . ReadMultiBuffer ( )
if err1 != nil {
return err1 // ...
}
if err := clientWriter . WriteMultiBuffer ( multiBuffer ) ; err != nil {
return err // ...
}
2024-07-12 01:20:06 +03:00
// Flush; bufferWriter.WriteMultiBuffer now is bufferWriter.writer.WriteMultiBuffer
2020-11-25 14:01:53 +03:00
if err := bufferWriter . SetBuffered ( false ) ; err != nil {
2024-06-29 21:32:57 +03:00
return errors . New ( "failed to write A response payload" ) . Base ( err ) . AtWarning ( )
2020-11-25 14:01:53 +03:00
}
2022-10-29 07:51:59 +03:00
var err error
2023-06-22 09:43:22 +03:00
if requestAddons . Flow == vless . XRV {
2024-05-14 06:14:29 +03:00
err = encoding . XtlsWrite ( serverReader , clientWriter , timer , connection , trafficState , nil , ctx )
2022-10-29 07:51:59 +03:00
} else {
2024-07-12 01:20:06 +03:00
// from serverReader.ReadMultiBuffer to clientWriter.WriteMultiBuffer
2022-10-29 07:51:59 +03:00
err = buf . Copy ( serverReader , clientWriter , buf . UpdateActivity ( timer ) )
}
if err != nil {
2024-06-29 21:32:57 +03:00
return errors . New ( "failed to transfer response payload" ) . Base ( err ) . AtInfo ( )
2020-11-25 14:01:53 +03:00
}
// Indicates the end of response payload.
switch responseAddons . Flow {
default :
}
return nil
}
if err := task . Run ( ctx , task . OnSuccess ( postRequest , task . Close ( serverWriter ) ) , getResponse ) ; err != nil {
common . Interrupt ( serverReader )
common . Interrupt ( serverWriter )
2024-06-29 21:32:57 +03:00
return errors . New ( "connection ends" ) . Base ( err ) . AtInfo ( )
2020-11-25 14:01:53 +03:00
}
return nil
}