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  }