diff --git a/dist/resource/proxy.cfg b/dist/resource/proxy.cfg index 19b3c7b..d0e539c 100755 --- a/dist/resource/proxy.cfg +++ b/dist/resource/proxy.cfg @@ -1,4 +1,4 @@ # --- point.cfg --- # This file define the configuration for OpenLAN Proxy. -OPTIONS='-log:file /dev/null -conf /etc/openlan/proxy.json' \ No newline at end of file +OPTIONS='-terminal off -log:file /dev/null' \ No newline at end of file diff --git a/pkg/config/cert.go b/pkg/config/cert.go index df9892e..bda8ad7 100755 --- a/pkg/config/cert.go +++ b/pkg/config/cert.go @@ -17,7 +17,7 @@ func (c *Crypt) IsZero() bool { return c.Algo == "" && c.Secret == "" } -func (c *Crypt) Default() { +func (c *Crypt) Correct() { if c.Secret != "" && c.Algo == "" { c.Algo = "xor" } diff --git a/pkg/config/config.go b/pkg/config/config.go index a3f9156..74855f7 100755 --- a/pkg/config/config.go +++ b/pkg/config/config.go @@ -5,7 +5,7 @@ type manager struct { } var Manager = manager{ - Switch: DefaultSwitch(), + Switch: &Switch{}, } func Reload() { diff --git a/pkg/config/limit.go b/pkg/config/limit.go index 82bba13..ab9cbf5 100755 --- a/pkg/config/limit.go +++ b/pkg/config/limit.go @@ -20,7 +20,7 @@ var ( QdVWr = 32 * 4 ) -func (q *Queue) Default() { +func (q *Queue) Correct() { if q.SockWr == 0 { q.SockWr = QdSwr } @@ -39,5 +39,5 @@ func (q *Queue) Default() { if q.VirWrt == 0 { q.VirWrt = QdVWr } - libol.Debug("Queue.Default %v", q) + libol.Debug("Queue.Correct %v", q) } diff --git a/pkg/config/point.go b/pkg/config/point.go index 5f4ed9d..67194b9 100755 --- a/pkg/config/point.go +++ b/pkg/config/point.go @@ -41,42 +41,26 @@ type Point struct { PidFile string `json:"pid,omitempty"` } -func DefaultPoint() *Point { - obj := &Point{ - Alias: "", - Connection: "xx.openlan.net", - Network: "default", - Protocol: "tcp", // udp, kcp, tcp, tls, ws and wss etc. - Timeout: 60, - Log: Log{ - File: "./point.log", - Verbose: libol.INFO, - }, - Interface: Interface{ - IPMtu: 1500, - Provider: "kernel", - Name: "", - Cost: 1000, - }, - SaveFile: "./point.json", - RequestAddr: true, - Crypt: &Crypt{}, - Cert: &Cert{}, - Terminal: "on", +func (i *Interface) Correct() { + if i.Provider == "" { + i.Provider = "kernel" + } + if i.Cost == 0 { + i.Cost = 666 + } + if i.IPMtu == 0 { + i.IPMtu = 1500 + } +} + +func (l *Log) Correct() { + if l.Verbose == 0 { + l.Verbose = libol.INFO } - obj.Correct(nil) - return obj } func NewPoint() *Point { - obj := DefaultPoint() - p := &Point{ - RequestAddr: true, - Crypt: obj.Crypt, - Cert: obj.Cert, - Interface: obj.Interface, - } - p.Flags() + p := &Point{RequestAddr: true} p.Parse() if p.Terminal == "off" { log.SetFlags(0) @@ -85,20 +69,11 @@ func NewPoint() *Point { return p } -func (ap *Point) Flags() { - obj := DefaultPoint() - flag.StringVar(&ap.Alias, "alias", obj.Alias, "Alias for this point") - flag.StringVar(&ap.Terminal, "terminal", obj.Terminal, "Run interactive terminal") - flag.StringVar(&ap.Connection, "conn", obj.Connection, "Connection access to") - flag.StringVar(&ap.Log.File, "log:file", obj.Log.File, "File log saved to") - flag.IntVar(&ap.Log.Verbose, "log:level", obj.Log.Verbose, "Log level value") - flag.StringVar(&ap.SaveFile, "conf", obj.SaveFile, "The configuration file") - flag.StringVar(&ap.PProf, "pprof", obj.PProf, "Http listen for pprof debug") - flag.StringVar(&ap.Cert.CaFile, "cacert", obj.Cert.CaFile, "CA certificate file") - flag.StringVar(&ap.PidFile, "pid", obj.PidFile, "Write pid to file") -} - func (ap *Point) Parse() { + flag.StringVar(&ap.Alias, "alias", "", "Alias for this point") + flag.StringVar(&ap.Log.File, "log:file", "", "File log saved to") + flag.StringVar(&ap.Terminal, "terminal", "", "Run interactive terminal") + flag.StringVar(&ap.SaveFile, "conf", "", "The configuration file") flag.Parse() } @@ -110,58 +85,50 @@ func (ap *Point) Initialize() { if err := ap.Load(); err != nil { libol.Warn("NewPoint.Initialize %s", err) } - ap.Default() + ap.Correct() libol.SetLogger(ap.Log.File, ap.Log.Verbose) } -func (ap *Point) Correct(obj *Point) { +func (ap *Point) Correct() { if ap.Alias == "" { ap.Alias = GetAlias() } if ap.Network == "" { if strings.Contains(ap.Username, "@") { ap.Network = strings.SplitN(ap.Username, "@", 2)[1] - } else if obj != nil { - ap.Network = obj.Network } } CorrectAddr(&ap.Connection, 10002) if runtime.GOOS == "darwin" { ap.Interface.Provider = "tun" } + if ap.Terminal == "" { + ap.Terminal = "on" + } if ap.Protocol == "tls" || ap.Protocol == "wss" { - if ap.Cert == nil && obj != nil { - ap.Cert = obj.Cert + if ap.Cert == nil { + ap.Cert = &Cert{} } } - if ap.Protocol == "" && obj != nil { - ap.Protocol = obj.Protocol + if ap.Protocol == "" { + ap.Protocol = "tcp" } if ap.Cert != nil { ap.Cert.Correct() } - if ap.Timeout == 0 && obj != nil { - ap.Timeout = obj.Timeout + if ap.Crypt == nil { + ap.Crypt = &Crypt{} } - if ap.Interface.Cost == 0 && obj != nil { - ap.Interface.Cost = obj.Interface.Cost + ap.Crypt.Correct() + if ap.Timeout == 0 { + ap.Timeout = 60 } - if ap.Interface.IPMtu == 0 && obj != nil { - ap.Interface.IPMtu = obj.Interface.IPMtu - } -} - -func (ap *Point) Default() { - obj := DefaultPoint() - ap.Correct(obj) + ap.Interface.Correct() + ap.Log.Correct() if ap.Queue == nil { ap.Queue = &Queue{} } - ap.Queue.Default() - //reset zero value to default - if ap.Crypt != nil { - ap.Crypt.Default() - } + ap.Queue.Correct() } func (ap *Point) Load() error { diff --git a/pkg/config/point_test.go b/pkg/config/point_test.go new file mode 100644 index 0000000..633f001 --- /dev/null +++ b/pkg/config/point_test.go @@ -0,0 +1,40 @@ +package config + +import ( + "fmt" + "github.com/luscis/openlan/pkg/libol" + "github.com/stretchr/testify/assert" + "os" + "testing" +) + +func TestPointFlags(t *testing.T) { + ap := Point{} + os.Args = []string{ + "app", + "-conf", "/etc/openlan/fake.json", + "-terminal", "off", + "-alias", "fake", + } + ap.Parse() + fmt.Println(ap) + assert.Equal(t, "fake", ap.Alias, "be the same.") + assert.Equal(t, "/etc/openlan/fake.json", ap.SaveFile, "be the same.") + assert.Equal(t, "off", ap.Terminal, "be the same.") +} + +func TestPoint(t *testing.T) { + ap := Point{ + Username: "user0@fake", + } + ap.Correct() + assert.Equal(t, libol.INFO, ap.Log.Verbose, "be the same.") + assert.Equal(t, "tcp", ap.Protocol, "be the same.") + assert.Equal(t, "", ap.Crypt.Algo, "be the same.") + assert.Equal(t, "fake", ap.Network, "be the same.") + assert.Equal(t, "on", ap.Terminal, "be the same.") + + ap.Crypt.Secret = "fake-pass" + ap.Correct() + assert.Equal(t, "xor", ap.Crypt.Algo, "be the same.") +} diff --git a/pkg/config/proxy.go b/pkg/config/proxy.go index a42d156..491c611 100755 --- a/pkg/config/proxy.go +++ b/pkg/config/proxy.go @@ -41,34 +41,18 @@ type Proxy struct { PProf string `json:"pprof"` } -func DefaultProxy() *Proxy { - obj := &Proxy{ - Log: Log{ - File: LogFile("openlan-proxy.log"), - Verbose: libol.INFO, - }, - } - obj.Correct(nil) - return obj -} - func NewProxy() *Proxy { p := &Proxy{} - p.Flags() p.Parse() p.Initialize() return p } -func (p *Proxy) Flags() { - obj := DefaultProxy() - flag.StringVar(&p.Log.File, "log:file", obj.Log.File, "Configure log file") - flag.StringVar(&p.Conf, "conf", obj.Conf, "The configure file") - flag.StringVar(&p.PProf, "prof", obj.PProf, "Http listen for CPU prof") - flag.IntVar(&p.Log.Verbose, "log:level", obj.Log.Verbose, "Configure log level") -} - func (p *Proxy) Parse() { + flag.StringVar(&p.Log.File, "log:file", "", "Configure log file") + flag.StringVar(&p.Conf, "conf", "", "The configure file") + flag.StringVar(&p.PProf, "prof", "", "Http listen for CPU prof") + flag.IntVar(&p.Log.Verbose, "log:level", 20, "Configure log level") flag.Parse() } @@ -80,16 +64,17 @@ func (p *Proxy) Initialize() { libol.Debug("Proxy.Initialize %v", p) } -func (p *Proxy) Correct(obj *Proxy) { +func (p *Proxy) Correct() { for _, h := range p.Http { if h.Cert != nil { h.Cert.Correct() } } + p.Log.Correct() } func (p *Proxy) Default() { - p.Correct(nil) + p.Correct() } func (p *Proxy) Load() error { diff --git a/pkg/config/switch.go b/pkg/config/switch.go index aed156e..1524ce3 100755 --- a/pkg/config/switch.go +++ b/pkg/config/switch.go @@ -6,20 +6,6 @@ import ( "path/filepath" ) -func DefaultPerf() *Perf { - return &Perf{ - Point: 64, - Neighbor: 64, - OnLine: 64, - Link: 64, - User: 1024, - Esp: 64, - State: 64 * 4, - Policy: 64 * 8, - VxLAN: 64, - } -} - type Perf struct { Point int `json:"point"` Neighbor int `json:"neighbor"` @@ -32,33 +18,33 @@ type Perf struct { VxLAN int `json:"vxlan"` } -func (p *Perf) Correct(obj *Perf) { - if p.Point == 0 && obj != nil { - p.Point = obj.Point +func (p *Perf) Correct() { + if p.Point == 0 { + p.Point = 64 } - if p.Neighbor == 0 && obj != nil { - p.Neighbor = obj.Neighbor + if p.Neighbor == 0 { + p.Neighbor = 64 } - if p.OnLine == 0 && obj != nil { - p.OnLine = obj.OnLine + if p.OnLine == 0 { + p.OnLine = 64 } - if p.Link == 0 && obj != nil { - p.Link = obj.Link + if p.Link == 0 { + p.Link = 64 } - if p.User == 0 && obj != nil { - p.User = obj.User + if p.User == 0 { + p.User = 1024 } - if p.Esp == 0 && obj != nil { - p.Esp = obj.Esp + if p.Esp == 0 { + p.Esp = 64 } - if p.State == 0 && obj != nil { - p.State = obj.State + if p.State == 0 { + p.State = 64 * 4 } - if p.Policy == 0 && obj != nil { - p.Policy = obj.Policy + if p.Policy == 0 { + p.Policy = 64 * 8 } - if p.VxLAN == 0 && obj != nil { - p.VxLAN = obj.VxLAN + if p.VxLAN == 0 { + p.VxLAN = 64 } } @@ -85,40 +71,17 @@ type Switch struct { TokenFile string `json:"-"` } -func DefaultSwitch() *Switch { - obj := &Switch{ - Timeout: 120, - Log: Log{ - File: LogFile("openlan-switch.log"), - Verbose: libol.INFO, - }, - Http: &Http{ - Listen: "0.0.0.0:10000", - }, - Listen: "0.0.0.0:10002", - Cert: &Cert{}, - Crypt: &Crypt{}, - } - obj.Correct(nil) - return obj -} - func NewSwitch() *Switch { s := Manager.Switch - s.Flags() s.Parse() s.Initialize() return s } -func (s *Switch) Flags() { - obj := DefaultSwitch() - flag.StringVar(&s.Log.File, "log:file", obj.Log.File, "Configure log file") - flag.StringVar(&s.ConfDir, "conf:dir", obj.ConfDir, "Configure switch's directory") - flag.IntVar(&s.Log.Verbose, "log:level", obj.Log.Verbose, "Configure log level") -} - func (s *Switch) Parse() { + flag.StringVar(&s.Log.File, "log:file", "", "Configure log file") + flag.StringVar(&s.ConfDir, "conf:dir", "", "Configure switch's directory") + flag.IntVar(&s.Log.Verbose, "log:level", 20, "Configure log level") flag.Parse() } @@ -127,31 +90,48 @@ func (s *Switch) Initialize() { if err := s.Load(); err != nil { libol.Error("Switch.Initialize %s", err) } - s.Default() + s.Correct() + s.LoadExt() libol.Debug("Switch.Initialize %v", s) } -func (s *Switch) Correct(obj *Switch) { +func (s *Switch) LoadExt() { + s.LoadAcl() + s.LoadNetwork() +} + +func (s *Switch) Correct() { if s.Alias == "" { s.Alias = GetAlias() } + if s.Listen == "" { + s.Listen = "0.0.0.0:10002" + } CorrectAddr(&s.Listen, 10002) + if s.Http == nil { + s.Http = &Http{ + Listen: "0.0.0.0:10000", + } + } if s.Http != nil { CorrectAddr(&s.Http.Listen, 10000) } + if s.Timeout == 0 { + s.Timeout = 120 + } libol.Debug("Proxy.Correct Http %v", s.Http) s.TokenFile = filepath.Join(s.ConfDir, "token") s.File = filepath.Join(s.ConfDir, "switch.json") if s.Cert == nil { - s.Cert = obj.Cert - } else { - s.Cert.Correct() + s.Cert = &Cert{} } + s.Cert.Correct() if s.Crypt == nil { - s.Crypt = obj.Crypt + s.Crypt = &Crypt{} } - perf := &s.Perf - perf.Correct(DefaultPerf()) + s.Log.Correct() + s.Crypt.Correct() + s.Perf.Correct() s.PassFile = filepath.Join(s.ConfDir, "password") if s.Protocol == "" { s.Protocol = "tcp" @@ -159,6 +139,7 @@ func (s *Switch) Correct(obj *Switch) { if s.AddrPool == "" { s.AddrPool = "100.44" } + s.Queue.Correct() } func (s *Switch) Dir(elem ...string) string { @@ -211,7 +192,7 @@ func (s *Switch) LoadNetwork() { s.Format() for _, obj := range s.Network { for _, link := range obj.Links { - link.Default() + link.Correct() } obj.Correct() obj.Alias = s.Alias @@ -246,21 +227,6 @@ func (s *Switch) LoadAcl() { } } -func (s *Switch) Default() { - obj := DefaultSwitch() - s.Correct(obj) - if s.Timeout == 0 { - s.Timeout = obj.Timeout - } - if s.Crypt != nil { - s.Crypt.Default() - } - queue := &s.Queue - queue.Default() - s.LoadAcl() - s.LoadNetwork() -} - func (s *Switch) Load() error { return libol.UnmarshalLoad(s, s.File) } diff --git a/pkg/config/switch_test.go b/pkg/config/switch_test.go new file mode 100644 index 0000000..eb7c317 --- /dev/null +++ b/pkg/config/switch_test.go @@ -0,0 +1,18 @@ +package config + +import ( + "github.com/luscis/openlan/pkg/libol" + "github.com/stretchr/testify/assert" + "testing" +) + +func TestSwitch(t *testing.T) { + sw := Switch{} + sw.Correct() + assert.Equal(t, libol.INFO, sw.Log.Verbose, "be the same.") + assert.Equal(t, "0.0.0.0:10002", sw.Listen, "be the same.") + assert.Equal(t, "0.0.0.0:10000", sw.Http.Listen, "be the same.") + sw.Listen = "192.168.1.0" + sw.Correct() + assert.Equal(t, "192.168.1.0:10002", sw.Listen, "be the same.") +} diff --git a/pkg/libol/logger.go b/pkg/libol/logger.go index ba2a1ad..49aa874 100755 --- a/pkg/libol/logger.go +++ b/pkg/libol/logger.go @@ -10,7 +10,7 @@ import ( ) const ( - PRINT = 00 + PRINT = 01 LOG = 05 STACK = 06 DEBUG = 10 diff --git a/pkg/libol/socket.go b/pkg/libol/socket.go index 8f3640b..543052a 100755 --- a/pkg/libol/socket.go +++ b/pkg/libol/socket.go @@ -2,6 +2,7 @@ package libol import ( "bytes" + "crypto/md5" "net" "sync" "time" @@ -214,27 +215,28 @@ func (s *SocketClientImpl) negotiate() error { return err } s.status = ClNegotiating - if reply, err := s.ReadMsg(); err == nil { - if reply.IsControl() { - action, params := reply.CmdAndParams() - if action != NegoResp { - return NewErr("wrong message type: %s", action) - } - if bytes.Compare(key, params) != 0 { - return NewErr("negotiate key failed: %s != %s", key, params) - } - if block := s.message.Crypt(); block != nil { - block.Update(string(key)) - } - s.status = ClNegotiated - return nil - } else { - Info("SocketClientImpl.negotiate %s", reply.String()) - } - return NewErr("wrong message type") - } else { + reply, err := s.ReadMsg() + if err != nil { return err } + if !reply.IsControl() { + Info("SocketClientImpl.negotiate %s", reply.String()) + return NewErr("wrong message type") + } + action, params := reply.CmdAndParams() + if action != NegoResp { + return NewErr("wrong message type: %s", action) + } + Cmd("SocketClientImpl.negotiate %s %x", action, params) + sum := md5.Sum(key) + if bytes.Compare(sum[:md5.Size], params) != 0 { + return NewErr("negotiate key failed: %x != %x", key, params) + } + if block := s.message.Crypt(); block != nil { + block.Update(string(key)) + } + s.status = ClNegotiated + return nil } // MUST IMPLEMENT @@ -454,27 +456,28 @@ func (t *SocketServerImpl) negotiate(client SocketClient) error { if client.Key() == "" { return nil } - if request, err := client.ReadMsg(); err == nil { - if request.IsControl() { - client.SetStatus(ClNegotiated) - action, params := request.CmdAndParams() - if action == NegoReq { - Info("SocketServerImpl.negotiate %s", params) - reply := NewControlFrame(NegoResp, params) - if err := client.WriteMsg(reply); err != nil { - return err - } - client.SetKey(string(params)) - return nil - } - return NewErr("wrong message type: %s", action) - } else { - Info("SocketServerImpl.negotiate %s", request.String()) - } - return NewErr("wrong message type") - } else { + request, err := client.ReadMsg() + if err != nil { return err } + if !request.IsControl() { + Info("SocketServerImpl.negotiate %s", request.String()) + return NewErr("wrong message type") + } + client.SetStatus(ClNegotiated) + action, params := request.CmdAndParams() + if action == NegoReq { + Cmd("SocketServerImpl.negotiate %s", params) + sum := md5.Sum(params) + reply := NewControlFrame(NegoResp, sum[:md5.Size]) + if err := client.WriteMsg(reply); err != nil { + return err + } + client.SetKey(string(params)) + return nil + } + return NewErr("wrong message type: %s", action) + } func (t *SocketServerImpl) doOnClient(call ServerListener, client SocketClient) { diff --git a/pkg/network/firewall.go b/pkg/network/firewall.go index 87a7499..ee6d8e8 100755 --- a/pkg/network/firewall.go +++ b/pkg/network/firewall.go @@ -83,6 +83,7 @@ func (f *FireWall) jumpOLC() { } func (f *FireWall) Initialize() { + IpInit() // Init chains f.addOLC() f.jumpOLC() @@ -174,7 +175,3 @@ func (f *FireWall) Refresh() { f.cancel() f.install() } - -func init() { - IpInit() -} diff --git a/pkg/network/iptables.go b/pkg/network/iptables.go index 2e935fc..94e1e96 100755 --- a/pkg/network/iptables.go +++ b/pkg/network/iptables.go @@ -238,7 +238,13 @@ func (chains IpChains) Pop(obj IpChain) IpChains { return news[:index] } +var __iptablesInit__ = false + func IpInit() { + if __iptablesInit__ { + return + } + __iptablesInit__ = true if err := iptables.FirewalldInit(); err != nil { libol.Error("IpInit %s", err) } diff --git a/pkg/switch/link.go b/pkg/switch/link.go index 472554f..a987351 100755 --- a/pkg/switch/link.go +++ b/pkg/switch/link.go @@ -87,8 +87,7 @@ func (l *Link) Start() { } libol.Go(func() { args := []string{ - "-alias", l.cfg.Network, - "-conn", l.cfg.Connection, + "-alias", l.cfg.Connection + "@" + l.cfg.Network, "-conf", file, "-terminal", "ww", } diff --git a/pkg/switch/openlan.go b/pkg/switch/openlan.go index 6a490a7..97af5f4 100755 --- a/pkg/switch/openlan.go +++ b/pkg/switch/openlan.go @@ -79,9 +79,9 @@ func (w *OpenLANWorker) Initialize() { func (w *OpenLANWorker) LoadLinks() { if w.cfg.Links != nil { - for _, lin := range w.cfg.Links { - lin.Default() - w.AddLink(&lin) + for _, link := range w.cfg.Links { + link.Correct() + w.AddLink(&link) } } }