Пример #1
0
func wsDial(src v2net.Address, dest v2net.Destination, options internet.DialerOptions) (*wsconn, error) {
	networkSettings, err := options.Stream.GetEffectiveNetworkSettings()
	if err != nil {
		return nil, err
	}
	wsSettings := networkSettings.(*Config)

	commonDial := func(network, addr string) (net.Conn, error) {
		return internet.DialToDest(src, dest)
	}

	dialer := websocket.Dialer{
		NetDial:         commonDial,
		ReadBufferSize:  65536,
		WriteBufferSize: 65536,
	}

	protocol := "ws"

	if options.Stream != nil && options.Stream.HasSecuritySettings() {
		protocol = "wss"
		securitySettings, err := options.Stream.GetEffectiveSecuritySettings()
		if err != nil {
			log.Error("WebSocket: Failed to create security settings: ", err)
			return nil, err
		}
		tlsConfig, ok := securitySettings.(*v2tls.Config)
		if ok {
			dialer.TLSClientConfig = tlsConfig.GetTLSConfig()
			if dest.Address.Family().IsDomain() {
				dialer.TLSClientConfig.ServerName = dest.Address.Domain()
			}
		}
	}

	uri := func(dst v2net.Destination, pto string, path string) string {
		return fmt.Sprintf("%v://%v/%v", pto, dst.NetAddr(), path)
	}(dest, protocol, wsSettings.Path)

	conn, resp, err := dialer.Dial(uri, nil)
	if err != nil {
		if resp != nil {
			reason, reasonerr := ioutil.ReadAll(resp.Body)
			log.Info(string(reason), reasonerr)
		}
		return nil, err
	}
	return func() internet.Connection {
		connv2ray := &wsconn{
			wsc:         conn,
			connClosing: false,
			config:      wsSettings,
		}
		connv2ray.setup()
		return connv2ray
	}().(*wsconn), nil
}
Пример #2
0
func wsDial(ctx context.Context, dest v2net.Destination) (*wsconn, error) {
	src := internet.DialerSourceFromContext(ctx)
	wsSettings := internet.TransportSettingsFromContext(ctx).(*Config)

	commonDial := func(network, addr string) (net.Conn, error) {
		return internet.DialSystem(src, dest)
	}

	dialer := websocket.Dialer{
		NetDial:         commonDial,
		ReadBufferSize:  32 * 1024,
		WriteBufferSize: 32 * 1024,
	}

	protocol := "ws"

	if securitySettings := internet.SecuritySettingsFromContext(ctx); securitySettings != nil {
		tlsConfig, ok := securitySettings.(*v2tls.Config)
		if ok {
			protocol = "wss"
			dialer.TLSClientConfig = tlsConfig.GetTLSConfig()
			if dest.Address.Family().IsDomain() {
				dialer.TLSClientConfig.ServerName = dest.Address.Domain()
			}
		}
	}

	host := dest.NetAddr()
	if (protocol == "ws" && dest.Port == 80) || (protocol == "wss" && dest.Port == 443) {
		host = dest.Address.String()
	}
	uri := protocol + "://" + host + "/" + wsSettings.Path

	conn, resp, err := dialer.Dial(uri, nil)
	if err != nil {
		if resp != nil {
			reason, reasonerr := ioutil.ReadAll(resp.Body)
			log.Info(string(reason), reasonerr)
		}
		return nil, err
	}
	return func() internet.Connection {
		connv2ray := &wsconn{
			wsc:         conn,
			connClosing: false,
			config:      wsSettings,
		}
		connv2ray.setup()
		return connv2ray
	}().(*wsconn), nil
}
Пример #3
0
// Connect create new bitfinex websocket connection
func (w *WebSocketService) Connect() error {
	var d = websocket.Dialer{
		Subprotocols:    []string{"p1", "p2"},
		ReadBufferSize:  1024,
		WriteBufferSize: 1024,
		Proxy:           http.ProxyFromEnvironment,
	}

	if w.client.WebSocketTLSSkipVerify {
		d.TLSClientConfig = &tls.Config{InsecureSkipVerify: true}
	}

	ws, _, err := d.Dial(w.client.WebSocketURL, nil)
	if err != nil {
		return err
	}
	w.ws = ws
	return nil
}
Пример #4
0
func (w *WebSocketService) ConnectPrivate(ch chan TermData) {

	var d = websocket.Dialer{
		Subprotocols:    []string{"p1", "p2"},
		ReadBufferSize:  1024,
		WriteBufferSize: 1024,
		Proxy:           http.ProxyFromEnvironment,
	}

	ws, _, err := d.Dial(w.client.WebSocketURL, nil)

	if w.client.WebSocketTLSSkipVerify {
		d.TLSClientConfig = &tls.Config{InsecureSkipVerify: true}
	}

	ws, _, err = d.Dial(w.client.WebSocketURL, nil)
	if err != nil {
		ch <- TermData{
			Error: err.Error(),
		}
		return
	}

	payload := "AUTH" + fmt.Sprintf("%v", time.Now().Unix())
	connectMsg, _ := json.Marshal(&privateConnect{
		Event:       "auth",
		ApiKey:      w.client.ApiKey,
		AuthSig:     w.client.signPayload(payload),
		AuthPayload: payload,
	})

	// Send auth message
	err = ws.WriteMessage(websocket.TextMessage, connectMsg)
	if err != nil {
		ch <- TermData{
			Error: err.Error(),
		}
		ws.Close()
		return
	}

	var msg string
	for {
		_, p, err := ws.ReadMessage()
		if err != nil {
			ch <- TermData{
				Error: err.Error(),
			}
			ws.Close()
			return
		} else {
			msg = string(p)
			event := &privateResponse{}
			err = json.Unmarshal([]byte(msg), &event)
			if err != nil {
				// received data update
				var data []interface{}
				err = json.Unmarshal([]byte(msg), &data)
				if err == nil {
					dataTerm := data[1].(string)
					dataList := data[2].([]interface{})

					// check for empty data
					if len(dataList) > 0 {
						if reflect.TypeOf(dataList[0]) == reflect.TypeOf([]interface{}{}) {
							// received list of lists
							for _, v := range dataList {
								ch <- TermData{
									Term: dataTerm,
									Data: v.([]interface{}),
								}
							}
						} else {
							// received flat list
							ch <- TermData{
								Term: dataTerm,
								Data: dataList,
							}
						}
					}
				}
			} else {
				// received auth response
				if event.Event == "auth" && event.Status != "OK" {
					ch <- TermData{
						Error: "Error connecting to private web socket channel.",
					}
					ws.Close()
				}
			}
		}
	}
}