Liu Song’s Projects


~/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
 		}