Exemple #1
0
func serverMethodSelected(method uint8, conn net.Conn) (net.Conn, error) {
	switch method {
	case MethodTLS:
		var cert tls.Certificate
		var err error

		if len(CertFile) == 0 || len(KeyFile) == 0 {
			cert, err = tls.X509KeyPair([]byte(rawCert), []byte(rawKey))
		} else {
			cert, err = tls.LoadX509KeyPair(CertFile, KeyFile)
		}

		if err != nil {
			return nil, err
		}
		conn = tls.Server(conn, &tls.Config{Certificates: []tls.Certificate{cert}})
		if err := svrTLSAuth(conn); err != nil {
			return nil, err
		}
	case MethodAES128, MethodAES192, MethodAES256,
		MethodDES, MethodBF, MethodCAST5, MethodRC4MD5, MethodRC4, MethodTable:
		cipher, err := shadowsocks.NewCipher(Methods[method], Password)
		if err != nil {
			return nil, err
		}
		conn = shadowsocks.NewConn(conn, cipher)
	case gosocks5.MethodNoAcceptable:
		return nil, gosocks5.ErrBadMethod
	}

	return conn, nil
}
Exemple #2
0
func handleShadow(conn net.Conn, arg Args) {
	if arg.User != nil {
		method := arg.User.Username()
		password, _ := arg.User.Password()
		cipher, err := shadowsocks.NewCipher(method, password)
		if err != nil {
			glog.V(LWARNING).Infoln("shadowsocks:", err)
			return
		}
		conn = shadowsocks.NewConn(conn, cipher)
	}

	addr, extra, err := getShadowRequest(conn)
	if err != nil {
		glog.V(LWARNING).Infoln("shadowsocks:", err)
		return
	}
	glog.V(LINFO).Infoln("shadowsocks connect:", addr.String())

	sconn, err := Connect(addr.String())
	if err != nil {
		glog.V(LWARNING).Infoln("shadowsocks:", err)
		return
	}
	defer sconn.Close()

	if extra != nil {
		if _, err := sconn.Write(extra); err != nil {
			glog.V(LWARNING).Infoln("shadowsocks:", err)
			return
		}
	}

	Transport(conn, sconn)
}
Exemple #3
0
func runWithCustomMethod(user user.User) {
	// port, password string, Cipher *ss.Cipher
	port := strconv.Itoa(user.GetPort())
	password := user.GetPasswd()
	ln, err := net.Listen("tcp", ":"+port)
	if err != nil {
		Log.Error(fmt.Sprintf("error listening port %v: %v\n", port, err))
		os.Exit(1)
	}
	passwdManager.add(port, password, ln)
	cipher, err := user.GetCipher()
	if err != nil {
		return
	}
	Log.Info(fmt.Sprintf("server listening port %v ...\n", port))
	for {
		conn, err := ln.Accept()
		if err != nil {
			// listener maybe closed to update password
			Log.Debug(fmt.Sprintf("accept error: %v\n", err))
			return
		}
		// Creating cipher upon first connection.
		if cipher == nil {
			Log.Debug("creating cipher for port:", port)
			cipher, err = ss.NewCipher(user.GetMethod(), password)
			if err != nil {
				Log.Error(fmt.Sprintf("Error generating cipher for port: %s %v\n", port, err))
				conn.Close()
				continue
			}
		}
		go handleConnection(user, ss.NewConn(conn, cipher.Copy()))
	}
}
Exemple #4
0
func (cp *meowProxy) Serve(wg *sync.WaitGroup) {
	defer func() {
		wg.Done()
	}()
	ln, err := net.Listen("tcp", cp.addr)
	if err != nil {
		fmt.Println("listen meow failed:", err)
		return
	}
	info.Printf("meow proxy address %s\n", cp.addr)

	for {
		conn, err := ln.Accept()
		if err != nil {
			errl.Printf("meow proxy(%s) accept %v\n", ln.Addr(), err)
			if isErrTooManyOpenFd(err) {
				connPool.CloseAll()
			}
			time.Sleep(time.Millisecond)
			continue
		}
		ssConn := ss.NewConn(conn, cp.cipher.Copy())
		c := newClientConn(ssConn, cp)
		go c.serve()
	}
}
Exemple #5
0
func run(port, password string) {
	ln, err := net.Listen("tcp", ":"+port)
	if err != nil {
		log.Printf("error listening port %v: %v\n", port, err)
		return
	}
	passwdManager.add(port, password, ln)
	var cipher *ss.Cipher
	log.Printf("server listening port %v ...\n", port)
	for {
		conn, err := ln.Accept()
		if err != nil {
			// listener maybe closed to update password
			debug.Printf("accept error: %v\n", err)
			return
		}
		// Creating cipher upon first connection.
		if cipher == nil {
			log.Println("creating cipher for port:", port)
			cipher, err = ss.NewCipher(config.Method, password)
			if err != nil {
				log.Printf("Error generating cipher for port: %s %v\n", port, err)
				conn.Close()
				continue
			}
		}
		go handleConnection(ss.NewConn(conn, cipher.Copy()))
	}
}
Exemple #6
0
func clientMethodSelected(method uint8, conn net.Conn) (net.Conn, error) {
	switch method {
	case gosocks5.MethodUserPass:
		user, pass := parseUserPass(Password)
		if err := clientSocksAuth(conn, user, pass); err != nil {
			return nil, err
		}
	case MethodTLS, MethodTLSAuth:
		conn = tls.Client(conn, &tls.Config{InsecureSkipVerify: true})
		if method == MethodTLSAuth {
			if len(Password) == 0 {
				return nil, ErrEmptyAuth
			}
			if err := clientSocksAuth(conn, "", Password); err != nil {
				return nil, err
			}
		}
	case MethodAES128, MethodAES192, MethodAES256,
		MethodDES, MethodBF, MethodCAST5, MethodRC4MD5, MethodRC4, MethodTable:
		cipher, err := shadowsocks.NewCipher(Methods[method], Password)
		if err != nil {
			log.Println(err)
			return nil, err
		}
		conn = shadowsocks.NewConn(conn, cipher)
	case gosocks5.MethodNoAcceptable:
		return nil, gosocks5.ErrBadMethod
	}

	return conn, nil
}
Exemple #7
0
func forward(conn net.Conn, arg Args) (net.Conn, error) {
	var err error
	if glog.V(LINFO) {
		proto := arg.Protocol
		if proto == "default" {
			proto = "http" // default is http
		}
		glog.Infof("forward: %s/%s %s", proto, arg.Transport, arg.Addr)
	}
	switch arg.Transport {
	case "ws": // websocket connection
		conn, err = wsClient(conn, arg.Addr)
		if err != nil {
			return nil, err
		}
	case "tls": // tls connection
		conn = tls.Client(conn, &tls.Config{InsecureSkipVerify: true})
	case "tcp":
		fallthrough
	default:
	}

	switch arg.Protocol {
	case "socks", "socks5":
		selector := &clientSelector{
			methods: []uint8{
				gosocks5.MethodNoAuth,
				gosocks5.MethodUserPass,
				MethodTLS,
			},
			arg: arg,
		}
		c := gosocks5.ClientConn(conn, selector)
		if err := c.Handleshake(); err != nil {
			return nil, err
		}
		conn = c
	case "ss": // shadowsocks
		if arg.User != nil {
			method := arg.User.Username()
			password, _ := arg.User.Password()
			cipher, err := shadowsocks.NewCipher(method, password)
			if err != nil {
				return nil, err
			}
			conn = shadowsocks.NewConn(conn, cipher)
		}
	case "http":
		fallthrough
	default:
	}

	return conn, nil
}
Exemple #8
0
func (cp *cowParent) connect(url *URL) (net.Conn, error) {
	c, err := net.Dial("tcp", cp.server)
	if err != nil {
		errl.Printf("can't connect to cow parent %s for %s: %v\n",
			cp.server, url.HostPort, err)
		return nil, err
	}
	debug.Printf("connected to: %s via cow parent: %s\n",
		url.HostPort, cp.server)
	ssconn := ss.NewConn(c, cp.cipher.Copy())
	return cowConn{ssconn, cp}, nil
}
Exemple #9
0
func (s *ProxyServer) newClient(conn net.Conn) {

	conn.SetReadDeadline(time.Now().Add(s.config.Timeout * time.Second))

	client := &client{
		Conn:   ss.NewConn(conn, s.Cip.Copy()),
		server: s,
	}

	go client.listen()
	s.CallbackMethods.NewClient(client)
}
Exemple #10
0
func runWithCustomMethod(user user.User) {
	// port, password string, Cipher *ss.Cipher
	port := strconv.Itoa(user.GetPort())
	// 检测端口是否已存在
	_, ok := passwdManager.get(port)
	// 如果存在
	if ok {
		return
	}
	password := user.GetPasswd()
	ln, err := net.Listen("tcp", ":"+port)
	if err != nil {
		Log.Error(fmt.Sprintf("error listening port %v: %v\n", port, err))
		// os.Exit(1)
		return
	}
	passwdManager.add(port, password, ln)
	cipher, err, auth := user.GetCipher()
	if err != nil {
		return
	}
	Log.Info(fmt.Sprintf("server listening port %v ...\n", port))
	for {
		conn, err := ln.Accept()
		if err != nil {
			// listener maybe closed to update password
			Log.Debug(fmt.Sprintf("accept error: %v\n", err))
			return
		}
		// Creating cipher upon first connection.
		if cipher == nil {
			Log.Debug("creating cipher for port:", port)
			method := user.GetMethod()

			if strings.HasSuffix(method, "-auth") {
				method = method[:len(method)-5]
				auth = true
			} else {
				auth = false
			}

			cipher, err = ss.NewCipher(method, password)
			if err != nil {
				Log.Error(fmt.Sprintf("Error generating cipher for port: %s %v\n", port, err))
				conn.Close()
				continue
			}
		}
		go handleConnection(user, ss.NewConn(conn, cipher.Copy()), auth)
	}
}
Exemple #11
0
func serverMethodSelected(method uint8, conn net.Conn) (net.Conn, error) {
	//log.Println(method)
	switch method {
	case gosocks5.MethodUserPass:
		var username, password string

		if listenUrl != nil && listenUrl.User != nil {
			username = listenUrl.User.Username()
			password, _ = listenUrl.User.Password()
		}

		if err := serverSocksAuth(conn, username, password); err != nil {
			return nil, err
		}
	case MethodTLS, MethodTLSAuth:
		var cert tls.Certificate
		var err error

		if len(CertFile) == 0 || len(KeyFile) == 0 {
			cert, err = tls.X509KeyPair([]byte(rawCert), []byte(rawKey))
		} else {
			cert, err = tls.LoadX509KeyPair(CertFile, KeyFile)
		}

		if err != nil {
			return nil, err
		}
		conn = tls.Server(conn, &tls.Config{Certificates: []tls.Certificate{cert}})
		if method == MethodTLSAuth {
			// password is mandatory
			if len(Password) == 0 {
				return nil, ErrEmptyAuth
			}
			if err := serverSocksAuth(conn, "", Password); err != nil {
				return nil, err
			}
		}
	case MethodAES128, MethodAES192, MethodAES256,
		MethodDES, MethodBF, MethodCAST5, MethodRC4MD5, MethodRC4, MethodTable:
		cipher, err := shadowsocks.NewCipher(Methods[method], Password)
		if err != nil {
			return nil, err
		}
		conn = shadowsocks.NewConn(conn, cipher)
	case gosocks5.MethodNoAcceptable:
		return nil, gosocks5.ErrBadMethod
	}

	return conn, nil
}
Exemple #12
0
func run(port, password string) {

	var addr string
	var lastTime int64

	ln, err := net.Listen("tcp", ":"+port)
	if err != nil {
		log.Printf("error listening port %v: %v\n", port, err)
		return
	}
	passwdManager.add(port, password, ln)
	var cipher *ss.Cipher
	log.Printf("server listening port %v ...\n", port)
	for {
		conn, err := ln.Accept()
		if err != nil {
			// listener maybe closed to update password
			debug.Printf("accept error: %v\n", err)
			return
		}

		newaddr := conn.RemoteAddr().String()
		nowtime := time.Now().Unix()
		if addr != newaddr && lastTime >= nowtime {
			conn.Close()
			continue
		}
		lastTime = nowtime
		addr = newaddr

		// Creating cipher upon first connection.
		if cipher == nil {
			log.Println("creating cipher for port:", port)
			cipher, err = ss.NewCipher(config.Method, password)
			if err != nil {
				log.Printf("Error generating cipher for port: %s %v\n", port, err)
				conn.Close()
				continue
			}
		}
		go handleConnection(ss.NewConn(conn, cipher.Copy()))
	}
}
func run(port, password string) {
	ln, err := net.Listen("tcp", ":"+port)
	if err != nil {
		log.Printf("try listening port %v: %v\n", port, err)
		return
	}
	passwdManager.add(port, password, ln)
	encTbl := getTable(password)
	atomic.AddInt32(&table.getCnt, 1)
	log.Printf("server listening port %v ...\n", port)
	for {
		conn, err := ln.Accept()
		if err != nil {
			// listener maybe closed to update password
			debug.Printf("accept error: %v\n", err)
			return
		}
		go handleConnection(ss.NewConn(conn, encTbl))
	}
}
Exemple #14
0
func cliHandle(conn net.Conn) {
	defer conn.Close()

	if Shadows {
		cipher, _ := shadowsocks.NewCipher(SMethod, SPassword)
		conn = shadowsocks.NewConn(conn, cipher)
		handleShadow(conn)
		return
	}

	b := mpool.Take()
	defer mpool.put(b)

	n, err := io.ReadAtLeast(conn, b, 2)
	if err != nil {
		return
	}

	if b[0] == gosocks5.Ver5 {
		mn := int(b[1]) // methods count
		length := 2 + mn
		if n < length {
			if _, err := io.ReadFull(conn, b[n:length]); err != nil {
				return
			}
		}

		methods := b[2 : 2+mn]
		handleSocks5(conn, methods)
		return
	}

	req, err := http.ReadRequest(bufio.NewReader(newReqReader(b[:n], conn)))
	if err != nil {
		//log.Println(hex.Dump(b[:n]))
		log.Println(err)
		return
	}
	handleHttp(req, conn)
}
Exemple #15
0
func (cp *cowProxy) Serve(wg *sync.WaitGroup) {
	defer func() {
		wg.Done()
	}()
	ln, err := net.Listen("tcp", cp.addr)
	if err != nil {
		fmt.Println("listen cow failed:", err)
		return
	}
	info.Printf("COW %s cow proxy address %s\n", version, cp.addr)

	for {
		conn, err := ln.Accept()
		if err != nil {
			errl.Printf("cow proxy(%s) accept %v\n", ln.Addr(), err)
			continue
		}
		ssConn := ss.NewConn(conn, cp.cipher.Copy())
		c := newClientConn(ssConn, cp)
		go c.serve()
	}
}
Exemple #16
0
func run(port string) {
	ln, err := net.Listen("tcp", ":"+port)
	if err != nil {
		log.Printf("error listening port %v: %v\n", port, err)
		os.Exit(0)
	}
	var cipher *ss.Cipher
	log.Printf("server listening port %v ...\n", port)
	for {
		conn, err := ln.Accept()
		if err != nil {
			log.Printf("accept error: %v\n", err)
			continue
		}

		user, err := getUser(conn)
		if err != nil {
			log.Printf("Error get passeoed: %s %v\n", port, err)
			conn.Close()
			continue
		}
		size, err := storage.GetSize("flow:" + user.Name)
		if user.Limit < size {
			log.Printf("Error user runover: %s\n", size)
			conn.Close()
			continue
		}

		// log.Println("creating cipher for user:"******"Error generating cipher for user: %s %v\n", user.Name, err)
			conn.Close()
			continue
		}
		go handleConnection(user, ss.NewConn(conn, cipher.Copy()))
	}
}
Exemple #17
0
func DialWithRawAddr(rawaddr []byte, user User, server string, cipher *ss.Cipher) (remote *ss.Conn, err error) {
	conn, err := net.Dial("tcp", server)
	if err != nil {
		return nil, err
	}
	buf := make([]byte, 2)
	buf[0] = 1
	buf[1] = byte(len(user.Name))
	if _, err = conn.Write(buf); err != nil {
		conn.Close()
		return nil, err
	}
	if _, err = conn.Write([]byte(user.Name)); err != nil {
		conn.Close()
		return nil, err
	}
	remote = ss.NewConn(conn, cipher)
	if _, err = remote.Write(rawaddr); err != nil {
		remote.Close()
		return nil, err
	}
	return
}
Exemple #18
0
func (cp *cowProxy) Serve(wg *sync.WaitGroup, quit <-chan struct{}) {
	defer func() {
		wg.Done()
	}()

	ln, err := net.Listen("tcp", cp.addr)
	if err != nil {
		fmt.Println("listen cow failed:", err)
		return
	}
	info.Printf("COW %s cow proxy address %s\n", version, cp.addr)
	var exit bool
	go func() {
		<-quit
		exit = true
		ln.Close()
	}()
	for {
		conn, err := ln.Accept()
		if err != nil && !exit {
			errl.Printf("cow proxy(%s) accept %v\n", ln.Addr(), err)
			if isErrTooManyOpenFd(err) {
				connPool.CloseAll()
			}
			time.Sleep(time.Millisecond)
			continue
		}
		if exit {
			debug.Println("exiting cow listner")
			break
		}
		ssConn := ss.NewConn(conn, cp.cipher.Copy())
		c := newClientConn(ssConn, cp)
		go c.serve()
	}
}
Exemple #19
0
func TestSsProxy(t *testing.T) {

	// 测试域名
	testAddr := "www.test123.com:80"
	testData := []byte("dsgbhdfhgsq36jhrawdxghucn46ggetst")
	testServerAddr := "127.0.0.1:1458"
	testMethod := "aes-256-cfb"
	testPassword := "******"
	testRawAddr, err := ss.RawAddr(testAddr)
	if err != nil {
		t.Fatal(err)
	}

	// 简单模拟服务器
	cipher, err := ss.NewCipher(testMethod, testPassword)
	if err != nil {
		t.Fatal(err)
	}

	l, err := net.Listen("tcp", testServerAddr)
	if err != nil {
		t.Fatal(err)
	}
	defer l.Close()

	go func() {
		c, err := l.Accept()
		if err != nil {
			t.Fatal(err)
		}
		c.SetDeadline(time.Now().Add(5 * time.Second))

		sc := ss.NewConn(c, cipher)
		defer sc.Close()

		// 读内容并返回
		for i := 0; i < 2; i++ {
			buf := make([]byte, 1024)
			if n, err := sc.Read(buf); err != nil {
				t.Fatal("i=", i, "服务器读内容错误:", err)
			} else {
				if _, err := sc.Write(buf[:n]); err != nil {
					t.Fatal(err)
				}
			}
		}
	}()

	// 发出请求,然后解密。
	p, err := newSsProxyClient(testServerAddr, testMethod, testPassword, nil, nil)
	if err != nil {
		t.Fatal(err)
	}

	c, err := p.DialTimeout("tcp", testAddr, 1*time.Second)
	if err != nil {
		t.Fatal(err)
	}
	defer c.Close()

	// 比较地址是否正确
	buf := make([]byte, 1024)
	if n, err := c.Read(buf); err != nil {
		t.Fatal("读地址错误:", err)
	} else {
		if bytes.Compare(buf[:n], testRawAddr) != 0 {
			t.Fatal("地址未正确发送")
		}
	}

	// 发送测试数据,并读取比较
	if _, err := c.Write(testData); err != nil {
		t.Fatal(err)
	}

	if n, err := c.Read(buf); err != nil {
		t.Fatal(err)
	} else {
		if bytes.Compare(buf[:n], testData) != 0 {
			t.Fatal("数据未正确发送")
		}
	}
}
Exemple #20
0
func (s *ProxyServer) handleConn(conn net.Conn) {
	defer conn.Close()

	switch s.Node.Protocol {
	case "ss": // shadowsocks
		server := NewShadowServer(ss.NewConn(conn, s.cipher.Copy()), s)
		server.OTA = s.Node.getBool("ota")
		server.Serve()
		return
	case "http":
		req, err := http.ReadRequest(bufio.NewReader(conn))
		if err != nil {
			glog.V(LWARNING).Infoln("[http]", err)
			return
		}
		NewHttpServer(conn, s).HandleRequest(req)
		return
	case "socks", "socks5":
		conn = gosocks5.ServerConn(conn, s.selector)
		req, err := gosocks5.ReadRequest(conn)
		if err != nil {
			glog.V(LWARNING).Infoln("[socks5]", err)
			return
		}
		NewSocks5Server(conn, s).HandleRequest(req)
		return
	}

	// http or socks5
	b := make([]byte, MediumBufferSize)

	n, err := io.ReadAtLeast(conn, b, 2)
	if err != nil {
		glog.V(LWARNING).Infoln(err)
		return
	}

	// TODO: use bufio.Reader
	if b[0] == gosocks5.Ver5 {
		mn := int(b[1]) // methods count
		length := 2 + mn
		if n < length {
			if _, err := io.ReadFull(conn, b[n:length]); err != nil {
				glog.V(LWARNING).Infoln("[socks5]", err)
				return
			}
		}
		// TODO: use gosocks5.ServerConn
		methods := b[2 : 2+mn]
		method := s.selector.Select(methods...)
		if _, err := conn.Write([]byte{gosocks5.Ver5, method}); err != nil {
			glog.V(LWARNING).Infoln("[socks5] select:", err)
			return
		}
		c, err := s.selector.OnSelected(method, conn)
		if err != nil {
			glog.V(LWARNING).Infoln("[socks5] onselected:", err)
			return
		}
		conn = c

		req, err := gosocks5.ReadRequest(conn)
		if err != nil {
			glog.V(LWARNING).Infoln("[socks5] request:", err)
			return
		}
		NewSocks5Server(conn, s).HandleRequest(req)
		return
	}

	req, err := http.ReadRequest(bufio.NewReader(&reqReader{b: b[:n], r: conn}))
	if err != nil {
		glog.V(LWARNING).Infoln("[http]", err)
		return
	}
	NewHttpServer(conn, s).HandleRequest(req)
}
Exemple #21
0
func (c *ProxyConn) handshake() error {
	var tlsUsed bool

	switch c.Node.Transport {
	case "ws": // websocket connection
		u := url.URL{Scheme: "ws", Host: c.Node.Addr, Path: "/ws"}
		conn, err := WebsocketClientConn(u.String(), c.conn, nil)
		if err != nil {
			return err
		}
		c.conn = conn
	case "wss": // websocket security
		tlsUsed = true
		u := url.URL{Scheme: "wss", Host: c.Node.Addr, Path: "/ws"}
		config := &tls.Config{
			InsecureSkipVerify: c.Node.insecureSkipVerify(),
			ServerName:         c.Node.serverName,
		}
		conn, err := WebsocketClientConn(u.String(), c.conn, config)
		if err != nil {
			return err
		}
		c.conn = conn
	case "tls", "http2": // tls connection
		tlsUsed = true
		cfg := &tls.Config{
			InsecureSkipVerify: c.Node.insecureSkipVerify(),
			ServerName:         c.Node.serverName,
		}
		c.conn = tls.Client(c.conn, cfg)
	case "h2": // same as http2, but just set a flag for later using.
		tlsUsed = true
	case "kcp": // kcp connection
		tlsUsed = true
	default:
	}

	switch c.Node.Protocol {
	case "socks", "socks5": // socks5 handshake with auth and tls supported
		selector := &clientSelector{
			methods: []uint8{
				gosocks5.MethodNoAuth,
				gosocks5.MethodUserPass,
				//MethodTLS,
			},
			user: c.Node.User,
		}

		if !tlsUsed { // if transport is not security, enable security socks5
			selector.methods = append(selector.methods, MethodTLS)
			selector.tlsConfig = &tls.Config{
				InsecureSkipVerify: c.Node.insecureSkipVerify(),
				ServerName:         c.Node.serverName,
			}
		}

		conn := gosocks5.ClientConn(c.conn, selector)
		if err := conn.Handleshake(); err != nil {
			return err
		}
		c.conn = conn
	case "ss": // shadowsocks
		if c.Node.User != nil {
			method := c.Node.User.Username()
			password, _ := c.Node.User.Password()
			cipher, err := shadowsocks.NewCipher(method, password)
			if err != nil {
				return err
			}
			c.conn = &shadowConn{conn: shadowsocks.NewConn(c.conn, cipher)}
		}
	case "http", "http2":
		fallthrough
	default:
	}

	c.handshaked = true

	return nil
}
Exemple #22
0
func (p *ssProxyClient) DialTCPSAddrTimeout(network string, raddr string, timeout time.Duration) (rconn ProxyTCPConn, rerr error) {
	// 截止时间
	finalDeadline := time.Time{}
	if timeout != 0 {
		finalDeadline = time.Now().Add(timeout)
	}

	ra, err := ss.RawAddr(raddr)
	if err != nil {
		return
	}

	c, err := p.upProxy.DialTCPSAddrTimeout(network, p.proxyAddr, timeout)
	if err != nil {
		return nil, fmt.Errorf("无法连接代理服务器 %v ,错误:%v", p.proxyAddr, err)
	}
	ch := make(chan int)
	defer close(ch)

	// 实际执行部分
	run := func() {
		sc := ss.NewConn(c, p.cipher.Copy())

		closed := false
		// 当连接不被使用时,ch<-1会引发异常,这时将关闭连接。
		defer func() {
			e := recover()
			if e != nil && closed == false {
				sc.Close()
			}
		}()

		if _, err := sc.Write(ra); err != nil {
			closed = true
			sc.Close()
			rerr = err
			ch <- 0
			return
		}

		r := ssTCPConn{TCPConn: c, sc: sc, proxyClient: p} //{c,net.ResolveTCPAddr("tcp","0.0.0.0:0"),net.ResolveTCPAddr("tcp","0.0.0.0:0"),"","",0,0  p}

		rconn = &r
		ch <- 1
	}

	if timeout == 0 {
		go run()

		select {
		case <-ch:
			return
		}
	} else {
		c.SetDeadline(finalDeadline)

		ntimeout := finalDeadline.Sub(time.Now())
		if ntimeout <= 0 {
			return nil, fmt.Errorf("timeout")
		}
		t := time.NewTimer(ntimeout)
		defer t.Stop()

		go run()

		select {
		case <-t.C:
			return nil, fmt.Errorf("连接超时。")
		case <-ch:
			if rerr == nil {
				c.SetDeadline(time.Time{})
			}
			return
		}
	}
}