diff --git a/parse/addr.go b/parse/addr.go index e48339d..b8b7039 100644 --- a/parse/addr.go +++ b/parse/addr.go @@ -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() diff --git a/proxy/quic/client.go b/proxy/quic/client.go index be7e16b..b1662e8 100644 --- a/proxy/quic/client.go +++ b/proxy/quic/client.go @@ -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, + // }, } } diff --git a/proxy/quic/server.go b/proxy/quic/server.go index 914310a..b6fcdb2 100644 --- a/proxy/quic/server.go +++ b/proxy/quic/server.go @@ -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, + // }, } } diff --git a/shadow/doc.go b/shadow/doc.go new file mode 100644 index 0000000..6b6b512 --- /dev/null +++ b/shadow/doc.go @@ -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 diff --git a/shadow/shadow.go b/shadow/shadow.go index df948f8..73c9ca1 100644 --- a/shadow/shadow.go +++ b/shadow/shadow.go @@ -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 }