From bbec4f68218e46b5ca2a7adb5c361d525e4438ef Mon Sep 17 00:00:00 2001 From: lilo Date: Thu, 24 Feb 2022 13:27:20 +0800 Subject: [PATCH] workable on macOS/Linux --- .vscode/launch.json | 2 +- cmd/up.go | 15 +++--- conf/client-1.yaml | 2 +- conf/client-2.yaml | 2 +- conf/server.yaml | 2 +- dhcp/dhcpRPC.go | 4 +- p2p/peer.go | 107 +++++++++++++++++++++++++++-------------- route/routeTable.go | 9 ++++ tun/netutil.go | 9 ++-- tun/netutil_windows.go | 19 ++++---- 10 files changed, 108 insertions(+), 63 deletions(-) create mode 100644 route/routeTable.go diff --git a/.vscode/launch.json b/.vscode/launch.json index f758d15..fdbed93 100644 --- a/.vscode/launch.json +++ b/.vscode/launch.json @@ -23,7 +23,7 @@ "request": "launch", "mode": "auto", "program": "main.go", - "args": ["up", "-c", "/tmp/ALTGVN/client.yaml"], + "args": ["up", "-c", "conf/client-1.yaml"], }, { "name": "Debug cobra cli - up server", "type": "go", diff --git a/cmd/up.go b/cmd/up.go index 7448055..3bcf028 100644 --- a/cmd/up.go +++ b/cmd/up.go @@ -16,7 +16,6 @@ limitations under the License. package cmd import ( - "bufio" "encoding/binary" "fmt" "net" @@ -30,6 +29,7 @@ import ( "github.com/libp2p/go-libp2p-core/protocol" "github.com/liloew/altgvn/dhcp" "github.com/liloew/altgvn/p2p" + "github.com/liloew/altgvn/route" "github.com/liloew/altgvn/tun" "github.com/sirupsen/logrus" "github.com/songgao/packets/ethernet" @@ -93,8 +93,7 @@ func upCommand(cmd *cobra.Command) { "RemoteAddr": stream.Conn().RemoteMultiaddr(), "Protocol": stream.Protocol(), }).Info("handler new stream") - rw := bufio.NewReadWriter(bufio.NewReader(stream), bufio.NewWriter(stream)) - go readData(stream, rw) + go readData(stream) }) var bootstraps []string @@ -155,7 +154,7 @@ func upCommand(cmd *cobra.Command) { "ID": r.Id, "Subnet": r.Subnets, }).Info("Refresh local vip table") - p2p.RouteTable.AddByString(strings.Split(r.Ip, "/")[0]+"/32", r.Id) + route.RouteTable.AddByString(strings.Split(r.Ip, "/")[0]+"/32", r.Id) if r.Id != host.ID().Pretty() { subnets = append(subnets, r.Subnets...) } @@ -244,7 +243,7 @@ func upCommand(cmd *cobra.Command) { select {} } -func readData(stream network.Stream, rw *bufio.ReadWriter) { +func readData(stream network.Stream) { for { var psize = make([]byte, 2) if _, err := stream.Read(psize); err != nil { @@ -258,10 +257,8 @@ func readData(stream network.Stream, rw *bufio.ReadWriter) { "ERROR": err, "SIZE": n, }).Error("Read data error") - if err.Error() == "EOF" { - break - } - continue + stream.Close() + break } logrus.WithFields(logrus.Fields{ "LocalPeer": stream.Conn().LocalPeer().Pretty(), diff --git a/conf/client-1.yaml b/conf/client-1.yaml index edfcf1b..da86317 100644 --- a/conf/client-1.yaml +++ b/conf/client-1.yaml @@ -4,7 +4,7 @@ dev: name: utun4 mtu: 1420 subnets: - - 10.30.20.0/24 + - 10.30.22.0/24 - 172.16.13.0/24 version: 1.0.0 priKey: !!binary | diff --git a/conf/client-2.yaml b/conf/client-2.yaml index 02065e0..3a614f2 100644 --- a/conf/client-2.yaml +++ b/conf/client-2.yaml @@ -4,7 +4,7 @@ dev: name: utun4 mtu: 1420 subnets: - - 10.30.21.0/24 + # - 10.30.21.0/24 version: 1.0.0 priKey: !!binary | CAASqAkwggSkAgEAAoIBAQDjbJ/cot0GYydpfzQ5B1KZsQ6OgcVZoBMUXRn81btTJlFCqZ diff --git a/conf/server.yaml b/conf/server.yaml index d4dcae9..939cec6 100644 --- a/conf/server.yaml +++ b/conf/server.yaml @@ -6,7 +6,7 @@ dev: vip: 192.168.1.1/24 mtu: 1500 subnets: - #- "10.30.22.0/24" + - 10.30.20.0/24 version: 1.0.0 priKey: !!binary | CAASpwkwggSjAgEAAoIBAQC3pxvCIViNopIFRoDRvngT3AEfPheSYuPbd8I1AZMTKoqgip diff --git a/dhcp/dhcpRPC.go b/dhcp/dhcpRPC.go index 186f503..86d1459 100644 --- a/dhcp/dhcpRPC.go +++ b/dhcp/dhcpRPC.go @@ -10,7 +10,7 @@ import ( "github.com/libp2p/go-libp2p-core/peer" "github.com/libp2p/go-libp2p-core/protocol" rpc "github.com/libp2p/go-libp2p-gorpc" - "github.com/liloew/altgvn/p2p" + "github.com/liloew/altgvn/route" "github.com/multiformats/go-multiaddr" "github.com/sirupsen/logrus" ) @@ -100,7 +100,7 @@ func (s *DHCPService) DHCP(ctx context.Context, req Request, res *Response) erro }).Info("RPC - Client requested data") // vip/mask -> vip/32 - p2p.RouteTable.AddByString(strings.Split(data.Ip, "/")[0]+"/32", data.Id) + route.RouteTable.AddByString(strings.Split(data.Ip, "/")[0]+"/32", data.Id) mu.Unlock() return nil } diff --git a/p2p/peer.go b/p2p/peer.go index a87a89d..7dd8837 100644 --- a/p2p/peer.go +++ b/p2p/peer.go @@ -14,10 +14,12 @@ import ( "github.com/libp2p/go-libp2p-core/host" "github.com/libp2p/go-libp2p-core/network" pubsub "github.com/libp2p/go-libp2p-pubsub" + "github.com/liloew/altgvn/dhcp" + "github.com/liloew/altgvn/route" "github.com/liloew/altgvn/tun" "github.com/sirupsen/logrus" "github.com/songgao/water/waterutil" - "github.com/zmap/go-iptree/iptree" + "github.com/spf13/viper" ) type MessageType uint @@ -46,9 +48,8 @@ type Message struct { } var ( - RouteTable = iptree.New() - Streams = make(map[string]network.Stream) - VIP string + Streams = make(map[string]network.Stream) + VIP string ) func init() { @@ -104,9 +105,6 @@ func NewPubSub(host host.Host, topic string) *Publisher { for { if msg, err := sub.Next(context.Background()); err == nil { message := new(Message) - if msg.ReceivedFrom.Pretty() == host.ID().Pretty() { - continue - } if err := json.Unmarshal(msg.Data, message); err != nil { logrus.WithFields(logrus.Fields{ "ERROR": err, @@ -116,12 +114,49 @@ func NewPubSub(host host.Host, topic string) *Publisher { "Message": message, }).Info("Receive message from topic") if message.MessageType == MessageTypeRoute { + if msg.ReceivedFrom.Pretty() == host.ID().Pretty() { + continue + } // TODO: add MASQUERADE if self tun.RefreshRoute(message.Subnets) for _, subnet := range message.Subnets { // Add will override the exist one - RouteTable.AddByString(strings.TrimSpace(subnet), message.Id) + route.RouteTable.AddByString(strings.TrimSpace(subnet), message.Id) } + } else if message.MessageType == MessageTypeOnline { + // route.RouteTable.AddByString(strings.Split(message.Vip, "/")[0]+"/32", message.Id) + // refresh clients + if viper.GetUint("mode") == 1 { + // server + continue + } else { + req := dhcp.Request{} + var ress []dhcp.Response + if err := dhcp.Call("DHCPService", "Clients", req, &ress); err == nil { + subnets := make([]string, 0) + for _, r := range ress { + if r.Id == host.ID().Pretty() { + continue + } + logrus.WithFields(logrus.Fields{ + "VIP": r.Ip, + "ID": r.Id, + "Subnet": r.Subnets, + }).Info("Refresh local vip table") + route.RouteTable.AddByString(strings.Split(r.Ip, "/")[0]+"/32", r.Id) + if r.Id != host.ID().Pretty() { + subnets = append(subnets, r.Subnets...) + } + } + logrus.WithFields(logrus.Fields{ + "subnets": subnets, + }).Info("Refresh subnets") + tun.RefreshRoute(subnets) + } + + } + } else if message.MessageType == MessageTypeOffline { + route.RouteTable.DeleteByString(strings.Split(message.Vip, "/")[0] + "/32") } } } else { @@ -141,41 +176,43 @@ func NewPubSub(host host.Host, topic string) *Publisher { } func (p *Publisher) Publish(peerId string, vip string, subnets []string) { + message := &Message{ + Id: peerId, + MessageType: MessageTypeRoute, + Vip: vip, + } if len(subnets) > 0 { - message := &Message{ - Id: peerId, - MessageType: MessageTypeRoute, - Vip: vip, - Subnets: subnets, - } - if bytes, err := json.Marshal(message); err == nil { - ticker := time.NewTicker(10 * time.Second) - go func(tk *time.Ticker) { - interval := 10 - for _ = range tk.C { - if err := p.pub.Publish(context.Background(), bytes); err != nil { - logrus.WithFields(logrus.Fields{ - "ERROR": err, - "Message": message, - }).Error("Publish message from to topic error") - } - if interval < 30*60 { - // half of hour for the longest - interval *= 2 - } + message.Subnets = subnets + } else { + message.MessageType = MessageTypeOnline + } + if bytes, err := json.Marshal(message); err == nil { + ticker := time.NewTicker(10 * time.Second) + go func(tk *time.Ticker) { + interval := 10 + for _ = range tk.C { + if err := p.pub.Publish(context.Background(), bytes); err != nil { logrus.WithFields(logrus.Fields{ - "Interval": interval, - }).Info("") - ticker.Reset(time.Duration(interval) * time.Second) + "ERROR": err, + "Message": message, + }).Error("Publish message from to topic error") } - }(ticker) - } + if interval < 30*60 { + // half of hour for the longest + interval *= 2 + } + logrus.WithFields(logrus.Fields{ + "Interval": interval, + }).Info("") + ticker.Reset(time.Duration(interval) * time.Second) + } + }(ticker) } } func ForwardPacket(host host.Host, zone string, packets []byte, vipNet *net.IPNet) { dst := waterutil.IPv4Destination(packets) - if peerId, found, err := RouteTable.GetByString(dst.String()); err == nil && found { + if peerId, found, err := route.RouteTable.GetByString(dst.String()); err == nil && found { if stream, ok := Streams[peerId.(string)]; ok { binary.Write(stream, binary.LittleEndian, uint16(len(packets))) if n, err := stream.Write(packets); n != len(packets) || err != nil { diff --git a/route/routeTable.go b/route/routeTable.go new file mode 100644 index 0000000..19ceed2 --- /dev/null +++ b/route/routeTable.go @@ -0,0 +1,9 @@ +package route + +import ( + "github.com/zmap/go-iptree/iptree" +) + +var ( + RouteTable = iptree.New() +) diff --git a/tun/netutil.go b/tun/netutil.go index 7c654f3..3adb599 100644 --- a/tun/netutil.go +++ b/tun/netutil.go @@ -7,6 +7,7 @@ import ( "fmt" "io/ioutil" "net" + "os" "strings" "github.com/sirupsen/logrus" @@ -134,7 +135,7 @@ fi` return err } // remove if success otherwise for debug - // defer os.Remove(tmpfile.Name()) + defer os.Remove(tmpfile.Name()) return nil } @@ -246,7 +247,7 @@ fi` return err } // remove if success otherwise for debug - // defer os.Remove(tmpfile.Name()) + defer os.Remove(tmpfile.Name()) return nil } @@ -319,7 +320,7 @@ fi` return err } // remove if success otherwise for debug - // defer os.Remove(tmpfile.Name()) + defer os.Remove(tmpfile.Name()) return nil } @@ -391,7 +392,7 @@ fi` return err } // remove if success otherwise for debug - // defer os.Remove(tmpfile.Name()) + defer os.Remove(tmpfile.Name()) return nil } diff --git a/tun/netutil_windows.go b/tun/netutil_windows.go index ae8437b..6b59e94 100644 --- a/tun/netutil_windows.go +++ b/tun/netutil_windows.go @@ -54,11 +54,11 @@ func ConfigAddr(dev Device) error { "COMMAND": content, }).Debug("Execute command") - if err := RunCommand(tmpfile.Name()); err == nil { - // remove if success otherwise for debug - defer os.Remove(tmpfile.Name()) + if err := RunCommand(tmpfile.Name()); err != nil { + return err } - + // remove if success otherwise for debug + defer os.Remove(tmpfile.Name()) return nil } @@ -97,9 +97,10 @@ func RemoveRoute(subnets []string) error { return err } - if err := RunCommand(tmpfile.Name()); err == nil { - defer os.Remove(tmpfile.Name()) + if err := RunCommand(tmpfile.Name()); err != nil { + return err } + defer os.Remove(tmpfile.Name()) return nil } @@ -143,10 +144,10 @@ func AddRoute(subnets []string) error { return err } - if err := RunCommand(tmpfile.Name()); err == nil { - defer os.Remove(tmpfile.Name()) + if err := RunCommand(tmpfile.Name()); err != nil { + return err } - + defer os.Remove(tmpfile.Name()) return nil }