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) } }
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 }
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 }
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 }
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) } }
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 }