SSL_CONNECT(3ossl)

πŸ’– SSL_CONNECT πŸ’–

okay so bestie, welcome to SSL_connect from the OpenSSL fam β€” this is the page for SSL_CONNECT(3ossl), and yes it's exactly the one you want when you're the client side of the handshake. client energy only, we're not accepting anything here 🌸


✨ NAME ✨

SSL_connect β€” initiate the TLS/SSL handshake with an TLS/SSL server 🫢


✨ SYNOPSIS ✨

#include <openssl/ssl.h>

int SSL_connect(SSL *ssl);

✨ DESCRIPTION ✨

So SSL_connect() kicks off the TLS/SSL handshake with a server. iconic, the moment we've all been waiting for πŸ’…

But β€” and this is the part nobody reads and then everyone cries about β€” the communication channel has to already be set up and assigned to the ssl by setting an underlying BIO first. Like, you can't just show up, babe. You have to be seated. πŸŽ€

Also ssl MUST NOT be NULL. Not a vibe. Not allowed. genuinely do not do this. πŸ’€


✨ NOTES ✨

okay so the behaviour of SSL_connect() depends on the underlying BIO. literally the whole personality of this function changes based on that. 🌈

  • If the underlying BIO is blocking, SSL_connect() will only return once the handshake has been finished or an error occurred. That's it. It sits there. It waits. It commits. main character energy, honestly.
  • If the underlying BIO is nonblocking, SSL_connect() will also return when the underlying BIO could not satisfy the needs of SSL_connect() to continue the handshake β€” and it'll tell you about it by returning -1. πŸ™ˆ
    • In that case, calling SSL_get_error() with the return value of SSL_connect() will give you either SSL_ERROR_WANT_READ or SSL_ERROR_WANT_WRITE. πŸ“–
    • Then the calling process must repeat the call after taking appropriate action to satisfy the needs of SSL_connect(). The action depends on the underlying BIO, bestie, it's not one-size-fits-all:
      • When using a nonblocking socket, nothing is to be done, but select() can be used to check for the required condition. πŸ¦‹
      • When using a buffering BIO, like a BIO pair, data must be written into or retrieved out of the BIO before being able to continue. πŸ“

okay now the Nagle's algorithm section, and honestly? it's giving "subtle performance jumpscare." 😭

Many systems implement Nagle's algorithm by default, which means it will buffer outgoing TCP data if a TCP packet has already been sent for which no corresponding ACK has been received yet from the peer. 🫠

This can have performance impacts after:

  • a successful TLSv1.3 handshake, or
  • a successful TLSv1.2 (or below) resumption handshake,

because the last peer to communicate in the handshake is the client. And if the client is also the first to send application data (as is typical for many protocols), then this data could be buffered until an ACK has been received for the final handshake message. the way that one buffered packet can just ruin your latency… ⭐

The TCP_NODELAY socket option is often available to disable Nagle's algorithm. If an application opts to disable Nagle's algorithm, consideration should be given to turning it back on again later if appropriate. yes bestie, toggle responsibly, we love a reversible decision πŸ’œ

The helper function BIO_set_tcp_ndelay() can be used to turn on or off the TCP_NODELAY option. πŸ‘‘


✨ RETURN VALUES ✨

The following return values can occur:

  • 0 β€” The TLS/SSL handshake was not successful, but was shut down controlled and by the specifications of the TLS/SSL protocol. Call SSL_get_error() with the return value ret to find out the reason. πŸŽ€
  • 1 β€” The TLS/SSL handshake was successfully completed, a TLS/SSL connection has been established. WE ATE. WE SLAYYYY. πŸ”₯
  • <0 β€” The TLS/SSL handshake was not successful, because a fatal error occurred either at the protocol level or a connection failure occurred. The shutdown was not clean. It can also occur if action is needed to continue the operation for nonblocking BIOs. Call SSL_get_error() with the return value ret to find out the reason. πŸ’€
fr fr, if you get anything other than 1, the move is always the same: call SSL_get_error() with ret. don't guess, don't assume, just ask the error function. 😀

✨ SEE ALSO ✨

SSL_get_error(3), SSL_accept(3), SSL_shutdown(3), ssl(7), bio(7), SSL_set_connect_state(3), SSL_do_handshake(3), SSL_CTX_new(3) 🌸

iykyk, the whole squad is linked above β€” go read them too, don't just skim this one and call it a day. 🫢


Copyright 2000-2020 The OpenSSL Project Authors. All Rights Reserved.

Licensed under the Apache License 2.0 (the "License"). You may not use this file except in compliance with the License. You can obtain a copy in the file LICENSE in the source distribution or at <https://www.openssl.org/source/license.html>. πŸ’œ


and that's the page, bestie!! πŸŽ€ this was SSL_CONNECT(3ossl) from OpenSSL, version 3.5.9, dated 2026-09-29 β€” go forth and handshake responsibly. mwah. πŸ’…βœ¨

πŸ“¦ where this page comes from