mirror of
https://github.com/net-byte/vtun
synced 2024-03-14 10:50:03 +08:00
force aes-256-gcm encryption for http/https/tcp protocols.
This commit is contained in:
parent
47bd7b930d
commit
0e83cdbc27
@ -20,8 +20,9 @@ A simple VPN written in Go.
|
|||||||
* VPN over utls
|
* VPN over utls
|
||||||
* VPN over dtls
|
* VPN over dtls
|
||||||
* VPN over h2
|
* VPN over h2
|
||||||
* VPN over http
|
* VPN over http (Use aes-256-gcm encryption by default)
|
||||||
* VPN over tcp
|
* VPN over tcp (Use aes-256-gcm encryption by default)
|
||||||
|
* VPN over https (Use aes-256-gcm encryption by default)
|
||||||
# Usage
|
# Usage
|
||||||
|
|
||||||
```
|
```
|
||||||
@ -49,7 +50,7 @@ Usage of vtun:
|
|||||||
-obfs
|
-obfs
|
||||||
enable data obfuscation
|
enable data obfuscation
|
||||||
-p string
|
-p string
|
||||||
protocol udp/tls/grpc/quic/utls/dtls/h2/http/tcp/ws/wss (default "udp")
|
protocol udp/tls/grpc/quic/utls/dtls/h2/http/tcp/https/ws/wss (default "udp")
|
||||||
-path string
|
-path string
|
||||||
websocket path (default "/freedom")
|
websocket path (default "/freedom")
|
||||||
-privatekey string
|
-privatekey string
|
||||||
|
@ -22,6 +22,7 @@
|
|||||||
* 支持h2
|
* 支持h2
|
||||||
* 支持http
|
* 支持http
|
||||||
* 支持tcp
|
* 支持tcp
|
||||||
|
* 支持https
|
||||||
|
|
||||||
# 用法
|
# 用法
|
||||||
|
|
||||||
@ -50,7 +51,7 @@ Usage of vtun:
|
|||||||
-obfs
|
-obfs
|
||||||
enable data obfuscation
|
enable data obfuscation
|
||||||
-p string
|
-p string
|
||||||
protocol udp/tls/grpc/quic/utls/dtls/h2/http/tcp/ws/wss (default "udp")
|
protocol udp/tls/grpc/quic/utls/dtls/h2/http/tcp/https/ws/wss (default "udp")
|
||||||
-path string
|
-path string
|
||||||
websocket path (default "/freedom")
|
websocket path (default "/freedom")
|
||||||
-privatekey string
|
-privatekey string
|
||||||
|
63
common/xcrypto/xcrypto.go
Normal file
63
common/xcrypto/xcrypto.go
Normal file
@ -0,0 +1,63 @@
|
|||||||
|
package xcrypto
|
||||||
|
|
||||||
|
import (
|
||||||
|
"crypto/aes"
|
||||||
|
"crypto/cipher"
|
||||||
|
"crypto/sha1"
|
||||||
|
"crypto/sha256"
|
||||||
|
)
|
||||||
|
|
||||||
|
type XCrypto struct {
|
||||||
|
Key []byte
|
||||||
|
Nonce []byte
|
||||||
|
aesGcm cipher.AEAD
|
||||||
|
}
|
||||||
|
|
||||||
|
func (x *XCrypto) Load(key string) {
|
||||||
|
x.LoadKey(key)
|
||||||
|
x.LoadNonce(key)
|
||||||
|
}
|
||||||
|
|
||||||
|
func (x *XCrypto) LoadKey(key string) {
|
||||||
|
h := sha256.New()
|
||||||
|
h.Write([]byte(key))
|
||||||
|
x.Key = h.Sum(nil)
|
||||||
|
}
|
||||||
|
|
||||||
|
func (x *XCrypto) LoadNonce(key string) {
|
||||||
|
h := sha1.New()
|
||||||
|
h.Write([]byte(key))
|
||||||
|
b := h.Sum(nil)
|
||||||
|
x.Nonce = b[:12]
|
||||||
|
}
|
||||||
|
|
||||||
|
func (x *XCrypto) Init(key string) error {
|
||||||
|
x.Load(key)
|
||||||
|
return x.init()
|
||||||
|
}
|
||||||
|
|
||||||
|
func (x *XCrypto) init() error {
|
||||||
|
block, err := aes.NewCipher(x.Key)
|
||||||
|
if err != nil {
|
||||||
|
return err
|
||||||
|
}
|
||||||
|
aesGcm, err := cipher.NewGCM(block)
|
||||||
|
if err != nil {
|
||||||
|
return err
|
||||||
|
}
|
||||||
|
x.aesGcm = aesGcm
|
||||||
|
return nil
|
||||||
|
}
|
||||||
|
|
||||||
|
func (x *XCrypto) Encode(pl []byte) ([]byte, error) {
|
||||||
|
ci := x.aesGcm.Seal(nil, x.Nonce, pl, nil)
|
||||||
|
return ci, nil
|
||||||
|
}
|
||||||
|
|
||||||
|
func (x *XCrypto) Decode(ci []byte) ([]byte, error) {
|
||||||
|
pl, err := x.aesGcm.Open(nil, x.Nonce, ci, nil)
|
||||||
|
if err != nil {
|
||||||
|
return nil, err
|
||||||
|
}
|
||||||
|
return pl, nil
|
||||||
|
}
|
@ -3,11 +3,10 @@ package h1
|
|||||||
import (
|
import (
|
||||||
"errors"
|
"errors"
|
||||||
"fmt"
|
"fmt"
|
||||||
|
"github.com/net-byte/vtun/common/xcrypto"
|
||||||
"github.com/net-byte/vtun/common/xproto"
|
"github.com/net-byte/vtun/common/xproto"
|
||||||
"log"
|
"log"
|
||||||
"net"
|
"net"
|
||||||
"runtime"
|
|
||||||
"strings"
|
|
||||||
"time"
|
"time"
|
||||||
|
|
||||||
"github.com/golang/snappy"
|
"github.com/golang/snappy"
|
||||||
@ -41,7 +40,6 @@ func StartClient(iFace *water.Interface, config config.Config) {
|
|||||||
netutil.PrintErr(err, config.Verbose)
|
netutil.PrintErr(err, config.Verbose)
|
||||||
continue
|
continue
|
||||||
}
|
}
|
||||||
//go checkH1SessionAlive(conn, config)
|
|
||||||
cache.GetCache().Set("conn", conn, 24*time.Hour)
|
cache.GetCache().Set("conn", conn, 24*time.Hour)
|
||||||
h1ToTun(config, conn, iFace)
|
h1ToTun(config, conn, iFace)
|
||||||
cache.GetCache().Delete("conn")
|
cache.GetCache().Delete("conn")
|
||||||
@ -71,10 +69,16 @@ func handshake(config config.Config, conn net.Conn) error {
|
|||||||
return nil
|
return nil
|
||||||
}
|
}
|
||||||
|
|
||||||
// tunToH1 sends packets from tun to tls
|
// tunToH1 sends packets from tun to h1
|
||||||
func tunToH1(config config.Config, iFace *water.Interface) {
|
func tunToH1(config config.Config, iFace *water.Interface) {
|
||||||
authKey := xproto.ParseAuthKeyFromString(config.Key)
|
authKey := xproto.ParseAuthKeyFromString(config.Key)
|
||||||
buffer := make([]byte, config.BufferSize)
|
buffer := make([]byte, config.BufferSize)
|
||||||
|
xp := &xcrypto.XCrypto{}
|
||||||
|
err := xp.Init(config.Key)
|
||||||
|
if err != nil {
|
||||||
|
netutil.PrintErr(err, config.Verbose)
|
||||||
|
return
|
||||||
|
}
|
||||||
for {
|
for {
|
||||||
n, err := iFace.Read(buffer)
|
n, err := iFace.Read(buffer)
|
||||||
if err != nil {
|
if err != nil {
|
||||||
@ -86,6 +90,11 @@ func tunToH1(config config.Config, iFace *water.Interface) {
|
|||||||
if config.Obfs {
|
if config.Obfs {
|
||||||
b = cipher.XOR(b)
|
b = cipher.XOR(b)
|
||||||
}
|
}
|
||||||
|
b, err = xp.Encode(b)
|
||||||
|
if err != nil {
|
||||||
|
netutil.PrintErr(err, config.Verbose)
|
||||||
|
break
|
||||||
|
}
|
||||||
if config.Compress {
|
if config.Compress {
|
||||||
b = snappy.Encode(nil, b)
|
b = snappy.Encode(nil, b)
|
||||||
}
|
}
|
||||||
@ -112,11 +121,17 @@ func tunToH1(config config.Config, iFace *water.Interface) {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
// h1ToTun sends packets from tls to tun
|
// h1ToTun sends packets from h1 to tun
|
||||||
func h1ToTun(config config.Config, conn net.Conn, iFace *water.Interface) {
|
func h1ToTun(config config.Config, conn net.Conn, iFace *water.Interface) {
|
||||||
defer conn.Close()
|
defer conn.Close()
|
||||||
header := make([]byte, xproto.ServerSendPacketHeaderLength)
|
header := make([]byte, xproto.ServerSendPacketHeaderLength)
|
||||||
packet := make([]byte, config.BufferSize)
|
packet := make([]byte, config.BufferSize)
|
||||||
|
xp := &xcrypto.XCrypto{}
|
||||||
|
err := xp.Init(config.Key)
|
||||||
|
if err != nil {
|
||||||
|
netutil.PrintErr(err, config.Verbose)
|
||||||
|
return
|
||||||
|
}
|
||||||
for {
|
for {
|
||||||
n, err := conn.Read(header)
|
n, err := conn.Read(header)
|
||||||
if err != nil {
|
if err != nil {
|
||||||
@ -149,6 +164,11 @@ func h1ToTun(config config.Config, conn net.Conn, iFace *water.Interface) {
|
|||||||
break
|
break
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
b, err = xp.Decode(b)
|
||||||
|
if err != nil {
|
||||||
|
netutil.PrintErr(err, config.Verbose)
|
||||||
|
break
|
||||||
|
}
|
||||||
if config.Obfs {
|
if config.Obfs {
|
||||||
b = cipher.XOR(b)
|
b = cipher.XOR(b)
|
||||||
}
|
}
|
||||||
@ -160,26 +180,3 @@ func h1ToTun(config config.Config, conn net.Conn, iFace *water.Interface) {
|
|||||||
counter.IncrReadBytes(n)
|
counter.IncrReadBytes(n)
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
func checkH1SessionAlive(conn net.Conn, config config.Config) {
|
|
||||||
os := runtime.GOOS
|
|
||||||
defer conn.Close()
|
|
||||||
for {
|
|
||||||
if os == "windows" {
|
|
||||||
result := netutil.ExecCmd("ping", "-n", "2", "-l", "21", "-w", "1200", config.ServerIP)
|
|
||||||
if strings.Contains(result, `100%`) {
|
|
||||||
netutil.PrintErr(errors.New("ping server failed, reconnecting"), config.Verbose)
|
|
||||||
break
|
|
||||||
}
|
|
||||||
continue
|
|
||||||
} else if os == "linux" || os == "darwin" {
|
|
||||||
result := netutil.ExecCmd("ping", "-c", "2", "-s", "21", "-w", "1200", config.ServerIP)
|
|
||||||
// macos return "100.0% packet loss", linux return "100% packet loss"
|
|
||||||
if strings.Contains(result, `100.0%`) || strings.Contains(result, `100%`) {
|
|
||||||
netutil.PrintErr(errors.New("ping server failed, reconnecting"), config.Verbose)
|
|
||||||
break
|
|
||||||
}
|
|
||||||
continue
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
@ -10,6 +10,7 @@ import (
|
|||||||
"github.com/net-byte/vtun/common/config"
|
"github.com/net-byte/vtun/common/config"
|
||||||
"github.com/net-byte/vtun/common/counter"
|
"github.com/net-byte/vtun/common/counter"
|
||||||
"github.com/net-byte/vtun/common/netutil"
|
"github.com/net-byte/vtun/common/netutil"
|
||||||
|
"github.com/net-byte/vtun/common/xcrypto"
|
||||||
"github.com/net-byte/vtun/common/xproto"
|
"github.com/net-byte/vtun/common/xproto"
|
||||||
"github.com/net-byte/water"
|
"github.com/net-byte/water"
|
||||||
"log"
|
"log"
|
||||||
@ -60,9 +61,15 @@ func StartServer(iFace *water.Interface, config config.Config) {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
// toClient sends packets from iFace to conn
|
// toClient sends packets from tun to h1
|
||||||
func toClient(config config.Config, iFace *water.Interface) {
|
func toClient(config config.Config, iFace *water.Interface) {
|
||||||
buffer := make([]byte, config.BufferSize)
|
buffer := make([]byte, config.BufferSize)
|
||||||
|
xp := &xcrypto.XCrypto{}
|
||||||
|
err := xp.Init(config.Key)
|
||||||
|
if err != nil {
|
||||||
|
netutil.PrintErr(err, config.Verbose)
|
||||||
|
return
|
||||||
|
}
|
||||||
for {
|
for {
|
||||||
n, err := iFace.Read(buffer)
|
n, err := iFace.Read(buffer)
|
||||||
if err != nil {
|
if err != nil {
|
||||||
@ -75,6 +82,11 @@ func toClient(config config.Config, iFace *water.Interface) {
|
|||||||
if config.Obfs {
|
if config.Obfs {
|
||||||
b = cipher.XOR(b)
|
b = cipher.XOR(b)
|
||||||
}
|
}
|
||||||
|
b, err = xp.Encode(b)
|
||||||
|
if err != nil {
|
||||||
|
netutil.PrintErr(err, config.Verbose)
|
||||||
|
break
|
||||||
|
}
|
||||||
if config.Compress {
|
if config.Compress {
|
||||||
b = snappy.Encode(nil, b)
|
b = snappy.Encode(nil, b)
|
||||||
}
|
}
|
||||||
@ -103,13 +115,19 @@ func toClient(config config.Config, iFace *water.Interface) {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
// toServer sends packets from conn to iFace
|
// toServer sends packets from h1 to tun
|
||||||
func toServer(config config.Config, conn net.Conn, iFace *water.Interface) {
|
func toServer(config config.Config, conn net.Conn, iFace *water.Interface) {
|
||||||
defer conn.Close()
|
defer conn.Close()
|
||||||
handshake := make([]byte, xproto.ClientHandshakePacketLength)
|
handshake := make([]byte, xproto.ClientHandshakePacketLength)
|
||||||
header := make([]byte, xproto.ClientSendPacketHeaderLength)
|
header := make([]byte, xproto.ClientSendPacketHeaderLength)
|
||||||
packet := make([]byte, config.BufferSize)
|
packet := make([]byte, config.BufferSize)
|
||||||
authKey := xproto.ParseAuthKeyFromString(config.Key)
|
authKey := xproto.ParseAuthKeyFromString(config.Key)
|
||||||
|
xp := &xcrypto.XCrypto{}
|
||||||
|
err := xp.Init(config.Key)
|
||||||
|
if err != nil {
|
||||||
|
netutil.PrintErr(err, config.Verbose)
|
||||||
|
return
|
||||||
|
}
|
||||||
n, err := conn.Read(handshake)
|
n, err := conn.Read(handshake)
|
||||||
if err != nil {
|
if err != nil {
|
||||||
netutil.PrintErr(err, config.Verbose)
|
netutil.PrintErr(err, config.Verbose)
|
||||||
@ -166,6 +184,11 @@ func toServer(config config.Config, conn net.Conn, iFace *water.Interface) {
|
|||||||
break
|
break
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
b, err = xp.Decode(b)
|
||||||
|
if err != nil {
|
||||||
|
netutil.PrintErr(err, config.Verbose)
|
||||||
|
break
|
||||||
|
}
|
||||||
if config.Obfs {
|
if config.Obfs {
|
||||||
b = cipher.XOR(b)
|
b = cipher.XOR(b)
|
||||||
}
|
}
|
||||||
|
@ -3,6 +3,7 @@ package tcp
|
|||||||
import (
|
import (
|
||||||
"errors"
|
"errors"
|
||||||
"fmt"
|
"fmt"
|
||||||
|
"github.com/net-byte/vtun/common/xcrypto"
|
||||||
"github.com/net-byte/vtun/common/xproto"
|
"github.com/net-byte/vtun/common/xproto"
|
||||||
"log"
|
"log"
|
||||||
"net"
|
"net"
|
||||||
@ -66,6 +67,12 @@ func handshake(config config.Config, conn net.Conn) error {
|
|||||||
func tunToTcp(config config.Config, iFace *water.Interface) {
|
func tunToTcp(config config.Config, iFace *water.Interface) {
|
||||||
authKey := xproto.ParseAuthKeyFromString(config.Key)
|
authKey := xproto.ParseAuthKeyFromString(config.Key)
|
||||||
buffer := make([]byte, config.BufferSize)
|
buffer := make([]byte, config.BufferSize)
|
||||||
|
xp := &xcrypto.XCrypto{}
|
||||||
|
err := xp.Init(config.Key)
|
||||||
|
if err != nil {
|
||||||
|
netutil.PrintErr(err, config.Verbose)
|
||||||
|
return
|
||||||
|
}
|
||||||
for {
|
for {
|
||||||
n, err := iFace.Read(buffer)
|
n, err := iFace.Read(buffer)
|
||||||
if err != nil {
|
if err != nil {
|
||||||
@ -77,6 +84,11 @@ func tunToTcp(config config.Config, iFace *water.Interface) {
|
|||||||
if config.Obfs {
|
if config.Obfs {
|
||||||
b = cipher.XOR(b)
|
b = cipher.XOR(b)
|
||||||
}
|
}
|
||||||
|
b, err = xp.Encode(b)
|
||||||
|
if err != nil {
|
||||||
|
netutil.PrintErr(err, config.Verbose)
|
||||||
|
break
|
||||||
|
}
|
||||||
if config.Compress {
|
if config.Compress {
|
||||||
b = snappy.Encode(nil, b)
|
b = snappy.Encode(nil, b)
|
||||||
}
|
}
|
||||||
@ -108,6 +120,12 @@ func tcpToTun(config config.Config, conn net.Conn, iFace *water.Interface) {
|
|||||||
defer conn.Close()
|
defer conn.Close()
|
||||||
header := make([]byte, xproto.ServerSendPacketHeaderLength)
|
header := make([]byte, xproto.ServerSendPacketHeaderLength)
|
||||||
packet := make([]byte, config.BufferSize)
|
packet := make([]byte, config.BufferSize)
|
||||||
|
xp := &xcrypto.XCrypto{}
|
||||||
|
err := xp.Init(config.Key)
|
||||||
|
if err != nil {
|
||||||
|
netutil.PrintErr(err, config.Verbose)
|
||||||
|
return
|
||||||
|
}
|
||||||
for {
|
for {
|
||||||
n, err := conn.Read(header)
|
n, err := conn.Read(header)
|
||||||
if err != nil {
|
if err != nil {
|
||||||
@ -140,6 +158,11 @@ func tcpToTun(config config.Config, conn net.Conn, iFace *water.Interface) {
|
|||||||
break
|
break
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
b, err = xp.Decode(b)
|
||||||
|
if err != nil {
|
||||||
|
netutil.PrintErr(err, config.Verbose)
|
||||||
|
break
|
||||||
|
}
|
||||||
if config.Obfs {
|
if config.Obfs {
|
||||||
b = cipher.XOR(b)
|
b = cipher.XOR(b)
|
||||||
}
|
}
|
||||||
|
@ -9,6 +9,7 @@ import (
|
|||||||
"github.com/net-byte/vtun/common/config"
|
"github.com/net-byte/vtun/common/config"
|
||||||
"github.com/net-byte/vtun/common/counter"
|
"github.com/net-byte/vtun/common/counter"
|
||||||
"github.com/net-byte/vtun/common/netutil"
|
"github.com/net-byte/vtun/common/netutil"
|
||||||
|
"github.com/net-byte/vtun/common/xcrypto"
|
||||||
"github.com/net-byte/vtun/common/xproto"
|
"github.com/net-byte/vtun/common/xproto"
|
||||||
"github.com/net-byte/water"
|
"github.com/net-byte/water"
|
||||||
"log"
|
"log"
|
||||||
@ -40,6 +41,12 @@ func StartServer(iFace *water.Interface, config config.Config) {
|
|||||||
// toClient sends packets from iFace to conn
|
// toClient sends packets from iFace to conn
|
||||||
func toClient(config config.Config, iFace *water.Interface) {
|
func toClient(config config.Config, iFace *water.Interface) {
|
||||||
buffer := make([]byte, config.BufferSize)
|
buffer := make([]byte, config.BufferSize)
|
||||||
|
xp := &xcrypto.XCrypto{}
|
||||||
|
err := xp.Init(config.Key)
|
||||||
|
if err != nil {
|
||||||
|
netutil.PrintErr(err, config.Verbose)
|
||||||
|
return
|
||||||
|
}
|
||||||
for {
|
for {
|
||||||
n, err := iFace.Read(buffer)
|
n, err := iFace.Read(buffer)
|
||||||
if err != nil {
|
if err != nil {
|
||||||
@ -55,6 +62,11 @@ func toClient(config config.Config, iFace *water.Interface) {
|
|||||||
if config.Obfs {
|
if config.Obfs {
|
||||||
b = cipher.XOR(b)
|
b = cipher.XOR(b)
|
||||||
}
|
}
|
||||||
|
b, err = xp.Encode(b)
|
||||||
|
if err != nil {
|
||||||
|
netutil.PrintErr(err, config.Verbose)
|
||||||
|
break
|
||||||
|
}
|
||||||
if config.Compress {
|
if config.Compress {
|
||||||
b = snappy.Encode(nil, b)
|
b = snappy.Encode(nil, b)
|
||||||
}
|
}
|
||||||
@ -67,7 +79,6 @@ func toClient(config config.Config, iFace *water.Interface) {
|
|||||||
if err != nil {
|
if err != nil {
|
||||||
netutil.PrintErr(err, config.Verbose)
|
netutil.PrintErr(err, config.Verbose)
|
||||||
cache.GetCache().Delete(key)
|
cache.GetCache().Delete(key)
|
||||||
//fmt.Printf("del %s %v\r\n", key, conn)
|
|
||||||
conn.Close()
|
conn.Close()
|
||||||
continue
|
continue
|
||||||
}
|
}
|
||||||
@ -78,7 +89,6 @@ func toClient(config config.Config, iFace *water.Interface) {
|
|||||||
if err != nil {
|
if err != nil {
|
||||||
netutil.PrintErr(err, config.Verbose)
|
netutil.PrintErr(err, config.Verbose)
|
||||||
cache.GetCache().Delete(key)
|
cache.GetCache().Delete(key)
|
||||||
//fmt.Printf("del %s %v\r\n", key, conn)
|
|
||||||
conn.Close()
|
conn.Close()
|
||||||
continue
|
continue
|
||||||
}
|
}
|
||||||
@ -86,8 +96,6 @@ func toClient(config config.Config, iFace *water.Interface) {
|
|||||||
fmt.Printf("conn-p write: %v\n", b)
|
fmt.Printf("conn-p write: %v\n", b)
|
||||||
}
|
}
|
||||||
counter.IncrWrittenBytes(n)
|
counter.IncrWrittenBytes(n)
|
||||||
//} else {
|
|
||||||
// fmt.Printf("%s not ok!!!\n", key)
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@ -100,6 +108,12 @@ func toServer(config config.Config, conn net.Conn, iFace *water.Interface) {
|
|||||||
header := make([]byte, xproto.ClientSendPacketHeaderLength)
|
header := make([]byte, xproto.ClientSendPacketHeaderLength)
|
||||||
packet := make([]byte, config.BufferSize)
|
packet := make([]byte, config.BufferSize)
|
||||||
authKey := xproto.ParseAuthKeyFromString(config.Key)
|
authKey := xproto.ParseAuthKeyFromString(config.Key)
|
||||||
|
xp := &xcrypto.XCrypto{}
|
||||||
|
err := xp.Init(config.Key)
|
||||||
|
if err != nil {
|
||||||
|
netutil.PrintErr(err, config.Verbose)
|
||||||
|
return
|
||||||
|
}
|
||||||
n, err := conn.Read(handshake)
|
n, err := conn.Read(handshake)
|
||||||
if err != nil {
|
if err != nil {
|
||||||
netutil.PrintErr(err, config.Verbose)
|
netutil.PrintErr(err, config.Verbose)
|
||||||
@ -165,6 +179,11 @@ func toServer(config config.Config, conn net.Conn, iFace *water.Interface) {
|
|||||||
break
|
break
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
b, err = xp.Decode(b)
|
||||||
|
if err != nil {
|
||||||
|
netutil.PrintErr(err, config.Verbose)
|
||||||
|
break
|
||||||
|
}
|
||||||
if config.Obfs {
|
if config.Obfs {
|
||||||
b = cipher.XOR(b)
|
b = cipher.XOR(b)
|
||||||
}
|
}
|
||||||
|
Loading…
Reference in New Issue
Block a user