ustream-ssl: increase number of read buffers
[project/ustream-ssl.git] / ustream-ssl.c
index b6b74017e90f4e480a68c6e787dad27cae714609..d3048ca2ded69f4ced3a0ddd778b1e6e923fdd20 100644 (file)
@@ -40,6 +40,26 @@ static void ustream_ssl_check_conn(struct ustream_ssl *us)
                return;
 
        if (__ustream_ssl_connect(us) == U_SSL_OK) {
+
+               /* __ustream_ssl_connect() will also return U_SSL_OK when certificate
+                * verification failed!
+                *
+                * Applications may register a custom .notify_verify_error callback in the
+                * struct ustream_ssl which is called upon verification failures, but there
+                * is no straight forward way for the callback to terminate the connection
+                * initiation right away, e.g. through a true or false return value.
+                *
+                * Instead, existing implementations appear to set .eof field of the underlying
+                * ustream in the hope that this inhibits further operations on the stream.
+                *
+                * Declare this informal behaviour "official" and check for the state of the
+                * .eof member after __ustream_ssl_connect() returned, and do not write the
+                * pending data if it is set to true.
+                */
+
+               if (us->stream.eof)
+                       return;
+
                us->connected = true;
                if (us->notify_connected)
                        us->notify_connected(us);
@@ -64,6 +84,11 @@ static bool __ustream_ssl_poll(struct ustream *s)
                        break;
 
                ret = __ustream_ssl_read(us, buf, len);
+               if (ret == U_SSL_PENDING) {
+                       ustream_poll(us->conn);
+                       ret = __ustream_ssl_read(us, buf, len);
+               }
+
                switch (ret) {
                case U_SSL_PENDING:
                        return more;
@@ -153,7 +178,7 @@ static bool ustream_ssl_poll(struct ustream *s)
        bool fd_poll;
 
        fd_poll = ustream_poll(us->conn);
-       return __ustream_ssl_poll(s) || fd_poll;
+       return __ustream_ssl_poll(us->conn) || fd_poll;
 }
 
 static void ustream_ssl_stream_init(struct ustream_ssl *us)
@@ -183,9 +208,14 @@ static int _ustream_ssl_init(struct ustream_ssl *us, struct ustream *conn, struc
        if (!us->ssl)
                return -ENOMEM;
 
+       conn->r.max_buffers = 4;
        conn->next = &us->stream;
        ustream_set_io(ctx, us->ssl, conn);
        ustream_ssl_stream_init(us);
+
+       if (us->server_name)
+               __ustream_ssl_set_server_name(us);
+
        ustream_ssl_check_conn(us);
 
        return 0;
@@ -204,6 +234,9 @@ const struct ustream_ssl_ops ustream_ssl_ops = {
        .context_set_crt_file = __ustream_ssl_set_crt_file,
        .context_set_key_file = __ustream_ssl_set_key_file,
        .context_add_ca_crt_file = __ustream_ssl_add_ca_crt_file,
+       .context_set_ciphers = __ustream_ssl_set_ciphers,
+       .context_set_require_validation = __ustream_ssl_set_require_validation,
+       .context_set_debug = __ustream_ssl_set_debug,
        .context_free = __ustream_ssl_context_free,
        .init = _ustream_ssl_init,
        .set_peer_cn = _ustream_ssl_set_peer_cn,