mirror of
https://github.com/e1732a364fed/v2ray_simple.git
synced 2026-04-22 22:47:04 +08:00
修订shadowTls代码
This commit is contained in:
@@ -338,7 +338,12 @@ func handleNewIncomeConnection(inServer proxy.Server, defaultClientForThis proxy
|
||||
iics.inServerTlsRawReadRecorder.StartRecord()
|
||||
}
|
||||
|
||||
iics.inServerTlsConn = tlsConn
|
||||
realtlsConn, ok := tlsConn.(tlsLayer.Conn)
|
||||
if ok {
|
||||
iics.inServerTlsConn = realtlsConn
|
||||
|
||||
}
|
||||
|
||||
wrappedConn = tlsConn
|
||||
|
||||
}
|
||||
|
||||
@@ -5,8 +5,6 @@ import (
|
||||
"net"
|
||||
"os"
|
||||
"sync"
|
||||
|
||||
"github.com/e1732a364fed/v2ray_simple/utils"
|
||||
)
|
||||
|
||||
// 选择性从 OptionalReader读取, 直到 RemainFirstBufLen 小于等于0 为止;
|
||||
@@ -30,16 +28,6 @@ func (rw *ReadWrapper) Read(p []byte) (n int, err error) {
|
||||
|
||||
}
|
||||
|
||||
func (rw *ReadWrapper) WriteBuffers(buffers [][]byte) (int64, error) {
|
||||
bigbs, dup := utils.MergeBuffers(buffers)
|
||||
n, e := rw.Write(bigbs)
|
||||
if dup {
|
||||
utils.PutPacket(bigbs)
|
||||
}
|
||||
return int64(n), e
|
||||
|
||||
}
|
||||
|
||||
// 一个自定义的由多个组件组成的实现 net.Conn 的结构, 也通过设置 Rejecter 实现 RejectConn
|
||||
type IOWrapper struct {
|
||||
EasyNetAddresser
|
||||
|
||||
@@ -18,11 +18,22 @@ type FakeAppDataConn struct {
|
||||
net.Conn
|
||||
readRemaining int
|
||||
|
||||
OptionalReader io.Reader
|
||||
OptionalReaderRemainLen int
|
||||
|
||||
//for readv
|
||||
rr syscall.RawConn
|
||||
}
|
||||
|
||||
func (c *FakeAppDataConn) Read(p []byte) (n int, err error) {
|
||||
if c.OptionalReaderRemainLen > 0 {
|
||||
n, err := c.OptionalReader.Read(p)
|
||||
if n > 0 {
|
||||
c.OptionalReaderRemainLen -= n
|
||||
}
|
||||
return n, err
|
||||
}
|
||||
|
||||
if c.readRemaining > 0 {
|
||||
if len(p) > c.readRemaining {
|
||||
p = p[:c.readRemaining]
|
||||
|
||||
+17
-8
@@ -14,6 +14,8 @@ type Server struct {
|
||||
|
||||
tlstype int
|
||||
|
||||
//用于shadowTls,使用shadowTls时 我们不使用 tlsConfig
|
||||
serverName string
|
||||
shadowpass string
|
||||
}
|
||||
|
||||
@@ -37,25 +39,32 @@ func NewServer(conf Conf) (*Server, error) {
|
||||
}
|
||||
|
||||
s := &Server{
|
||||
tlsConfig: GetTlsConfig(true, conf),
|
||||
tlstype: conf.Tls_type,
|
||||
tlstype: conf.Tls_type,
|
||||
}
|
||||
|
||||
if conf.Tls_type == ShadowTls2_t {
|
||||
s.shadowpass = getShadowTlsPasswordFromExtra(conf.Extra)
|
||||
if conf.IsShadowTls() {
|
||||
s.serverName = conf.Host
|
||||
|
||||
if conf.Tls_type == ShadowTls2_t {
|
||||
s.shadowpass = getShadowTlsPasswordFromExtra(conf.Extra)
|
||||
}
|
||||
} else {
|
||||
s.tlsConfig = GetTlsConfig(true, conf)
|
||||
|
||||
}
|
||||
|
||||
return s, nil
|
||||
}
|
||||
|
||||
func (s *Server) Handshake(clientConn net.Conn) (tlsConn Conn, err error) {
|
||||
// tls时返回 tlsLayer.Conn, shadowTls1时返回原 clientConn, shadowTls2时返回 FakeAppDataConn
|
||||
func (s *Server) Handshake(clientConn net.Conn) (result net.Conn, err error) {
|
||||
|
||||
switch s.tlstype {
|
||||
case ShadowTls_t:
|
||||
return shadowTls1(s.tlsConfig.ServerName, clientConn)
|
||||
|
||||
return clientConn, shadowTls1(s.serverName, clientConn)
|
||||
case ShadowTls2_t:
|
||||
return shadowTls2(s.tlsConfig.ServerName, clientConn, s.shadowpass)
|
||||
return shadowTls2(s.serverName, clientConn, s.shadowpass)
|
||||
|
||||
}
|
||||
|
||||
@@ -67,7 +76,7 @@ func (s *Server) Handshake(clientConn net.Conn) (tlsConn Conn, err error) {
|
||||
return
|
||||
}
|
||||
|
||||
tlsConn = &conn{
|
||||
result = &conn{
|
||||
Conn: rawTlsConn,
|
||||
ptr: unsafe.Pointer(rawTlsConn),
|
||||
}
|
||||
|
||||
+35
-30
@@ -27,7 +27,8 @@ func getShadowTlsPasswordFromExtra(extra map[string]any) string {
|
||||
return ""
|
||||
}
|
||||
|
||||
func shadowTls1(servername string, clientConn net.Conn) (tlsConn *conn, err error) {
|
||||
// 转发并判断tls1握手结束后直接返回
|
||||
func shadowTls1(servername string, clientConn net.Conn) (err error) {
|
||||
var fakeConn net.Conn
|
||||
fakeConn, err = net.Dial("tcp", servername+":443")
|
||||
if err != nil {
|
||||
@@ -70,22 +71,18 @@ func shadowTls1(servername string, clientConn net.Conn) (tlsConn *conn, err erro
|
||||
{Index: 2, E: e2},
|
||||
}}
|
||||
|
||||
return nil, e
|
||||
return e
|
||||
}
|
||||
|
||||
if ce := utils.CanLogDebug("shadowTls fake ok "); ce != nil {
|
||||
ce.Write()
|
||||
}
|
||||
|
||||
tlsConn = &conn{
|
||||
Conn: clientConn,
|
||||
tlsType: ShadowTls_t,
|
||||
}
|
||||
|
||||
return
|
||||
}
|
||||
|
||||
func shadowTls2(servername string, clientConn net.Conn, password string) (tlsConn *conn, err error) {
|
||||
// 握手成功后返回 *FakeAppDataConn
|
||||
func shadowTls2(servername string, clientConn net.Conn, password string) (result net.Conn, err error) {
|
||||
var fakeConn net.Conn
|
||||
fakeConn, err = net.Dial("tcp", servername+":443")
|
||||
if err != nil {
|
||||
@@ -112,21 +109,12 @@ func shadowTls2(servername string, clientConn net.Conn, password string) (tlsCon
|
||||
|
||||
realconn := &FakeAppDataConn{
|
||||
Conn: clientConn,
|
||||
|
||||
OptionalReader: firstPayload,
|
||||
OptionalReaderRemainLen: firstPayload.Len(),
|
||||
}
|
||||
|
||||
allDataConn := &netLayer.IOWrapper{
|
||||
Reader: &utils.ReadWrapper{
|
||||
Reader: realconn,
|
||||
OptionalReader: firstPayload,
|
||||
RemainFirstBufLen: firstPayload.Len(),
|
||||
},
|
||||
Writer: realconn,
|
||||
}
|
||||
|
||||
return &conn{
|
||||
Conn: allDataConn,
|
||||
tlsType: ShadowTls2_t,
|
||||
}, nil
|
||||
return realconn, nil
|
||||
} else if err == utils.ErrFailed {
|
||||
if ce := utils.CanLogWarn("shadowTls2 fake failed!"); ce != nil {
|
||||
ce.Write()
|
||||
@@ -140,12 +128,13 @@ func shadowTls2(servername string, clientConn net.Conn, password string) (tlsCon
|
||||
|
||||
}
|
||||
|
||||
// 根据shadowTls v2的方式,它一定会返回一个 firstPayload
|
||||
func shadowCopyHandshakeClientToFake(fakeConn, clientConn net.Conn, hashW *utils.HashWriter) (*bytes.Buffer, error) {
|
||||
var header [5]byte
|
||||
step := 0
|
||||
var applicationDataCount int
|
||||
|
||||
buf := utils.GetBuf()
|
||||
var firstPayload *bytes.Buffer
|
||||
|
||||
for {
|
||||
if ce := utils.CanLogDebug("shadowTls2 copy "); ce != nil {
|
||||
@@ -159,6 +148,10 @@ func shadowCopyHandshakeClientToFake(fakeConn, clientConn net.Conn, hashW *utils
|
||||
netLayer.PersistConn(clientConn)
|
||||
|
||||
if err != nil {
|
||||
if firstPayload != nil {
|
||||
utils.PutBuf(firstPayload)
|
||||
|
||||
}
|
||||
return nil, utils.ErrInErr{ErrDetail: err, ErrDesc: "shadowTls2, io.ReadFull err"}
|
||||
}
|
||||
|
||||
@@ -174,21 +167,25 @@ func shadowCopyHandshakeClientToFake(fakeConn, clientConn net.Conn, hashW *utils
|
||||
|
||||
if contentType == 23 {
|
||||
|
||||
if firstPayload == nil {
|
||||
firstPayload = utils.GetBuf()
|
||||
}
|
||||
|
||||
netLayer.SetCommonReadTimeout(clientConn)
|
||||
|
||||
_, err = io.Copy(buf, io.LimitReader(clientConn, int64(length)))
|
||||
_, err = io.Copy(firstPayload, io.LimitReader(clientConn, int64(length)))
|
||||
|
||||
netLayer.PersistRead(clientConn)
|
||||
|
||||
if err != nil {
|
||||
utils.PutBuf(buf)
|
||||
utils.PutBuf(firstPayload)
|
||||
return nil, utils.ErrInErr{ErrDetail: err, ErrDesc: "shadowTls2, copy err1"}
|
||||
}
|
||||
|
||||
if hashW.Written() && length >= 8 {
|
||||
|
||||
checksum := hashW.Sum()
|
||||
first8 := buf.Bytes()[:8]
|
||||
first8 := firstPayload.Bytes()[:8]
|
||||
|
||||
if ce := utils.CanLogDebug("shadowTls2 check "); ce != nil {
|
||||
ce.Write(zap.Int("step", step),
|
||||
@@ -198,23 +195,23 @@ func shadowCopyHandshakeClientToFake(fakeConn, clientConn net.Conn, hashW *utils
|
||||
}
|
||||
|
||||
if bytes.Equal(first8, checksum) {
|
||||
buf.Next(8)
|
||||
return buf, nil
|
||||
firstPayload.Next(8)
|
||||
return firstPayload, nil
|
||||
}
|
||||
}
|
||||
|
||||
netLayer.SetCommonWriteTimeout(fakeConn)
|
||||
|
||||
_, err = io.Copy(fakeConn, io.MultiReader(bytes.NewReader(header[:]), buf))
|
||||
_, err = io.Copy(fakeConn, io.MultiReader(bytes.NewReader(header[:]), firstPayload))
|
||||
|
||||
netLayer.PersistWrite(fakeConn)
|
||||
|
||||
if err != nil {
|
||||
utils.PutBuf(buf)
|
||||
utils.PutBuf(firstPayload)
|
||||
return nil, utils.ErrInErr{ErrDetail: err, ErrDesc: "shadowTls2, copy err2"}
|
||||
}
|
||||
|
||||
buf.Reset()
|
||||
firstPayload.Reset()
|
||||
|
||||
applicationDataCount++
|
||||
} else {
|
||||
@@ -228,17 +225,25 @@ func shadowCopyHandshakeClientToFake(fakeConn, clientConn net.Conn, hashW *utils
|
||||
netLayer.PersistWrite(fakeConn)
|
||||
|
||||
if err != nil {
|
||||
if firstPayload != nil {
|
||||
utils.PutBuf(firstPayload)
|
||||
}
|
||||
return nil, utils.ErrInErr{ErrDetail: err, ErrDesc: "shadowTls2, copy err3"}
|
||||
}
|
||||
}
|
||||
|
||||
const maxAppDataCount = 3
|
||||
if applicationDataCount > maxAppDataCount {
|
||||
utils.PutBuf(firstPayload)
|
||||
|
||||
return nil, utils.ErrFailed
|
||||
}
|
||||
step++
|
||||
|
||||
if step > 8 {
|
||||
if firstPayload != nil {
|
||||
utils.PutBuf(firstPayload)
|
||||
}
|
||||
return nil, errors.New("shadowTls2 copy loop > 8, maybe under attack")
|
||||
|
||||
}
|
||||
|
||||
Reference in New Issue
Block a user