From eda1f5482b371ffa72c1ee87f77a229546d9c842 Mon Sep 17 00:00:00 2001 From: frank Date: Mon, 11 Sep 2023 20:19:26 +0800 Subject: [PATCH] fix mobile issue: Sync is hanging in "syncing devices" stage (#4010) align another time of cert addressed feedback from @Samyoul @igor-sirotin add logger move line fix mobile issue #17223 --- VERSION | 2 +- server/pairing/certs.go | 4 +- server/pairing/client.go | 53 ++++++++++++++++++--------- server/pairing/preflight/preflight.go | 7 +++- 4 files changed, 45 insertions(+), 21 deletions(-) diff --git a/VERSION b/VERSION index 2897aa6e8..1f4108a97 100644 --- a/VERSION +++ b/VERSION @@ -1 +1 @@ -0.166.7 \ No newline at end of file +0.166.8 diff --git a/server/pairing/certs.go b/server/pairing/certs.go index 1f08451e6..55fec1d04 100644 --- a/server/pairing/certs.go +++ b/server/pairing/certs.go @@ -19,6 +19,8 @@ import ( "github.com/status-im/status-go/server" ) +const CertificateMaxClockDrift = time.Minute + func makeSerialNumberFromKey(pk *ecdsa.PrivateKey) *big.Int { h := sha256.New() h.Write(append(pk.D.Bytes(), append(pk.Y.Bytes(), pk.X.Bytes()...)...)) @@ -27,7 +29,7 @@ func makeSerialNumberFromKey(pk *ecdsa.PrivateKey) *big.Int { } func GenerateCertFromKey(pk *ecdsa.PrivateKey, from time.Time, IPAddresses []net.IP, DNSNames []string) (tls.Certificate, []byte, error) { - cert := server.GenerateX509Cert(makeSerialNumberFromKey(pk), from, from.Add(time.Hour), IPAddresses, DNSNames) + cert := server.GenerateX509Cert(makeSerialNumberFromKey(pk), from.Add(-CertificateMaxClockDrift), from.Add(time.Hour), IPAddresses, DNSNames) certPem, keyPem, err := server.GenerateX509PEMs(cert, pk) if err != nil { return tls.Certificate{}, nil, err diff --git a/server/pairing/client.go b/server/pairing/client.go index df345a637..00c8f1867 100644 --- a/server/pairing/client.go +++ b/server/pairing/client.go @@ -11,6 +11,9 @@ import ( "net/http" "net/http/cookiejar" "net/url" + "time" + + "go.uber.org/zap" "github.com/status-im/status-go/api" "github.com/status-im/status-go/logutils" @@ -35,22 +38,18 @@ type BaseClient struct { challengeTaker *ChallengeTaker } -// NewBaseClient returns a fully qualified BaseClient from the given ConnectionParams -func NewBaseClient(c *ConnectionParams) (*BaseClient, error) { - +func findServerCert(c *ConnectionParams) (*url.URL, *x509.Certificate, error) { + netIps, err := server.FindReachableAddressesForPairingClient(c.netIPs) + if err != nil { + return nil, nil, err + } var baseAddress *url.URL var serverCert *x509.Certificate var certErrs error - - netIps, err := server.FindReachableAddressesForPairingClient(c.netIPs) - if err != nil { - return nil, err - } - for i := range netIps { u, err := c.URL(i) if err != nil { - return nil, err + return nil, nil, err } serverCert, err = getServerCert(u) @@ -66,6 +65,26 @@ func NewBaseClient(c *ConnectionParams) (*BaseClient, error) { baseAddress = u break } + return baseAddress, serverCert, certErrs +} + +// NewBaseClient returns a fully qualified BaseClient from the given ConnectionParams +func NewBaseClient(c *ConnectionParams, logger *zap.Logger) (*BaseClient, error) { + var baseAddress *url.URL + var serverCert *x509.Certificate + var certErrs error + + maxRetries := 3 + for i := 0; i < maxRetries; i++ { + baseAddress, serverCert, certErrs = findServerCert(c) + if serverCert == nil { + certErrs = fmt.Errorf("failed to connect to any of given addresses. %w", certErrs) + time.Sleep(1 * time.Second) + logger.Warn("failed to connect to any of given addresses. Retrying...", zap.Error(certErrs)) + } else { + break + } + } if serverCert == nil { certErrs = fmt.Errorf("failed to connect to any of given addresses. %w", certErrs) @@ -76,7 +95,7 @@ func NewBaseClient(c *ConnectionParams) (*BaseClient, error) { // No error on the dial out then the URL.Host is accessible signal.SendLocalPairingEvent(Event{Type: EventConnectionSuccess, Action: ActionConnect}) - err = verifyCert(serverCert, c.publicKey) + err := verifyCert(serverCert, c.publicKey) if err != nil { return nil, err } @@ -149,7 +168,7 @@ func NewSenderClient(backend *api.GethStatusBackend, c *ConnectionParams, config logger := logutils.ZapLogger().Named("SenderClient") pe := NewPayloadEncryptor(c.aesKey) - bc, err := NewBaseClient(c) + bc, err := NewBaseClient(c, logger) if err != nil { return nil, err } @@ -320,12 +339,13 @@ type ReceiverClient struct { // NewReceiverClient returns a fully qualified ReceiverClient created with the incoming parameters func NewReceiverClient(backend *api.GethStatusBackend, c *ConnectionParams, config *ReceiverClientConfig) (*ReceiverClient, error) { - bc, err := NewBaseClient(c) + logger := logutils.ZapLogger().Named("ReceiverClient") + + bc, err := NewBaseClient(c, logger) if err != nil { return nil, err } - logger := logutils.ZapLogger().Named("ReceiverClient") pe := NewPayloadEncryptor(c.aesKey) ar, rmr, imr, err := NewPayloadReceivers(logger, pe, backend, config.ReceiverConfig) @@ -526,12 +546,11 @@ type KeystoreFilesReceiverClient struct { } func NewKeystoreFilesReceiverClient(backend *api.GethStatusBackend, c *ConnectionParams, config *KeystoreFilesReceiverClientConfig) (*KeystoreFilesReceiverClient, error) { - bc, err := NewBaseClient(c) + logger := logutils.ZapLogger().Named("ReceiverClient") + bc, err := NewBaseClient(c, logger) if err != nil { return nil, err } - - logger := logutils.ZapLogger().Named("ReceiverClient") pe := NewPayloadEncryptor(c.aesKey) kfrc, err := NewKeystoreFilesPayloadReceiver(backend, pe, config.ReceiverConfig, logger) diff --git a/server/pairing/preflight/preflight.go b/server/pairing/preflight/preflight.go index c3187de44..383005cff 100644 --- a/server/pairing/preflight/preflight.go +++ b/server/pairing/preflight/preflight.go @@ -11,6 +11,8 @@ import ( "sync" "time" + "github.com/status-im/status-go/server/pairing" + "go.uber.org/zap" "github.com/status-im/status-go/logutils" @@ -34,8 +36,9 @@ func preflightHandler(w http.ResponseWriter, r *http.Request) { } func makeCert(address net.IP) (*tls.Certificate, []byte, error) { - notBefore := time.Now() - notAfter := notBefore.Add(time.Minute) + now := time.Now() + notBefore := now.Add(-pairing.CertificateMaxClockDrift) + notAfter := now.Add(pairing.CertificateMaxClockDrift) return server.GenerateTLSCert(notBefore, notAfter, []net.IP{address}, []string{}) }