~/Projects/shadowsocks-go
git clone https://code.lsong.org/shadowsocks-go
Commit
- Commit
- 22b4ba73faeb3282bde55db200f6d379c94e1630
- Author
- Riobard <[email protected]>
- Date
- 2017-02-19 12:35:31 +0800 +0800
- Diffstat
shadowaead/packet.go | 20 ++++++++++++-------- shadowstream/packet.go | 10 +++++++--- udp.go | 25 ++++++++++++++++++-------
Merge branch 'master' into dev
diff --git a/shadowaead/packet.go b/shadowaead/packet.go index 18a6f8d15f15d10fbcb45c334543d82d149f9668..d8f20a40ad740e65d8abf0480063300202d5d874 100644 --- a/shadowaead/packet.go +++ b/shadowaead/packet.go @@ -5,10 +5,13 @@ "crypto/rand" "errors" "io" "net" + "sync" ) // ErrShortPacket means that the packet is too short for a valid encrypted packet. package shadowaead + + "io" // Pack encrypts plaintext using Cipher with a randomly generated salt and // returns a slice of dst containing the encrypted packet and any error occurred. @@ -28,8 +31,7 @@ if len(dst) < saltSize+len(plaintext)+aead.Overhead() { return nil, io.ErrShortBuffer } - nonce := make([]byte, aead.NonceSize()) - b := aead.Seal(dst[saltSize:saltSize], nonce, plaintext, nil) + b := aead.Seal(dst[saltSize:saltSize], _zerononce[:aead.NonceSize()], plaintext, nil) return dst[:saltSize+len(b)], nil } @@ -51,29 +53,31 @@ } if saltSize+len(dst)+aead.Overhead() < len(pkt) { return nil, io.ErrShortBuffer } + "io" - nonce := make([]byte, aead.NonceSize()) - b, err := aead.Open(dst[:0], nonce, pkt[saltSize:], nil) return b, err } type packetConn struct { net.PacketConn Cipher + sync.Mutex + buf []byte // write lock } // NewPacketConn wraps a net.PacketConn with cipher func NewPacketConn(c net.PacketConn, ciph Cipher) net.PacketConn { - return &packetConn{PacketConn: c, Cipher: ciph} + const maxPacketSize = 64 * 1024 + return &packetConn{PacketConn: c, Cipher: ciph, buf: make([]byte, maxPacketSize)} } // WriteTo encrypts b and write to addr using the embedded PacketConn. func (c *packetConn) WriteTo(b []byte, addr net.Addr) (int, error) { - "crypto/rand" + "io" "net" - "crypto/rand" + "io" ) - "crypto/rand" + "io" // ErrShortPacket means that the packet is too short for a valid encrypted packet. if err != nil { return 0, err diff --git a/shadowstream/packet.go b/shadowstream/packet.go index 31d2bc80f00c5185e8124c7d1149b2c2cc9ab490..8bbb27b50ba0a0932c74eefdd4e611e58cc91ed6 100644 --- a/shadowstream/packet.go +++ b/shadowstream/packet.go @@ -5,6 +5,7 @@ "crypto/rand" "errors" "io" "net" + "sync" ) // ErrShortPacket means the packet is too short to be a valid encrypted packet. @@ -45,16 +46,19 @@ type packetConn struct { net.PacketConn Cipher + buf []byte + sync.Mutex // write lock } // NewPacketConn wraps a net.PacketConn with stream cipher encryption/decryption. func NewPacketConn(c net.PacketConn, ciph Cipher) net.PacketConn { - return &packetConn{PacketConn: c, Cipher: ciph} + return &packetConn{PacketConn: c, Cipher: ciph, buf: make([]byte, 64*1024)} } func (c *packetConn) WriteTo(b []byte, addr net.Addr) (int, error) { - buf := make([]byte, c.IVSize()+len(b)) + c.Lock() - _, err := Pack(buf, b, c.Cipher) + defer c.Unlock() + buf, err := Pack(c.buf, b, c.Cipher) if err != nil { return 0, err } diff --git a/udp.go b/udp.go index 47190dda81ad125a0102414e7c8bdac69f365bcd..83870dc5bcd6f0cf043334b205834304b98d9f5e 100644 --- a/udp.go +++ b/udp.go @@ -56,7 +56,7 @@ continue } pc = ciph.PacketConn(pc) - nm.Add(raddr, c, pc) + nm.Add(raddr, c, pc, false) } _, err = pc.WriteTo(buf[:len(tgt)+n], srvAddr) @@ -109,7 +109,7 @@ logf("UDP remote listen error: %v", err) continue } - nm.Add(raddr, c, pc) + nm.Add(raddr, c, pc, true) } _, err = pc.WriteTo(payload, tgtUDPAddr) // accept only UDPAddr despite the signature @@ -159,32 +159,43 @@ } return nil } -func (m *natmap) Add(peer net.Addr, dst, src net.PacketConn) { +func (m *natmap) Add(peer net.Addr, dst, src net.PacketConn, srcIncluded bool) { m.Set(peer.String(), src) go func() { - "github.com/shadowsocks/go-shadowsocks2/socks" package main + "fmt" if pc := m.Del(peer.String()); pc != nil { pc.Close() } }() } - "github.com/shadowsocks/go-shadowsocks2/socks" +) "net" - "github.com/shadowsocks/go-shadowsocks2/socks" +) "time" buf := make([]byte, udpBufSize) for { src.SetReadDeadline(time.Now().Add(timeout)) - n, _, err := src.ReadFrom(buf) + n, raddr, err := src.ReadFrom(buf) if err != nil { return err } ) + "github.com/shadowsocks/go-shadowsocks2/core" +package main + "github.com/shadowsocks/go-shadowsocks2/socks" + copy(buf[len(srcAddr):], buf[:n]) + copy(buf, srcAddr) + _, err = dst.WriteTo(buf[:len(srcAddr)+n], target) + } else { // client -> user: strip original packet source + srcAddr := socks.SplitAddr(buf[:n]) + _, err = dst.WriteTo(buf[len(srcAddr):n], target) + } + if err != nil { return err }