it-swarm.com.de

javax.net.ssl.SSLException: Lesefehler: ssl = 0x9524b800: E/A-Fehler während des Systemaufrufs, Verbindung von Peer zurückgesetzt

Unsere Kunden sehen in den letzten Wochen bereits Hunderte dieser "SSLException-Fehler - Verbindung von Peer zurückgesetzt" und ich weiß nicht, warum

  1. Wir verwenden Retrofit mit okhttp, keine spezielle Konfiguration

    public class OkHttpClientProvider implements IOkHttpClientProvider {
    
        OkHttpClient okHttpClient;
    
        public OkHttpClientProvider() {
            this.okHttpClient = createClient();
        }
    
        public OkHttpClient getOkHttpClient() {
            return this.okHttpClient;
        }
    
        private OkHttpClient createClient() {
            return new OkHttpClient();
        }
    }
    

Der obige Client-Provider ist ein Singleton. Der RestAdapter wird mit diesem injizierten Client erstellt (wir verwenden Dolch) - 

RestAdapter.Builder restAdapterBuilder = new RestAdapter.Builder()
                                        .setConverter(converter)
                                        .setEndpoint(networkRequestDetails.getServerUrl())
                                        .setClient(new OkClient(okHttpClientProvider.getOkHttpClient()))
                                        .setErrorHandler(new NetworkSynchronousErrorHandler(eventBus))
                                        );

Basierend auf Stack Overflow-Lösungen, was ich herausgefunden habe - 

  1. Die Keep-Alive-Dauer auf dem Server beträgt 180 Sekunden, OkHttp hat einen Standardwert von 300 Sekunden

  2. Der Server gibt "Connection: close" im Header zurück, die Clientanforderung sendet jedoch "Connection: keepAlive".

  3. Der Server unterstützt TLS 1.0/1.1/1.2 und verwendet Open SSL

  4. Unsere Server sind kürzlich zu einem anderen Hosting-Provider in eine andere Geografie umgezogen, daher weiß ich nicht, ob es sich um DNS-Fehler handelt oder nicht

  5. Wir haben versucht, Dinge wie KeepAlive zu optimieren, OpenSSL auf dem Server neu zu konfigurieren, aber aus irgendeinem Grund wird der Fehler beim Android-Client immer wieder angezeigt

  6. Es geschieht sofort ohne Verzögerung, wenn Sie versuchen, mit der App etwas zu posten oder zum Aktualisieren zu ziehen (es wird nicht einmal eine Netzwerkverbindung hergestellt oder es kommt zu einer Verzögerung, bevor diese Ausnahme auftritt, was bedeuten würde, dass die Verbindung bereits unterbrochen ist). Aber wenn wir es mehrmals versuchen, "repariert es irgendwie" und wir werden erfolgreich. Es passiert später wieder

  7. Wir haben unsere DNS-Einträge auf dem Server für ungültig erklärt, um zu sehen, ob dies die Ursache war, aber das hat nicht geholfen

  8. Es passiert meistens auf LTE, aber ich habe es auch auf Wifi gesehen

Ich möchte Keep Alive nicht deaktivieren, da die meisten modernen Kunden das nicht tun. Außerdem verwenden wir OkHttp 2.4. Dies ist ein Problem bei Post-Ice Cream Sandwich-Geräten. Ich hoffe, es sollte sich um die zugrunde liegenden Netzwerkprobleme kümmern. Der iOS-Client erhält diese Ausnahmen ebenfalls, ist jedoch fast 100-mal geringer (iOS-Client verwendet AFNetworking 2.0). Ich habe Mühe, neue Dinge zu finden, um an diesem Punkt etwas zu versuchen. Hilfe/Ideen?

