mirror of
				https://github.com/TeaOSLab/EdgeNode.git
				synced 2025-11-04 16:00:25 +08:00 
			
		
		
		
	临时提交
This commit is contained in:
		
							
								
								
									
										2
									
								
								build/.gitignore
									
									
									
									
										vendored
									
									
										Normal file
									
								
							
							
						
						
									
										2
									
								
								build/.gitignore
									
									
									
									
										vendored
									
									
										Normal file
									
								
							@@ -0,0 +1,2 @@
 | 
			
		||||
bin/*
 | 
			
		||||
configs/node.yaml
 | 
			
		||||
							
								
								
									
										0
									
								
								build/configs/node.template.yaml
									
									
									
									
									
										Normal file
									
								
							
							
						
						
									
										0
									
								
								build/configs/node.template.yaml
									
									
									
									
									
										Normal file
									
								
							
							
								
								
									
										9
									
								
								build/www/index.html
									
									
									
									
									
										Normal file
									
								
							
							
						
						
									
										9
									
								
								build/www/index.html
									
									
									
									
									
										Normal file
									
								
							@@ -0,0 +1,9 @@
 | 
			
		||||
<!DOCTYPE html>
 | 
			
		||||
<html lang="en">
 | 
			
		||||
<head>
 | 
			
		||||
	<title>Welcome</title>
 | 
			
		||||
</head>
 | 
			
		||||
<body>
 | 
			
		||||
I am index.
 | 
			
		||||
</body>
 | 
			
		||||
</html>
 | 
			
		||||
							
								
								
									
										11
									
								
								cmd/edge-node/main.go
									
									
									
									
									
										Normal file
									
								
							
							
						
						
									
										11
									
								
								cmd/edge-node/main.go
									
									
									
									
									
										Normal file
									
								
							@@ -0,0 +1,11 @@
 | 
			
		||||
package main
 | 
			
		||||
 | 
			
		||||
import (
 | 
			
		||||
	"github.com/TeaOSLab/EdgeNode/internal/nodes"
 | 
			
		||||
	_ "github.com/iwind/TeaGo/bootstrap"
 | 
			
		||||
)
 | 
			
		||||
 | 
			
		||||
func main() {
 | 
			
		||||
	node := nodes.NewNode()
 | 
			
		||||
	node.Start()
 | 
			
		||||
}
 | 
			
		||||
							
								
								
									
										12
									
								
								go.mod
									
									
									
									
									
										Normal file
									
								
							
							
						
						
									
										12
									
								
								go.mod
									
									
									
									
									
										Normal file
									
								
							@@ -0,0 +1,12 @@
 | 
			
		||||
module github.com/TeaOSLab/EdgeNode
 | 
			
		||||
 | 
			
		||||
go 1.14
 | 
			
		||||
 | 
			
		||||
require (
 | 
			
		||||
	github.com/go-yaml/yaml v2.1.0+incompatible
 | 
			
		||||
	github.com/iwind/TeaGo v0.0.0-20200720020412-96dbe21b81d4
 | 
			
		||||
	github.com/niemeyer/pretty v0.0.0-20200227124842-a10e7caefd8e // indirect
 | 
			
		||||
	github.com/pquerna/ffjson v0.0.0-20190930134022-aa0246cd15f7 // indirect
 | 
			
		||||
	gopkg.in/check.v1 v1.0.0-20200227125254-8fa46927fb4f // indirect
 | 
			
		||||
	gopkg.in/yaml.v2 v2.3.0 // indirect
 | 
			
		||||
)
 | 
			
		||||
							
								
								
									
										16
									
								
								go.sum
									
									
									
									
									
										Normal file
									
								
							
							
						
						
									
										16
									
								
								go.sum
									
									
									
									
									
										Normal file
									
								
							@@ -0,0 +1,16 @@
 | 
			
		||||
github.com/go-yaml/yaml v2.1.0+incompatible h1:RYi2hDdss1u4YE7GwixGzWwVo47T8UQwnTLB6vQiq+o=
 | 
			
		||||
github.com/go-yaml/yaml v2.1.0+incompatible/go.mod h1:w2MrLa16VYP0jy6N7M5kHaCkaLENm+P+Tv+MfurjSw0=
 | 
			
		||||
github.com/iwind/TeaGo v0.0.0-20200720020412-96dbe21b81d4 h1:893FbgV8PRV/rCqEAtpifgAmsIYTDrZruWHMWIw4+x8=
 | 
			
		||||
github.com/iwind/TeaGo v0.0.0-20200720020412-96dbe21b81d4/go.mod h1:taNzU+Tt7Axz5t1v8pEV7xRuioNJxbMeMAbDVQpxq20=
 | 
			
		||||
github.com/kr/pty v1.1.1/go.mod h1:pFQYn66WHrOpPYNljwOMqo10TkYh1fy3cYio2l3bCsQ=
 | 
			
		||||
github.com/kr/text v0.1.0 h1:45sCR5RtlFHMR4UwH9sdQ5TC8v0qDQCHnXt+kaKSTVE=
 | 
			
		||||
github.com/kr/text v0.1.0/go.mod h1:4Jbv+DJW3UT/LiOwJeYQe1efqtUx/iVham/4vfdArNI=
 | 
			
		||||
github.com/niemeyer/pretty v0.0.0-20200227124842-a10e7caefd8e h1:fD57ERR4JtEqsWbfPhv4DMiApHyliiK5xCTNVSPiaAs=
 | 
			
		||||
github.com/niemeyer/pretty v0.0.0-20200227124842-a10e7caefd8e/go.mod h1:zD1mROLANZcx1PVRCS0qkT7pwLkGfwJo4zjcN/Tysno=
 | 
			
		||||
github.com/pquerna/ffjson v0.0.0-20190930134022-aa0246cd15f7 h1:xoIK0ctDddBMnc74udxJYBqlo9Ylnsp1waqjLsnef20=
 | 
			
		||||
github.com/pquerna/ffjson v0.0.0-20190930134022-aa0246cd15f7/go.mod h1:YARuvh7BUWHNhzDq2OM5tzR2RiCcN2D7sapiKyCel/M=
 | 
			
		||||
gopkg.in/check.v1 v0.0.0-20161208181325-20d25e280405/go.mod h1:Co6ibVJAznAaIkqp8huTwlJQCZ016jof/cbN4VW5Yz0=
 | 
			
		||||
gopkg.in/check.v1 v1.0.0-20200227125254-8fa46927fb4f h1:BLraFXnmrev5lT+xlilqcH8XK9/i0At2xKjWk4p6zsU=
 | 
			
		||||
gopkg.in/check.v1 v1.0.0-20200227125254-8fa46927fb4f/go.mod h1:Co6ibVJAznAaIkqp8huTwlJQCZ016jof/cbN4VW5Yz0=
 | 
			
		||||
gopkg.in/yaml.v2 v2.3.0 h1:clyUAQHOM3G0M3f5vQj7LuJrETvjVot3Z5el9nffUtU=
 | 
			
		||||
gopkg.in/yaml.v2 v2.3.0/go.mod h1:hI93XBmqTisBFMUTm0b8Fm+jr3Dg1NNxqwp+5A1VGuI=
 | 
			
		||||
							
								
								
									
										4
									
								
								internal/configs/component_config.go
									
									
									
									
									
										Normal file
									
								
							
							
						
						
									
										4
									
								
								internal/configs/component_config.go
									
									
									
									
									
										Normal file
									
								
							@@ -0,0 +1,4 @@
 | 
			
		||||
package configs
 | 
			
		||||
 | 
			
		||||
type ComponentConfig struct {
 | 
			
		||||
}
 | 
			
		||||
							
								
								
									
										8
									
								
								internal/configs/ip_version.go
									
									
									
									
									
										Normal file
									
								
							
							
						
						
									
										8
									
								
								internal/configs/ip_version.go
									
									
									
									
									
										Normal file
									
								
							@@ -0,0 +1,8 @@
 | 
			
		||||
package configs
 | 
			
		||||
 | 
			
		||||
type IPVersion = string
 | 
			
		||||
 | 
			
		||||
const (
 | 
			
		||||
	IPv4 IPVersion = "4"
 | 
			
		||||
	IPv6 IPVersion = "6"
 | 
			
		||||
)
 | 
			
		||||
							
								
								
									
										4
									
								
								internal/configs/location_config.go
									
									
									
									
									
										Normal file
									
								
							
							
						
						
									
										4
									
								
								internal/configs/location_config.go
									
									
									
									
									
										Normal file
									
								
							@@ -0,0 +1,4 @@
 | 
			
		||||
package configs
 | 
			
		||||
 | 
			
		||||
type LocationConfig struct {
 | 
			
		||||
}
 | 
			
		||||
							
								
								
									
										5
									
								
								internal/configs/locker.go
									
									
									
									
									
										Normal file
									
								
							
							
						
						
									
										5
									
								
								internal/configs/locker.go
									
									
									
									
									
										Normal file
									
								
							@@ -0,0 +1,5 @@
 | 
			
		||||
package configs
 | 
			
		||||
 | 
			
		||||
import "sync"
 | 
			
		||||
 | 
			
		||||
var sharedLocker = &sync.RWMutex{}
 | 
			
		||||
							
								
								
									
										62
									
								
								internal/configs/node_config.go
									
									
									
									
									
										Normal file
									
								
							
							
						
						
									
										62
									
								
								internal/configs/node_config.go
									
									
									
									
									
										Normal file
									
								
							@@ -0,0 +1,62 @@
 | 
			
		||||
package configs
 | 
			
		||||
 | 
			
		||||
import (
 | 
			
		||||
	"github.com/go-yaml/yaml"
 | 
			
		||||
	"github.com/iwind/TeaGo/Tea"
 | 
			
		||||
	"io/ioutil"
 | 
			
		||||
)
 | 
			
		||||
 | 
			
		||||
var sharedNodeConfig *NodeConfig = nil
 | 
			
		||||
 | 
			
		||||
type NodeConfig struct {
 | 
			
		||||
	Id      string          `yaml:"id"`
 | 
			
		||||
	Servers []*ServerConfig `yaml:"servers"`
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
func SharedNodeConfig() (*NodeConfig, error) {
 | 
			
		||||
	sharedLocker.Lock()
 | 
			
		||||
	defer sharedLocker.Unlock()
 | 
			
		||||
 | 
			
		||||
	if sharedNodeConfig != nil {
 | 
			
		||||
		return sharedNodeConfig, nil
 | 
			
		||||
	}
 | 
			
		||||
 | 
			
		||||
	data, err := ioutil.ReadFile(Tea.ConfigFile("node.yaml"))
 | 
			
		||||
	if err != nil {
 | 
			
		||||
		return &NodeConfig{}, err
 | 
			
		||||
	}
 | 
			
		||||
 | 
			
		||||
	config := &NodeConfig{}
 | 
			
		||||
	err = yaml.Unmarshal(data, &config)
 | 
			
		||||
	if err != nil {
 | 
			
		||||
		return &NodeConfig{}, err
 | 
			
		||||
	}
 | 
			
		||||
 | 
			
		||||
	sharedNodeConfig = config
 | 
			
		||||
	return config, nil
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
// 根据网络地址和协议分组
 | 
			
		||||
func (this *NodeConfig) AvailableGroups() []*ServerGroup {
 | 
			
		||||
	groupMapping := map[string]*ServerGroup{} // protocol://addr => Server Group
 | 
			
		||||
	for _, server := range this.Servers {
 | 
			
		||||
		if !server.IsOn {
 | 
			
		||||
			continue
 | 
			
		||||
		}
 | 
			
		||||
		for _, addr := range server.FullAddresses() {
 | 
			
		||||
			group, ok := groupMapping[addr]
 | 
			
		||||
			if ok {
 | 
			
		||||
				group.Add(server)
 | 
			
		||||
			} else {
 | 
			
		||||
				group = NewServerGroup(addr)
 | 
			
		||||
				group.Add(server)
 | 
			
		||||
			}
 | 
			
		||||
			groupMapping[addr] = group
 | 
			
		||||
		}
 | 
			
		||||
	}
 | 
			
		||||
	result := []*ServerGroup{}
 | 
			
		||||
	for _, group := range groupMapping {
 | 
			
		||||
		result = append(result, group)
 | 
			
		||||
	}
 | 
			
		||||
	return result
 | 
			
		||||
}
 | 
			
		||||
							
								
								
									
										46
									
								
								internal/configs/node_config_test.go
									
									
									
									
									
										Normal file
									
								
							
							
						
						
									
										46
									
								
								internal/configs/node_config_test.go
									
									
									
									
									
										Normal file
									
								
							@@ -0,0 +1,46 @@
 | 
			
		||||
package configs
 | 
			
		||||
 | 
			
		||||
import (
 | 
			
		||||
	_ "github.com/iwind/TeaGo/bootstrap"
 | 
			
		||||
	"github.com/iwind/TeaGo/logs"
 | 
			
		||||
	"testing"
 | 
			
		||||
)
 | 
			
		||||
 | 
			
		||||
func TestSharedNodeConfig(t *testing.T) {
 | 
			
		||||
	{
 | 
			
		||||
		config, err := SharedNodeConfig()
 | 
			
		||||
		if err != nil {
 | 
			
		||||
			t.Fatal(err)
 | 
			
		||||
		}
 | 
			
		||||
		t.Log(config)
 | 
			
		||||
	}
 | 
			
		||||
 | 
			
		||||
	// read from memory cache
 | 
			
		||||
	{
 | 
			
		||||
		config, err := SharedNodeConfig()
 | 
			
		||||
		if err != nil {
 | 
			
		||||
			t.Fatal(err)
 | 
			
		||||
		}
 | 
			
		||||
		t.Log(config)
 | 
			
		||||
	}
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
func TestNodeConfig_Groups(t *testing.T) {
 | 
			
		||||
	config := &NodeConfig{}
 | 
			
		||||
	config.Servers = []*ServerConfig{
 | 
			
		||||
		{
 | 
			
		||||
			IsOn: true,
 | 
			
		||||
			HTTP: &HTTPProtocolConfig{
 | 
			
		||||
				IsOn:   true,
 | 
			
		||||
				Listen: []string{"127.0.0.1:1234", ":8080"},
 | 
			
		||||
			},
 | 
			
		||||
		},
 | 
			
		||||
		{
 | 
			
		||||
			HTTP: &HTTPProtocolConfig{
 | 
			
		||||
				IsOn:   true,
 | 
			
		||||
				Listen: []string{":8080"},
 | 
			
		||||
			},
 | 
			
		||||
		},
 | 
			
		||||
	}
 | 
			
		||||
	logs.PrintAsJSON(config.AvailableGroups(), t)
 | 
			
		||||
}
 | 
			
		||||
							
								
								
									
										4
									
								
								internal/configs/origin_server_config.go
									
									
									
									
									
										Normal file
									
								
							
							
						
						
									
										4
									
								
								internal/configs/origin_server_config.go
									
									
									
									
									
										Normal file
									
								
							@@ -0,0 +1,4 @@
 | 
			
		||||
package configs
 | 
			
		||||
 | 
			
		||||
type OriginServerConfig struct {
 | 
			
		||||
}
 | 
			
		||||
							
								
								
									
										29
									
								
								internal/configs/protocol.go
									
									
									
									
									
										Normal file
									
								
							
							
						
						
									
										29
									
								
								internal/configs/protocol.go
									
									
									
									
									
										Normal file
									
								
							@@ -0,0 +1,29 @@
 | 
			
		||||
package configs
 | 
			
		||||
 | 
			
		||||
type Protocol = string
 | 
			
		||||
 | 
			
		||||
const (
 | 
			
		||||
	ProtocolHTTP  Protocol = "http"
 | 
			
		||||
	ProtocolHTTPS Protocol = "https"
 | 
			
		||||
	ProtocolTCP   Protocol = "tcp"
 | 
			
		||||
	ProtocolTLS   Protocol = "tls"
 | 
			
		||||
	ProtocolUnix  Protocol = "unix"
 | 
			
		||||
	ProtocolUDP   Protocol = "udp"
 | 
			
		||||
 | 
			
		||||
	// 子协议
 | 
			
		||||
	ProtocolHTTP4 Protocol = "http4"
 | 
			
		||||
	ProtocolHTTP6 Protocol = "http6"
 | 
			
		||||
 | 
			
		||||
	ProtocolHTTPS4 Protocol = "https4"
 | 
			
		||||
	ProtocolHTTPS6 Protocol = "https6"
 | 
			
		||||
 | 
			
		||||
	ProtocolTCP4 Protocol = "tcp4"
 | 
			
		||||
	ProtocolTCP6 Protocol = "tcp6"
 | 
			
		||||
 | 
			
		||||
	ProtocolTLS4 Protocol = "tls4"
 | 
			
		||||
	ProtocolTLS6 Protocol = "tls6"
 | 
			
		||||
)
 | 
			
		||||
 | 
			
		||||
func AllProtocols() []Protocol {
 | 
			
		||||
	return []Protocol{ProtocolHTTP, ProtocolHTTPS, ProtocolTCP, ProtocolTLS, ProtocolUnix, ProtocolUDP, ProtocolHTTP4, ProtocolHTTP6, ProtocolHTTPS4, ProtocolHTTPS6, ProtocolTCP4, ProtocolTCP6, ProtocolTLS4, ProtocolTLS6}
 | 
			
		||||
}
 | 
			
		||||
							
								
								
									
										22
									
								
								internal/configs/protocol_http_config.go
									
									
									
									
									
										Normal file
									
								
							
							
						
						
									
										22
									
								
								internal/configs/protocol_http_config.go
									
									
									
									
									
										Normal file
									
								
							@@ -0,0 +1,22 @@
 | 
			
		||||
package configs
 | 
			
		||||
 | 
			
		||||
type HTTPProtocolConfig struct {
 | 
			
		||||
	IsOn      bool      `yaml:"isOn"`                 // 是否开启
 | 
			
		||||
	IPVersion IPVersion `yaml:"ipVersion"`            // 4, 6
 | 
			
		||||
	Listen    []string  `yaml:"listen" json:"listen"` // 监听地址
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
func (this *HTTPProtocolConfig) Addresses() []string {
 | 
			
		||||
	result := []string{}
 | 
			
		||||
	for _, listen := range this.Listen {
 | 
			
		||||
		switch this.IPVersion {
 | 
			
		||||
		case IPv4:
 | 
			
		||||
			result = append(result, ProtocolHTTP4+"://"+listen)
 | 
			
		||||
		case IPv6:
 | 
			
		||||
			result = append(result, ProtocolHTTP6+"://"+listen)
 | 
			
		||||
		default:
 | 
			
		||||
			result = append(result, ProtocolHTTP+"://"+listen)
 | 
			
		||||
		}
 | 
			
		||||
	}
 | 
			
		||||
	return result
 | 
			
		||||
}
 | 
			
		||||
							
								
								
									
										22
									
								
								internal/configs/protocol_https_config.go
									
									
									
									
									
										Normal file
									
								
							
							
						
						
									
										22
									
								
								internal/configs/protocol_https_config.go
									
									
									
									
									
										Normal file
									
								
							@@ -0,0 +1,22 @@
 | 
			
		||||
package configs
 | 
			
		||||
 | 
			
		||||
type HTTPSProtocolConfig struct {
 | 
			
		||||
	IsOn      bool     `yaml:"isOn"`                 // 是否开启
 | 
			
		||||
	IPVersion string   `yaml:"ipVersion"`            // 4, 6
 | 
			
		||||
	Listen    []string `yaml:"listen" json:"listen"` // 监听地址
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
func (this *HTTPSProtocolConfig) Addresses() []string {
 | 
			
		||||
	result := []string{}
 | 
			
		||||
	for _, listen := range this.Listen {
 | 
			
		||||
		switch this.IPVersion {
 | 
			
		||||
		case IPv4:
 | 
			
		||||
			result = append(result, ProtocolHTTPS4+"://"+listen)
 | 
			
		||||
		case IPv6:
 | 
			
		||||
			result = append(result, ProtocolHTTPS6+"://"+listen)
 | 
			
		||||
		default:
 | 
			
		||||
			result = append(result, ProtocolHTTPS+"://"+listen)
 | 
			
		||||
		}
 | 
			
		||||
	}
 | 
			
		||||
	return result
 | 
			
		||||
}
 | 
			
		||||
							
								
								
									
										22
									
								
								internal/configs/protocol_tcp_config.go
									
									
									
									
									
										Normal file
									
								
							
							
						
						
									
										22
									
								
								internal/configs/protocol_tcp_config.go
									
									
									
									
									
										Normal file
									
								
							@@ -0,0 +1,22 @@
 | 
			
		||||
package configs
 | 
			
		||||
 | 
			
		||||
type TCPProtocolConfig struct {
 | 
			
		||||
	IsOn      bool      `yaml:"isOn"`                 // 是否开启
 | 
			
		||||
	IPVersion IPVersion `yaml:"ipVersion"`            // 4, 6
 | 
			
		||||
	Listen    []string  `yaml:"listen" json:"listen"` // 监听地址
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
func (this *TCPProtocolConfig) Addresses() []string {
 | 
			
		||||
	result := []string{}
 | 
			
		||||
	for _, listen := range this.Listen {
 | 
			
		||||
		switch this.IPVersion {
 | 
			
		||||
		case IPv4:
 | 
			
		||||
			result = append(result, ProtocolTCP4+"://"+listen)
 | 
			
		||||
		case IPv6:
 | 
			
		||||
			result = append(result, ProtocolTCP6+"://"+listen)
 | 
			
		||||
		default:
 | 
			
		||||
			result = append(result, ProtocolTCP+"://"+listen)
 | 
			
		||||
		}
 | 
			
		||||
	}
 | 
			
		||||
	return result
 | 
			
		||||
}
 | 
			
		||||
							
								
								
									
										22
									
								
								internal/configs/protocol_tls_config.go
									
									
									
									
									
										Normal file
									
								
							
							
						
						
									
										22
									
								
								internal/configs/protocol_tls_config.go
									
									
									
									
									
										Normal file
									
								
							@@ -0,0 +1,22 @@
 | 
			
		||||
package configs
 | 
			
		||||
 | 
			
		||||
type TLSProtocolConfig struct {
 | 
			
		||||
	IsOn      bool     `yaml:"isOn"`                 // 是否开启
 | 
			
		||||
	IPVersion string   `yaml:"ipVersion"`            // 4, 6
 | 
			
		||||
	Listen    []string `yaml:"listen" json:"listen"` // 监听地址
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
func (this *TLSProtocolConfig) Addresses() []string {
 | 
			
		||||
	result := []string{}
 | 
			
		||||
	for _, listen := range this.Listen {
 | 
			
		||||
		switch this.IPVersion {
 | 
			
		||||
		case IPv4:
 | 
			
		||||
			result = append(result, ProtocolTLS4+"://"+listen)
 | 
			
		||||
		case IPv6:
 | 
			
		||||
			result = append(result, ProtocolTLS6+"://"+listen)
 | 
			
		||||
		default:
 | 
			
		||||
			result = append(result, ProtocolTLS+"://"+listen)
 | 
			
		||||
		}
 | 
			
		||||
	}
 | 
			
		||||
	return result
 | 
			
		||||
}
 | 
			
		||||
							
								
								
									
										14
									
								
								internal/configs/protocol_udp_config.go
									
									
									
									
									
										Normal file
									
								
							
							
						
						
									
										14
									
								
								internal/configs/protocol_udp_config.go
									
									
									
									
									
										Normal file
									
								
							@@ -0,0 +1,14 @@
 | 
			
		||||
package configs
 | 
			
		||||
 | 
			
		||||
type UDPProtocolConfig struct {
 | 
			
		||||
	IsOn   bool     `yaml:"isOn"`                 // 是否开启
 | 
			
		||||
	Listen []string `yaml:"listen" json:"listen"` // 监听地址
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
func (this *UDPProtocolConfig) Addresses() []string {
 | 
			
		||||
	result := []string{}
 | 
			
		||||
	for _, listen := range this.Listen {
 | 
			
		||||
		result = append(result, ProtocolUDP+"://"+listen)
 | 
			
		||||
	}
 | 
			
		||||
	return result
 | 
			
		||||
}
 | 
			
		||||
							
								
								
									
										14
									
								
								internal/configs/protocol_unix_config.go
									
									
									
									
									
										Normal file
									
								
							
							
						
						
									
										14
									
								
								internal/configs/protocol_unix_config.go
									
									
									
									
									
										Normal file
									
								
							@@ -0,0 +1,14 @@
 | 
			
		||||
package configs
 | 
			
		||||
 | 
			
		||||
type UnixProtocolConfig struct {
 | 
			
		||||
	IsOn   bool     `yaml:"isOn"`                 // 是否开启
 | 
			
		||||
	Listen []string `yaml:"listen" json:"listen"` // 监听地址
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
func (this *UnixProtocolConfig) Addresses() []string {
 | 
			
		||||
	result := []string{}
 | 
			
		||||
	for _, listen := range this.Listen {
 | 
			
		||||
		result = append(result, ProtocolUnix+":"+listen)
 | 
			
		||||
	}
 | 
			
		||||
	return result
 | 
			
		||||
}
 | 
			
		||||
							
								
								
									
										53
									
								
								internal/configs/server_config.go
									
									
									
									
									
										Normal file
									
								
							
							
						
						
									
										53
									
								
								internal/configs/server_config.go
									
									
									
									
									
										Normal file
									
								
							@@ -0,0 +1,53 @@
 | 
			
		||||
package configs
 | 
			
		||||
 | 
			
		||||
type ServerConfig struct {
 | 
			
		||||
	Id          string             `yaml:"id"`          // ID
 | 
			
		||||
	IsOn        bool               `yaml:"isOn"`        // 是否开启
 | 
			
		||||
	Components  []*ComponentConfig `yaml:"components"`  // 组件
 | 
			
		||||
	Name        string             `yaml:"name"`        // 名称
 | 
			
		||||
	Description string             `yaml:"description"` // 描述
 | 
			
		||||
	ServerNames []string           `yaml:"serverNames"` // 域名
 | 
			
		||||
 | 
			
		||||
	// 协议
 | 
			
		||||
	HTTP  *HTTPProtocolConfig  `yaml:"http"`  // HTTP配置
 | 
			
		||||
	HTTPS *HTTPSProtocolConfig `yaml:"https"` // HTTPS配置
 | 
			
		||||
	TCP   *TCPProtocolConfig   `yaml:"tcp"`   // TCP配置
 | 
			
		||||
	TLS   *TLSProtocolConfig   `yaml:"tls"`   // TLS配置
 | 
			
		||||
	Unix  *UnixProtocolConfig  `yaml:"unix"`  // Unix配置
 | 
			
		||||
	UDP   *UDPProtocolConfig   `yaml:"udp"`   // UDP配置
 | 
			
		||||
 | 
			
		||||
	// Web配置
 | 
			
		||||
	Web *WebConfig `yaml:"web"`
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
func NewServerConfig() *ServerConfig {
 | 
			
		||||
	return &ServerConfig{}
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
func (this *ServerConfig) Init() error {
 | 
			
		||||
	return nil
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
func (this *ServerConfig) FullAddresses() []string {
 | 
			
		||||
	result := []Protocol{}
 | 
			
		||||
	if this.HTTP != nil && this.HTTP.IsOn {
 | 
			
		||||
		result = append(result, this.HTTP.Addresses()...)
 | 
			
		||||
	}
 | 
			
		||||
	if this.HTTPS != nil && this.HTTPS.IsOn {
 | 
			
		||||
		result = append(result, this.HTTPS.Addresses()...)
 | 
			
		||||
	}
 | 
			
		||||
	if this.TCP != nil && this.TCP.IsOn {
 | 
			
		||||
		result = append(result, this.TCP.Addresses()...)
 | 
			
		||||
	}
 | 
			
		||||
	if this.TLS != nil && this.TLS.IsOn {
 | 
			
		||||
		result = append(result, this.TLS.Addresses()...)
 | 
			
		||||
	}
 | 
			
		||||
	if this.Unix != nil && this.Unix.IsOn {
 | 
			
		||||
		result = append(result, this.Unix.Addresses()...)
 | 
			
		||||
	}
 | 
			
		||||
	if this.UDP != nil && this.UDP.IsOn {
 | 
			
		||||
		result = append(result, this.UDP.Addresses()...)
 | 
			
		||||
	}
 | 
			
		||||
 | 
			
		||||
	return result
 | 
			
		||||
}
 | 
			
		||||
							
								
								
									
										21
									
								
								internal/configs/server_config_test.go
									
									
									
									
									
										Normal file
									
								
							
							
						
						
									
										21
									
								
								internal/configs/server_config_test.go
									
									
									
									
									
										Normal file
									
								
							@@ -0,0 +1,21 @@
 | 
			
		||||
package configs
 | 
			
		||||
 | 
			
		||||
import "testing"
 | 
			
		||||
 | 
			
		||||
func TestServerConfig_Protocols(t *testing.T) {
 | 
			
		||||
	{
 | 
			
		||||
		server := NewServerConfig()
 | 
			
		||||
		t.Log(server.FullAddresses())
 | 
			
		||||
	}
 | 
			
		||||
 | 
			
		||||
	{
 | 
			
		||||
		server := NewServerConfig()
 | 
			
		||||
		server.HTTP = &HTTPProtocolConfig{IsOn: true, Listen: []string{"127.0.0.1:1234"}}
 | 
			
		||||
		server.HTTPS = &HTTPSProtocolConfig{IsOn: true, Listen: []string{"127.0.0.1:1234"}}
 | 
			
		||||
		server.TCP = &TCPProtocolConfig{IsOn: true, Listen: []string{"127.0.0.1:1234"}}
 | 
			
		||||
		server.TLS = &TLSProtocolConfig{IsOn: true, Listen: []string{"127.0.0.1:1234"}}
 | 
			
		||||
		server.Unix = &UnixProtocolConfig{IsOn: true, Listen: []string{"127.0.0.1:1234"}}
 | 
			
		||||
		server.UDP = &UDPProtocolConfig{IsOn: true, Listen: []string{"127.0.0.1:1234"}}
 | 
			
		||||
		t.Log(server.FullAddresses())
 | 
			
		||||
	}
 | 
			
		||||
}
 | 
			
		||||
							
								
								
									
										41
									
								
								internal/configs/server_group.go
									
									
									
									
									
										Normal file
									
								
							
							
						
						
									
										41
									
								
								internal/configs/server_group.go
									
									
									
									
									
										Normal file
									
								
							@@ -0,0 +1,41 @@
 | 
			
		||||
package configs
 | 
			
		||||
 | 
			
		||||
import "strings"
 | 
			
		||||
 | 
			
		||||
type ServerGroup struct {
 | 
			
		||||
	fullAddr string
 | 
			
		||||
	Servers  []*ServerConfig
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
func NewServerGroup(fullAddr string) *ServerGroup {
 | 
			
		||||
	return &ServerGroup{fullAddr: fullAddr}
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
// 添加服务
 | 
			
		||||
func (this *ServerGroup) Add(server *ServerConfig) {
 | 
			
		||||
	this.Servers = append(this.Servers, server)
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
// 获取完整的地址
 | 
			
		||||
func (this *ServerGroup) FullAddr() string {
 | 
			
		||||
	return this.fullAddr
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
// 获取当前分组的协议
 | 
			
		||||
func (this *ServerGroup) Protocol() Protocol {
 | 
			
		||||
	for _, p := range AllProtocols() {
 | 
			
		||||
		if strings.HasPrefix(this.fullAddr, p+":") {
 | 
			
		||||
			return p
 | 
			
		||||
		}
 | 
			
		||||
	}
 | 
			
		||||
	return ProtocolHTTP
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
// 获取当前分组的地址
 | 
			
		||||
func (this *ServerGroup) Addr() string {
 | 
			
		||||
	protocol := this.Protocol()
 | 
			
		||||
	if protocol == ProtocolUnix {
 | 
			
		||||
		return strings.TrimPrefix(this.fullAddr, protocol+":")
 | 
			
		||||
	}
 | 
			
		||||
	return strings.TrimPrefix(this.fullAddr, protocol+"://")
 | 
			
		||||
}
 | 
			
		||||
							
								
								
									
										34
									
								
								internal/configs/server_group_test.go
									
									
									
									
									
										Normal file
									
								
							
							
						
						
									
										34
									
								
								internal/configs/server_group_test.go
									
									
									
									
									
										Normal file
									
								
							@@ -0,0 +1,34 @@
 | 
			
		||||
package configs
 | 
			
		||||
 | 
			
		||||
import (
 | 
			
		||||
	"github.com/iwind/TeaGo/assert"
 | 
			
		||||
	"testing"
 | 
			
		||||
)
 | 
			
		||||
 | 
			
		||||
func TestServerGroup_Protocol(t *testing.T) {
 | 
			
		||||
	a := assert.NewAssertion(t)
 | 
			
		||||
 | 
			
		||||
	{
 | 
			
		||||
		group := NewServerGroup("tcp://127.0.0.1:1234")
 | 
			
		||||
		a.IsTrue(group.Protocol() == ProtocolTCP)
 | 
			
		||||
		a.IsTrue(group.Addr() == "127.0.0.1:1234")
 | 
			
		||||
	}
 | 
			
		||||
 | 
			
		||||
	{
 | 
			
		||||
		group := NewServerGroup("http4://127.0.0.1:1234")
 | 
			
		||||
		a.IsTrue(group.Protocol() == ProtocolHTTP4)
 | 
			
		||||
		a.IsTrue(group.Addr() == "127.0.0.1:1234")
 | 
			
		||||
	}
 | 
			
		||||
 | 
			
		||||
	{
 | 
			
		||||
		group := NewServerGroup("127.0.0.1:1234")
 | 
			
		||||
		a.IsTrue(group.Protocol() == ProtocolHTTP)
 | 
			
		||||
		a.IsTrue(group.Addr() == "127.0.0.1:1234")
 | 
			
		||||
	}
 | 
			
		||||
 | 
			
		||||
	{
 | 
			
		||||
		group := NewServerGroup("unix:/tmp/my.sock")
 | 
			
		||||
		a.IsTrue(group.Protocol() == ProtocolUnix)
 | 
			
		||||
		a.IsTrue(group.Addr() == "/tmp/my.sock")
 | 
			
		||||
	}
 | 
			
		||||
}
 | 
			
		||||
							
								
								
									
										8
									
								
								internal/configs/web_config.go
									
									
									
									
									
										Normal file
									
								
							
							
						
						
									
										8
									
								
								internal/configs/web_config.go
									
									
									
									
									
										Normal file
									
								
							@@ -0,0 +1,8 @@
 | 
			
		||||
package configs
 | 
			
		||||
 | 
			
		||||
type WebConfig struct {
 | 
			
		||||
	Locations   []*LocationConfig  `yaml:"locations"`   // 路径规则
 | 
			
		||||
 | 
			
		||||
	// 本地静态资源配置
 | 
			
		||||
	Root string `yaml:"root" json:"root"` // 资源根目录
 | 
			
		||||
}
 | 
			
		||||
							
								
								
									
										81
									
								
								internal/nodes/listener.go
									
									
									
									
									
										Normal file
									
								
							
							
						
						
									
										81
									
								
								internal/nodes/listener.go
									
									
									
									
									
										Normal file
									
								
							@@ -0,0 +1,81 @@
 | 
			
		||||
package nodes
 | 
			
		||||
 | 
			
		||||
import (
 | 
			
		||||
	"errors"
 | 
			
		||||
	"github.com/TeaOSLab/EdgeNode/internal/configs"
 | 
			
		||||
	"sync"
 | 
			
		||||
)
 | 
			
		||||
 | 
			
		||||
type Listener struct {
 | 
			
		||||
	group  *configs.ServerGroup
 | 
			
		||||
	locker sync.RWMutex
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
func NewListener() *Listener {
 | 
			
		||||
	return &Listener{}
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
func (this *Listener) Reload(group *configs.ServerGroup) {
 | 
			
		||||
	this.locker.Lock()
 | 
			
		||||
	defer this.locker.Unlock()
 | 
			
		||||
	this.group = group
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
func (this *Listener) FullAddr() string {
 | 
			
		||||
	if this.group != nil {
 | 
			
		||||
		return this.group.FullAddr()
 | 
			
		||||
	}
 | 
			
		||||
	return ""
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
func (this *Listener) Listen() error {
 | 
			
		||||
	if this.group == nil {
 | 
			
		||||
		return nil
 | 
			
		||||
	}
 | 
			
		||||
	protocol := this.group.Protocol()
 | 
			
		||||
	switch protocol {
 | 
			
		||||
	case configs.ProtocolHTTP:
 | 
			
		||||
		return this.listenHTTP()
 | 
			
		||||
	case configs.ProtocolHTTPS:
 | 
			
		||||
		return this.ListenHTTPS()
 | 
			
		||||
	case configs.ProtocolTCP:
 | 
			
		||||
		return this.listenTCP()
 | 
			
		||||
	case configs.ProtocolTLS:
 | 
			
		||||
		return this.listenTLS()
 | 
			
		||||
	case configs.ProtocolUnix:
 | 
			
		||||
		return this.listenUnix()
 | 
			
		||||
	case configs.ProtocolUDP:
 | 
			
		||||
		return this.listenUDP()
 | 
			
		||||
	default:
 | 
			
		||||
		return errors.New("unknown protocol '" + protocol + "'")
 | 
			
		||||
	}
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
func (this *Listener) Close() error {
 | 
			
		||||
	// TODO 需要实现
 | 
			
		||||
	return nil
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
func (this *Listener) listenHTTP() error {
 | 
			
		||||
	return nil
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
func (this *Listener) ListenHTTPS() error {
 | 
			
		||||
	return nil
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
func (this *Listener) listenTCP() error {
 | 
			
		||||
	return nil
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
func (this *Listener) listenTLS() error {
 | 
			
		||||
	return nil
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
func (this *Listener) listenUnix() error {
 | 
			
		||||
	return nil
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
func (this *Listener) listenUDP() error {
 | 
			
		||||
	return nil
 | 
			
		||||
}
 | 
			
		||||
							
								
								
									
										63
									
								
								internal/nodes/listener_manager.go
									
									
									
									
									
										Normal file
									
								
							
							
						
						
									
										63
									
								
								internal/nodes/listener_manager.go
									
									
									
									
									
										Normal file
									
								
							@@ -0,0 +1,63 @@
 | 
			
		||||
package nodes
 | 
			
		||||
 | 
			
		||||
import (
 | 
			
		||||
	"github.com/TeaOSLab/EdgeNode/internal/configs"
 | 
			
		||||
	"github.com/iwind/TeaGo/lists"
 | 
			
		||||
	"github.com/iwind/TeaGo/logs"
 | 
			
		||||
	"sync"
 | 
			
		||||
)
 | 
			
		||||
 | 
			
		||||
var sharedListenerManager = NewListenerManager()
 | 
			
		||||
 | 
			
		||||
type ListenerManager struct {
 | 
			
		||||
	listenersMap map[string]*Listener // addr => *Listener
 | 
			
		||||
	locker       sync.Mutex
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
func NewListenerManager() *ListenerManager {
 | 
			
		||||
	return &ListenerManager{
 | 
			
		||||
		listenersMap: map[string]*Listener{},
 | 
			
		||||
	}
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
func (this *ListenerManager) Start(node *configs.NodeConfig) error {
 | 
			
		||||
	this.locker.Lock()
 | 
			
		||||
	defer this.locker.Unlock()
 | 
			
		||||
 | 
			
		||||
	// 所有的新地址
 | 
			
		||||
	groupAddrs := []string{}
 | 
			
		||||
	for _, group := range node.AvailableGroups() {
 | 
			
		||||
		addr := group.FullAddr()
 | 
			
		||||
		groupAddrs = append(groupAddrs, addr)
 | 
			
		||||
	}
 | 
			
		||||
 | 
			
		||||
	// 停掉老的
 | 
			
		||||
	for _, listener := range this.listenersMap {
 | 
			
		||||
		addr := listener.FullAddr()
 | 
			
		||||
		if !lists.ContainsString(groupAddrs, addr) {
 | 
			
		||||
			logs.Println("[LISTENER_MANAGER]close '" + addr + "'")
 | 
			
		||||
			_ = listener.Close()
 | 
			
		||||
		}
 | 
			
		||||
	}
 | 
			
		||||
 | 
			
		||||
	// 启动新的或修改老的
 | 
			
		||||
	for _, group := range node.AvailableGroups() {
 | 
			
		||||
		addr := group.FullAddr()
 | 
			
		||||
		listener, ok := this.listenersMap[addr]
 | 
			
		||||
		if ok {
 | 
			
		||||
			logs.Println("[LISTENER_MANAGER]reload '" + addr + "'")
 | 
			
		||||
			listener.Reload(group)
 | 
			
		||||
		} else {
 | 
			
		||||
			logs.Println("[LISTENER_MANAGER]listen '" + addr + "'")
 | 
			
		||||
			listener = NewListener()
 | 
			
		||||
			listener.Reload(group)
 | 
			
		||||
			err := listener.Listen()
 | 
			
		||||
			if err != nil {
 | 
			
		||||
				return err
 | 
			
		||||
			}
 | 
			
		||||
			this.listenersMap[addr] = listener
 | 
			
		||||
		}
 | 
			
		||||
	}
 | 
			
		||||
 | 
			
		||||
	return nil
 | 
			
		||||
}
 | 
			
		||||
							
								
								
									
										55
									
								
								internal/nodes/listener_manager_test.go
									
									
									
									
									
										Normal file
									
								
							
							
						
						
									
										55
									
								
								internal/nodes/listener_manager_test.go
									
									
									
									
									
										Normal file
									
								
							@@ -0,0 +1,55 @@
 | 
			
		||||
package nodes
 | 
			
		||||
 | 
			
		||||
import (
 | 
			
		||||
	"github.com/TeaOSLab/EdgeNode/internal/configs"
 | 
			
		||||
	"testing"
 | 
			
		||||
)
 | 
			
		||||
 | 
			
		||||
func TestListenerManager_Listen(t *testing.T) {
 | 
			
		||||
	manager := NewListenerManager()
 | 
			
		||||
	err := manager.Start(&configs.NodeConfig{
 | 
			
		||||
		Servers: []*configs.ServerConfig{
 | 
			
		||||
			{
 | 
			
		||||
				IsOn: true,
 | 
			
		||||
				HTTP: &configs.HTTPProtocolConfig{
 | 
			
		||||
					IsOn:   true,
 | 
			
		||||
					Listen: []string{"127.0.0.1:1234"},
 | 
			
		||||
				},
 | 
			
		||||
			},
 | 
			
		||||
			{
 | 
			
		||||
				IsOn: true,
 | 
			
		||||
				HTTP: &configs.HTTPProtocolConfig{
 | 
			
		||||
					IsOn:   true,
 | 
			
		||||
					Listen: []string{"127.0.0.1:1235"},
 | 
			
		||||
				},
 | 
			
		||||
			},
 | 
			
		||||
		},
 | 
			
		||||
	})
 | 
			
		||||
	if err != nil {
 | 
			
		||||
		t.Fatal(err)
 | 
			
		||||
	}
 | 
			
		||||
 | 
			
		||||
	err = manager.Start(&configs.NodeConfig{
 | 
			
		||||
		Servers: []*configs.ServerConfig{
 | 
			
		||||
			{
 | 
			
		||||
				IsOn: true,
 | 
			
		||||
				HTTP: &configs.HTTPProtocolConfig{
 | 
			
		||||
					IsOn:   true,
 | 
			
		||||
					Listen: []string{"127.0.0.1:1234"},
 | 
			
		||||
				},
 | 
			
		||||
			},
 | 
			
		||||
			{
 | 
			
		||||
				IsOn: true,
 | 
			
		||||
				HTTP: &configs.HTTPProtocolConfig{
 | 
			
		||||
					IsOn:   true,
 | 
			
		||||
					Listen: []string{"127.0.0.1:1236"},
 | 
			
		||||
				},
 | 
			
		||||
			},
 | 
			
		||||
		},
 | 
			
		||||
	})
 | 
			
		||||
	if err != nil {
 | 
			
		||||
		t.Fatal(err)
 | 
			
		||||
	}
 | 
			
		||||
 | 
			
		||||
	t.Log("all ok")
 | 
			
		||||
}
 | 
			
		||||
							
								
								
									
										26
									
								
								internal/nodes/node.go
									
									
									
									
									
										Normal file
									
								
							
							
						
						
									
										26
									
								
								internal/nodes/node.go
									
									
									
									
									
										Normal file
									
								
							@@ -0,0 +1,26 @@
 | 
			
		||||
package nodes
 | 
			
		||||
 | 
			
		||||
import (
 | 
			
		||||
	"github.com/TeaOSLab/EdgeNode/internal/configs"
 | 
			
		||||
	"github.com/iwind/TeaGo/logs"
 | 
			
		||||
)
 | 
			
		||||
 | 
			
		||||
var sharedNodeConfig *configs.NodeConfig = nil
 | 
			
		||||
 | 
			
		||||
type Node struct {
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
func NewNode() *Node {
 | 
			
		||||
	return &Node{}
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
func (this *Node) Start() {
 | 
			
		||||
	nodeConfig, err := configs.SharedNodeConfig()
 | 
			
		||||
	if err != nil {
 | 
			
		||||
		logs.Println("[NODE]start failed: read node config failed: " + err.Error())
 | 
			
		||||
		return
 | 
			
		||||
	}
 | 
			
		||||
	sharedNodeConfig = nodeConfig
 | 
			
		||||
 | 
			
		||||
	logs.PrintAsJSON(nodeConfig)
 | 
			
		||||
}
 | 
			
		||||
							
								
								
									
										11
									
								
								internal/nodes/node_test.go
									
									
									
									
									
										Normal file
									
								
							
							
						
						
									
										11
									
								
								internal/nodes/node_test.go
									
									
									
									
									
										Normal file
									
								
							@@ -0,0 +1,11 @@
 | 
			
		||||
package nodes
 | 
			
		||||
 | 
			
		||||
import (
 | 
			
		||||
	_ "github.com/iwind/TeaGo/bootstrap"
 | 
			
		||||
	"testing"
 | 
			
		||||
)
 | 
			
		||||
 | 
			
		||||
func TestNode(t *testing.T) {
 | 
			
		||||
	node := NewNode()
 | 
			
		||||
	node.Start()
 | 
			
		||||
}
 | 
			
		||||
							
								
								
									
										4
									
								
								internal/nodes/origin_server.go
									
									
									
									
									
										Normal file
									
								
							
							
						
						
									
										4
									
								
								internal/nodes/origin_server.go
									
									
									
									
									
										Normal file
									
								
							@@ -0,0 +1,4 @@
 | 
			
		||||
package nodes
 | 
			
		||||
 | 
			
		||||
type OriginServer struct {
 | 
			
		||||
}
 | 
			
		||||
							
								
								
									
										4
									
								
								internal/nodes/request.go
									
									
									
									
									
										Normal file
									
								
							
							
						
						
									
										4
									
								
								internal/nodes/request.go
									
									
									
									
									
										Normal file
									
								
							@@ -0,0 +1,4 @@
 | 
			
		||||
package nodes
 | 
			
		||||
 | 
			
		||||
type Request struct {
 | 
			
		||||
}
 | 
			
		||||
		Reference in New Issue
	
	Block a user