mirror of
https://github.com/fumiama/WireGold.git
synced 2026-06-12 12:50:28 +08:00
完善路由表
This commit is contained in:
@@ -44,8 +44,10 @@ func NewMe(privateKey *[32]byte, myIP string, myEndpoint string) (m Me) {
|
||||
}
|
||||
m.connections = make(map[string]*Link)
|
||||
m.router = &Router{
|
||||
routetable: make(map[string][]*Link),
|
||||
list: make([]*net.IPNet, 1, 16),
|
||||
table: make(map[string]*Link, 16),
|
||||
}
|
||||
m.router.SetDefault(nil)
|
||||
return
|
||||
}
|
||||
|
||||
|
||||
@@ -75,7 +75,7 @@ func (l *Link) Write(p *head.Packet) (n int, err error) {
|
||||
d, err = p.Marshal(l.me.me.String(), l.peerip.String())
|
||||
logrus.Debugln("[link] write data", string(d))
|
||||
if err == nil {
|
||||
n, err = l.me.myconn.WriteToUDP(d, l.NextHop(l.peerip).endpoint)
|
||||
n, err = l.me.myconn.WriteToUDP(d, l.me.router.NextHop(l.peerip.String()+"/32").endpoint)
|
||||
}
|
||||
return
|
||||
}
|
||||
|
||||
@@ -46,7 +46,7 @@ func (m *Me) AddPeer(peerip string, pubicKey *[32]byte, endPoint string, allowed
|
||||
_, cidr, err := net.ParseCIDR(ipnet)
|
||||
if err == nil {
|
||||
l.allowedips = append(l.allowedips, cidr)
|
||||
l.me.router.routetable[cidr.String()] = append(l.me.router.routetable[cidr.String()], l)
|
||||
l.me.router.SetItem(cidr, l)
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
@@ -1,6 +1,11 @@
|
||||
package link
|
||||
|
||||
import "github.com/fumiama/WireGold/gold/head"
|
||||
import (
|
||||
"encoding/json"
|
||||
"errors"
|
||||
|
||||
"github.com/fumiama/WireGold/gold/head"
|
||||
)
|
||||
|
||||
// 收到询问包的处理函数
|
||||
func (l *Link) onQuery(packet *head.Packet) {
|
||||
@@ -12,3 +17,16 @@ func (l *Link) onQuery(packet *head.Packet) {
|
||||
// ---- 封装 Notify 到 新的 packet.Data
|
||||
// ---- 调用 l.Send 发送到对方
|
||||
}
|
||||
|
||||
// SendQuery 主动发起查询,询问对方是否可以到达 peers
|
||||
func (l *Link) SendQuery(peers ...string) error {
|
||||
if len(peers) == 0 {
|
||||
return errors.New("len(peers) is 0")
|
||||
}
|
||||
data, err := json.Marshal(peers)
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
_, err = l.Write(head.NewPacket(head.ProtoQuery, 0, 0, data))
|
||||
return err
|
||||
}
|
||||
|
||||
@@ -3,11 +3,15 @@ package link
|
||||
import (
|
||||
"net"
|
||||
"sync"
|
||||
|
||||
"github.com/sirupsen/logrus"
|
||||
)
|
||||
|
||||
type Router struct {
|
||||
routetable map[string][]*Link
|
||||
routetablemu sync.RWMutex
|
||||
// map[cidr]*Link
|
||||
table map[string]*Link
|
||||
mu sync.RWMutex
|
||||
list []*net.IPNet
|
||||
}
|
||||
|
||||
// Accept 判断是否应当接受 ip 发来的包
|
||||
@@ -25,9 +29,42 @@ func (l *Link) IsToMe(ip net.IP) bool {
|
||||
return ip.Equal(l.me.me)
|
||||
}
|
||||
|
||||
// NextHop 得到前往 ip 的下一跳的 link
|
||||
func (l *Link) NextHop(ip net.IP) *Link {
|
||||
// TODO: 遍历 routetable,得到正确的下一跳
|
||||
// 注意使用 routetablemu 读写锁避免竞争
|
||||
return l
|
||||
// SetDefault 设置默认网关
|
||||
func (r *Router) SetDefault(l *Link) {
|
||||
defnet := &net.IPNet{IP: net.IPv4(0, 0, 0, 0), Mask: net.IPv4Mask(0, 0, 0, 0)}
|
||||
r.mu.Lock()
|
||||
r.list[len(r.list)-1] = defnet
|
||||
r.table[defnet.String()] = l
|
||||
r.mu.Unlock()
|
||||
}
|
||||
|
||||
// NextHop 得到前往 ip 的下一跳的 link
|
||||
func (r *Router) NextHop(cidr string) *Link {
|
||||
logrus.Infoln("[router] search for cidr", cidr)
|
||||
// TODO: 遍历 r.table,得到正确的下一跳
|
||||
// 注意使用 r.mu 读写锁避免竞争
|
||||
return r.table[cidr]
|
||||
}
|
||||
|
||||
func (r *Router) SetItem(ip *net.IPNet, l *Link) {
|
||||
r.mu.Lock()
|
||||
// 从第一条表项开始匹配
|
||||
for i := 0; i < len(r.list); i++ {
|
||||
if r.list[i].Contains(ip.IP) {
|
||||
// 是同一个网络
|
||||
if ip.Mask.String() == r.list[i].Mask.String() {
|
||||
logrus.Infoln("[router] change link of item", r.list[i], "from", r.table[r.list[i].String()], "to", l)
|
||||
r.table[r.list[i].String()] = l
|
||||
break
|
||||
}
|
||||
// 是新网络
|
||||
r.list = append(r.list, nil)
|
||||
copy(r.list[i+1:], r.list[i:len(r.list)-1])
|
||||
r.list[i] = ip
|
||||
r.table[ip.String()] = l
|
||||
logrus.Infoln("[router] add item: net =", ip, "link =", l)
|
||||
break
|
||||
}
|
||||
}
|
||||
r.mu.Unlock()
|
||||
}
|
||||
|
||||
Reference in New Issue
Block a user