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 }
func connectSocks5Proxy(addr string) (conn net.Conn, err error) { conn, err = dial(proxyURL.Host) if err != nil { return } conf := &gosocks5.Config{ // Methods: []uint8{gosocks5.MethodNoAuth, gosocks5.MethodUserPass}, MethodSelected: proxyMethodSelected, } if proxyURL.User != nil { conf.Methods = []uint8{gosocks5.MethodUserPass} } c := gosocks5.ClientConn(conn, conf) if err := c.Handleshake(); err != nil { conn.Close() return nil, err } conn = c s := strings.Split(addr, ":") host := s[0] port := 80 if len(s) == 2 { n, _ := strconv.ParseUint(s[1], 10, 16) port = int(n) } a := &gosocks5.Addr{ Type: gosocks5.AddrDomain, Host: host, Port: uint16(port), } if err := gosocks5.NewRequest(gosocks5.CmdConnect, a).Write(conn); err != nil { conn.Close() return nil, err } rep, err := gosocks5.ReadReply(conn) if err != nil { conn.Close() return nil, err } if rep.Rep != gosocks5.Succeeded { conn.Close() return nil, errors.New("Socks Failture") } return conn, nil }
func makeTunnel() (c net.Conn, err error) { if UseTLS || UseWebsocket || !UseHttp { c, err = connect(Saddr) } else { addr := Saddr if proxyURL != nil { addr = proxyURL.Host } c, err = dial(addr) } if err != nil { return } if UseTLS { config := &tls.Config{InsecureSkipVerify: true} c = tls.Client(c, config) } else if UseWebsocket { ws, resp, err := websocket.NewClient(c, &url.URL{Host: Saddr}, nil, 8192, 8192) if err != nil { c.Close() return nil, err } resp.Body.Close() c = NewWSConn(ws) } else if UseHttp { httpcli := NewHttpClientConn(c) if err = httpcli.Handshake(); err != nil { c.Close() return nil, err } c = httpcli //defer httpcli.Close() } sc := gosocks5.ClientConn(c, clientConfig) if err = sc.Handleshake(); err != nil { c.Close() return nil, err } c = sc return }
func forward(conn net.Conn, arg Args) (net.Conn, error) { var err error 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 "ss": // shadowsocks return nil, errors.New("Not implemented") 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 "http": fallthrough default: } return conn, nil }
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 }