Update - Hinzufügen eines vollständigen Stack-Trace durch okhttp

      retrofit.RetrofitError: Read error: ssl=0x9dd07200: I/O error during system call, Connection reset by peer
              at retrofit.RestAdapter$RestHandler.invokeRequest(RestAdapter.Java:390)
              at retrofit.RestAdapter$RestHandler.invoke(RestAdapter.Java:240)
              at Java.lang.reflect.Proxy.invoke(Proxy.Java:397)
              at $Proxy15.getAccessTokenUsingResourceOwnerPasswordCredentials(Unknown Source)
              at com.company.droid.repository.network.NetworkRepository.getAccessTokenUsingResourceOwnerPasswordCredentials(NetworkRepository.Java:76)
              at com.company.droid.ui.login.LoginTask.doInBackground(LoginTask.Java:88)
              at com.company.droid.ui.login.LoginTask.doInBackground(LoginTask.Java:23)
              at Android.os.AsyncTask$2.call(AsyncTask.Java:292)
              at Java.util.concurrent.FutureTask.run(FutureTask.Java:237)
              at Java.util.concurrent.ThreadPoolExecutor.runWorker(ThreadPoolExecutor.Java:1112)
              at Java.util.concurrent.ThreadPoolExecutor$Worker.run(ThreadPoolExecutor.Java:587)
              at Java.lang.Thread.run(Thread.Java:818)
       Caused by: javax.net.ssl.SSLException: Read error: ssl=0x9dd07200: I/O error during system call, Connection reset by peer
              at com.Android.org.conscrypt.NativeCrypto.SSL_read(Native Method)
              at com.Android.org.conscrypt.OpenSSLSocketImpl$SSLInputStream.read(OpenSSLSocketImpl.Java:699)
              at okio.Okio$2.read(Okio.Java:137)
              at okio.AsyncTimeout$2.read(AsyncTimeout.Java:211)
              at okio.RealBufferedSource.indexOf(RealBufferedSource.Java:306)
              at okio.RealBufferedSource.indexOf(RealBufferedSource.Java:300)
              at okio.RealBufferedSource.readUtf8LineStrict(RealBufferedSource.Java:196)
              at com.squareup.okhttp.internal.http.HttpConnection.readResponse(HttpConnection.Java:191)
              at com.squareup.okhttp.internal.http.HttpTransport.readResponseHeaders(HttpTransport.Java:80)
              at com.squareup.okhttp.internal.http.HttpEngine.readNetworkResponse(HttpEngine.Java:917)
              at com.squareup.okhttp.internal.http.HttpEngine.readResponse(HttpEngine.Java:793)
              at com.squareup.okhttp.internal.huc.HttpURLConnectionImpl.execute(HttpURLConnectionImpl.Java:439)
              at com.squareup.okhttp.internal.huc.HttpURLConnectionImpl.getResponse(HttpURLConnectionImpl.Java:384)
              at com.squareup.okhttp.internal.huc.HttpURLConnectionImpl.getResponseCode(HttpURLConnectionImpl.Java:497)
              at com.squareup.okhttp.internal.huc.DelegatingHttpsURLConnection.getResponseCode(DelegatingHttpsURLConnection.Java:105)
              at com.squareup.okhttp.internal.huc.HttpsURLConnectionImpl.getResponseCode(HttpsURLConnectionImpl.Java:25)
              at retrofit.client.UrlConnectionClient.readResponse(UrlConnectionClient.Java:73)
              at retrofit.client.UrlConnectionClient.execute(UrlConnectionClient.Java:38)
              at retrofit.RestAdapter$RestHandler.invokeRequest(RestAdapter.Java:321)
              at retrofit.RestAdapter$RestHandler.invoke(RestAdapter.Java:240)
              at Java.lang.reflect.Proxy.invoke(Proxy.Java:397)
              at $Proxy15.getAccessTokenUsingResourceOwnerPasswordCredentials(Unknown Source)
              at com.company.droid.repository.network.NetworkRepository.getAccessTokenUsingResourceOwnerPasswordCredentials(NetworkRepository.Java:76)
              at com.company.droid.ui.login.LoginTask.doInBackground(LoginTask.Java:88)
              at com.company.droid.ui.login.LoginTask.doInBackground(LoginTask.Java:23)
              at Android.os.AsyncTask$2.call(AsyncTask.Java:292)
              at Java.util.concurrent.FutureTask.run(FutureTask.Java:237)
              at Java.util.concurrent.ThreadPoolExecutor.runWorker(ThreadPoolExecutor.Java:1112)
              at Java.util.concurrent.ThreadPoolExecutor$Worker.run(ThreadPoolExecutor.Java:587)
              at Java.lang.Thread.run(Thread.Java:818)
      ]}
40
Rickster

