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