From e29d5b2f4861938ddf2a1f811662928b7640d5f3 Mon Sep 17 00:00:00 2001 From: fumiama Date: Mon, 25 Oct 2021 01:01:22 +0800 Subject: [PATCH] init complete --- gold/head/nat.go | 7 +++ gold/head/protos.go | 3 +- gold/link/crypto.go | 31 +++++++++++++ gold/link/link.go | 9 ++++ gold/link/{local.go => listen.go} | 66 +++++++++++++--------------- gold/link/nat.go | 8 ++++ gold/link/peer.go | 11 ++++- gold/link/router.go | 16 +++++++ upper/services/tunnel/tunnel_test.go | 2 +- 9 files changed, 115 insertions(+), 38 deletions(-) create mode 100644 gold/head/nat.go create mode 100644 gold/link/crypto.go rename gold/link/{local.go => listen.go} (54%) create mode 100644 gold/link/router.go diff --git a/gold/head/nat.go b/gold/head/nat.go new file mode 100644 index 0000000..b3b608a --- /dev/null +++ b/gold/head/nat.go @@ -0,0 +1,7 @@ +package head + +// map[peerip]endpoint +type Notify map[string]string + +// peerips array +type Query []string diff --git a/gold/head/protos.go b/gold/head/protos.go index 3eb46b8..a9e121f 100644 --- a/gold/head/protos.go +++ b/gold/head/protos.go @@ -2,6 +2,7 @@ package head const ( ProtoHello uint8 = iota - ProtoHelloAck + ProtoNotify + ProtoQuery ProtoData ) diff --git a/gold/link/crypto.go b/gold/link/crypto.go new file mode 100644 index 0000000..473367c --- /dev/null +++ b/gold/link/crypto.go @@ -0,0 +1,31 @@ +package link + +import "net" + +var ( + privKey [32]byte + me net.IP + myend *net.UDPAddr +) + +func SetMyself(privateKey [32]byte, myIP string, myEndpoint string) { + privKey = privateKey + var err error + myend, err = net.ResolveUDPAddr("udp", myEndpoint) + if err != nil { + panic(err) + } + me = net.ParseIP(myIP) + myconn, err = listen() + if err != nil { + panic(err) + } +} + +func (l *Link) Encode(b []byte) (eb []byte, err error) { + return b, nil +} + +func (l *Link) Decode(b []byte) (db []byte, err error) { + return b, nil +} diff --git a/gold/link/link.go b/gold/link/link.go index bb3c001..1d1d404 100644 --- a/gold/link/link.go +++ b/gold/link/link.go @@ -16,9 +16,17 @@ type Link struct { pipe chan *head.Packet peerip net.IP endpoint *net.UDPAddr + allowedips []*net.IPNet hasKeepRuning bool + status int } +const ( + LINK_STATUS_DOWN = iota + LINK_STATUS_HALFUP + LINK_STATUS_UP +) + var ( connections = make(map[string]*Link) connmapmu sync.RWMutex @@ -38,6 +46,7 @@ func (l *Link) Close() { connmapmu.Lock() delete(connections, l.peerip.String()) connmapmu.Unlock() + l.status = LINK_STATUS_DOWN } func (l *Link) Read() *head.Packet { diff --git a/gold/link/local.go b/gold/link/listen.go similarity index 54% rename from gold/link/local.go rename to gold/link/listen.go index d7ab33e..fe3aff2 100644 --- a/gold/link/local.go +++ b/gold/link/listen.go @@ -7,34 +7,6 @@ import ( "github.com/sirupsen/logrus" ) -var ( - privKey [32]byte - me net.IP - myend *net.UDPAddr -) - -func SetMyself(privateKey [32]byte, myIP string, myEndpoint string) { - privKey = privateKey - var err error - myend, err = net.ResolveUDPAddr("udp", myEndpoint) - if err != nil { - panic(err) - } - me = net.ParseIP(myIP) - myconn, err = listen() - if err != nil { - panic(err) - } -} - -func (l *Link) Encode(b []byte) (eb []byte, err error) { - return b, nil -} - -func (l *Link) Decode(b []byte) (db []byte, err error) { - return b, nil -} - func listen() (conn *net.UDPConn, err error) { conn, err = net.ListenUDP("udp", myend) if err == nil { @@ -58,17 +30,41 @@ func listen() (conn *net.UDPConn, err error) { p, ok := IsInPeer(packet.Src) logrus.Infoln("[link] recv from endpoint", addr, "src", packet.Src, "dst", packet.Dst) logrus.Debugln("[link] recv:", string(lbf)) - if ok { + if p.EndPoint == "" || p.EndPoint != addr.String() { + logrus.Infoln("[link] set endpoint of peer", p.peerip, "to", addr.String()) + p.endpoint = addr + p.EndPoint = addr.String() + } + if ok && p.Accept(net.IP(packet.Dst)) { packet.Data, err = p.Decode(packet.Data) if err == nil { - logrus.Infoln("[link] deliver to", p.peerip) - if p.EndPoint == "" { - logrus.Infoln("[link] set endpoint of peer", p.peerip, "to", addr.String()) - p.endpoint = addr - p.EndPoint = addr.String() + switch packet.Proto { + case head.ProtoHello: + switch p.status { + case LINK_STATUS_DOWN: + _, _ = p.Write(head.NewPacket(head.ProtoHello, 0, 0, nil)) + logrus.Infoln("[link] send hello ack packet") + p.status = LINK_STATUS_HALFUP + case LINK_STATUS_HALFUP: + p.status = LINK_STATUS_UP + case LINK_STATUS_UP: + break + } + case head.ProtoNotify: + logrus.Infoln("[link] recv notify") + onNotify(&packet) + case head.ProtoQuery: + logrus.Infoln("[link] recv query") + onQuery(&packet) + case head.ProtoData: + logrus.Infoln("[link] deliver to", p.peerip) + p.pipe <- &packet + default: + break } - p.pipe <- &packet } + } else { + logrus.Infoln("[link] packet to", packet.Dst, "is refused") } } } diff --git a/gold/link/nat.go b/gold/link/nat.go index 1a1e3a5..aa72b83 100644 --- a/gold/link/nat.go +++ b/gold/link/nat.go @@ -21,3 +21,11 @@ func (l *Link) keepAlive() { logrus.Infoln("[link.nat] start to keep alive") } } + +func onQuery(packet *head.Packet) { + // TODO: 完成data解包与notify分发 +} + +func onNotify(packet *head.Packet) { + // TODO: 完成data解包与endpoint注册 +} diff --git a/gold/link/peer.go b/gold/link/peer.go index 47efd23..2a86686 100644 --- a/gold/link/peer.go +++ b/gold/link/peer.go @@ -6,7 +6,7 @@ import ( "github.com/fumiama/WireGold/gold/head" ) -func AddPeer(peerip string, pubicKey [32]byte, endPoint string, keepAlive int64) (l *Link) { +func AddPeer(peerip string, pubicKey [32]byte, endPoint string, allowedIPs []string, keepAlive int64) (l *Link) { peerip = net.ParseIP(peerip).String() var ok bool l, ok = IsInPeer(peerip) @@ -27,6 +27,15 @@ func AddPeer(peerip string, pubicKey [32]byte, endPoint string, keepAlive int64) l.EndPoint = endPoint l.endpoint = e } + if allowedIPs != nil { + l.allowedips = make([]*net.IPNet, len(allowedIPs)) + for _, ipnet := range allowedIPs { + _, cidr, err := net.ParseCIDR(ipnet) + if err != nil { + l.allowedips = append(l.allowedips, cidr) + } + } + } connmapmu.Lock() connections[peerip] = l connmapmu.Unlock() diff --git a/gold/link/router.go b/gold/link/router.go new file mode 100644 index 0000000..8de4e58 --- /dev/null +++ b/gold/link/router.go @@ -0,0 +1,16 @@ +package link + +import "net" + +func (l *Link) Accept(ip net.IP) bool { + for _, cidr := range l.allowedips { + if cidr.Contains(ip) { + return true + } + } + return false +} + +func NextHop(ip net.IP) *Link { + return nil +} diff --git a/upper/services/tunnel/tunnel_test.go b/upper/services/tunnel/tunnel_test.go index 9fd9518..540a796 100644 --- a/upper/services/tunnel/tunnel_test.go +++ b/upper/services/tunnel/tunnel_test.go @@ -10,7 +10,7 @@ import ( func TestTunnel(t *testing.T) { logrus.SetLevel(logrus.DebugLevel) link.SetMyself([32]byte{}, "192.168.1.2", "127.0.0.1:1236") - link.AddPeer("192.168.1.2", [32]byte{}, "127.0.0.1:1236", 0) + link.AddPeer("192.168.1.2", [32]byte{}, "127.0.0.1:1236", nil, 0) tunn, err := Create("192.168.1.2", 1, 1) if err != nil { t.Error(err)