SSL wants a read first

Begonnen von Prof. Dr. Peter Henning, 26 April 2021, 17:24:03

Vorheriges Thema - Nächstes Thema

Prof. Dr. Peter Henning

Liebe Mitstreiter,

Erstmal Beschreibung der Symptome.

2 fast identische Staubsaugerroboter von Roomba. Besonderheit: Roomba baut dort einen MQTT-Server ein, der Zugriff von außen muss also über einen MQTT-Client erfolgen. Geht soweit, beide liefen damit astrein.

Dann ein Komplett-Reset des einen Roomba. Das gibt natürlich ein neues Passwort, soweit, so gut. Alles eingetragen, Verbindungsversuch endet mit einer Fehlermeldung der HttpUtils:

Zitat2021.04.26 17:16:51 4: IP: 192.168.0.xx -> 192.168.0.xx
2021.04.26 17:16:54 4: HttpUtils: https://192.168.0.xx:8883/: Can't connect(2) to https://192.168.0.xx:8883:  SSL wants a read first
Das Attribut sslargs hat den Wert SSL_version:SSLv23 und die Verbindung des zweiten MQTT-Client mit dem zweiten Roboter läuft problemlos. Es kann also nicht an den SSL-Einstellungen liegen.

Die Perl-Module sind soweit alle aktualisiert - und ich stehe vor einem Rätsel.

Natürlich bemühe ich brav die Suchfunktion und finde ganz viele FHEM-Posts mit der gleichen Problembeschreibung. Mal löst sich das Problem durch Update der Perl-Module. Mal verschwindet es von alleine. Und mal gar nicht.

So etwas finde ich unbefriedigend - hat jemand einen Schimmer, wie ich da herauskommen kann und was die systematische Lösung für dieses Problem ist?

LG

pah


herrmannj

Das ist entweder ein Fehler in IO::Socket:SSL (oder ..IP), kann aber auch unglücklich auftreten wenn geforked wird.

Beim SSL Handshake kann es passieren das perl (du) Nutzdaten schreiben möchte, die darunter liegende (transparente) SSL Verbindung aber etwas lesen muss was mit den SSL Handshake zu tun hat.

Forkst Du für den roomba? Wenn ja, versuch mal interimsweise ohne fork auszukommen (falls möglich). Die sich abzeichnende Frage ;) wäre danch: was dann? Falls es wirklich an dem forken liegt wäre eine Möglichkeit die Verbindung komplett im fork aufzubauen (also kein handle dieser Verbindung in den fork "rüber" zu nehmen)

Prof. Dr. Peter Henning

#2
Zunächst einmal habe ich das nicht im Zugriff, weil der Aufruf der HttpUtils aus MQTT2_DEVICE heraus erfolgt. Vlt. muss ich mal Rudi ansprechen.
Und warum es bei der einen Kiste geht, und bei der anderen nicht, ist mir beliebig unklar.

LG


pah


Edit: ich kriege Schreikrämpfe: Nach dem Update der Perl-Module funktioniert das Connect auch nicht mehr mit dem 2. Roboter. Und da gibt es noch nicht mal eine Fehlermeldung....

rudolfkoenig

Ich gehe davon aus, dass hier kein fork involviert ist, MQTT_CLIENT (bzw. => DevIo => HttpUtils_Connect) macht sowas nicht.
Da nach der TCP connect sofort IO::Socket::SSL->start_SSL aufgerufen wird, duerfte sich auch kein fork eines anderes Moduls sich dazwischendraengeln.

Vor start_SSL wird $hash->{conn}->blocking(1) gesetzt, mAn darf start_SSL deswegen nicht "want a read first" melden => Ich meine das ist ein Bug im IO::Socket::SSL bzw. darunter.

Als workaround koennte HttpUtils start_SSL nonblocking durchfuehren, und "want a read" / "want a write" so lange auswerten, bis das SSL-Handshake fertig ist. Trau mich noch nicht das anzugehen, da die Aendrung signifikant ist, und viele Module indirekt betrifft.
Vermutlich brauche ich Ermunterung :)

Prof. Dr. Peter Henning


herrmannj

der handshake kann auch jederzeit bei bereits bestehender Verbindung erneut auftreten. Das in Deinem letzten Satz beschriebene sollte implementiert werden (sein)

Zusätzlich IO::Socket::IP als default setzen?

rudolfkoenig

ZitatMeinst Du so etwas? ;D
Ja, ungefaehr :)

Der Einbau gestaltet sich schwierig:
- ich habe blocking(0) gesetzt, ein NonblockingGet funktioniert trotzdem
- in SSL.pm (version 2.070) wird in der Zeile 1622 (in start_SSL) blocking explizit auf 1 gesetzt, und zum Schluss restauriert, wenn noetig
@pah: welche SSL.pm Version hast Du?

Zitatder handshake kann auch jederzeit bei bereits bestehender Verbindung erneut auftreten.
Warum eigentlich?
Bisher hat niemand solche Probleme gemeldet, womoeglich setzt SSL.pm da auch wieder blocking.
Ich bin offen auf want_read/want_write zu reagieren, aber ich brauche was zum testen, sonst ist das sinnlos.

ZitatZusätzlich IO::Socket::IP als default setzen?
Das klingt so, als ob es irgendwo schon verwendet waere, und ich muesste nur die Voreinstellung aendern.
Da das eine groessere Anederung ist, waere eine Begruendung wichtig.
Seit welcher Perl-Version gehoert es zu Core?

Prof. Dr. Peter Henning

Ich bin wie Rudi sehr skeptisch gegen das Herumprobieren an zentralen Modulen

Ich bin heute bis Donnerstag leider komplett unter Wasser, sonst würde ich das hie rmal testen.
Hier gibt es nämlich einen Hinweis darauf, was eigentlich das Problem sein könnte.

LG

pah

Prof. Dr. Peter Henning

Uff, mit dem Einbau eines weiteren Attributes TIMEOUT in MQTT2_DEVICE und dem Setzen auf 6 (Sekunden) klappt tatsächlich alles, wie es sollte. ???

https://forum.fhem.de/index.php/topic,114166.msg1126994.html#msg1126994

LG

pah

rudolfkoenig

Ich habe dieses Attribut jetzt unter dem Namen connectTimeout in MQTT2_CLIENT eingebaut, allerdings habe ich Schwierigkeiten vorzustellen, warum ein Timeout als "SSL wants a read first" gemeldet wird.

Prof. Dr. Peter Henning

Ich auch. Aber das ist offenbar wirklich so.

Danke für die Umsetzung.

LG

pah

zap

Hattest Du mal versucht, als IO::Socket::SSL Option SSL_hostname => '' zu setzen?

(Habe ich aus einem uralten / 8 Jahre alten Hinweis. Das muss ich immer setzen, wenn z.B. der Server DNS Round Robin verwendet. Sonst bekomme ich die gleiche Fehlermeldung)
2xCCU3, Fenster, Rollläden, Themostate, Stromzähler, Steckdosen ...)
Entwicklung: FHEM auf AMD NUC (Ubuntu)
Produktiv inzwischen auf Home Assistant gewechselt.
Maintainer: FULLY, Meteohub, HMCCU, AndroidDB

Prof. Dr. Peter Henning

Nein, bisher nicht ausprobiert. Das muss wo rein?

LG

pah