2020-10-10 19:04:33 +08:00
|
|
|
package trojan
|
|
|
|
|
|
|
|
import (
|
|
|
|
"crypto/tls"
|
|
|
|
"net"
|
|
|
|
|
|
|
|
"github.com/nadoo/glider/log"
|
|
|
|
"github.com/nadoo/glider/pool"
|
|
|
|
"github.com/nadoo/glider/proxy"
|
2021-04-20 15:28:52 +08:00
|
|
|
"github.com/nadoo/glider/proxy/protocol/socks"
|
2020-10-10 19:04:33 +08:00
|
|
|
)
|
|
|
|
|
2020-10-11 01:15:28 +08:00
|
|
|
// NewClearTextDialer returns a trojan cleartext proxy dialer.
|
|
|
|
func NewClearTextDialer(s string, d proxy.Dialer) (proxy.Dialer, error) {
|
|
|
|
t, err := NewTrojan(s, d, nil)
|
|
|
|
if err != nil {
|
|
|
|
log.F("[trojan] create instance error: %s", err)
|
|
|
|
return nil, err
|
|
|
|
}
|
|
|
|
|
2020-10-11 19:53:38 +08:00
|
|
|
t.withTLS = false
|
2020-10-11 01:15:28 +08:00
|
|
|
return t, err
|
|
|
|
}
|
|
|
|
|
2020-10-10 19:04:33 +08:00
|
|
|
// NewTrojanDialer returns a trojan proxy dialer.
|
|
|
|
func NewTrojanDialer(s string, d proxy.Dialer) (proxy.Dialer, error) {
|
|
|
|
t, err := NewTrojan(s, d, nil)
|
|
|
|
if err != nil {
|
|
|
|
log.F("[trojan] create instance error: %s", err)
|
|
|
|
return nil, err
|
|
|
|
}
|
|
|
|
|
|
|
|
t.tlsConfig = &tls.Config{
|
|
|
|
ServerName: t.serverName,
|
|
|
|
InsecureSkipVerify: t.skipVerify,
|
|
|
|
NextProtos: []string{"http/1.1"},
|
|
|
|
MinVersion: tls.VersionTLS12,
|
|
|
|
}
|
|
|
|
|
|
|
|
return t, err
|
|
|
|
}
|
|
|
|
|
|
|
|
// Addr returns forwarder's address.
|
|
|
|
func (s *Trojan) Addr() string {
|
|
|
|
if s.addr == "" {
|
|
|
|
return s.dialer.Addr()
|
|
|
|
}
|
|
|
|
return s.addr
|
|
|
|
}
|
|
|
|
|
|
|
|
// Dial connects to the address addr on the network net via the proxy.
|
|
|
|
func (s *Trojan) Dial(network, addr string) (net.Conn, error) {
|
|
|
|
return s.dial(network, addr)
|
|
|
|
}
|
|
|
|
|
|
|
|
func (s *Trojan) dial(network, addr string) (net.Conn, error) {
|
|
|
|
rc, err := s.dialer.Dial("tcp", s.addr)
|
|
|
|
if err != nil {
|
|
|
|
log.F("[trojan]: dial to %s error: %s", s.addr, err)
|
|
|
|
return nil, err
|
|
|
|
}
|
|
|
|
|
2020-10-11 19:53:38 +08:00
|
|
|
if s.withTLS {
|
2020-10-11 01:15:28 +08:00
|
|
|
tlsConn := tls.Client(rc, s.tlsConfig)
|
|
|
|
if err := tlsConn.Handshake(); err != nil {
|
|
|
|
return nil, err
|
|
|
|
}
|
|
|
|
rc = tlsConn
|
2020-10-10 19:04:33 +08:00
|
|
|
}
|
|
|
|
|
2020-11-03 22:52:50 +08:00
|
|
|
buf := pool.GetBytesBuffer()
|
|
|
|
defer pool.PutBytesBuffer(buf)
|
2020-10-10 19:04:33 +08:00
|
|
|
|
|
|
|
buf.Write(s.pass[:])
|
|
|
|
buf.WriteString("\r\n")
|
|
|
|
|
|
|
|
cmd := socks.CmdConnect
|
|
|
|
if network == "udp" {
|
|
|
|
cmd = socks.CmdUDPAssociate
|
|
|
|
}
|
|
|
|
buf.WriteByte(cmd)
|
|
|
|
|
|
|
|
buf.Write(socks.ParseAddr(addr))
|
|
|
|
buf.WriteString("\r\n")
|
2020-10-11 01:15:28 +08:00
|
|
|
_, err = rc.Write(buf.Bytes())
|
2020-10-10 19:04:33 +08:00
|
|
|
|
2020-10-11 01:15:28 +08:00
|
|
|
return rc, err
|
2020-10-10 19:04:33 +08:00
|
|
|
}
|
|
|
|
|
|
|
|
// DialUDP connects to the given address via the proxy.
|
|
|
|
func (s *Trojan) DialUDP(network, addr string) (net.PacketConn, net.Addr, error) {
|
|
|
|
c, err := s.dial("udp", addr)
|
|
|
|
// TODO: check the addr in return value
|
2020-10-15 19:34:00 +08:00
|
|
|
return NewPktConn(c, socks.ParseAddr(addr)), nil, err
|
2020-10-10 19:04:33 +08:00
|
|
|
}
|