Vor kurzem habe ich mich mit dem Problem konfrontiert, als ich an einem alten Code arbeitete. Nach dem Googeln habe ich festgestellt, dass das Problem überall ist, jedoch ohne konkrete Lösung. Ich habe an verschiedenen Teilen der Ausnahmebotschaft gearbeitet und unten analysiert.

Analyse:

  1. SSLException: Ausnahme ist beim SSL (Secure Socket Layer) aufgetreten, das im javax.net.ssl-Paket des JDK (openJDK/oracleJDK/AndroidSDK) implementiert ist.
  2. Read error ssl=# I/O error during system call: Beim Lesen vom sicheren Socket ist ein Fehler aufgetreten. Dies geschah während der Verwendung der systemeigenen Systembibliotheken/Treiber. Bitte beachten Sie, dass alle Plattformen Solaris, Windows usw. über eigene Socket-Bibliotheken verfügen, die vom SSL verwendet werden. Windows verwendet die WINSOCK-Bibliothek.
  3. Connection reset by peer: Diese Meldung wird von der Systembibliothek gemeldet (Solaris-Berichte ECONNRESET, Windows meldet WSAECONNRESET), dass der bei der Datenübertragung verwendete Socket nicht mehr verwendet werden kann, da eine vorhandene Verbindung vom Remote-Host zwangsweise geschlossen wurde. Es muss ein neuer sicherer Pfad zwischen dem Host und dem Client erstellt werden

Grund:

Um das Problem zu verstehen, versuche ich, den Grund für das Zurücksetzen der Verbindung zu finden. Ich habe folgende Gründe gefunden:

  • Die Peer-Anwendung auf dem Remote-Host wird plötzlich gestoppt, der Host wird neu gestartet, der Host oder die Remote-Netzwerkschnittstelle ist deaktiviert, oder der Remote-Host verwendet eine feste Schließung.
  • Dieser Fehler kann auch auftreten, wenn eine Verbindung unterbrochen wurde, weil Keepalive-Aktivität einen Fehler feststellte, während eine oder mehrere Vorgänge ausgeführt wurden. Vorgänge, die gerade ausgeführt wurden, schlagen mit Network dropped connection on reset(On Windows(WSAENETRESET)) und nachfolgende Vorgänge mitConnection reset by peer(On Windows(WSAECONNRESET)) fehl.
  • Wenn der Zielserver durch eine Firewall geschützt ist, was in den meisten Fällen der Fall ist, schließt die mit dem Port verknüpfte Time-to-Life-Zeit (TTL) oder Timeout die Verbindung idle zwangsweise zum angegebenen Timeout. das ist etwas von unserem Interesse

Auflösung:

  1. Ereignisse auf der Server-Seite, wie z. B. plötzlicher Dienststopp, Neustart, deaktivierte Netzwerkschnittstelle, können auf keine Weise behandelt werden.
  2. Konfigurieren Sie auf der Serverseite die Firewall für den angegebenen Port mit den höheren TTL-Werten (Time to Live) oder Timeout-Werten wie 3600 Sekunden.
  3. Kunden können "Versuchen" Halten Sie das Netzwerk aktiv, um den Connection reset by peer zu vermeiden oder zu reduzieren.
  4. Normalerweise hält der Netzwerkverkehr die Verbindung aufrecht, und Probleme/Ausnahmen werden nicht häufig gesehen. Starkes WLAN hat geringste Chancen für Connection reset by peer.
  5. Mit den Mobilfunknetzen 2G, 3G und 4G Wenn die Paketdatenübermittlung intermittierend ist und von der Verfügbarkeit des Mobilfunknetzes abhängig ist, setzt sie möglicherweise den TTL - Timer auf der Serverseite nicht zurück und führt zu Connection reset by peer

