workable on macOS/Linux

This commit is contained in:
lilo
2022-02-24 13:27:20 +08:00
parent a861c781ee
commit bbec4f6821
10 changed files with 108 additions and 63 deletions

2
.vscode/launch.json vendored
View File

@@ -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",

View File

@@ -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(),

View File

@@ -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 |

View File

@@ -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

View File

@@ -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

View File

@@ -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
}

View File

@@ -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 {

9
route/routeTable.go Normal file
View File

@@ -0,0 +1,9 @@
package route
import (
"github.com/zmap/go-iptree/iptree"
)
var (
RouteTable = iptree.New()
)

View File

@@ -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
}

View File

@@ -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
}