Merge remote branch
This commit is contained in:
@ -27,12 +27,10 @@ var (
|
||||
ErrSmallBuffer = errors.New("buffer too small")
|
||||
)
|
||||
|
||||
var (
|
||||
defaultHeader = http.Header{
|
||||
"content-type": []string{"application/grpc"},
|
||||
"user-agent": []string{"grpc-go/1.36.0"},
|
||||
}
|
||||
)
|
||||
var defaultHeader = http.Header{
|
||||
"content-type": []string{"application/grpc"},
|
||||
"user-agent": []string{"grpc-go/1.36.0"},
|
||||
}
|
||||
|
||||
type DialFn = func(network, addr string) (net.Conn, error)
|
||||
|
||||
|
@ -78,6 +78,7 @@ func (to *TLSObfs) Read(b []byte) (int, error) {
|
||||
// type + ver = 3
|
||||
return to.read(b, 3)
|
||||
}
|
||||
|
||||
func (to *TLSObfs) Write(b []byte) (int, error) {
|
||||
length := len(b)
|
||||
for i := 0; i < length; i += chunkSize {
|
||||
|
@ -20,6 +20,7 @@ func (sc *snellCipher) SaltSize() int { return 16 }
|
||||
func (sc *snellCipher) Encrypter(salt []byte) (cipher.AEAD, error) {
|
||||
return sc.makeAEAD(snellKDF(sc.psk, salt, sc.KeySize()))
|
||||
}
|
||||
|
||||
func (sc *snellCipher) Decrypter(salt []byte) (cipher.AEAD, error) {
|
||||
return sc.makeAEAD(snellKDF(sc.psk, salt, sc.KeySize()))
|
||||
}
|
||||
|
@ -30,9 +30,7 @@ const (
|
||||
Version byte = 1
|
||||
)
|
||||
|
||||
var (
|
||||
endSignal = []byte{}
|
||||
)
|
||||
var endSignal = []byte{}
|
||||
|
||||
type Snell struct {
|
||||
net.Conn
|
||||
|
@ -184,7 +184,7 @@ func isReservedIP(ip net.IP) bool {
|
||||
}
|
||||
|
||||
func readUntilNull(r io.Reader) ([]byte, error) {
|
||||
var buf = &bytes.Buffer{}
|
||||
buf := &bytes.Buffer{}
|
||||
var data [1]byte
|
||||
|
||||
for {
|
||||
|
@ -14,8 +14,10 @@ import (
|
||||
"github.com/Dreamacro/clash/transport/ssr/tools"
|
||||
)
|
||||
|
||||
type hmacMethod func(key, data []byte) []byte
|
||||
type hashDigestMethod func([]byte) []byte
|
||||
type (
|
||||
hmacMethod func(key, data []byte) []byte
|
||||
hashDigestMethod func([]byte) []byte
|
||||
)
|
||||
|
||||
func init() {
|
||||
register("auth_aes128_sha1", newAuthAES128SHA1, 9)
|
||||
|
@ -8,10 +8,12 @@ import (
|
||||
"errors"
|
||||
"io"
|
||||
"net"
|
||||
"net/http"
|
||||
"sync"
|
||||
|
||||
"github.com/Dreamacro/clash/common/pool"
|
||||
"github.com/Dreamacro/clash/transport/socks5"
|
||||
"github.com/Dreamacro/clash/transport/vmess"
|
||||
)
|
||||
|
||||
const (
|
||||
@ -20,8 +22,10 @@ const (
|
||||
)
|
||||
|
||||
var (
|
||||
defaultALPN = []string{"h2", "http/1.1"}
|
||||
crlf = []byte{'\r', '\n'}
|
||||
defaultALPN = []string{"h2", "http/1.1"}
|
||||
defaultWebsocketALPN = []string{"http/1.1"}
|
||||
|
||||
crlf = []byte{'\r', '\n'}
|
||||
)
|
||||
|
||||
type Command = byte
|
||||
@ -38,6 +42,13 @@ type Option struct {
|
||||
SkipCertVerify bool
|
||||
}
|
||||
|
||||
type WebsocketOption struct {
|
||||
Host string
|
||||
Port string
|
||||
Path string
|
||||
Headers http.Header
|
||||
}
|
||||
|
||||
type Trojan struct {
|
||||
option *Option
|
||||
hexPassword []byte
|
||||
@ -64,6 +75,29 @@ func (t *Trojan) StreamConn(conn net.Conn) (net.Conn, error) {
|
||||
return tlsConn, nil
|
||||
}
|
||||
|
||||
func (t *Trojan) StreamWebsocketConn(conn net.Conn, wsOptions *WebsocketOption) (net.Conn, error) {
|
||||
alpn := defaultWebsocketALPN
|
||||
if len(t.option.ALPN) != 0 {
|
||||
alpn = t.option.ALPN
|
||||
}
|
||||
|
||||
tlsConfig := &tls.Config{
|
||||
NextProtos: alpn,
|
||||
MinVersion: tls.VersionTLS12,
|
||||
InsecureSkipVerify: t.option.SkipCertVerify,
|
||||
ServerName: t.option.ServerName,
|
||||
}
|
||||
|
||||
return vmess.StreamWebsocketConn(conn, &vmess.WebsocketConfig{
|
||||
Host: wsOptions.Host,
|
||||
Port: wsOptions.Port,
|
||||
Path: wsOptions.Path,
|
||||
Headers: wsOptions.Headers,
|
||||
TLS: true,
|
||||
TLSConfig: tlsConfig,
|
||||
})
|
||||
}
|
||||
|
||||
func (t *Trojan) WriteHeader(w io.Writer, command Command, socks5Addr []byte) error {
|
||||
buf := pool.GetBuffer()
|
||||
defer pool.PutBuffer(buf)
|
||||
|
@ -1,6 +1,7 @@
|
||||
package obfs
|
||||
|
||||
import (
|
||||
"crypto/tls"
|
||||
"net"
|
||||
"net/http"
|
||||
|
||||
@ -26,12 +27,22 @@ func NewV2rayObfs(conn net.Conn, option *Option) (net.Conn, error) {
|
||||
}
|
||||
|
||||
config := &vmess.WebsocketConfig{
|
||||
Host: option.Host,
|
||||
Port: option.Port,
|
||||
Path: option.Path,
|
||||
TLS: option.TLS,
|
||||
Headers: header,
|
||||
SkipCertVerify: option.SkipCertVerify,
|
||||
Host: option.Host,
|
||||
Port: option.Port,
|
||||
Path: option.Path,
|
||||
Headers: header,
|
||||
}
|
||||
|
||||
if option.TLS {
|
||||
config.TLS = true
|
||||
config.TLSConfig = &tls.Config{
|
||||
ServerName: option.Host,
|
||||
InsecureSkipVerify: option.SkipCertVerify,
|
||||
NextProtos: []string{"http/1.1"},
|
||||
}
|
||||
if host := config.Headers.Get("Host"); host != "" {
|
||||
config.TLSConfig.ServerName = host
|
||||
}
|
||||
}
|
||||
|
||||
var err error
|
||||
|
@ -92,7 +92,7 @@ func sealVMessAEADHeader(key [16]byte, data []byte, t time.Time) []byte {
|
||||
payloadHeaderAEADEncrypted = payloadHeaderAEAD.Seal(nil, payloadHeaderAEADNonce, data, generatedAuthID[:])
|
||||
}
|
||||
|
||||
var outputBuffer = &bytes.Buffer{}
|
||||
outputBuffer := &bytes.Buffer{}
|
||||
|
||||
outputBuffer.Write(generatedAuthID[:])
|
||||
outputBuffer.Write(payloadHeaderLengthAEADEncrypted)
|
||||
|
@ -28,6 +28,7 @@ type websocketConn struct {
|
||||
rMux sync.Mutex
|
||||
wMux sync.Mutex
|
||||
}
|
||||
|
||||
type websocketWithEarlyDataConn struct {
|
||||
net.Conn
|
||||
underlay net.Conn
|
||||
@ -44,8 +45,7 @@ type WebsocketConfig struct {
|
||||
Path string
|
||||
Headers http.Header
|
||||
TLS bool
|
||||
SkipCertVerify bool
|
||||
ServerName string
|
||||
TLSConfig *tls.Config
|
||||
MaxEarlyData int
|
||||
EarlyDataHeaderName string
|
||||
}
|
||||
@ -253,17 +253,7 @@ func streamWebsocketConn(conn net.Conn, c *WebsocketConfig, earlyData *bytes.Buf
|
||||
scheme := "ws"
|
||||
if c.TLS {
|
||||
scheme = "wss"
|
||||
dialer.TLSClientConfig = &tls.Config{
|
||||
ServerName: c.Host,
|
||||
InsecureSkipVerify: c.SkipCertVerify,
|
||||
NextProtos: []string{"http/1.1"},
|
||||
}
|
||||
|
||||
if c.ServerName != "" {
|
||||
dialer.TLSClientConfig.ServerName = c.ServerName
|
||||
} else if host := c.Headers.Get("Host"); host != "" {
|
||||
dialer.TLSClientConfig.ServerName = host
|
||||
}
|
||||
dialer.TLSClientConfig = c.TLSConfig
|
||||
}
|
||||
|
||||
uri := url.URL{
|
||||
|
Reference in New Issue
Block a user