diff --git a/gold/link/crypto.go b/gold/link/crypto.go index bc79e3d..a09dce1 100644 --- a/gold/link/crypto.go +++ b/gold/link/crypto.go @@ -1,73 +1,11 @@ package link import ( - "net" - "sync" "unsafe" tea "github.com/fumiama/gofastTEA" - - "github.com/fumiama/WireGold/gold/head" ) -// Me 是本机的抽象 -type Me struct { - // 本机私钥 - // 利用 Curve25519 生成 - // https://pkg.go.dev/golang.org/x/crypto/curve25519 - // https://www.zhihu.com/question/266758647 - privKey [32]byte - // 本机虚拟 ip - me net.IP - // 本机子网 - subnet net.IPNet - // 本机 endpoint - myend *net.UDPAddr - // 本机环回 link - loop *Link - // 本机活跃的所有连接 - connections map[string]*Link - // 读写同步锁 - connmapmu sync.RWMutex - // 本机监听的 endpoint - myconn *net.UDPConn - // 不分目的 link 的接收队列 - pipe chan *head.Packet - // 本机路由表 - router *Router -} - -// NewMe 设置本机参数 -func NewMe(privateKey *[32]byte, myipwithmask string, myEndpoint string, nopipeinlink bool) (m Me) { - m.privKey = *privateKey - var err error - m.myend, err = net.ResolveUDPAddr("udp", myEndpoint) - if err != nil { - panic(err) - } - ip, cidr, err := net.ParseCIDR(myipwithmask) - if err != nil { - panic(err) - } - m.me = ip - m.subnet = *cidr - m.myconn, err = m.listen() - if err != nil { - panic(err) - } - m.connections = make(map[string]*Link) - if nopipeinlink { - m.pipe = make(chan *head.Packet, 32) - } - m.router = &Router{ - list: make([]*net.IPNet, 1, 16), - table: make(map[string]*Link, 16), - } - m.router.SetDefault(nil) - m.loop = m.AddPeer(m.me.String(), nil, "127.0.0.1:56789", []string{myipwithmask}, 0, false, nopipeinlink) - return -} - // Encode 使用 TEA 加密 func (l *Link) Encode(b []byte) (eb []byte) { if b == nil { diff --git a/gold/link/link.go b/gold/link/link.go index 225de2e..53e180b 100644 --- a/gold/link/link.go +++ b/gold/link/link.go @@ -75,6 +75,39 @@ func (l *Link) Read() *head.Packet { // Write 向 peer 发包 func (l *Link) Write(p *head.Packet, istransfer bool) (n int, err error) { + if len(p.Data) <= int(l.me.mtu) { + return l.write(p, istransfer) + } + data := p.Data + offset := 0 + for len(data) > int(l.me.mtu) { + packet := *p + packet.Data = data[offset*int(l.me.mtu) : (offset+1)*int(l.me.mtu)] + i, err := l.write(&packet, istransfer) + n += i + if err != nil { + return n, err + } + data = data[(offset+1)*int(l.me.mtu):] + } + return n, nil +} + +func (l *Link) String() (n string) { + n = "default" + if l.pubk != nil { + b, err := base14.UTF16be2utf8(base14.Encode(l.pubk[:10])) + if err == nil { + n = helper.BytesToString(b) + } else { + n = err.Error() + } + } + return +} + +// write 向 peer 发一个包 +func (l *Link) write(p *head.Packet, istransfer bool) (n int, err error) { var d []byte if istransfer { d = p.Marshal(nil) @@ -102,16 +135,3 @@ func (l *Link) Write(p *head.Packet, istransfer bool) (n int, err error) { } return } - -func (l *Link) String() (n string) { - n = "default" - if l.pubk != nil { - b, err := base14.UTF16be2utf8(base14.Encode(l.pubk[:10])) - if err == nil { - n = helper.BytesToString(b) - } else { - n = err.Error() - } - } - return -} diff --git a/gold/link/me.go b/gold/link/me.go new file mode 100644 index 0000000..9a5fdc3 --- /dev/null +++ b/gold/link/me.go @@ -0,0 +1,74 @@ +package link + +import ( + "net" + "sync" + + "github.com/fumiama/WireGold/gold/head" +) + +// Me 是本机的抽象 +type Me struct { + // 本机私钥 + // 利用 Curve25519 生成 + // https://pkg.go.dev/golang.org/x/crypto/curve25519 + // https://www.zhihu.com/question/266758647 + privKey [32]byte + // 本机虚拟 ip + me net.IP + // 本机子网 + subnet net.IPNet + // 本机 endpoint + myend *net.UDPAddr + // 本机环回 link + loop *Link + // 本机活跃的所有连接 + connections map[string]*Link + // 读写同步锁 + connmapmu sync.RWMutex + // 本机监听的 endpoint + myconn *net.UDPConn + // 不分目的 link 的接收队列 + pipe chan *head.Packet + // 本机路由表 + router *Router + // 虚拟链路网卡 MTU + // 默认 30000 + mtu uint16 +} + +// NewMe 设置本机参数 +func NewMe(privateKey *[32]byte, myipwithmask string, myEndpoint string, nopipeinlink bool) (m Me) { + m.privKey = *privateKey + var err error + m.myend, err = net.ResolveUDPAddr("udp", myEndpoint) + if err != nil { + panic(err) + } + ip, cidr, err := net.ParseCIDR(myipwithmask) + if err != nil { + panic(err) + } + m.me = ip + m.subnet = *cidr + m.myconn, err = m.listen() + if err != nil { + panic(err) + } + m.connections = make(map[string]*Link) + if nopipeinlink { + m.pipe = make(chan *head.Packet, 32) + } + m.router = &Router{ + list: make([]*net.IPNet, 1, 16), + table: make(map[string]*Link, 16), + } + m.router.SetDefault(nil) + m.loop = m.AddPeer(m.me.String(), nil, "127.0.0.1:56789", []string{myipwithmask}, 0, false, nopipeinlink) + m.mtu = 30000 + return +} + +func (m *Me) SetMTU(mtu uint16) { + m.mtu = mtu +} diff --git a/lower/nic.go b/lower/nic.go index b07fb8a..ce97cc8 100644 --- a/lower/nic.go +++ b/lower/nic.go @@ -57,8 +57,8 @@ func (nc *NIC) Start(m *link.Me) { logrus.Infoln("[lower] recv write", n, "bytes packet to nic") } }() - buf := make([]byte, 4096) - for nc.hasstart { // 从 NIC 发送 + buf := make([]byte, 32768) // Ring capacity + for nc.hasstart { // 从 NIC 发送 packet := buf n, err := nc.ifce.Read(packet) if err != nil {