mirror of
https://github.com/p4gefau1t/trojan-go.git
synced 2024-04-21 12:21:34 +00:00
add client api service
This commit is contained in:
+4
-1
@@ -5,6 +5,7 @@ import (
|
||||
|
||||
"github.com/p4gefau1t/trojan-go/common"
|
||||
"github.com/p4gefau1t/trojan-go/conf"
|
||||
"github.com/p4gefau1t/trojan-go/log"
|
||||
"github.com/p4gefau1t/trojan-go/stat"
|
||||
"google.golang.org/grpc"
|
||||
"v2ray.com/core/common/net"
|
||||
@@ -16,6 +17,7 @@ type ClientAPIService struct {
|
||||
}
|
||||
|
||||
func (s *ClientAPIService) QueryStats(ctx context.Context, req *StatsRequest) (*StatsReply, error) {
|
||||
log.Debug("query stats, password", req.Password)
|
||||
password := req.Password
|
||||
passwordHash := common.SHA224String(password)
|
||||
sent, recv := s.meter.Query(passwordHash)
|
||||
@@ -26,7 +28,7 @@ func (s *ClientAPIService) QueryStats(ctx context.Context, req *StatsRequest) (*
|
||||
return reply, nil
|
||||
}
|
||||
|
||||
func RunClientAPIService(ctx context.Context, config conf.GlobalConfig, meter stat.TrafficMeter) error {
|
||||
func RunClientAPIService(ctx context.Context, config *conf.GlobalConfig, meter stat.TrafficMeter) error {
|
||||
server := grpc.NewServer()
|
||||
service := &ClientAPIService{
|
||||
meter: meter,
|
||||
@@ -36,6 +38,7 @@ func RunClientAPIService(ctx context.Context, config conf.GlobalConfig, meter st
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
log.Info("client api service is running at", config.API.APIAddress)
|
||||
errChan := make(chan error, 1)
|
||||
go func() {
|
||||
errChan <- server.Serve(listener)
|
||||
|
||||
+10
-1
@@ -13,7 +13,7 @@ import (
|
||||
|
||||
func TestClientAPI(t *testing.T) {
|
||||
meter := &stat.MemoryTrafficMeter{}
|
||||
go RunClientAPIService(context.Background(), conf.GlobalConfig{
|
||||
go RunClientAPIService(context.Background(), &conf.GlobalConfig{
|
||||
API: conf.APIConfig{
|
||||
APIAddress: common.NewAddress("127.0.0.1", 10000, "tcp"),
|
||||
},
|
||||
@@ -29,3 +29,12 @@ func TestClientAPI(t *testing.T) {
|
||||
t.Fatal("wrong result")
|
||||
}
|
||||
}
|
||||
|
||||
func TestRealClientAPI(t *testing.T) {
|
||||
conn, err := grpc.Dial("127.0.0.1:10000", grpc.WithInsecure())
|
||||
common.Must(err)
|
||||
client := NewTrojanServiceClient(conn)
|
||||
reply, err := client.QueryStats(context.Background(), &StatsRequest{})
|
||||
common.Must(err)
|
||||
fmt.Println(reply.Download, reply.Upload)
|
||||
}
|
||||
|
||||
@@ -6,15 +6,15 @@ require (
|
||||
github.com/LiamHaworth/go-tproxy v0.0.0-20190726054950-ef7efd7f24ed
|
||||
github.com/go-acme/lego/v3 v3.5.0
|
||||
github.com/go-sql-driver/mysql v1.5.0
|
||||
github.com/golang/protobuf v1.4.0-rc.4.0.20200313231945-b860323f09d0
|
||||
github.com/golang/protobuf v1.4.0
|
||||
github.com/pkg/errors v0.9.1 // indirect
|
||||
github.com/smartystreets/goconvey v1.6.4
|
||||
github.com/valyala/tcplisten v0.0.0-20161114210144-ceec8f93295a
|
||||
github.com/xtaci/smux v2.0.1+incompatible
|
||||
golang.org/x/crypto v0.0.0-20200406173513-056763e48d71
|
||||
golang.org/x/crypto v0.0.0-20200414173820-0848c9571904
|
||||
golang.org/x/net v0.0.0-20200324143707-d3edc9973b7e
|
||||
golang.org/x/sys v0.0.0-20200409092240-59c9f1ba88fa
|
||||
google.golang.org/grpc v1.27.1
|
||||
golang.org/x/sys v0.0.0-20200413165638-669c56c373c4
|
||||
google.golang.org/grpc v1.28.1
|
||||
google.golang.org/protobuf v1.21.0 // indirect
|
||||
v2ray.com/core v4.19.1+incompatible
|
||||
)
|
||||
|
||||
@@ -62,6 +62,7 @@ github.com/chzyer/readline v0.0.0-20180603132655-2972be24d48e/go.mod h1:nSuG5e5P
|
||||
github.com/chzyer/test v0.0.0-20180213035817-a1ea475d72b1/go.mod h1:Q3SI9o4m/ZMnBNeIyt5eFwwo7qiLfzFZmjNmxjkiQlU=
|
||||
github.com/client9/misspell v0.3.4/go.mod h1:qj6jICC3Q7zFZvVWo7KLAzC3yx5G7kyvSDkc90ppPyw=
|
||||
github.com/cloudflare/cloudflare-go v0.10.2/go.mod h1:qhVI5MKwBGhdNU89ZRz2plgYutcJ5PCekLxXn56w6SY=
|
||||
github.com/cncf/udpa/go v0.0.0-20191209042840-269d4d468f6f/go.mod h1:M8M6+tZqaGXZJjfX53e64911xZQV5JYwmTeXPW+k8Sc=
|
||||
github.com/cpu/goacmedns v0.0.1/go.mod h1:sesf/pNnCYwUevQEQfEwY0Y3DydlQWSGZbaMElOWxok=
|
||||
github.com/cpuguy83/go-md2man/v2 v2.0.0-20190314233015-f79a8a8ca69d/go.mod h1:maD7wRr/U5Z6m/iR4s+kqSMx2CaBsrgA7czyZG/E6dU=
|
||||
github.com/davecgh/go-spew v1.1.0/go.mod h1:J7Y8YcW2NihsgmVo/mv3lAwl/skON4iLHjSsI+c5H38=
|
||||
@@ -74,7 +75,9 @@ github.com/dnsimple/dnsimple-go v0.30.0/go.mod h1:O5TJ0/U6r7AfT8niYNlmohpLbCSG+c
|
||||
github.com/eapache/go-resiliency v1.1.0/go.mod h1:kFI+JgMyC7bLPUVY133qvEBtVayf5mFgVsvEsIPBvNs=
|
||||
github.com/eapache/go-xerial-snappy v0.0.0-20180814174437-776d5712da21/go.mod h1:+020luEh2TKB4/GOp8oxxtq0Daoen/Cii55CzbTV6DU=
|
||||
github.com/eapache/queue v1.1.0/go.mod h1:6eCeP0CKFpHLu8blIFXhExK/dRa7WDZfr6jVFPTqq+I=
|
||||
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.4/go.mod h1:6rpuAdCZL397s3pYoYcLgu1mIlRU8Am5FuJP05cCM98=
|
||||
github.com/envoyproxy/protoc-gen-validate v0.1.0/go.mod h1:iSmxcyjqTsJpI2R4NaDN7+kN2VEUnK/pcBlmesArF7c=
|
||||
github.com/exoscale/egoscale v0.18.1/go.mod h1:Z7OOdzzTOz1Q1PjQXumlz9Wn/CddH0zSYdCF3rnBKXE=
|
||||
github.com/fatih/structs v1.1.0/go.mod h1:9NiDSp5zOcgEDl+j00MP/WkGVPOlPRLejGD8Ga6PJ7M=
|
||||
@@ -122,6 +125,8 @@ github.com/golang/protobuf v1.4.0-rc.1.0.20200221234624-67d41d38c208/go.mod h1:x
|
||||
github.com/golang/protobuf v1.4.0-rc.2/go.mod h1:LlEzMj4AhA7rCAGe4KMBDvJI+AwstrUpVNzEA03Pprs=
|
||||
github.com/golang/protobuf v1.4.0-rc.4.0.20200313231945-b860323f09d0 h1:aRz0NBceriICVtjhCgKkDvl+RudKu1CT6h0ZvUTrNfE=
|
||||
github.com/golang/protobuf v1.4.0-rc.4.0.20200313231945-b860323f09d0/go.mod h1:WU3c8KckQ9AFe+yFwt9sWVRKCVIyN9cPHBJSNnbL67w=
|
||||
github.com/golang/protobuf v1.4.0 h1:oOuy+ugB+P/kBdUnG5QaMXSIyJ1q38wWSojYCb3z5VQ=
|
||||
github.com/golang/protobuf v1.4.0/go.mod h1:jodUvKwWbYaEsadDk5Fwe5c77LiNKVO9IDvqG2KuDX0=
|
||||
github.com/golang/snappy v0.0.0-20180518054509-2e65f85255db/go.mod h1:/XxbfmMg8lxefKM7IXC3fBNl/7bRcc72aCRzEWrmP2Q=
|
||||
github.com/google/btree v0.0.0-20180813153112-4030bb1f1f0c/go.mod h1:lNA+9X1NB3Zf8V7Ke586lFgjr2dZNuvo3lPJSGZ5JPQ=
|
||||
github.com/google/btree v1.0.0/go.mod h1:lNA+9X1NB3Zf8V7Ke586lFgjr2dZNuvo3lPJSGZ5JPQ=
|
||||
@@ -289,6 +294,8 @@ golang.org/x/crypto v0.0.0-20200320181102-891825fb96df h1:lDWgvUvNnaTnNBc/dwOty8
|
||||
golang.org/x/crypto v0.0.0-20200320181102-891825fb96df/go.mod h1:LzIPMQfyMNhhGPhUkYOs5KpL4U8rLKemX1yGLhDgUto=
|
||||
golang.org/x/crypto v0.0.0-20200406173513-056763e48d71 h1:DOmugCavvUtnUD114C1Wh+UgTgQZ4pMLzXxi1pSt+/Y=
|
||||
golang.org/x/crypto v0.0.0-20200406173513-056763e48d71/go.mod h1:LzIPMQfyMNhhGPhUkYOs5KpL4U8rLKemX1yGLhDgUto=
|
||||
golang.org/x/crypto v0.0.0-20200414173820-0848c9571904 h1:bXoxMPcSLOq08zI3/c5dEBT6lE4eh+jOh886GHrn6V8=
|
||||
golang.org/x/crypto v0.0.0-20200414173820-0848c9571904/go.mod h1:LzIPMQfyMNhhGPhUkYOs5KpL4U8rLKemX1yGLhDgUto=
|
||||
golang.org/x/exp v0.0.0-20190121172915-509febef88a4/go.mod h1:CJ0aWSM057203Lf6IL+f9T1iT9GByDxfZKAQTCR3kQA=
|
||||
golang.org/x/exp v0.0.0-20190306152737-a1d7652674e8/go.mod h1:CJ0aWSM057203Lf6IL+f9T1iT9GByDxfZKAQTCR3kQA=
|
||||
golang.org/x/exp v0.0.0-20190510132918-efd6b22b2522/go.mod h1:ZjyILWgesfNpC6sMxTJOJm9Kp84zZh5NQWvqDGG3Qr8=
|
||||
@@ -397,6 +404,8 @@ golang.org/x/sys v0.0.0-20200408040146-ea54a3c99b9b h1:h03Ur1RlPrGTjua4koYdpGl8W
|
||||
golang.org/x/sys v0.0.0-20200408040146-ea54a3c99b9b/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs=
|
||||
golang.org/x/sys v0.0.0-20200409092240-59c9f1ba88fa h1:mQTN3ECqfsViCNBgq+A40vdwhkGykrrQlYe3mPj6BoU=
|
||||
golang.org/x/sys v0.0.0-20200409092240-59c9f1ba88fa/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs=
|
||||
golang.org/x/sys v0.0.0-20200413165638-669c56c373c4 h1:opSr2sbRXk5X5/givKrrKj9HXxFpW2sdCiP8MJSKLQY=
|
||||
golang.org/x/sys v0.0.0-20200413165638-669c56c373c4/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs=
|
||||
golang.org/x/text v0.0.0-20170915032832-14c0d48ead0c/go.mod h1:NqM8EUOU14njkJ3fqMW+pc6Ldnwhi/IjpwHt7yyuwOQ=
|
||||
golang.org/x/text v0.3.0 h1:g61tztE5qeGQ89tm6NTjjM9VPIm088od1l6aSorWRWg=
|
||||
golang.org/x/text v0.3.0/go.mod h1:NqM8EUOU14njkJ3fqMW+pc6Ldnwhi/IjpwHt7yyuwOQ=
|
||||
@@ -487,10 +496,13 @@ google.golang.org/grpc v1.19.1/go.mod h1:mqu4LbDTu4XGKhr4mRzUsmM4RtVoemTSY81AxZi
|
||||
google.golang.org/grpc v1.20.1/go.mod h1:10oTOabMzJvdu6/UiuZezV6QK5dSlG84ov/aaiqXj38=
|
||||
google.golang.org/grpc v1.21.1/go.mod h1:oYelfM1adQP15Ek0mdvEgi9Df8B9CZIaU1084ijfRaM=
|
||||
google.golang.org/grpc v1.23.0/go.mod h1:Y5yQAOtifL1yxbo5wqy6BxZv8vAUGQwXBOALyacEbxg=
|
||||
google.golang.org/grpc v1.25.1/go.mod h1:c3i+UQWmh7LiEpx4sFZnkU36qjEYZ0imhYfXVyQciAY=
|
||||
google.golang.org/grpc v1.26.0/go.mod h1:qbnxyOmOxrQa7FizSgH+ReBfzJrCY1pSN7KXBS8abTk=
|
||||
google.golang.org/grpc v1.27.0/go.mod h1:qbnxyOmOxrQa7FizSgH+ReBfzJrCY1pSN7KXBS8abTk=
|
||||
google.golang.org/grpc v1.27.1 h1:zvIju4sqAGvwKspUQOhwnpcqSbzi7/H6QomNNjTL4sk=
|
||||
google.golang.org/grpc v1.27.1/go.mod h1:qbnxyOmOxrQa7FizSgH+ReBfzJrCY1pSN7KXBS8abTk=
|
||||
google.golang.org/grpc v1.28.1 h1:C1QC6KzgSiLyBabDi87BbjaGreoRgGUF5nOyvfrAZ1k=
|
||||
google.golang.org/grpc v1.28.1/go.mod h1:rpkK4SK4GF4Ach/+MFLZUBavHOvF2JJB5uozKKal+60=
|
||||
google.golang.org/protobuf v0.0.0-20200109180630-ec00e32a8dfd/go.mod h1:DFci5gLYBciE7Vtevhsrf46CRTquxDuWsQurQQe4oz8=
|
||||
google.golang.org/protobuf v0.0.0-20200221191635-4d8936d0db64/go.mod h1:kwYJMbMJ01Woi6D6+Kah6886xMZcty6N08ah7+eCXa0=
|
||||
google.golang.org/protobuf v0.0.0-20200228230310-ab0ca4ff8a60/go.mod h1:cfTl7dwQJ+fmap5saPgwCLgHXTUD7jkjRqWcaiX5VyM=
|
||||
|
||||
@@ -24,6 +24,10 @@ type TrojanOutboundConnSession struct {
|
||||
meter stat.TrafficMeter
|
||||
}
|
||||
|
||||
func (o *TrojanOutboundConnSession) SetMeter(meter stat.TrafficMeter) {
|
||||
o.meter = meter
|
||||
}
|
||||
|
||||
func (o *TrojanOutboundConnSession) Write(p []byte) (int, error) {
|
||||
n, err := o.bufReadWriter.Write(p)
|
||||
o.meter.Count("", uint64(n), 0)
|
||||
@@ -54,10 +58,7 @@ func (o *TrojanOutboundConnSession) writeRequest() error {
|
||||
o.bufReadWriter.Write([]byte(hash))
|
||||
o.bufReadWriter.Write(crlf)
|
||||
o.bufReadWriter.WriteByte(byte(o.request.Command))
|
||||
err := protocol.WriteAddress(o.bufReadWriter, o.request)
|
||||
if err != nil {
|
||||
return common.NewError("failed to write address").Base(err)
|
||||
}
|
||||
protocol.WriteAddress(o.bufReadWriter, o.request)
|
||||
o.bufReadWriter.Write(crlf)
|
||||
return o.bufReadWriter.Flush()
|
||||
}
|
||||
|
||||
+15
-9
@@ -8,6 +8,7 @@ import (
|
||||
"net"
|
||||
"time"
|
||||
|
||||
"github.com/p4gefau1t/trojan-go/api"
|
||||
"github.com/p4gefau1t/trojan-go/common"
|
||||
"github.com/p4gefau1t/trojan-go/conf"
|
||||
"github.com/p4gefau1t/trojan-go/log"
|
||||
@@ -19,6 +20,7 @@ import (
|
||||
"github.com/p4gefau1t/trojan-go/protocol/trojan"
|
||||
"github.com/p4gefau1t/trojan-go/proxy"
|
||||
"github.com/p4gefau1t/trojan-go/router"
|
||||
"github.com/p4gefau1t/trojan-go/stat"
|
||||
)
|
||||
|
||||
func DialTLSToServer(config *conf.GlobalConfig) (io.ReadWriteCloser, error) {
|
||||
@@ -74,6 +76,7 @@ type Client struct {
|
||||
mux *muxPoolManager
|
||||
associatedChan chan time.Time
|
||||
router router.Router
|
||||
meter stat.TrafficMeter
|
||||
}
|
||||
|
||||
func (c *Client) handleSocksConn(conn net.Conn, rw *bufio.ReadWriter) {
|
||||
@@ -142,7 +145,7 @@ func (c *Client) handleSocksConn(conn net.Conn, rw *bufio.ReadWriter) {
|
||||
log.Info("[block]conn from", conn.RemoteAddr(), "to", req)
|
||||
return
|
||||
}
|
||||
|
||||
var outboundConn protocol.ConnSession
|
||||
if c.config.Mux.Enabled {
|
||||
stream, info, err := c.mux.OpenMuxConn()
|
||||
if err != nil {
|
||||
@@ -150,31 +153,29 @@ func (c *Client) handleSocksConn(conn net.Conn, rw *bufio.ReadWriter) {
|
||||
return
|
||||
}
|
||||
|
||||
outboundConn, err := mux.NewOutboundConnSession(stream, req)
|
||||
outboundConn, err = mux.NewOutboundConnSession(stream, req)
|
||||
if err != nil {
|
||||
stream.Close()
|
||||
log.Error(common.NewError("fail to start trojan session over mux conn").Base(err))
|
||||
return
|
||||
}
|
||||
defer outboundConn.Close()
|
||||
log.Info("conn from", conn.RemoteAddr(), "mux tunneling to", req, "mux id", info.id)
|
||||
proxy.ProxyConn(c.ctx, inboundConn, outboundConn)
|
||||
} else {
|
||||
rwc, err := DialTLSToServer(c.config)
|
||||
tlsConn, err := DialTLSToServer(c.config)
|
||||
if err != nil {
|
||||
log.Error(common.NewError("failed to dail to remote server").Base(err))
|
||||
return
|
||||
}
|
||||
outboundConn, err := trojan.NewOutboundConnSession(req, rwc, c.config)
|
||||
outboundConn, err = trojan.NewOutboundConnSession(req, tlsConn, c.config)
|
||||
if err != nil {
|
||||
log.Error(common.NewError("failed to start new outbound session").Base(err))
|
||||
return
|
||||
}
|
||||
defer outboundConn.Close()
|
||||
|
||||
log.Info("conn from", conn.RemoteAddr(), "tunneling to", req)
|
||||
proxy.ProxyConn(c.ctx, inboundConn, outboundConn)
|
||||
}
|
||||
defer outboundConn.Close()
|
||||
outboundConn.(protocol.NeedMeter).SetMeter(c.meter)
|
||||
proxy.ProxyConn(c.ctx, inboundConn, outboundConn)
|
||||
}
|
||||
|
||||
func (c *Client) handleHTTPConn(conn net.Conn, rw *bufio.ReadWriter) {
|
||||
@@ -237,6 +238,7 @@ func (c *Client) handleHTTPConn(conn net.Conn, rw *bufio.ReadWriter) {
|
||||
}
|
||||
log.Info("conn from", conn.RemoteAddr(), "tunneling to", req)
|
||||
}
|
||||
outboundConn.(protocol.NeedMeter).SetMeter(c.meter)
|
||||
defer outboundConn.Close()
|
||||
proxy.ProxyConn(c.ctx, inboundConn, outboundConn)
|
||||
} else {
|
||||
@@ -407,6 +409,9 @@ func (c *Client) Run() error {
|
||||
errChan := make(chan error, 2)
|
||||
go c.listenUDP(errChan)
|
||||
go c.listenTCP(errChan)
|
||||
if c.config.API.Enabled {
|
||||
go api.RunClientAPIService(c.ctx, c.config, c.meter)
|
||||
}
|
||||
select {
|
||||
case err := <-errChan:
|
||||
return err
|
||||
@@ -426,6 +431,7 @@ func (c *Client) Build(config *conf.GlobalConfig) (common.Runnable, error) {
|
||||
c.router = &router.EmptyRouter{
|
||||
DefaultPolicy: router.Proxy,
|
||||
}
|
||||
c.meter = &stat.MemoryTrafficMeter{}
|
||||
c.associatedChan = make(chan time.Time, 1)
|
||||
var err error
|
||||
if config.Mux.Enabled {
|
||||
|
||||
+1
-1
@@ -46,5 +46,5 @@ type updateOption struct {
|
||||
}
|
||||
|
||||
func init() {
|
||||
|
||||
// TODO auto updating
|
||||
}
|
||||
|
||||
Reference in New Issue
Block a user