mirror of https://github.com/ginuerzh/gost
10 changed files with 230 additions and 0 deletions
@ -0,0 +1,10 @@ |
|||||
|
package gost |
||||
|
|
||||
|
import "net" |
||||
|
|
||||
|
// Client represents a node client
|
||||
|
type Client interface { |
||||
|
Connect() (net.Conn, error) |
||||
|
Handshake(conn net.Conn) (net.Conn, error) |
||||
|
Dial(conn net.Conn, addr string) (net.Conn, error) |
||||
|
} |
||||
@ -0,0 +1,77 @@ |
|||||
|
package gost |
||||
|
|
||||
|
import ( |
||||
|
"log" |
||||
|
"reflect" |
||||
|
) |
||||
|
|
||||
|
// Options holds options of node
|
||||
|
type Options interface { |
||||
|
Get(opt string) (v interface{}) |
||||
|
Set(opt string, v interface{}) |
||||
|
} |
||||
|
|
||||
|
type Option func(Options) |
||||
|
|
||||
|
type DefaultOptions struct { |
||||
|
Addr string `opt:"addr"` // [host]:port
|
||||
|
Protocol string `opt:"protocol"` // protocol: http/socks5/ss
|
||||
|
Transport string `opt:"transport"` // transport: ws/wss/tls/http2/tcp/udp/rtcp/rudp
|
||||
|
} |
||||
|
|
||||
|
func (o *DefaultOptions) Get(opt string) interface{} { |
||||
|
return GetOption(o, opt) |
||||
|
} |
||||
|
|
||||
|
func (o *DefaultOptions) Set(opt string, v interface{}) { |
||||
|
SetOption(o, opt, v) |
||||
|
} |
||||
|
|
||||
|
func AddrOption(a string) Option { |
||||
|
return func(opts Options) { |
||||
|
SetOption(opts, "addr", a) |
||||
|
} |
||||
|
} |
||||
|
|
||||
|
func ProtocolOption(p string) Option { |
||||
|
return func(opts Options) { |
||||
|
SetOption(opts, "protocol", p) |
||||
|
} |
||||
|
} |
||||
|
|
||||
|
func TransportOption(t string) Option { |
||||
|
return func(opts Options) { |
||||
|
SetOption(opts, "transport", t) |
||||
|
} |
||||
|
} |
||||
|
|
||||
|
func GetOption(i interface{}, opt string) interface{} { |
||||
|
ps := reflect.ValueOf(i) |
||||
|
if ps.Kind() != reflect.Ptr && ps.Kind() != reflect.Interface { |
||||
|
return nil |
||||
|
} |
||||
|
s := ps.Elem() |
||||
|
for n := 0; n < s.NumField(); n++ { |
||||
|
log.Println("tag:", s.Type().Field(n).Tag.Get("opt")) |
||||
|
if opt == s.Type().Field(n).Tag.Get("opt") && s.Field(n).CanInterface() { |
||||
|
// return s.Field(n).Interface()
|
||||
|
} |
||||
|
} |
||||
|
return nil |
||||
|
} |
||||
|
|
||||
|
func SetOption(i interface{}, opt string, v interface{}) { |
||||
|
ps := reflect.ValueOf(i) |
||||
|
if ps.Kind() != reflect.Ptr || ps.Kind() != reflect.Interface { |
||||
|
return |
||||
|
} |
||||
|
s := ps.Elem() |
||||
|
|
||||
|
for n := 0; n < s.NumField(); n++ { |
||||
|
if opt == s.Type().Field(n).Tag.Get("opt") && |
||||
|
s.Field(n).IsValid() && s.Field(n).CanSet() { |
||||
|
s.Field(n).Set(reflect.ValueOf(v)) |
||||
|
return |
||||
|
} |
||||
|
} |
||||
|
} |
||||
@ -0,0 +1,18 @@ |
|||||
|
package tcp |
||||
|
|
||||
|
import "net" |
||||
|
|
||||
|
type nodeClient struct { |
||||
|
} |
||||
|
|
||||
|
func (c *nodeClient) Connect() (net.Conn, error) { |
||||
|
return nil, nil |
||||
|
} |
||||
|
|
||||
|
func (c *nodeClient) Handshake(conn net.Conn) (net.Conn, error) { |
||||
|
return conn, nil |
||||
|
} |
||||
|
|
||||
|
func (c *nodeClient) Dial(conn net.Conn, addr string) (net.Conn, error) { |
||||
|
return nil, nil |
||||
|
} |
||||
@ -0,0 +1,43 @@ |
|||||
|
package tcp |
||||
|
|
||||
|
import ( |
||||
|
"github.com/ginuerzh/gost" |
||||
|
) |
||||
|
|
||||
|
type tcpNode struct { |
||||
|
options *tcpNodeOptions |
||||
|
client *nodeClient |
||||
|
server *nodeServer |
||||
|
} |
||||
|
|
||||
|
// NewNode creates a tcpNode with options
|
||||
|
func NewNode(opts ...gost.Option) gost.Node { |
||||
|
node := &tcpNode{ |
||||
|
options: new(tcpNodeOptions), |
||||
|
} |
||||
|
for _, opt := range opts { |
||||
|
opt(node.options) |
||||
|
} |
||||
|
|
||||
|
return node |
||||
|
} |
||||
|
|
||||
|
func (node *tcpNode) Init(opts ...gost.Option) error { |
||||
|
for _, opt := range opts { |
||||
|
opt(node.options) |
||||
|
} |
||||
|
|
||||
|
return nil |
||||
|
} |
||||
|
|
||||
|
func (node *tcpNode) Client() gost.Client { |
||||
|
return node.client |
||||
|
} |
||||
|
|
||||
|
func (node *tcpNode) Server() gost.Server { |
||||
|
return node.server |
||||
|
} |
||||
|
|
||||
|
func (node *tcpNode) Options() gost.Options { |
||||
|
return node.options |
||||
|
} |
||||
@ -0,0 +1,26 @@ |
|||||
|
package tcp |
||||
|
|
||||
|
import ( |
||||
|
"net/url" |
||||
|
|
||||
|
"github.com/ginuerzh/gost" |
||||
|
) |
||||
|
|
||||
|
type tcpNodeOptions struct { |
||||
|
*gost.DefaultOptions |
||||
|
Users []url.Userinfo `opt:"users"` // authentication for proxy
|
||||
|
} |
||||
|
|
||||
|
func (o *tcpNodeOptions) Get(opt string) interface{} { |
||||
|
return gost.GetOption(o, opt) |
||||
|
} |
||||
|
|
||||
|
func (o *tcpNodeOptions) Set(opt string, v interface{}) { |
||||
|
gost.SetOption(o, opt, v) |
||||
|
} |
||||
|
|
||||
|
func UsersOption(users ...url.Userinfo) gost.Option { |
||||
|
return func(opts gost.Options) { |
||||
|
gost.SetOption(opts, "users", users) |
||||
|
} |
||||
|
} |
||||
@ -0,0 +1,31 @@ |
|||||
|
package tcp |
||||
|
|
||||
|
import "testing" |
||||
|
import "net/url" |
||||
|
import "reflect" |
||||
|
|
||||
|
var tests = []struct { |
||||
|
Opt string |
||||
|
Value interface{} |
||||
|
}{ |
||||
|
{"addr", "localhost:8080"}, |
||||
|
{"protocol", "http"}, |
||||
|
{"transport", "tcp"}, |
||||
|
{"users", []url.Userinfo{*url.UserPassword("admin", "123456")}}, |
||||
|
} |
||||
|
|
||||
|
func TestOptions(t *testing.T) { |
||||
|
opts := new(tcpNodeOptions) |
||||
|
for _, test := range tests { |
||||
|
opts.Set(test.Opt, test.Value) |
||||
|
v := opts.Get(test.Opt) |
||||
|
if !reflect.DeepEqual(v, test.Value) { |
||||
|
t.Log("not equal:", test.Opt, v) |
||||
|
t.Fail() |
||||
|
} |
||||
|
} |
||||
|
t.Log("addr:", opts.Addr) |
||||
|
t.Log("protocol:", opts.Protocol) |
||||
|
t.Log("transport:", opts.Transport) |
||||
|
t.Log("users:", opts.Users) |
||||
|
} |
||||
@ -0,0 +1,8 @@ |
|||||
|
package tcp |
||||
|
|
||||
|
type nodeServer struct { |
||||
|
} |
||||
|
|
||||
|
func (s *nodeServer) Run() error { |
||||
|
return nil |
||||
|
} |
||||
Loading…
Reference in new issue