Ich habe einen Netzwerkserver geschrieben, der OpenSSL für SSL/TLS verwendet. Der Server sendet und empfängt große Datenblöcke und führt dazwischen verschiedene Transformationen durch. Aus Performancegründen werden Transformationen hauptsächlich mit Vektorinformationen ausgeführt (siehe iovec von POSIX), die teure Speicherverschiebungen vermeiden (memcpy() usw.). Wenn Daten zum Senden bereit sind, verwende ich die writev() POSIX-Funktion, die Daten aus dem Speicher unter Verwendung dieser Vektoren sammelt und sie normalerweise als ein Netzwerkpaket sendet.OpenSSL SSL_write von mehreren Puffern/SSL_writev
Jetzt mit OpenSSL, ist es nicht vollständig möglich, weil OpenSSL nur die Funktion SSL_write() bietet, soweit ich weiß. Das heißt, ich muss diese Funktion für jeden Vektoreintrag aufrufen, den ich senden möchte. Dies führt leider dazu, dass jedes Vektor-Datenpaket in seinem eigenen SSL-Frame übertragen wird, was unerwünschten und unnötigen Netzwerk-Overhead mit sich bringt.
Meine Frage ist: Gibt es SSL_writev() entspricht writev()? Oder gibt es generell eine Technik, wie ich OpenSSL mitteilen kann, SSL_write() Daten in einen einzigen SSL-Anwendungsdatensatz (Typ 22) zu speichern, ohne es zu senden (und dann natürlich eine Art von flush() -Funktion)?
Bearbeiten: Wie unten diskutiert, ist ein praktikabler Ansatz, vectored Daten in einem großen Chunk vor einem abschließenden einzelnen Aufruf SSL_write() zu konsolidieren. Es gibt jedoch einen Overhead mit 2 Kopien (1. während der Konsolidierung, 2. wenn SSL_write() die AES-Verschlüsselung durchführt). Theoretischer Aufruf von SSL_writev() führt diesen Overhead nicht ein.
Ich denke, dass Sie eine "Pull-up" -Funktion benötigen. Das heißt, eines, das mehrere Puffer zu einem kombiniert. – jww
Genau das mache ich heute. Aber es ist ziemlich teuer b/c es bewegt sich ein großer Teil der Daten im Speicher. –
Es scheint, als ob die großen Brocken die Kosten von TCP-Overhead amortisieren. Vielleicht sollten Sie die separaten Schreibvorgänge für große Daten zulassen und nur kleinere aufziehen. Wenn Sie mit '-march = native' und' -O3' kompilieren, sollten Sie die SSE4- und AVX-Versionen von 'memcpy' und' memmove' auf moderner Hardware bekommen. Sie sind blitzschnell, weil sie sich 16, 32 und 64 Bytes gleichzeitig bewegen. – jww