add new interfaces

This commit is contained in:
rui.zheng 2017-07-17 23:21:46 +08:00
parent 791bd63dd5
commit eb99d97f71
10 changed files with 230 additions and 0 deletions

View File

@ -556,3 +556,7 @@ func (c *ProxyChain) getQuicConn(header http.Header) (net.Conn, error) {
conn.remoteAddr, _ = net.ResolveUDPAddr("udp", quicNode.Addr)
return conn, nil
}
type Chain struct {
nodes []Node
}

10
client.go Normal file
View File

@ -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)
}

View File

@ -211,3 +211,11 @@ func (node *ProxyNode) keyFile() string {
func (node ProxyNode) String() string {
return fmt.Sprintf("transport: %s, protocol: %s, addr: %s, whitelist: %v, blacklist: %v", node.Transport, node.Protocol, node.Addr, node.Whitelist, node.Blacklist)
}
// Node represents a proxy node
type Node interface {
Init(opts ...Option) error
Client() Client
Server() Server
Options() Options
}

77
options.go Normal file
View File

@ -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
}
}
}

View File

@ -295,3 +295,8 @@ func (_ *ProxyServer) transport(conn1, conn2 net.Conn) (err error) {
return
}
// Server represents a node server
type Server interface {
Run() error
}

18
tcp/client.go Normal file
View File

@ -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
}

43
tcp/node.go Normal file
View File

@ -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
}

26
tcp/options.go Normal file
View File

@ -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)
}
}

31
tcp/options_test.go Normal file
View File

@ -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)
}

8
tcp/server.go Normal file
View File

@ -0,0 +1,8 @@
package tcp
type nodeServer struct {
}
func (s *nodeServer) Run() error {
return nil
}