add tun listener

This commit is contained in:
ginuerzh 2021-12-19 23:20:35 +08:00
parent 34d6e393a1
commit a853d99d92
18 changed files with 584 additions and 70 deletions

View File

@ -60,6 +60,7 @@ import (
_ "github.com/go-gost/gost/pkg/listener/tcp" _ "github.com/go-gost/gost/pkg/listener/tcp"
_ "github.com/go-gost/gost/pkg/listener/tls" _ "github.com/go-gost/gost/pkg/listener/tls"
_ "github.com/go-gost/gost/pkg/listener/tls/mux" _ "github.com/go-gost/gost/pkg/listener/tls/mux"
_ "github.com/go-gost/gost/pkg/listener/tun"
_ "github.com/go-gost/gost/pkg/listener/udp" _ "github.com/go-gost/gost/pkg/listener/udp"
_ "github.com/go-gost/gost/pkg/listener/ws" _ "github.com/go-gost/gost/pkg/listener/ws"
_ "github.com/go-gost/gost/pkg/listener/ws/mux" _ "github.com/go-gost/gost/pkg/listener/ws/mux"

4
go.mod
View File

@ -25,6 +25,7 @@ require (
github.com/magiconair/properties v1.8.5 // indirect github.com/magiconair/properties v1.8.5 // indirect
github.com/marten-seemann/qtls-go1-16 v0.1.4 // indirect github.com/marten-seemann/qtls-go1-16 v0.1.4 // indirect
github.com/marten-seemann/qtls-go1-17 v0.1.0 // indirect github.com/marten-seemann/qtls-go1-17 v0.1.0 // indirect
github.com/milosgajdos/tenus v0.0.3
github.com/mitchellh/mapstructure v1.4.2 // indirect github.com/mitchellh/mapstructure v1.4.2 // indirect
github.com/mmcloughlin/avo v0.0.0-20200803215136-443f81d77104 // indirect github.com/mmcloughlin/avo v0.0.0-20200803215136-443f81d77104 // indirect
github.com/nxadm/tail v1.4.8 // indirect github.com/nxadm/tail v1.4.8 // indirect
@ -35,6 +36,7 @@ require (
github.com/shadowsocks/go-shadowsocks2 v0.1.4 github.com/shadowsocks/go-shadowsocks2 v0.1.4
github.com/shadowsocks/shadowsocks-go v0.0.0-20200409064450-3e585ff90601 github.com/shadowsocks/shadowsocks-go v0.0.0-20200409064450-3e585ff90601
github.com/sirupsen/logrus v1.8.1 github.com/sirupsen/logrus v1.8.1
github.com/songgao/water v0.0.0-20200317203138-2b4b6d7c09d8
github.com/spf13/afero v1.6.0 // indirect github.com/spf13/afero v1.6.0 // indirect
github.com/spf13/cast v1.4.1 // indirect github.com/spf13/cast v1.4.1 // indirect
github.com/spf13/jwalterweatherman v1.1.0 // indirect github.com/spf13/jwalterweatherman v1.1.0 // indirect
@ -58,3 +60,5 @@ require (
gopkg.in/tomb.v1 v1.0.0-20141024135613-dd632973f1e7 // indirect gopkg.in/tomb.v1 v1.0.0-20141024135613-dd632973f1e7 // indirect
gopkg.in/yaml.v2 v2.4.0 gopkg.in/yaml.v2 v2.4.0
) )
require github.com/docker/libcontainer v2.2.1+incompatible // indirect

9
go.sum
View File

@ -88,6 +88,8 @@ github.com/coreos/go-systemd/v22 v22.3.2/go.mod h1:Y58oyj3AT4RCenI/lSvhwexgC+NSV
github.com/davecgh/go-spew v1.1.0/go.mod h1:J7Y8YcW2NihsgmVo/mv3lAwl/skON4iLHjSsI+c5H38= github.com/davecgh/go-spew v1.1.0/go.mod h1:J7Y8YcW2NihsgmVo/mv3lAwl/skON4iLHjSsI+c5H38=
github.com/davecgh/go-spew v1.1.1 h1:vj9j/u1bqnvCEfJOwUhtlOARqs3+rkHYY13jYWTU97c= github.com/davecgh/go-spew v1.1.1 h1:vj9j/u1bqnvCEfJOwUhtlOARqs3+rkHYY13jYWTU97c=
github.com/davecgh/go-spew v1.1.1/go.mod h1:J7Y8YcW2NihsgmVo/mv3lAwl/skON4iLHjSsI+c5H38= github.com/davecgh/go-spew v1.1.1/go.mod h1:J7Y8YcW2NihsgmVo/mv3lAwl/skON4iLHjSsI+c5H38=
github.com/docker/libcontainer v2.2.1+incompatible h1:++SbbkCw+X8vAd4j2gOCzZ2Nn7s2xFALTf7LZKmM1/0=
github.com/docker/libcontainer v2.2.1+incompatible/go.mod h1:osvj61pYsqhNCMLGX31xr7klUBhHb/ZBuXS0o1Fvwbw=
github.com/dustin/go-humanize v1.0.0/go.mod h1:HtrtbFcZ19U5GC7JDqmcUSB87Iq5E25KnS6fMYU6eOk= github.com/dustin/go-humanize v1.0.0/go.mod h1:HtrtbFcZ19U5GC7JDqmcUSB87Iq5E25KnS6fMYU6eOk=
github.com/envoyproxy/go-control-plane v0.9.0/go.mod h1:YTl/9mNaCwkRvm6d1a2C3ymFceY/DCBVvsKhRF0iEA4= github.com/envoyproxy/go-control-plane v0.9.0/go.mod h1:YTl/9mNaCwkRvm6d1a2C3ymFceY/DCBVvsKhRF0iEA4=
github.com/envoyproxy/go-control-plane v0.9.1-0.20191026205805-5f8ba28d4473/go.mod h1:YTl/9mNaCwkRvm6d1a2C3ymFceY/DCBVvsKhRF0iEA4= github.com/envoyproxy/go-control-plane v0.9.1-0.20191026205805-5f8ba28d4473/go.mod h1:YTl/9mNaCwkRvm6d1a2C3ymFceY/DCBVvsKhRF0iEA4=
@ -280,6 +282,8 @@ github.com/matttproud/golang_protobuf_extensions v1.0.1/go.mod h1:D8He9yQNgCq6Z5
github.com/microcosm-cc/bluemonday v1.0.1/go.mod h1:hsXNsILzKxV+sX77C5b8FSuKF00vh2OMYv+xgHpAMF4= github.com/microcosm-cc/bluemonday v1.0.1/go.mod h1:hsXNsILzKxV+sX77C5b8FSuKF00vh2OMYv+xgHpAMF4=
github.com/miekg/dns v1.0.14/go.mod h1:W1PPwlIAgtquWBMBEV9nkV9Cazfe8ScdGz/Lj7v3Nrg= github.com/miekg/dns v1.0.14/go.mod h1:W1PPwlIAgtquWBMBEV9nkV9Cazfe8ScdGz/Lj7v3Nrg=
github.com/miekg/dns v1.1.26/go.mod h1:bPDLeHnStXmXAq1m/Ch/hvfNHr14JKNPMBo3VZKjuso= github.com/miekg/dns v1.1.26/go.mod h1:bPDLeHnStXmXAq1m/Ch/hvfNHr14JKNPMBo3VZKjuso=
github.com/milosgajdos/tenus v0.0.3 h1:jmaJzwaY1DUyYVD0lM4U+uvP2kkEg1VahDqRFxIkVBE=
github.com/milosgajdos/tenus v0.0.3/go.mod h1:eIjx29vNeDOYWJuCnaHY2r4fq5egetV26ry3on7p8qY=
github.com/mitchellh/cli v1.1.0/go.mod h1:xcISNoH86gajksDmfB23e/pu+B+GeFRMYmoHXxx3xhI= github.com/mitchellh/cli v1.1.0/go.mod h1:xcISNoH86gajksDmfB23e/pu+B+GeFRMYmoHXxx3xhI=
github.com/mitchellh/go-homedir v1.1.0/go.mod h1:SfyaCUpYCn1Vlf4IUYiD9fPX4A5wJrkLzIz1N1q0pr0= github.com/mitchellh/go-homedir v1.1.0/go.mod h1:SfyaCUpYCn1Vlf4IUYiD9fPX4A5wJrkLzIz1N1q0pr0=
github.com/mitchellh/go-testing-interface v1.0.0/go.mod h1:kRemZodwjscx+RGhAo8eIhFbs2+BFgRtFPeD/KE+zxI= github.com/mitchellh/go-testing-interface v1.0.0/go.mod h1:kRemZodwjscx+RGhAo8eIhFbs2+BFgRtFPeD/KE+zxI=
@ -362,6 +366,8 @@ github.com/shurcooL/users v0.0.0-20180125191416-49c67e49c537/go.mod h1:QJTqeLYED
github.com/shurcooL/webdavfs v0.0.0-20170829043945-18c3829fa133/go.mod h1:hKmq5kWdCj2z2KEozexVbfEZIWiTjhE0+UjmZgPqehw= github.com/shurcooL/webdavfs v0.0.0-20170829043945-18c3829fa133/go.mod h1:hKmq5kWdCj2z2KEozexVbfEZIWiTjhE0+UjmZgPqehw=
github.com/sirupsen/logrus v1.8.1 h1:dJKuHgqk1NNQlqoA6BTlM1Wf9DOH3NBjQyu0h9+AZZE= github.com/sirupsen/logrus v1.8.1 h1:dJKuHgqk1NNQlqoA6BTlM1Wf9DOH3NBjQyu0h9+AZZE=
github.com/sirupsen/logrus v1.8.1/go.mod h1:yWOB1SBYBC5VeMP7gHvWumXLIWorT60ONWic61uBYv0= github.com/sirupsen/logrus v1.8.1/go.mod h1:yWOB1SBYBC5VeMP7gHvWumXLIWorT60ONWic61uBYv0=
github.com/songgao/water v0.0.0-20200317203138-2b4b6d7c09d8 h1:TG/diQgUe0pntT/2D9tmUCz4VNwm9MfrtPr0SU2qSX8=
github.com/songgao/water v0.0.0-20200317203138-2b4b6d7c09d8/go.mod h1:P5HUIBuIWKbyjl083/loAegFkfbFNx5i2qEP4CNbm7E=
github.com/sourcegraph/annotate v0.0.0-20160123013949-f4cad6c6324d/go.mod h1:UdhH50NIW0fCiwBSr0co2m7BnFLdv4fQTgdqdJTHFeE= github.com/sourcegraph/annotate v0.0.0-20160123013949-f4cad6c6324d/go.mod h1:UdhH50NIW0fCiwBSr0co2m7BnFLdv4fQTgdqdJTHFeE=
github.com/sourcegraph/syntaxhighlight v0.0.0-20170531221838-bd320f5d308e/go.mod h1:HuIsMU8RRBOtsCgI77wP899iHVBQpCmg4ErYMZB+2IA= github.com/sourcegraph/syntaxhighlight v0.0.0-20170531221838-bd320f5d308e/go.mod h1:HuIsMU8RRBOtsCgI77wP899iHVBQpCmg4ErYMZB+2IA=
github.com/spaolacci/murmur3 v0.0.0-20180118202830-f09979ecbc72/go.mod h1:JwIasOWyU6f++ZhiEuf87xNszmSA2myDM2Kzu9HwQUA= github.com/spaolacci/murmur3 v0.0.0-20180118202830-f09979ecbc72/go.mod h1:JwIasOWyU6f++ZhiEuf87xNszmSA2myDM2Kzu9HwQUA=
@ -440,7 +446,6 @@ golang.org/x/crypto v0.0.0-20200221231518-2aa609cf4a9d/go.mod h1:LzIPMQfyMNhhGPh
golang.org/x/crypto v0.0.0-20200622213623-75b288015ac9/go.mod h1:LzIPMQfyMNhhGPhUkYOs5KpL4U8rLKemX1yGLhDgUto= golang.org/x/crypto v0.0.0-20200622213623-75b288015ac9/go.mod h1:LzIPMQfyMNhhGPhUkYOs5KpL4U8rLKemX1yGLhDgUto=
golang.org/x/crypto v0.0.0-20200728195943-123391ffb6de/go.mod h1:LzIPMQfyMNhhGPhUkYOs5KpL4U8rLKemX1yGLhDgUto= golang.org/x/crypto v0.0.0-20200728195943-123391ffb6de/go.mod h1:LzIPMQfyMNhhGPhUkYOs5KpL4U8rLKemX1yGLhDgUto=
golang.org/x/crypto v0.0.0-20210220033148-5ea612d1eb83/go.mod h1:jdWPYTVW3xRLrWPugEBEK3UY2ZEsg3UU495nc5E+M+I= golang.org/x/crypto v0.0.0-20210220033148-5ea612d1eb83/go.mod h1:jdWPYTVW3xRLrWPugEBEK3UY2ZEsg3UU495nc5E+M+I=
golang.org/x/crypto v0.0.0-20210817164053-32db794688a5 h1:HWj/xjIHfjYU5nVXpTM0s39J9CbLn7Cc5a7IC5rwsMQ=
golang.org/x/crypto v0.0.0-20210817164053-32db794688a5/go.mod h1:GvvjBRRGRdwPK5ydBHafDWAxML/pGHZbMvKqRZ5+Abc= golang.org/x/crypto v0.0.0-20210817164053-32db794688a5/go.mod h1:GvvjBRRGRdwPK5ydBHafDWAxML/pGHZbMvKqRZ5+Abc=
golang.org/x/crypto v0.0.0-20211215153901-e495a2d5b3d3 h1:0es+/5331RGQPcXlMfP+WrnIIS6dNnNRe0WB02W0F4M= golang.org/x/crypto v0.0.0-20211215153901-e495a2d5b3d3 h1:0es+/5331RGQPcXlMfP+WrnIIS6dNnNRe0WB02W0F4M=
golang.org/x/crypto v0.0.0-20211215153901-e495a2d5b3d3/go.mod h1:IxCIyHEi3zRg3s0A5j5BB6A9Jmi73HwBIUl50j+osU4= golang.org/x/crypto v0.0.0-20211215153901-e495a2d5b3d3/go.mod h1:IxCIyHEi3zRg3s0A5j5BB6A9Jmi73HwBIUl50j+osU4=
@ -524,6 +529,7 @@ golang.org/x/net v0.0.0-20210316092652-d523dce5a7f4/go.mod h1:RBQZq4jEuRlivfhVLd
golang.org/x/net v0.0.0-20210405180319-a5a99cb37ef4/go.mod h1:p54w0d4576C0XHj96bSt6lcn1PtDYWL6XObtHCRCNQM= golang.org/x/net v0.0.0-20210405180319-a5a99cb37ef4/go.mod h1:p54w0d4576C0XHj96bSt6lcn1PtDYWL6XObtHCRCNQM=
golang.org/x/net v0.0.0-20210428140749-89ef3d95e781/go.mod h1:OJAsFXCWl8Ukc7SiCT/9KSuxbyM7479/AVlXFRxuMCk= golang.org/x/net v0.0.0-20210428140749-89ef3d95e781/go.mod h1:OJAsFXCWl8Ukc7SiCT/9KSuxbyM7479/AVlXFRxuMCk=
golang.org/x/net v0.0.0-20210503060351-7fd8e65b6420/go.mod h1:9nx3DQGgdP8bBQD5qxJ1jj9UTztislL4KSBs9R2vV5Y= golang.org/x/net v0.0.0-20210503060351-7fd8e65b6420/go.mod h1:9nx3DQGgdP8bBQD5qxJ1jj9UTztislL4KSBs9R2vV5Y=
golang.org/x/net v0.0.0-20211112202133-69e39bad7dc2/go.mod h1:9nx3DQGgdP8bBQD5qxJ1jj9UTztislL4KSBs9R2vV5Y=
golang.org/x/net v0.0.0-20211209124913-491a49abca63 h1:iocB37TsdFuN6IBRZ+ry36wrkoV51/tl5vOWqkcPGvY= golang.org/x/net v0.0.0-20211209124913-491a49abca63 h1:iocB37TsdFuN6IBRZ+ry36wrkoV51/tl5vOWqkcPGvY=
golang.org/x/net v0.0.0-20211209124913-491a49abca63/go.mod h1:9nx3DQGgdP8bBQD5qxJ1jj9UTztislL4KSBs9R2vV5Y= golang.org/x/net v0.0.0-20211209124913-491a49abca63/go.mod h1:9nx3DQGgdP8bBQD5qxJ1jj9UTztislL4KSBs9R2vV5Y=
golang.org/x/oauth2 v0.0.0-20180821212333-d2e6202438be/go.mod h1:N/0e6XlmueqKjAGxoOufVs8QHGRruUQn6yWY3a++T0U= golang.org/x/oauth2 v0.0.0-20180821212333-d2e6202438be/go.mod h1:N/0e6XlmueqKjAGxoOufVs8QHGRruUQn6yWY3a++T0U=
@ -621,6 +627,7 @@ golang.org/x/sys v0.0.0-20210806184541-e5e7981a1069/go.mod h1:oPkhp1MJrh7nUepCBc
golang.org/x/sys v0.0.0-20210823070655-63515b42dcdf h1:2ucpDCmfkl8Bd/FsLtiD653Wf96cW37s+iGx93zsu4k= golang.org/x/sys v0.0.0-20210823070655-63515b42dcdf h1:2ucpDCmfkl8Bd/FsLtiD653Wf96cW37s+iGx93zsu4k=
golang.org/x/sys v0.0.0-20210823070655-63515b42dcdf/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg= golang.org/x/sys v0.0.0-20210823070655-63515b42dcdf/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg=
golang.org/x/term v0.0.0-20201117132131-f5c789dd3221/go.mod h1:Nr5EML6q2oocZ2LXRh80K7BxOlk5/8JxuGnuhpl+muw= golang.org/x/term v0.0.0-20201117132131-f5c789dd3221/go.mod h1:Nr5EML6q2oocZ2LXRh80K7BxOlk5/8JxuGnuhpl+muw=
golang.org/x/term v0.0.0-20201126162022-7de9c90e9dd1 h1:v+OssWQX+hTHEmOBgwxdZxK4zHq3yOs8F9J7mk0PY8E=
golang.org/x/term v0.0.0-20201126162022-7de9c90e9dd1/go.mod h1:bj7SfCRtBDWHUb9snDiAeCFNEtKQo2Wmx5Cou7ajbmo= golang.org/x/term v0.0.0-20201126162022-7de9c90e9dd1/go.mod h1:bj7SfCRtBDWHUb9snDiAeCFNEtKQo2Wmx5Cou7ajbmo=
golang.org/x/text v0.0.0-20170915032832-14c0d48ead0c/go.mod h1:NqM8EUOU14njkJ3fqMW+pc6Ldnwhi/IjpwHt7yyuwOQ= golang.org/x/text v0.0.0-20170915032832-14c0d48ead0c/go.mod h1:NqM8EUOU14njkJ3fqMW+pc6Ldnwhi/IjpwHt7yyuwOQ=
golang.org/x/text v0.3.0/go.mod h1:NqM8EUOU14njkJ3fqMW+pc6Ldnwhi/IjpwHt7yyuwOQ= golang.org/x/text v0.3.0/go.mod h1:NqM8EUOU14njkJ3fqMW+pc6Ldnwhi/IjpwHt7yyuwOQ=

View File

@ -1,13 +1,12 @@
package http package http
import ( import (
"fmt"
"net/http" "net/http"
"net/url" "net/url"
"strings" "strings"
"time" "time"
md "github.com/go-gost/gost/pkg/metadata" mdata "github.com/go-gost/gost/pkg/metadata"
) )
type metadata struct { type metadata struct {
@ -16,7 +15,7 @@ type metadata struct {
header http.Header header http.Header
} }
func (c *httpConnector) parseMetadata(md md.Metadata) (err error) { func (c *httpConnector) parseMetadata(md mdata.Metadata) (err error) {
const ( const (
connectTimeout = "timeout" connectTimeout = "timeout"
user = "user" user = "user"
@ -34,12 +33,12 @@ func (c *httpConnector) parseMetadata(md md.Metadata) (err error) {
} }
} }
if mm, _ := md.Get(header).(map[interface{}]interface{}); len(mm) > 0 { if mm := mdata.GetStringMapString(md, header); len(mm) > 0 {
h := http.Header{} hd := http.Header{}
for k, v := range mm { for k, v := range mm {
h.Add(fmt.Sprintf("%v", k), fmt.Sprintf("%v", v)) hd.Add(k, v)
} }
c.md.header = h c.md.header = hd
} }
return return

View File

@ -1,12 +1,11 @@
package http package http
import ( import (
"fmt"
"net/http" "net/http"
"strings" "strings"
"github.com/go-gost/gost/pkg/auth" "github.com/go-gost/gost/pkg/auth"
md "github.com/go-gost/gost/pkg/metadata" mdata "github.com/go-gost/gost/pkg/metadata"
) )
type metadata struct { type metadata struct {
@ -18,7 +17,7 @@ type metadata struct {
header http.Header header http.Header
} }
func (h *httpHandler) parseMetadata(md md.Metadata) error { func (h *httpHandler) parseMetadata(md mdata.Metadata) error {
const ( const (
header = "header" header = "header"
users = "users" users = "users"
@ -29,25 +28,23 @@ func (h *httpHandler) parseMetadata(md md.Metadata) error {
enableUDP = "udp" enableUDP = "udp"
) )
if v, _ := md.Get(users).([]interface{}); len(v) > 0 { if auths := md.GetStrings(users); len(auths) > 0 {
authenticator := auth.NewLocalAuthenticator(nil) authenticator := auth.NewLocalAuthenticator(nil)
for _, auth := range v { for _, auth := range auths {
if s, _ := auth.(string); s != "" { ss := strings.SplitN(auth, ":", 2)
ss := strings.SplitN(s, ":", 2) if len(ss) == 1 {
if len(ss) == 1 { authenticator.Add(ss[0], "")
authenticator.Add(ss[0], "") } else {
} else { authenticator.Add(ss[0], ss[1])
authenticator.Add(ss[0], ss[1])
}
} }
} }
h.md.authenticator = authenticator h.md.authenticator = authenticator
} }
if mm, _ := md.Get(header).(map[interface{}]interface{}); len(mm) > 0 { if mm := mdata.GetStringMapString(md, header); len(mm) > 0 {
hd := http.Header{} hd := http.Header{}
for k, v := range mm { for k, v := range mm {
hd.Add(fmt.Sprintf("%v", k), fmt.Sprintf("%v", v)) hd.Add(k, v)
} }
h.md.header = hd h.md.header = hd
} }

View File

@ -29,16 +29,14 @@ func (h *http2Handler) parseMetadata(md md.Metadata) error {
h.md.proxyAgent = md.GetString(proxyAgent) h.md.proxyAgent = md.GetString(proxyAgent)
if v, _ := md.Get(users).([]interface{}); len(v) > 0 { if auths := md.GetStrings(users); len(auths) > 0 {
authenticator := auth.NewLocalAuthenticator(nil) authenticator := auth.NewLocalAuthenticator(nil)
for _, auth := range v { for _, auth := range auths {
if s, _ := auth.(string); s != "" { ss := strings.SplitN(auth, ":", 2)
ss := strings.SplitN(s, ":", 2) if len(ss) == 1 {
if len(ss) == 1 { authenticator.Add(ss[0], "")
authenticator.Add(ss[0], "") } else {
} else { authenticator.Add(ss[0], ss[1])
authenticator.Add(ss[0], ss[1])
}
} }
} }
h.md.authenticator = authenticator h.md.authenticator = authenticator

View File

@ -27,20 +27,19 @@ func (h *relayHandler) parseMetadata(md md.Metadata) (err error) {
noDelay = "nodelay" noDelay = "nodelay"
) )
if v, _ := md.Get(users).([]interface{}); len(v) > 0 { if auths := md.GetStrings(users); len(auths) > 0 {
authenticator := auth.NewLocalAuthenticator(nil) authenticator := auth.NewLocalAuthenticator(nil)
for _, auth := range v { for _, auth := range auths {
if s, _ := auth.(string); s != "" { ss := strings.SplitN(auth, ":", 2)
ss := strings.SplitN(s, ":", 2) if len(ss) == 1 {
if len(ss) == 1 { authenticator.Add(ss[0], "")
authenticator.Add(ss[0], "") } else {
} else { authenticator.Add(ss[0], ss[1])
authenticator.Add(ss[0], ss[1])
}
} }
} }
h.md.authenticator = authenticator h.md.authenticator = authenticator
} }
h.md.readTimeout = md.GetDuration(readTimeout) h.md.readTimeout = md.GetDuration(readTimeout)
h.md.retryCount = md.GetInt(retryCount) h.md.retryCount = md.GetInt(retryCount)
h.md.enableBind = md.GetBool(enableBind) h.md.enableBind = md.GetBool(enableBind)

View File

@ -1,27 +1,26 @@
package http package http
import ( import (
"fmt"
"net/http" "net/http"
md "github.com/go-gost/gost/pkg/metadata" mdata "github.com/go-gost/gost/pkg/metadata"
) )
type metadata struct { type metadata struct {
header http.Header header http.Header
} }
func (l *obfsListener) parseMetadata(md md.Metadata) (err error) { func (l *obfsListener) parseMetadata(md mdata.Metadata) (err error) {
const ( const (
header = "header" header = "header"
) )
if mm, _ := md.Get(header).(map[interface{}]interface{}); len(mm) > 0 { if mm := mdata.GetStringMapString(md, header); len(mm) > 0 {
h := http.Header{} hd := http.Header{}
for k, v := range mm { for k, v := range mm {
h.Add(fmt.Sprintf("%v", k), fmt.Sprintf("%v", v)) hd.Add(k, v)
} }
l.md.header = h l.md.header = hd
} }
return return
} }

46
pkg/listener/tun/conn.go Normal file
View File

@ -0,0 +1,46 @@
package tun
import (
"errors"
"net"
"time"
"github.com/songgao/water"
)
type tunConn struct {
ifce *water.Interface
addr net.Addr
}
func (c *tunConn) Read(b []byte) (n int, err error) {
return c.ifce.Read(b)
}
func (c *tunConn) Write(b []byte) (n int, err error) {
return c.ifce.Write(b)
}
func (c *tunConn) Close() (err error) {
return c.ifce.Close()
}
func (c *tunConn) LocalAddr() net.Addr {
return c.addr
}
func (c *tunConn) RemoteAddr() net.Addr {
return &net.IPAddr{}
}
func (c *tunConn) SetDeadline(t time.Time) error {
return &net.OpError{Op: "set", Net: "tuntap", Source: nil, Addr: nil, Err: errors.New("deadline not supported")}
}
func (c *tunConn) SetReadDeadline(t time.Time) error {
return &net.OpError{Op: "set", Net: "tuntap", Source: nil, Addr: nil, Err: errors.New("deadline not supported")}
}
func (c *tunConn) SetWriteDeadline(t time.Time) error {
return &net.OpError{Op: "set", Net: "tuntap", Source: nil, Addr: nil, Err: errors.New("deadline not supported")}
}

View File

@ -0,0 +1,87 @@
package tun
import (
"net"
"github.com/go-gost/gost/pkg/listener"
"github.com/go-gost/gost/pkg/logger"
md "github.com/go-gost/gost/pkg/metadata"
"github.com/go-gost/gost/pkg/registry"
)
// ipRoute is an IP routing entry
type ipRoute struct {
Dest net.IPNet
Gateway net.IP
}
func init() {
registry.RegisterListener("tun", NewListener)
}
type tunListener struct {
saddr string
addr net.Addr
cqueue chan net.Conn
closed chan struct{}
logger logger.Logger
md metadata
}
func NewListener(opts ...listener.Option) listener.Listener {
options := &listener.Options{}
for _, opt := range opts {
opt(options)
}
return &tunListener{
saddr: options.Addr,
logger: options.Logger,
}
}
func (l *tunListener) Init(md md.Metadata) (err error) {
if err = l.parseMetadata(md); err != nil {
return
}
conn, ifce, err := l.createTun()
if err != nil {
return
}
addrs, _ := ifce.Addrs()
l.logger.Infof("name: %s, net: %s, mtu: %d, addrs: %s",
ifce.Name, conn.LocalAddr(), ifce.MTU, addrs)
l.addr = conn.LocalAddr()
l.cqueue = make(chan net.Conn, 1)
l.closed = make(chan struct{})
l.cqueue <- conn
return
}
func (l *tunListener) Accept() (net.Conn, error) {
select {
case conn := <-l.cqueue:
return conn, nil
case <-l.closed:
}
return nil, listener.ErrClosed
}
func (l *tunListener) Addr() net.Addr {
return l.addr
}
func (l *tunListener) Close() error {
select {
case <-l.closed:
return net.ErrClosed
default:
close(l.closed)
}
return nil
}

View File

@ -0,0 +1,70 @@
package tun
import (
"net"
"strings"
md "github.com/go-gost/gost/pkg/metadata"
)
const (
DefaultMTU = 1350
)
type metadata struct {
name string
net string
// peer addr of point-to-point on MacOS
peer string
mtu int
routes []ipRoute
// default gateway
gateway string
tcp bool
}
func (l *tunListener) parseMetadata(md md.Metadata) (err error) {
const (
name = "name"
netKey = "net"
peer = "peer"
mtu = "mtu"
routes = "routes"
gateway = "gw"
tcp = "tcp"
)
l.md.name = md.GetString(name)
l.md.net = md.GetString(netKey)
l.md.peer = md.GetString(peer)
l.md.mtu = md.GetInt(mtu)
if l.md.mtu <= 0 {
l.md.mtu = DefaultMTU
}
l.md.gateway = md.GetString(gateway)
l.md.tcp = md.GetBool(tcp)
gw := net.ParseIP(l.md.gateway)
for _, s := range md.GetStrings(routes) {
ss := strings.SplitN(s, " ", 2)
if len(ss) == 2 {
var route ipRoute
_, ipNet, _ := net.ParseCIDR(strings.TrimSpace(ss[0]))
if ipNet == nil {
continue
}
route.Dest = *ipNet
route.Gateway = net.ParseIP(ss[1])
if route.Gateway == nil {
route.Gateway = gw
}
l.md.routes = append(l.md.routes, route)
}
}
return
}

View File

@ -0,0 +1,65 @@
package tun
import (
"fmt"
"net"
"os/exec"
"strings"
"github.com/songgao/water"
)
func (l *tunListener) createTun() (conn net.Conn, itf *net.Interface, err error) {
ip, _, err := net.ParseCIDR(l.md.net)
if err != nil {
return
}
ifce, err := water.New(water.Config{
DeviceType: water.TUN,
})
if err != nil {
return
}
peer := l.md.peer
if peer == "" {
peer = ip.String()
}
cmd := fmt.Sprintf("ifconfig %s inet %s %s mtu %d up",
ifce.Name(), l.md.net, l.md.peer, l.md.mtu)
l.logger.Debug(cmd)
args := strings.Split(cmd, " ")
if err = exec.Command(args[0], args[1:]...).Run(); err != nil {
return
}
if err = l.addRoutes(ifce.Name(), l.md.routes...); err != nil {
return
}
itf, err = net.InterfaceByName(ifce.Name())
if err != nil {
return
}
conn = &tunConn{
ifce: ifce,
addr: &net.IPAddr{IP: ip},
}
return
}
func (l *tunListener) addRoutes(ifName string, routes ...ipRoute) error {
for _, route := range routes {
cmd := fmt.Sprintf("route add -net %s -interface %s", route.Dest.String(), ifName)
l.logger.Debug(cmd)
args := strings.Split(cmd, " ")
if err := exec.Command(args[0], args[1:]...).Run(); err != nil {
return err
}
}
return nil
}

View File

@ -0,0 +1,75 @@
package tun
import (
"errors"
"net"
"syscall"
"github.com/docker/libcontainer/netlink"
"github.com/milosgajdos/tenus"
"github.com/songgao/water"
)
func (l *tunListener) createTun() (conn net.Conn, itf *net.Interface, err error) {
ip, ipNet, err := net.ParseCIDR(l.md.net)
if err != nil {
return
}
ifce, err := water.New(water.Config{
DeviceType: water.TUN,
PlatformSpecificParams: water.PlatformSpecificParams{
Name: l.md.name,
},
})
if err != nil {
return
}
link, err := tenus.NewLinkFrom(ifce.Name())
if err != nil {
return
}
l.logger.Debugf("ip link set dev %s mtu %d", ifce.Name(), l.md.mtu)
if err = link.SetLinkMTU(l.md.mtu); err != nil {
return
}
l.logger.Debugf("ip address add %s dev %s", l.md.net, ifce.Name())
if err = link.SetLinkIp(ip, ipNet); err != nil {
return
}
l.logger.Debugf("ip link set dev %s up", ifce.Name())
if err = link.SetLinkUp(); err != nil {
return
}
if err = l.addRoutes(ifce.Name(), l.md.routes...); err != nil {
return
}
itf, err = net.InterfaceByName(ifce.Name())
if err != nil {
return
}
conn = &tunConn{
ifce: ifce,
addr: &net.IPAddr{IP: ip},
}
return
}
func (l *tunListener) addRoutes(ifName string, routes ...ipRoute) error {
for _, route := range routes {
l.logger.Debugf("ip route add %s dev %s", route.Dest.String(), ifName)
if err := netlink.AddRoute(route.Dest.String(), "", "", ifName); err != nil && !errors.Is(err, syscall.EEXIST) {
return err
}
}
return nil
}

View File

@ -0,0 +1,62 @@
//go:build !linux && !windows && !darwin
package tun
import (
"fmt"
"net"
"os/exec"
"strings"
"github.com/songgao/water"
)
func (l *tunListener) createTun() (conn net.Conn, itf *net.Interface, err error) {
ip, _, err := net.ParseCIDR(l.md.net)
if err != nil {
return
}
ifce, err := water.New(water.Config{
DeviceType: water.TUN,
})
if err != nil {
return
}
cmd := fmt.Sprintf("ifconfig %s inet %s mtu %d up",
ifce.Name(), l.md.net, l.md.mtu)
l.logger.Debug(cmd)
args := strings.Split(cmd, " ")
if er := exec.Command(args[0], args[1:]...).Run(); er != nil {
err = fmt.Errorf("%s: %v", cmd, er)
return
}
if err = l.addRoutes(ifce.Name(), l.md.routes...); err != nil {
return
}
itf, err = net.InterfaceByName(ifce.Name())
if err != nil {
return
}
conn = &tunConn{
ifce: ifce,
addr: &net.IPAddr{IP: ip},
}
return
}
func (l *tunListener) addRoutes(ifName string, routes ...ipRoute) error {
for _, route := range routes {
cmd := fmt.Sprintf("route add -net %s -interface %s", route.Dest.String(), ifName)
l.logger.Debug(cmd)
args := strings.Split(cmd, " ")
if er := exec.Command(args[0], args[1:]...).Run(); er != nil {
return fmt.Errorf("%s: %v", cmd, er)
}
}
return nil
}

View File

@ -0,0 +1,85 @@
package tun
import (
"fmt"
"net"
"os/exec"
"strings"
"github.com/songgao/water"
)
func (l *tunListener) createTun() (conn net.Conn, itf *net.Interface, err error) {
ip, ipNet, err := net.ParseCIDR(l.md.net)
if err != nil {
return
}
ifce, err := water.New(water.Config{
DeviceType: water.TUN,
PlatformSpecificParams: water.PlatformSpecificParams{
ComponentID: "tap0901",
InterfaceName: l.md.name,
Network: l.md.net,
},
})
if err != nil {
return
}
cmd := fmt.Sprintf("netsh interface ip set address name=%s "+
"source=static addr=%s mask=%s gateway=none",
ifce.Name(), ip.String(), ipMask(ipNet.Mask))
l.logger.Debug(cmd)
args := strings.Split(cmd, " ")
if er := exec.Command(args[0], args[1:]...).Run(); er != nil {
err = fmt.Errorf("%s: %v", cmd, er)
return
}
if err = l.addRoutes(ifce.Name(), l.md.gateway, l.md.routes...); err != nil {
return
}
itf, err = net.InterfaceByName(ifce.Name())
if err != nil {
return
}
conn = &tunConn{
ifce: ifce,
addr: &net.IPAddr{IP: ip},
}
return
}
func (l *tunListener) addRoutes(ifName string, gw string, routes ...ipRoute) error {
for _, route := range routes {
l.deleteRoute(ifName, route.Dest.String())
cmd := fmt.Sprintf("netsh interface ip add route prefix=%s interface=%s store=active",
route.Dest.String(), ifName)
if gw != "" {
cmd += " nexthop=" + gw
}
l.logger.Debug(cmd)
args := strings.Split(cmd, " ")
if er := exec.Command(args[0], args[1:]...).Run(); er != nil {
return fmt.Errorf("%s: %v", cmd, er)
}
}
return nil
}
func (l *tunListener) deleteRoute(ifName string, route string) error {
cmd := fmt.Sprintf("netsh interface ip delete route prefix=%s interface=%s store=active",
route, ifName)
l.logger.Debug(cmd)
args := strings.Split(cmd, " ")
return exec.Command(args[0], args[1:]...).Run()
}
func ipMask(mask net.IPMask) string {
return fmt.Sprintf("%d.%d.%d.%d", mask[0], mask[1], mask[2], mask[3])
}

View File

@ -2,12 +2,11 @@ package ws
import ( import (
"crypto/tls" "crypto/tls"
"fmt"
"net/http" "net/http"
"time" "time"
tls_util "github.com/go-gost/gost/pkg/common/util/tls" tls_util "github.com/go-gost/gost/pkg/common/util/tls"
md "github.com/go-gost/gost/pkg/metadata" mdata "github.com/go-gost/gost/pkg/metadata"
) )
const ( const (
@ -29,7 +28,7 @@ type metadata struct {
header http.Header header http.Header
} }
func (l *wsListener) parseMetadata(md md.Metadata) (err error) { func (l *wsListener) parseMetadata(md mdata.Metadata) (err error) {
const ( const (
certFile = "certFile" certFile = "certFile"
keyFile = "keyFile" keyFile = "keyFile"
@ -72,13 +71,12 @@ func (l *wsListener) parseMetadata(md md.Metadata) (err error) {
l.md.writeBufferSize = md.GetInt(writeBufferSize) l.md.writeBufferSize = md.GetInt(writeBufferSize)
l.md.enableCompression = md.GetBool(enableCompression) l.md.enableCompression = md.GetBool(enableCompression)
if mm, _ := md.Get(header).(map[interface{}]interface{}); len(mm) > 0 { if mm := mdata.GetStringMapString(md, header); len(mm) > 0 {
h := http.Header{} hd := http.Header{}
for k, v := range mm { for k, v := range mm {
h.Add(fmt.Sprintf("%v", k), fmt.Sprintf("%v", v)) hd.Add(k, v)
} }
l.md.header = h l.md.header = hd
} }
return return
} }

View File

@ -2,12 +2,11 @@ package mux
import ( import (
"crypto/tls" "crypto/tls"
"fmt"
"net/http" "net/http"
"time" "time"
tls_util "github.com/go-gost/gost/pkg/common/util/tls" tls_util "github.com/go-gost/gost/pkg/common/util/tls"
md "github.com/go-gost/gost/pkg/metadata" mdata "github.com/go-gost/gost/pkg/metadata"
) )
const ( const (
@ -35,7 +34,7 @@ type metadata struct {
muxMaxStreamBuffer int muxMaxStreamBuffer int
} }
func (l *mwsListener) parseMetadata(md md.Metadata) (err error) { func (l *mwsListener) parseMetadata(md mdata.Metadata) (err error) {
const ( const (
path = "path" path = "path"
backlog = "backlog" backlog = "backlog"
@ -91,12 +90,12 @@ func (l *mwsListener) parseMetadata(md md.Metadata) (err error) {
l.md.muxMaxReceiveBuffer = md.GetInt(muxMaxReceiveBuffer) l.md.muxMaxReceiveBuffer = md.GetInt(muxMaxReceiveBuffer)
l.md.muxMaxStreamBuffer = md.GetInt(muxMaxStreamBuffer) l.md.muxMaxStreamBuffer = md.GetInt(muxMaxStreamBuffer)
if mm, _ := md.Get(header).(map[interface{}]interface{}); len(mm) > 0 { if mm := mdata.GetStringMapString(md, header); len(mm) > 0 {
h := http.Header{} hd := http.Header{}
for k, v := range mm { for k, v := range mm {
h.Add(fmt.Sprintf("%v", k), fmt.Sprintf("%v", v)) hd.Add(k, v)
} }
l.md.header = h l.md.header = hd
} }
return return
} }

View File

@ -1,6 +1,7 @@
package metadata package metadata
import ( import (
"fmt"
"strconv" "strconv"
"time" "time"
) )
@ -12,8 +13,9 @@ type Metadata interface {
GetBool(key string) bool GetBool(key string) bool
GetInt(key string) int GetInt(key string) int
GetFloat(key string) float64 GetFloat(key string) float64
GetString(key string) string
GetDuration(key string) time.Duration GetDuration(key string) time.Duration
GetString(key string) string
GetStrings(key string) []string
} }
type MapMetadata map[string]interface{} type MapMetadata map[string]interface{}
@ -76,13 +78,6 @@ func (m MapMetadata) GetFloat(key string) (v float64) {
return return
} }
func (m MapMetadata) GetString(key string) (v string) {
if m != nil {
v, _ = m[key].(string)
}
return
}
func (m MapMetadata) GetDuration(key string) (v time.Duration) { func (m MapMetadata) GetDuration(key string) (v time.Duration) {
if m != nil { if m != nil {
switch vv := m[key].(type) { switch vv := m[key].(type) {
@ -94,3 +89,31 @@ func (m MapMetadata) GetDuration(key string) (v time.Duration) {
} }
return return
} }
func (m MapMetadata) GetString(key string) (v string) {
if m != nil {
v, _ = m[key].(string)
}
return
}
func (m MapMetadata) GetStrings(key string) (ss []string) {
if v, _ := m.Get(key).([]interface{}); len(v) > 0 {
for _, vv := range v {
if s, ok := vv.(string); ok {
ss = append(ss, s)
}
}
}
return
}
func GetStringMapString(md Metadata, key string) (m map[string]string) {
if mm, _ := md.Get(key).(map[interface{}]interface{}); len(mm) > 0 {
m = make(map[string]string)
for k, v := range mm {
m[fmt.Sprintf("%v", k)] = fmt.Sprintf("%v", v)
}
}
return
}