Example #1
0
func JoinSession(invitation protocol.SessionInvitation) (net.Conn, error) {
	addr := net.JoinHostPort(net.IP(invitation.Address).String(), strconv.Itoa(int(invitation.Port)))

	conn, err := dialer.Dial("tcp", addr)
	if err != nil {
		return nil, err
	}

	request := protocol.JoinSessionRequest{
		Key: invitation.Key,
	}

	conn.SetDeadline(time.Now().Add(10 * time.Second))
	err = protocol.WriteMessage(conn, request)
	if err != nil {
		return nil, err
	}

	message, err := protocol.ReadMessage(conn)
	if err != nil {
		return nil, err
	}

	conn.SetDeadline(time.Time{})

	switch msg := message.(type) {
	case protocol.Response:
		if msg.Code != 0 {
			return nil, fmt.Errorf("Incorrect response code %d: %s", msg.Code, msg.Message)
		}
		return conn, nil
	default:
		return nil, fmt.Errorf("protocol error: expecting response got %v", msg)
	}
}
Example #2
0
func makeTCPDialer(network string) DialerFactory {
	return func(uri *url.URL, tlsCfg *tls.Config) (*tls.Conn, error) {
		// Check that there is a port number in uri.Host, otherwise add one.
		host, port, err := net.SplitHostPort(uri.Host)
		if err != nil && strings.HasPrefix(err.Error(), "missing port") {
			// addr is on the form "1.2.3.4"
			uri.Host = net.JoinHostPort(uri.Host, "22000")
		} else if err == nil && port == "" {
			// addr is on the form "1.2.3.4:"
			uri.Host = net.JoinHostPort(host, "22000")
		}

		// Don't try to resolve the address before dialing. The dialer may be a
		// proxy, and we should let the proxy do the resolving in that case.
		conn, err := dialer.Dial(network, uri.Host)
		if err != nil {
			l.Debugln(err)
			return nil, err
		}

		tc := tls.Client(conn, tlsCfg)
		err = tc.Handshake()
		if err != nil {
			tc.Close()
			return nil, err
		}

		return tc, nil
	}
}
func tcpDialer(uri *url.URL, tlsCfg *tls.Config) (*tls.Conn, error) {
	host, port, err := net.SplitHostPort(uri.Host)
	if err != nil && strings.HasPrefix(err.Error(), "missing port") {
		// addr is on the form "1.2.3.4"
		uri.Host = net.JoinHostPort(uri.Host, "22000")
	} else if err == nil && port == "" {
		// addr is on the form "1.2.3.4:"
		uri.Host = net.JoinHostPort(host, "22000")
	}

	raddr, err := net.ResolveTCPAddr("tcp", uri.Host)
	if err != nil {
		l.Debugln(err)
		return nil, err
	}

	conn, err := dialer.Dial(raddr.Network(), raddr.String())
	if err != nil {
		l.Debugln(err)
		return nil, err
	}

	tc := tls.Client(conn, tlsCfg)
	err = tc.Handshake()
	if err != nil {
		tc.Close()
		return nil, err
	}

	return tc, nil
}
Example #4
0
func (c *ProtocolClient) connect() error {
	if c.URI.Scheme != "relay" {
		return fmt.Errorf("Unsupported relay schema: %v", c.URI.Scheme)
	}

	t0 := time.Now()
	tcpConn, err := dialer.Dial("tcp", c.URI.Host)
	if err != nil {
		return err
	}

	c.mut.Lock()
	c.latency = time.Since(t0)
	c.mut.Unlock()

	conn := tls.Client(tcpConn, c.config)
	if err = conn.Handshake(); err != nil {
		return err
	}

	if err := conn.SetDeadline(time.Now().Add(10 * time.Second)); err != nil {
		conn.Close()
		return err
	}

	if err := performHandshakeAndValidation(conn, c.URI); err != nil {
		conn.Close()
		return err
	}

	c.conn = conn
	return nil
}
Example #5
0
func localIP(url *url.URL) (string, error) {
	conn, err := dialer.Dial("tcp", url.Host)
	if err != nil {
		return "", err
	}
	defer conn.Close()

	localIPAddress, _, err := net.SplitHostPort(conn.LocalAddr().String())
	if err != nil {
		return "", err
	}

	return localIPAddress, nil
}
Example #6
0
func GetInvitationFromRelay(uri *url.URL, id syncthingprotocol.DeviceID, certs []tls.Certificate) (protocol.SessionInvitation, error) {
	if uri.Scheme != "relay" {
		return protocol.SessionInvitation{}, fmt.Errorf("Unsupported relay scheme: %v", uri.Scheme)
	}

	rconn, err := dialer.Dial("tcp", uri.Host)
	if err != nil {
		return protocol.SessionInvitation{}, err
	}

	conn := tls.Client(rconn, configForCerts(certs))
	conn.SetDeadline(time.Now().Add(10 * time.Second))

	if err := performHandshakeAndValidation(conn, uri); err != nil {
		return protocol.SessionInvitation{}, err
	}

	defer conn.Close()

	request := protocol.ConnectRequest{
		ID: id[:],
	}

	if err := protocol.WriteMessage(conn, request); err != nil {
		return protocol.SessionInvitation{}, err
	}

	message, err := protocol.ReadMessage(conn)
	if err != nil {
		return protocol.SessionInvitation{}, err
	}

	switch msg := message.(type) {
	case protocol.Response:
		return protocol.SessionInvitation{}, fmt.Errorf("Incorrect response code %d: %s", msg.Code, msg.Message)
	case protocol.SessionInvitation:
		l.Debugln("Received invitation", msg, "via", conn.LocalAddr())
		ip := net.IP(msg.Address)
		if len(ip) == 0 || ip.IsUnspecified() {
			msg.Address = conn.RemoteAddr().(*net.TCPAddr).IP[:]
		}
		return msg, nil
	default:
		return protocol.SessionInvitation{}, fmt.Errorf("protocol error: unexpected message %v", msg)
	}
}
Example #7
0
func (s *usageReportingService) sendUsageReport() error {
	d := reportData(s.cfg, s.model)
	var b bytes.Buffer
	json.NewEncoder(&b).Encode(d)

	transp := &http.Transport{}
	client := &http.Client{Transport: transp}
	if BuildEnv == "android" {
		// This works around the lack of DNS resolution on Android... :(
		transp.Dial = func(network, addr string) (net.Conn, error) {
			return dialer.Dial(network, "194.126.249.13:443")
		}
	}

	if s.cfg.Options().URPostInsecurely {
		transp.TLSClientConfig = &tls.Config{
			InsecureSkipVerify: true,
		}
	}
	_, err := client.Post(s.cfg.Options().URURL, "application/json", &b)
	return err
}