Hier sind die Begriffe, die in verschiedenen Foren zur Lösung des Problems vorgeschlagen werden

  • ConnectionTimeout: Wird nur beim Verbindungsaufbau verwendet. Wenn Host Zeit benötigt, um eine Verbindung herzustellen, wird der Client auf die Verbindung warten.
  • </ li>
  • SoTimeout: Socket-Zeitüberschreitung - Gibt die maximale Zeit an, in der ein Datenpaket empfangen wird, um die Verbindung als aktiv zu betrachten. Wenn innerhalb der angegebenen Zeit keine Daten empfangen werden, wird die Verbindung als blockiert/unterbrochen angesehen.
  • Linger: Bis zu welcher Uhrzeit der Socket nicht geschlossen werden soll, wenn Daten zum Senden in die Warteschlange gestellt werden und die Socket-Funktion Schließen am Socket aufgerufen wird.
  • TcpNoDelay: Möchten Sie den Puffer deaktivieren, der die TCP - Pakete enthält und sammelt, und sie senden, sobald ein Schwellenwert erreicht ist? Wenn Sie diese Option auf "true" setzen, wird die Pufferung von TCP übersprungen, sodass jede Anforderung sofort gesendet wird. Verlangsamungen im Netzwerk können durch eine Zunahme des Netzwerkverkehrs aufgrund einer kleineren und häufigeren Paketübertragung verursacht werden.
  • </ li>

Daher trägt keiner der oben genannten Parameter dazu bei, das Netzwerk am Leben zu halten und somit unwirksam zu bleiben.

Ich habe eine Einstellung gefunden, die bei der Lösung des Problems helfen kann, bei dem es sich um diese Funktionen handelt

setKeepAlive(true)
setSoKeepalive(HttpParams params, enableKeepalive="true") 

Wie habe ich mein Problem gelöst?

  • Stellen Sie die HttpConnectionParams.setSoKeepAlive(params, true) ein
  • Fangen Sie die Variable SSLException ab und suchen Sie nach der Ausnahmemeldung für Connection reset by peer.
  • Wenn eine Ausnahme gefunden wird, speichern Sie den Download-/Lesevorgang und erstellen Sie eine neue Verbindung.
  • Wenn möglich den Download fortsetzen/lesen, andernfalls den Download erneut starten

Ich hoffe die Details helfen. Happy Coding ...

78
Devendra Vaja

Wenn Sie Nginx verwenden und ein ähnliches Problem erhalten, kann dies helfen:

Scannen Sie Ihre Domäne unter sslTesturl und prüfen Sie, ob die Verbindung für Ihre Geräteversion zulässig ist.

Wenn Geräte mit niedrigerer Version (wie <Android 4.4.2 usw.) aufgrund der TLS-Unterstützung keine Verbindung herstellen können, fügen Sie diese der Nginx-Konfigurationsdatei hinzu

ssl_protocols TLSv1 TLSv1.1 TLSv1.2;
11
jayiitb

wir hatten das gleiche Problem ab heute morgen und haben es gelöst ... hoffe das hilft ...

SSL an IIS 8

  1. Gestern und gestern Abend hat alles gut funktioniert, unser SSL wurde auf der IIS Site aktualisiert.
  2. Beim Auschecken der Site Bindings to SSL hat IIS8 ein neues Ankreuzfeld Require Server Name Indication angezeigt. Es wurde nicht aktiviert, um es zu aktivieren.
  3. Das hat das Problem ausgelöst.
  4. Ging zurück zu IIS, deaktivierte die Checkbox .... Problem gelöst !!!!

Hoffe das hilft!!!

4
Jorge Navarro

Eine andere mögliche Ursache für diese Fehlermeldung ist, wenn die HTTP-Methode vom Server oder vom Load Balancer blockiert wird.

Es scheint eine Standard-Sicherheitsmethode zu sein, nicht verwendete HTTP-Methoden zu blockieren. Wir stießen darauf, weil HEAD vom Load Balancer blockiert wurde (aber seltsamerweise nicht alle Server mit Lastausgleich, die dazu führten, dass sie nur zeitweise ausfielen). Ich konnte testen, dass die Anforderung selbst gut funktionierte, indem sie vorübergehend auf die GET-Methode geändert wurde.

Der Fehlercode unter iOS war: Fehler beim Anfordern von App Code: Fehler Domain = NSURLErrorDomain Code = -1005 "Die Netzwerkverbindung ist unterbrochen worden."

0
Mykaelos

Android Unterstützt standardmäßig die SSL-Implementierung mit Ausnahme von Android N (API-Ebene 24) und unter Android 5.1 (API-Ebene 22).
Ich habe den Fehler erhalten, als ich den API-Aufruf unter Geräten der API-Ebene 22 durchführte, nachdem SSL auf der Serverseite implementiert wurde. Dies war beim Erstellen des OkHttpClient-Clientobjekts der Fall, und das Problem wurde durch das Hinzufügen der connectionSpecs () - Methode der OkHttpClient.Builder-Klasse behoben.

