github.com/yaling888/clash@v1.53.0/adapter/outbound/mitm.go (about)

     1  package outbound
     2  
     3  import (
     4  	"context"
     5  	"net"
     6  	"time"
     7  
     8  	"github.com/yaling888/clash/component/auth"
     9  	"github.com/yaling888/clash/component/dialer"
    10  	C "github.com/yaling888/clash/constant"
    11  )
    12  
    13  var _ C.ProxyAdapter = (*Mitm)(nil)
    14  
    15  type Mitm struct {
    16  	*Base
    17  	serverAddr      *net.TCPAddr
    18  	httpProxyClient *Http
    19  }
    20  
    21  // DialContext implements C.ProxyAdapter
    22  func (m *Mitm) DialContext(_ context.Context, metadata *C.Metadata, _ ...dialer.Option) (C.Conn, error) {
    23  	c, err := net.DialTCP("tcp", nil, m.serverAddr)
    24  	if err != nil {
    25  		return nil, err
    26  	}
    27  
    28  	_ = c.SetKeepAlive(true)
    29  	_ = c.SetKeepAlivePeriod(60 * time.Second)
    30  
    31  	metadata.Type = C.MITM
    32  
    33  	hc, err := m.httpProxyClient.StreamConn(c, metadata)
    34  	if err != nil {
    35  		_ = c.Close()
    36  		return nil, err
    37  	}
    38  
    39  	return NewConn(hc, m), nil
    40  }
    41  
    42  func NewMitm(serverAddr string, auths auth.Authenticator) *Mitm {
    43  	var (
    44  		option     = HttpOption{}
    45  		tcpAddr, _ = net.ResolveTCPAddr("tcp", serverAddr)
    46  	)
    47  	if auths != nil {
    48  		if user := auths.RandomUser(); user != nil {
    49  			option.UserName = user.User
    50  			option.Password = user.Pass
    51  		}
    52  	}
    53  	return &Mitm{
    54  		Base: &Base{
    55  			name: "Mitm",
    56  			tp:   C.Mitm,
    57  		},
    58  		serverAddr:      tcpAddr,
    59  		httpProxyClient: NewHttp(option),
    60  	}
    61  }