102 lines
2.1 KiB
Go
102 lines
2.1 KiB
Go
package shadow
|
|
|
|
import (
|
|
"fmt"
|
|
"github.com/refraction-networking/utls"
|
|
"io"
|
|
"net"
|
|
"time"
|
|
)
|
|
|
|
type Client struct {
|
|
ListenAddress string
|
|
ServerAddress string
|
|
FakeAddressSNI string
|
|
}
|
|
|
|
func NewClient(listenAddress string, serverAddress string, fakeAddressSNI string) *Client {
|
|
client := &Client{
|
|
ListenAddress: listenAddress,
|
|
ServerAddress: serverAddress,
|
|
FakeAddressSNI: fakeAddressSNI,
|
|
}
|
|
return client
|
|
}
|
|
|
|
func (c *Client) Start() {
|
|
listen, err := net.Listen("tcp", c.ListenAddress)
|
|
if err != nil {
|
|
fmt.Printf("[Client] Start client error: %v\n", err)
|
|
return
|
|
}
|
|
defer listen.Close()
|
|
fmt.Printf("[Client] Listening at:%v\n", c.ListenAddress)
|
|
for {
|
|
conn, err := listen.Accept()
|
|
if err != nil {
|
|
fmt.Printf("[Client] accept error: %v\n", err)
|
|
continue
|
|
}
|
|
go handlerClient(conn, c.ServerAddress, c.FakeAddressSNI)
|
|
}
|
|
}
|
|
|
|
func handlerClient(conn net.Conn, serverAddress string, fakeAddressSNI string) {
|
|
config := &tls.Config{
|
|
ServerName: fakeAddressSNI,
|
|
}
|
|
if HandshakePassword != "" {
|
|
config.Rand = RandReaderObj
|
|
}
|
|
|
|
rawConn, err := net.DialTimeout("tcp", serverAddress, time.Second*5)
|
|
if err != nil {
|
|
fmt.Printf("[Client] Dial server error: %v\n", err)
|
|
return
|
|
}
|
|
dial := tls.UClient(rawConn, config, tls.HelloChrome_102)
|
|
err = dial.Handshake()
|
|
if err != nil {
|
|
fmt.Printf("[Client] Handshake error: %v\n", err)
|
|
return
|
|
}
|
|
//dial.GetUnderlyingConn().SetDeadline(time.Now())
|
|
//dial.GetUnderlyingConn().SetDeadline(time.Time{})
|
|
|
|
p := &PackAppData{Conn: dial.GetUnderlyingConn()}
|
|
|
|
defer p.Close()
|
|
defer conn.Close()
|
|
exitCh := make(chan int, 1)
|
|
|
|
go MyCopy(conn, p, exitCh)
|
|
go MyCopy(p, conn, exitCh)
|
|
<-exitCh
|
|
}
|
|
|
|
func MyCopy(src io.ReadWriteCloser, dst io.ReadWriteCloser, ch chan int) {
|
|
buf := make([]byte, 32*1024)
|
|
for {
|
|
nr, er := src.Read(buf)
|
|
if er != nil {
|
|
if er == io.EOF {
|
|
break
|
|
} else {
|
|
fmt.Printf("Read err: %v\n", er)
|
|
break
|
|
}
|
|
} else {
|
|
nw, ew := dst.Write(buf[0:nr])
|
|
if ew != nil {
|
|
fmt.Printf("Write error:%v\n", ew)
|
|
break
|
|
}
|
|
if nr != nw {
|
|
fmt.Printf("Write less then buffered \n")
|
|
break
|
|
}
|
|
}
|
|
}
|
|
ch <- 1
|
|
}
|