1
1
package socks
2
2
3
3
import (
4
+ "bytes"
4
5
"context"
5
6
"io"
6
7
"time"
@@ -19,6 +20,7 @@ import (
19
20
"github.com/xtls/xray-core/features"
20
21
"github.com/xtls/xray-core/features/policy"
21
22
"github.com/xtls/xray-core/features/routing"
23
+ "github.com/xtls/xray-core/proxy/http"
22
24
"github.com/xtls/xray-core/transport/internet/stat"
23
25
"github.com/xtls/xray-core/transport/internet/udp"
24
26
)
@@ -29,6 +31,7 @@ type Server struct {
29
31
policyManager policy.Manager
30
32
cone bool
31
33
udpFilter * UDPFilter
34
+ httpServer * http.Server
32
35
}
33
36
34
37
// NewServer creates a new Server object.
@@ -39,9 +42,14 @@ func NewServer(ctx context.Context, config *ServerConfig) (*Server, error) {
39
42
policyManager : v .GetFeature (policy .ManagerType ()).(policy.Manager ),
40
43
cone : ctx .Value ("cone" ).(bool ),
41
44
}
45
+ httpConfig := & http.ServerConfig {
46
+ UserLevel : config .UserLevel ,
47
+ }
42
48
if config .AuthType == AuthType_PASSWORD {
49
+ httpConfig .Accounts = config .Accounts
43
50
s .udpFilter = new (UDPFilter ) // We only use this when auth is enabled
44
51
}
52
+ s .httpServer , _ = http .NewServer (ctx , httpConfig )
45
53
return s , nil
46
54
}
47
55
@@ -77,15 +85,21 @@ func (s *Server) Process(ctx context.Context, network net.Network, conn stat.Con
77
85
78
86
switch network {
79
87
case net .Network_TCP :
80
- return s .processTCP (ctx , conn , dispatcher )
88
+ firstbyte := make ([]byte , 1 )
89
+ conn .Read (firstbyte )
90
+ if firstbyte [0 ] != 5 && firstbyte [0 ] != 4 { // Check if it is Socks5/4/4a
91
+ errors .LogDebug (ctx , "Not Socks request, try to parse as HTTP request" )
92
+ return s .httpServer .ProcessWithFirstbyte (ctx , network , conn , dispatcher , firstbyte ... )
93
+ }
94
+ return s .processTCP (ctx , conn , dispatcher , firstbyte )
81
95
case net .Network_UDP :
82
96
return s .handleUDPPayload (ctx , conn , dispatcher )
83
97
default :
84
98
return errors .New ("unknown network: " , network )
85
99
}
86
100
}
87
101
88
- func (s * Server ) processTCP (ctx context.Context , conn stat.Connection , dispatcher routing.Dispatcher ) error {
102
+ func (s * Server ) processTCP (ctx context.Context , conn stat.Connection , dispatcher routing.Dispatcher , firstbyte [] byte ) error {
89
103
plcy := s .policy ()
90
104
if err := conn .SetReadDeadline (time .Now ().Add (plcy .Timeouts .Handshake )); err != nil {
91
105
errors .LogInfoInner (ctx , err , "failed to set deadline" )
@@ -103,7 +117,11 @@ func (s *Server) processTCP(ctx context.Context, conn stat.Connection, dispatche
103
117
localAddress : net .IPAddress (conn .LocalAddr ().(* net.TCPAddr ).IP ),
104
118
}
105
119
106
- reader := & buf.BufferedReader {Reader : buf .NewReader (conn )}
120
+ // Firstbyte is for forwarded conn from SOCKS inbound
121
+ // Because it needs first byte to choose protocol
122
+ // We need to add it back
123
+ readerWithoutFirstbyte := & buf.BufferedReader {Reader : buf .NewReader (conn )}
124
+ reader := io .MultiReader (bytes .NewReader (firstbyte ), readerWithoutFirstbyte )
107
125
request , err := svrSession .Handshake (reader , conn )
108
126
if err != nil {
109
127
if inbound .Source .IsValid () {
0 commit comments