github.com/xxf098/lite-proxy@v0.15.1-0.20230422081941-12c69f323218/core/core.go (about)

     1  package core
     2  
     3  import (
     4  	"context"
     5  	"errors"
     6  	"fmt"
     7  	"log"
     8  	"net"
     9  	"strconv"
    10  	"time"
    11  
    12  	"github.com/xxf098/lite-proxy/config"
    13  	_ "github.com/xxf098/lite-proxy/config"
    14  	"github.com/xxf098/lite-proxy/dns"
    15  	"github.com/xxf098/lite-proxy/outbound"
    16  	"github.com/xxf098/lite-proxy/proxy"
    17  	"github.com/xxf098/lite-proxy/request"
    18  	"github.com/xxf098/lite-proxy/transport/resolver"
    19  	"github.com/xxf098/lite-proxy/tunnel"
    20  	"github.com/xxf098/lite-proxy/tunnel/adapter"
    21  	"github.com/xxf098/lite-proxy/tunnel/http"
    22  	"github.com/xxf098/lite-proxy/tunnel/socks"
    23  	"github.com/xxf098/lite-proxy/utils"
    24  )
    25  
    26  func StartInstance(c Config) (*proxy.Proxy, error) {
    27  	ctx := context.Background()
    28  	ctx = context.WithValue(ctx, "LocalHost", c.LocalHost)
    29  	ctx = context.WithValue(ctx, "LocalPort", c.LocalPort)
    30  	adapterServer, err := adapter.NewServer(ctx, nil)
    31  	if err != nil {
    32  		return nil, err
    33  	}
    34  	httpServer, err := http.NewServer(ctx, adapterServer)
    35  	if err != nil {
    36  		return nil, err
    37  	}
    38  	socksServer, err := socks.NewServer(ctx, adapterServer)
    39  	if err != nil {
    40  		return nil, err
    41  	}
    42  	sources := []tunnel.Server{httpServer, socksServer}
    43  	sink, err := createSink(ctx, c.Link)
    44  	if err != nil {
    45  		return nil, err
    46  	}
    47  	ctx, cancel := context.WithCancel(context.Background())
    48  	go func(link string) {
    49  		if c.Ping < 1 {
    50  			return
    51  		}
    52  		if cfg, err := config.Link2Config(c.Link); err == nil {
    53  			opt := request.PingOption{
    54  				Attempts: c.Ping,
    55  				TimeOut:  1200 * time.Millisecond,
    56  			}
    57  			info := fmt.Sprintf("%s %s", cfg.Remarks, net.JoinHostPort(cfg.Server, strconv.Itoa(cfg.Port)))
    58  			if elapse, err := request.PingLinkInternal(link, opt); err == nil {
    59  				info = fmt.Sprintf("%s \033[32m%dms\033[0m", info, elapse)
    60  			} else {
    61  				info = fmt.Sprintf("\033[31m%s\033[0m", err.Error())
    62  			}
    63  			log.Print(info)
    64  		}
    65  	}(c.Link)
    66  	setDefaultResolver()
    67  	p := proxy.NewProxy(ctx, cancel, sources, sink)
    68  	return p, nil
    69  }
    70  
    71  func createSink(ctx context.Context, link string) (tunnel.Client, error) {
    72  	var d outbound.Dialer
    73  	matches, err := utils.CheckLink(link)
    74  	if err != nil {
    75  		return nil, err
    76  	}
    77  	creator, err := outbound.GetDialerCreator(matches[1])
    78  	if err != nil {
    79  		return nil, err
    80  	}
    81  	d, err = creator(link)
    82  	if err != nil {
    83  		return nil, err
    84  	}
    85  	if d != nil {
    86  		return proxy.NewClient(ctx, d), nil
    87  	}
    88  
    89  	return nil, errors.New("not supported link")
    90  }
    91  
    92  func setDefaultResolver() {
    93  	resolver.DefaultResolver = dns.DefaultResolver()
    94  }