Fix shadow

This commit is contained in:
wweir
2019-01-07 22:28:32 +08:00
parent 6e4a6c794e
commit a8089af235
5 changed files with 80 additions and 27 deletions
+3 -3
View File
@@ -14,9 +14,9 @@ func ParseAddr(conn net.Conn) (teeConn *TeeConn, addr string, err error) {
teeConn.StartOrReset()
defer teeConn.Stop()
buf := make([]byte, 1<<10)
if n, err := teeConn.Read(buf); err != nil || n != 1 {
return teeConn, "", fmt.Errorf("Read conn fail: %v, readed: %d %v", err, n, buf)
buf := make([]byte, 1)
if n, err := teeConn.Read(buf); err != nil {
return teeConn, "", fmt.Errorf("Read conn fail: %v, readed: %v", err, buf[:n])
}
teeConn.StartOrReset()
+5 -5
View File
@@ -16,11 +16,11 @@ type client struct {
func NewClient() *client {
return &client{
conf: &quic.Config{
HandshakeTimeout: 5 * time.Second,
MaxIncomingStreams: 1024,
KeepAlive: true,
},
// conf: &quic.Config{
// HandshakeTimeout: 5 * time.Second,
// MaxIncomingStreams: 1024,
// KeepAlive: true,
// },
}
}
+5 -6
View File
@@ -2,7 +2,6 @@ package quic
import (
"net"
"time"
"github.com/golang/glog"
quic "github.com/lucas-clemente/quic-go"
@@ -15,11 +14,11 @@ type server struct {
func NewServer() *server {
return &server{
conf: &quic.Config{
HandshakeTimeout: 5 * time.Second,
MaxIncomingStreams: 1024,
KeepAlive: true,
},
// conf: &quic.Config{
// HandshakeTimeout: 5 * time.Second,
// MaxIncomingStreams: 1024,
// KeepAlive: true,
// },
}
}
+6
View File
@@ -0,0 +1,6 @@
// transter conn to be a crypto conn
// stream mode, blocksize is 1350, for mtu
// data [0 ... 1332]
// block [size][2 ... 1350]
// payload size + data size + aead overhead => (2+1332+16)
package shadow
+61 -13
View File
@@ -5,40 +5,86 @@ import (
"crypto/cipher"
"encoding/binary"
"io"
"log"
"math/rand"
"net"
"github.com/pkg/errors"
)
func init() {
log.SetFlags(log.Ltime | log.Lshortfile)
}
var MTU = 1350 //MTU must little than 0xFFFF
type conn struct {
blockSize int
dataSize int
aead cipher.AEAD
encryptNonce func() []byte
decryptNonce func() []byte
writeBuf []byte
readBuf []byte
readOffset int
net.Conn
}
func (c *conn) Read(b []byte) (n int, err error) {
bLength := len(b)
if bLength%c.blockSize != 0 {
return 0, errors.Errorf("aead: block size %d not match", c.blockSize)
offset := 0
if c.readOffset != 0 {
offset = copy(b, c.readBuf[c.readOffset:])
if offset+c.readOffset < c.dataSize {
c.readOffset += offset
return offset, nil
}
c.readOffset = 0
}
n, err = c.Conn.Read(b)
if err != nil {
return n, err
for ; offset < bLength; offset += c.readOffset {
n, err = io.ReadFull(c.Conn, c.readBuf)
if err != nil {
return offset, err
}
_, err = c.aead.Open(c.readBuf[:0], c.decryptNonce(), c.readBuf, nil)
if err != nil {
return offset, err
}
// BigEndian
payloadSize := int(c.readBuf[0])<<8 + int(c.readBuf[1])
c.readOffset = copy(b[offset:], c.readBuf[2:2+payloadSize])
if c.readOffset < payloadSize { // b is full
c.readOffset += 2
return len(b), nil
}
}
_, err = c.aead.Open(b[:0], c.decryptNonce(), b[:n], nil)
return bLength - c.aead.Overhead(), err
c.readOffset = 0
log.Println(offset)
return len(b), nil
}
func (c *conn) Write(b []byte) (n int, err error) {
c.writeBuf = c.aead.Seal(nil, c.encryptNonce(), b, nil)
for n < len(c.writeBuf) {
n, err = c.Conn.Write(c.writeBuf)
bLength := len(b)
size := 0
for offset := 0; offset < bLength; offset += size {
if offset+c.dataSize <= bLength {
size = c.dataSize
} else {
size = bLength - offset
}
// BigEndian
c.writeBuf[0], c.writeBuf[1] = byte((size&0xFF00)>>8), byte(size&0xFF)
copy(c.writeBuf[2:size+2], b[offset:offset+size])
c.aead.Seal(c.writeBuf[:0], c.encryptNonce(), c.writeBuf[:c.dataSize+2], nil)
_, err = c.Conn.Write(c.writeBuf)
if err != nil && err != io.EOF {
return 0, err
return offset, err
}
}
return len(b), err
@@ -56,10 +102,12 @@ func Shadow(c net.Conn, password string) (net.Conn, error) {
}
return &conn{
blockSize: block.BlockSize() * 8,
dataSize: MTU - aead.Overhead() - 2,
aead: aead,
encryptNonce: newNonce(password, aead.NonceSize()),
decryptNonce: newNonce(password, aead.NonceSize()),
writeBuf: make([]byte, MTU),
readBuf: make([]byte, MTU),
Conn: c,
}, nil
}