der Fehler war

antwortfehler: javax.net.ssl.SSLException: SSL-Handshake abgebrochen: ssl = 0xb8882c00: E/A-Fehler während des Systemaufrufs, Verbindung von Peer zurückgesetzt

also habe ich das behoben, indem ich den check gerne hinzugefügt habe 

if ( Build.VERSION.SDK_INT < Build.VERSION_CODES.Lollipop_MR1) {
            // Do something for below api level 22
            List<ConnectionSpec> specsList = getSpecsBelowLollipopMR1(okb);
            if (specsList != null) {
                okb.connectionSpecs(specsList);
            }
        }

Auch für Android N (API Level 24); Ich habe den Fehler beim HTTP-Aufruf erhalten 

HTTP FAILED: javax.net.ssl.SSLHandshakeException: Handshake fehlgeschlagen

und dies wird durch Hinzufügen des Schecks für Android 7 behoben

if (Android.os.Build.VERSION.SDK_INT == Build.VERSION_CODES.N){
            // Do something for naugat ; 7
            okb.connectionSpecs(Collections.singletonList(getSpec()));
        }

Mein letztes OkHttpClient-Objekt wird also wie folgt aussehen:

         OkHttpClient client
         HttpLoggingInterceptor httpLoggingInterceptor2 = new
         HttpLoggingInterceptor();
         httpLoggingInterceptor2.setLevel(HttpLoggingInterceptor.Level.BODY);

         OkHttpClient.Builder okb = new OkHttpClient.Builder()
                 .addInterceptor(httpLoggingInterceptor2)
               .addInterceptor(new Interceptor() {
                     @Override
                     public Response intercept(Chain chain) throws IOException {
                         Request request = chain.request();
                         Request request2 = request.newBuilder().addHeader(AUTH_KEYWORD, AUTH_TYPE_JW + " " + password).build();
                         return chain.proceed(request2);
                     }
                 }).connectTimeout(30, TimeUnit.SECONDS)
                 .writeTimeout(30, TimeUnit.SECONDS)
                 .readTimeout(30, TimeUnit.SECONDS);

         if (Android.os.Build.VERSION.SDK_INT == Build.VERSION_CODES.N){
             // Do something for naugat ; 7
             okb.connectionSpecs(Collections.singletonList(getSpec()));
         }

         if ( Build.VERSION.SDK_INT < Build.VERSION_CODES.Lollipop_MR1) {
             List<ConnectionSpec> specsList = getSpecsBelowLollipopMR1(okb);
             if (specsList != null) {
                 okb.connectionSpecs(specsList);
             }
         }

         //init client
         client = okb.build();

getSpecsBelowLollipopMR1-Funktion ist wie: 

   private List<ConnectionSpec> getSpecsBelowLollipopMR1(OkHttpClient.Builder okb) {

        try {

            SSLContext sc = SSLContext.getInstance("TLSv1.2");
            sc.init(null, null, null);
            okb.sslSocketFactory(new Tls12SocketFactory(sc.getSocketFactory()));

            ConnectionSpec cs = new ConnectionSpec.Builder(ConnectionSpec.MODERN_TLS)
                    .tlsVersions(TlsVersion.TLS_1_2)
                    .build();

            List<ConnectionSpec> specs = new ArrayList<>();
            specs.add(cs);
            specs.add(ConnectionSpec.COMPATIBLE_TLS);

            return specs;

        } catch (Exception exc) {
            Timber.e("OkHttpTLSCompat Error while setting TLS 1.2"+ exc);

            return null;
        }
    }

Die Tls12SocketFactory-Klasse wird unter dem folgenden Link gefunden (Kommentar von gotev): 

https://github.com/square/okhttp/issues/2372


Für weitere Unterstützung, indem Sie unten einige Links hinzufügen, wird dies Ihnen im Detail helfen.

https://developer.Android.com/training/articles/security-ssl

D/OkHttp: <- HTTP FAILED: javax.net.ssl.SSLException: SSL-Handshake abgebrochen: ssl = 0x64e3c938: E/A-Fehler während des Systemaufrufs, Zurücksetzung der Verbindung durch Peer

0
tejraj