return -1;
}
-static int create_ssl_handle(struct esp_tls *tls)
+static int create_ssl_handle(struct esp_tls *tls, const char *hostname, size_t hostlen, struct esp_tls_cfg *cfg)
{
int ret;
SSL_CTX_set_mode(ssl_ctx, SSL_MODE_AUTO_RETRY);
SSL_CTX_set_mode(ssl_ctx, SSL_MODE_RELEASE_BUFFERS);
#endif
+ if (cfg->alpn_protos) {
+ SSL_CTX_set_alpn_protos(ssl_ctx, cfg->alpn_protos, strlen((char *)cfg->alpn_protos));
+ }
SSL *ssl = SSL_new(ssl_ctx);
if (!ssl) {
SSL_CTX_free(ssl_ctx);
return -1;
}
+ char *use_host = strndup(hostname, hostlen);
+ if (!use_host) {
+ SSL_CTX_free(ssl_ctx);
+ return -1;
+ }
+ SSL_set_tlsext_host_name(ssl, use_host);
+ free(use_host);
+
SSL_set_fd(ssl, tls->sockfd);
ret = SSL_connect(ssl);
if (ret < 1) {
return SSL_write(tls->ssl, data, datalen);
}
-struct esp_tls *esp_tls_conn_new(const char *hostname, int hostlen, int port, bool is_tls)
+struct esp_tls *esp_tls_conn_new(const char *hostname, int hostlen, int port, struct esp_tls_cfg *cfg)
{
int sockfd = esp_tcp_connect(hostname, hostlen, port);
if (sockfd < 0) {
tls->read = tcp_read;
tls->write = tcp_write;
- if (is_tls) {
- if (create_ssl_handle(tls) != 0) {
+ if (cfg) {
+ if (create_ssl_handle(tls, hostname, hostlen, cfg) != 0) {
esp_tls_conn_delete(tls);
return NULL;
}
#include <sys/socket.h>
#include <openssl/ssl.h>
+#ifdef __cplusplus
+extern "C" {
+#endif
+
+struct esp_tls_cfg {
+ /* If HTTP2/ALPN support is required, a list of protocols that
+ * should be negotiated. The format is length followed by protocol
+ * name.
+ * For the most common cases the following is ok:
+ * "\x02h2"
+ * - where the first '2' is the length of the protocol and
+ * - the subsequent 'h2' is the protocol name
+ */
+ const unsigned char *alpn_protos;
+};
+
struct esp_tls {
SSL_CTX *ctx;
SSL *ssl;
ssize_t (*write)(struct esp_tls *tls, const char *data, size_t datalen);
};
-struct esp_tls *esp_tls_conn_new(const char *hostname, int hostlen, int port, bool is_tls);
+/*
+ *
+ * cfg: If you wish to open non-TLS connection, keep this NULL. For TLS
+ * connection, a pass pointer to 'struct esp_tls_cfg'. At a minimum, this
+ * structure should be zero-initialized.
+ */
+struct esp_tls *esp_tls_conn_new(const char *hostname, int hostlen, int port, struct esp_tls_cfg *cfg);
static inline ssize_t esp_tls_conn_write(struct esp_tls *tls, const char *data, size_t datalen)
{
void esp_tls_conn_delete(struct esp_tls *tls);
+#ifdef __cplusplus
+}
+#endif
+
#endif /* ! _ESP_TLS_H_ */