1
0
forked from x/icebergs
icebergs/base/tcp/tcp.go
2020-05-06 14:22:06 +08:00

176 lines
5.1 KiB
Go

package tcp
import (
"github.com/shylinux/icebergs"
"github.com/shylinux/toolkits"
"bufio"
"net"
"net/url"
"strings"
)
type Frame struct {
}
var Index = &ice.Context{Name: "tcp", Help: "通信模块",
Caches: map[string]*ice.Cache{},
Configs: map[string]*ice.Config{
"getport": &ice.Config{Name: "getport", Help: "getport", Value: kit.Data(
"begin", 10000, "end", 20000,
)},
},
Commands: map[string]*ice.Command{
ice.ICE_INIT: {Hand: func(m *ice.Message, c *ice.Context, cmd string, arg ...string) {
m.Load()
}},
ice.ICE_EXIT: {Hand: func(m *ice.Message, c *ice.Context, cmd string, arg ...string) {
m.Save("getport")
}},
"ip": {Name: "ifconfig [name]", Help: "网络配置", Hand: func(m *ice.Message, c *ice.Context, cmd string, arg ...string) {
if addr, e := net.InterfaceAddrs(); m.Assert(e) {
for _, v := range addr {
m.Info("%v", v)
}
}
}},
"getport": {Name: "getport", Help: "分配端口", Hand: func(m *ice.Message, c *ice.Context, cmd string, arg ...string) {
begin := kit.Int(m.Conf("getport", "meta.begin"))
end := kit.Int(m.Conf("getport", "meta.end"))
if begin >= end {
begin = 10000
}
for i := begin; i < end; i++ {
if m.Cmd(ice.CLI_SYSTEM, "lsof", "-i", kit.Format(":%d", i)).Append("code") != "0" {
m.Conf("getport", "meta.begin", i+1)
m.Echo("%d", i)
break
}
}
}},
"netstat": {Name: "netstat [name]", Help: "网络配置", Hand: func(m *ice.Message, c *ice.Context, cmd string, arg ...string) {
m.Cmdy(ice.CLI_SYSTEM, "netstat", "-lanp")
}},
"ifconfig": {Name: "ifconfig [name]", Help: "网络配置", Hand: func(m *ice.Message, c *ice.Context, cmd string, arg ...string) {
if ifs, e := net.Interfaces(); m.Assert(e) {
for _, v := range ifs {
if len(arg) > 0 && !strings.Contains(v.Name, arg[0]) {
continue
}
if ips, e := v.Addrs(); m.Assert(e) {
for _, x := range ips {
ip := strings.Split(x.String(), "/")
if strings.Contains(ip[0], ":") || len(ip) == 0 {
continue
}
if len(v.HardwareAddr.String()) == 0 {
continue
}
m.Push("index", v.Index)
m.Push("name", v.Name)
m.Push("ip", ip[0])
m.Push("mask", ip[1])
m.Push("hard", v.HardwareAddr.String())
}
}
}
}
}},
"check": {Name: "check addr", Help: "server", Hand: func(m *ice.Message, c *ice.Context, cmd string, arg ...string) {
if strings.Contains(arg[0], ".") {
switch list := strings.Split(arg[0], ":"); list[0] {
case "127.0.0.1":
m.Echo("local")
}
} else {
switch list := strings.Split(arg[0], "]:"); strings.TrimPrefix(list[0], "[") {
case "::1":
m.Echo("local")
}
}
}},
"server": {Name: "server [tcp4|tcp6|udp4|udp6] addr", Help: "server", Hand: func(m *ice.Message, c *ice.Context, cmd string, arg ...string) {
proto := "tcp4"
switch arg[0] {
case "tcp", "tcp4", "tcp6", "udp", "udp4", "udp6", "ip", "ip4", "ip6":
proto, arg = arg[0], arg[1:]
}
if l, e := net.Listen(proto, arg[0]); m.Assert(e) {
m.Gos(m, func(m *ice.Message) {
// 启动服务
m.Logs(ice.LOG_LISTEN, "addr", l.Addr())
for {
if c, e := l.Accept(); m.Assert(e) {
m.Gos(m.Spawns(), func(msg *ice.Message) {
// 建立连接
msg.Logs(ice.LOG_ACCEPT, "addr", c.RemoteAddr())
msg.Option(ice.MSG_USERADDR, c.RemoteAddr())
msg.Option(ice.MSG_USERNAME, "")
msg.Option(ice.MSG_USERROLE, "")
switch msg.Cmdx("check", c.RemoteAddr().String()) {
case "local":
// 本机用户
msg.Option(ice.MSG_USERNAME, msg.Conf(ice.CLI_RUNTIME, "boot.username"))
msg.Option(ice.MSG_USERROLE, msg.Cmdx(ice.AAA_ROLE, "check", msg.Option(ice.MSG_USERNAME)))
msg.Logs(ice.LOG_AUTH, "name", msg.Option(ice.MSG_USERNAME), "role", msg.Option(ice.MSG_USERROLE))
}
cmds := []string{}
buf := bufio.NewWriter(c)
for bio := bufio.NewScanner(c); bio.Scan(); {
text := bio.Text()
msg.Logs("scan", "len", len(text), "text", text)
if len(text) == 0 {
if len(cmds) > 0 {
msg.Cmd(ice.AAA_ROLE, "right")
// 执行命令
res := msg.Cmd(cmds)
// 返回结果
for _, str := range res.Resultv() {
buf.WriteString("result:")
buf.WriteString(url.QueryEscape(str))
buf.WriteString("\n")
}
buf.WriteString("\n")
buf.Flush()
cmds = cmds[:0]
}
continue
}
// 解析请求
line := strings.SplitN(bio.Text(), ":", 2)
line[0], e = url.QueryUnescape(line[0])
m.Assert(e)
line[1], e = url.QueryUnescape(line[1])
m.Assert(e)
switch line[0] {
case "cmds", ice.MSG_DETAIL:
cmds = append(cmds, line[1])
default:
msg.Option(line[0], line[1])
}
}
msg.Logs(ice.LOG_FINISH, "addr", c.RemoteAddr())
})
}
}
m.Logs(ice.LOG_FINISH, "addr", l.Addr())
})
}
}},
},
}
func init() {
ice.Index.Register(Index, nil)
}