github.com/ipfans/trojan-go@v0.11.0/api/service/client.go (about) 1 package service 2 3 import ( 4 "context" 5 "net" 6 7 "github.com/ipfans/trojan-go/api" 8 "github.com/ipfans/trojan-go/common" 9 "github.com/ipfans/trojan-go/config" 10 "github.com/ipfans/trojan-go/log" 11 "github.com/ipfans/trojan-go/statistic" 12 "github.com/ipfans/trojan-go/tunnel/trojan" 13 ) 14 15 type ClientAPI struct { 16 TrojanClientServiceServer 17 18 auth statistic.Authenticator 19 ctx context.Context 20 uploadSpeed uint64 21 downloadSpeed uint64 22 lastSent uint64 23 lastRecv uint64 24 } 25 26 func (s *ClientAPI) GetTraffic(ctx context.Context, req *GetTrafficRequest) (*GetTrafficResponse, error) { 27 log.Debug("API: GetTraffic") 28 if req.User == nil { 29 return nil, common.NewError("User is unspecified") 30 } 31 if req.User.Hash == "" { 32 req.User.Hash = common.SHA224String(req.User.Password) 33 } 34 valid, user := s.auth.AuthUser(req.User.Hash) 35 if !valid { 36 return nil, common.NewError("User " + req.User.Hash + " not found") 37 } 38 sent, recv := user.GetTraffic() 39 sentSpeed, recvSpeed := user.GetSpeed() 40 resp := &GetTrafficResponse{ 41 Success: true, 42 TrafficTotal: &Traffic{ 43 UploadTraffic: sent, 44 DownloadTraffic: recv, 45 }, 46 SpeedCurrent: &Speed{ 47 UploadSpeed: sentSpeed, 48 DownloadSpeed: recvSpeed, 49 }, 50 } 51 return resp, nil 52 } 53 54 func RunClientAPI(ctx context.Context, auth statistic.Authenticator) error { 55 cfg := config.FromContext(ctx, Name).(*Config) 56 if !cfg.API.Enabled { 57 return nil 58 } 59 server, err := newAPIServer(cfg) 60 if err != nil { 61 return err 62 } 63 defer server.Stop() 64 service := &ClientAPI{ 65 ctx: ctx, 66 auth: auth, 67 } 68 RegisterTrojanClientServiceServer(server, service) 69 addr, err := net.ResolveIPAddr("ip", cfg.API.APIHost) 70 if err != nil { 71 return common.NewError("api found invalid addr").Base(err) 72 } 73 listener, err := net.Listen("tcp", (&net.TCPAddr{ 74 IP: addr.IP, 75 Port: cfg.API.APIPort, 76 Zone: addr.Zone, 77 }).String()) 78 if err != nil { 79 return common.NewError("client api failed to listen").Base(err) 80 } 81 defer listener.Close() 82 log.Info("client-side api service is listening on", listener.Addr().String()) 83 errChan := make(chan error, 1) 84 go func() { 85 errChan <- server.Serve(listener) 86 }() 87 select { 88 case err := <-errChan: 89 return err 90 case <-ctx.Done(): 91 log.Debug("closed") 92 return nil 93 } 94 } 95 96 func init() { 97 api.RegisterHandler(trojan.Name+"_CLIENT", RunClientAPI) 98 }