1
0
forked from x/icebergs
icebergs/base/tcp/tcp.go
2020-06-25 11:45:38 +08:00

187 lines
5.2 KiB
Go

package tcp
import (
"github.com/shylinux/icebergs"
"github.com/shylinux/icebergs/base/aaa"
"github.com/shylinux/icebergs/base/cli"
"github.com/shylinux/toolkits"
"bufio"
"net"
"net/url"
"strings"
)
func _port_list(m *ice.Message) string {
return ""
}
func _port_get(m *ice.Message) string {
current := kit.Int(m.Conf(PORT, "meta.current"))
end := kit.Int(m.Conf(PORT, "meta.end"))
if current >= end {
current = kit.Int(m.Conf(PORT, "meta.begin"))
}
for i := current; i < end; i++ {
if m.Cmd(cli.SYSTEM, "lsof", "-i", kit.Format(":%d", i)).Append(cli.CMD_CODE) != "0" {
m.Conf(PORT, "meta.current", i)
m.Log_CREATE(PORT, i)
return kit.Format("%d", i)
}
}
return ""
}
func _ip_list(m *ice.Message, ifname string) {
if ifs, e := net.Interfaces(); m.Assert(e) {
for _, v := range ifs {
if ifname != "" && !strings.Contains(v.Name, ifname) {
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())
}
}
}
}
}
func _ip_islocal(m *ice.Message, ip string) (ok bool) {
if ip == "::1" || strings.HasPrefix(ip, "127.") {
return true
}
return m.Richs(IP, kit.Keys("meta.white"), ip, nil) != nil
}
func IPIsLocal(m *ice.Message, ip string) bool {
return _ip_islocal(m, ip)
}
const (
IP = "ip"
PORT = "port"
)
var Index = &ice.Context{Name: "tcp", Help: "通信模块",
Configs: map[string]*ice.Config{
PORT: {Name: "port", Help: "端口", Value: kit.Data(
"begin", 10000, "current", 10000, "end", 20000,
)},
IP: {Name: "ip", Help: "地址", Value: kit.Data(
"black", kit.Dict(),
"white", kit.Data(kit.MDB_SHORT, kit.MDB_TEXT),
)},
},
Commands: map[string]*ice.Command{
ice.CTX_INIT: {Hand: func(m *ice.Message, c *ice.Context, cmd string, arg ...string) { m.Load() }},
ice.CTX_EXIT: {Hand: func(m *ice.Message, c *ice.Context, cmd string, arg ...string) { m.Save(PORT) }},
IP: {Name: "ip", Help: "地址", Action: map[string]*ice.Action{
"white": {Name: "show ip", Help: "白名单", Hand: func(m *ice.Message, arg ...string) {
m.Rich(IP, kit.Keys("meta.white"), kit.Dict(
kit.MDB_NAME, "",
kit.MDB_TEXT, arg[0],
))
}},
}, Hand: func(m *ice.Message, c *ice.Context, cmd string, arg ...string) {
_ip_list(m, "")
}},
PORT: {Name: "port", Help: "端口", Action: map[string]*ice.Action{
"get": {Name: "get", Help: "分配端口", Hand: func(m *ice.Message, arg ...string) {
m.Echo(_port_get(m))
}},
}, Hand: func(m *ice.Message, c *ice.Context, cmd string, arg ...string) {
_port_list(m)
}},
"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(cli.RUNTIME, "boot.username"))
msg.Option(ice.MSG_USERROLE, msg.Cmdx(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(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, IP, PORT) }