diff --git a/cmd/up.go b/cmd/up.go index 5fb8167..a7eaa14 100644 --- a/cmd/up.go +++ b/cmd/up.go @@ -28,8 +28,6 @@ import ( "github.com/liloew/altgvn/p2p" "github.com/liloew/altgvn/tun" "github.com/sirupsen/logrus" - "github.com/songgao/packets/ethernet" - "github.com/songgao/water/waterutil" "github.com/spf13/cobra" "github.com/spf13/viper" ) @@ -97,10 +95,17 @@ func upCommand(cmd *cobra.Command) { for _, addr := range host.Addrs() { bootstraps = append(bootstraps, fmt.Sprintf("%s/p2p/%s", addr.String(), host.ID().Pretty())) } - dhcp.NewRPCServer(host, zone) + dhcp.NewRPCServer(host, zone, viper.GetString("dev.vip")) + // auto config in server mode + devChan <- tun.Device{ + Name: viper.GetString("dev.name"), + Ip: viper.GetString("dev.vip"), + Mtu: viper.GetInt("dev.mtu"), + Subnets: viper.GetStringSlice("dev.subnets"), + } } p2p.NewDHT(host, zone, bootstraps) - // BEGIN: DHCP + // BEGIN: DHCP for client mode if MODE(viper.GetUint("mode")) == MODECLIENT { go func() { ticker := time.NewTicker(10 * time.Second) @@ -118,7 +123,12 @@ func upCommand(cmd *cobra.Command) { }).Info("DHCP - Got IP") // TODO: if rs OK and push to chan ticker.Stop() - devChan <- tun.Device{Name: res.Name, Ip: res.Id, Mtu: res.Mtu, Subnets: res.Subnets} + devChan <- tun.Device{ + Name: res.Name, + Ip: res.Ip, + Mtu: res.Mtu, + Subnets: res.Subnets, + } } } }() @@ -176,10 +186,6 @@ func upCommand(cmd *cobra.Command) { go func() { for { if msg, err := sub.Next(context.Background()); err == nil { - // didn't ignore self message because of we process the route uniformly - // if msg.ReceivedFrom == host.ID() { - // continue - // } message := new(p2p.Message) if err := json.Unmarshal(msg.Data, message); err != nil { logrus.WithFields(logrus.Fields{ @@ -209,39 +215,43 @@ func upCommand(cmd *cobra.Command) { case dev := <-devChan: // BEGIN: TUN tun.NewTun(dev) - var frame ethernet.Frame - // avoid create duplicate - close(devChan) - for { - frame.Resize(int(config.Dev.Mtu)) - n, err := tun.Read([]byte(frame)) - if err != nil { - logrus.WithFields(logrus.Fields{ - "ERROR": err, - }).Error("Read packet from TUN error") - } - frame = frame[:n] - if frame != nil && len(frame) > 0 { - if waterutil.IsIPv4(frame) { - // Only process IPv4 packet - if waterutil.IPv4Source(frame).String() == waterutil.IPv4Destination(frame).String() { - // FIXME: need't check src and dst ? - } else { - // TODO: froward to exactlly socket - // for id, stream := range streams { - // // TODO: check id and route - // if id != "" { - // bytes := append(frame, "\n"...) - // stream.Write(bytes) - // } - // } - p2p.ForwardPacket(frame) + /* + var frame ethernet.Frame + // avoid create duplicate + close(devChan) + for { + frame.Resize(int(config.Dev.Mtu)) + n, err := tun.Read([]byte(frame)) + if err != nil { + logrus.WithFields(logrus.Fields{ + "ERROR": err, + }).Error("Read packet from TUN error") + } + frame = frame[:n] + if frame != nil && len(frame) > 0 { + if waterutil.IsIPv4(frame) { + // Only process IPv4 packet + if waterutil.IPv4Source(frame).String() == waterutil.IPv4Destination(frame).String() { + // FIXME: need't check src and dst ? + } else { + // TODO: froward to exactlly socket + // for id, stream := range streams { + // // TODO: check id and route + // if id != "" { + // bytes := append(frame, "\n"...) + // stream.Write(bytes) + // } + // } + p2p.ForwardPacket(frame) + } } } } - } + */ // END: TUN } + ch := make(chan int, 1) + <-ch } func readData(stream network.Stream, rw *bufio.ReadWriter) { diff --git a/conf/client-1.yaml b/conf/client-1.yaml index cbe7f85..6320690 100644 --- a/conf/client-1.yaml +++ b/conf/client-1.yaml @@ -1,5 +1,5 @@ id: QmRXEg5o6PfQaoBaC9jUeWmW6u4teQFfLqZHAL47kVXoJL -server: "/ip4/172.168.0.18/tcp/54136/p2p/QmSGY3kKiJ3qHhhNeb3bMJgch7mo6HbK9zAhyLDyZCCjtz" +server: "/ip4/172.168.1.120/tcp/61505/p2p/QmSGY3kKiJ3qHhhNeb3bMJgch7mo6HbK9zAhyLDyZCCjtz" dev: name: utun4 mtu: 1420 diff --git a/conf/client-2.yaml b/conf/client-2.yaml index 394e4ed..a265b2e 100644 --- a/conf/client-2.yaml +++ b/conf/client-2.yaml @@ -1,5 +1,5 @@ id: QmZiwVDDPhByWJsk5tJqajnPFjvM15KV1NuasSb9WN3ZJq -server: "/ip4/172.168.0.18/tcp/54136/p2p/QmSGY3kKiJ3qHhhNeb3bMJgch7mo6HbK9zAhyLDyZCCjtz" +server: "/ip4/172.168.1.120/tcp/61505/p2p/QmSGY3kKiJ3qHhhNeb3bMJgch7mo6HbK9zAhyLDyZCCjtz" dev: name: utun4 mtu: 1420 diff --git a/dhcp/dhcpRPC.go b/dhcp/dhcpRPC.go index c8cb480..541f2e7 100644 --- a/dhcp/dhcpRPC.go +++ b/dhcp/dhcpRPC.go @@ -2,6 +2,9 @@ package dhcp import ( "context" + "net" + "strings" + "sync" "github.com/libp2p/go-libp2p-core/host" "github.com/libp2p/go-libp2p-core/peer" @@ -11,6 +14,11 @@ import ( "github.com/sirupsen/logrus" ) +var ( + MaxCIDR string + mu sync.Mutex +) + type Request struct { Id string Name string @@ -26,25 +34,59 @@ type Response struct { } type DHCPService struct { - // TODO: bind to database or KV store - Data interface{} + // bind to database or KV store + KV map[string]Response + // should be 192.168.1.1/24 for example + Cidr string } func (s *DHCPService) DHCP(ctx context.Context, req Request, res *Response) error { logrus.WithFields(logrus.Fields{ "Request": req, }).Info("RPC - request") - res.Id = req.Id - res.Name = req.Name - res.Subnets = req.Subnets - // TODO: find and increase - res.Id = "" + "/24" + mu.Lock() + data, ok := s.KV[req.Id] + if !ok { + data.Id = req.Id + data.Name = req.Name + data.Subnets = req.Subnets + // TODO: find and increase + // res.Ip = "" + "/24" + // s.KV[req.Id] = *res + // Calculate ip whitin the same subnet + + if MaxCIDR == "" { + MaxCIDR = s.Cidr + } + ipv4Addr, ipv4Net, err := net.ParseCIDR(MaxCIDR) + if err != nil { + logrus.WithFields(logrus.Fields{ + "PEER": MaxCIDR, + }).Fatal("IP addr is invalid") + } + ipv4Addr = ipv4Addr.To4() + ipv4Addr[3]++ + if ipv4Net.Contains(ipv4Addr) { + MaxCIDR = ipv4Addr.String() + "/" + strings.Split(MaxCIDR, "/")[1] + } else { + // TODO: loop for an available ip + } + data.Ip = MaxCIDR + } + s.KV[req.Id] = data + // res = &data + res.Id = data.Id + res.Ip = data.Ip + res.Name = data.Name + res.Mtu = data.Mtu + res.Subnets = data.Subnets + mu.Unlock() return nil } -func NewRPCServer(host host.Host, zone string) { +func NewRPCServer(host host.Host, zone string, cidr string) { server := rpc.NewServer(host, protocol.ID(zone)) - service := DHCPService{} + service := DHCPService{KV: map[string]Response{}, Cidr: cidr} if err := server.Register(&service); err != nil { logrus.WithFields(logrus.Fields{ "ERROR": err,