/*
- * Copyright (c) 2008, 2009, 2010 Nicira Networks.
+ * Copyright (c) 2008, 2009, 2010, 2011 Nicira Networks.
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
#include <errno.h>
#include <inttypes.h>
#include <string.h>
+#include <sys/types.h>
+#include <sys/socket.h>
#include <netinet/tcp.h>
#include <openssl/err.h>
#include <openssl/ssl.h>
static bool ssl_wants_io(int ssl_error);
static void ssl_close(struct stream *);
static void ssl_clear_txbuf(struct ssl_stream *);
+static void interpret_queued_ssl_error(const char *function);
static int interpret_ssl_error(const char *function, int ret, int error,
int *want);
static DH *tmp_dh_callback(SSL *ssl, int is_export OVS_UNUSED, int keylength);
if (!verify_peer_cert || (bootstrap_ca_cert && type == CLIENT)) {
SSL_set_verify(ssl, SSL_VERIFY_NONE, NULL);
}
+ if (type == CLIENT) {
+ /* Grab SSL session information from the cache. */
+ SSL_SESSION *session = shash_find_data(&client_sessions, name);
+ if (session && SSL_set_session(ssl, session) != 1) {
+ interpret_queued_ssl_error("SSL_set_session");
+ }
+ }
/* Create and return the ssl_stream. */
sslv = xmalloc(sizeof *sslv);
struct ssl_stream *sslv = ssl_stream_cast(stream);
SSL_SESSION *session;
- /* Statistics. */
- COVERAGE_INC(ssl_session);
- if (SSL_session_reused(sslv->ssl)) {
- COVERAGE_INC(ssl_session_reused);
- }
-
/* Get session from stream. */
session = SSL_get1_session(sslv->ssl);
if (session) {
}
}
}
- } else {
- /* There is no new session. This doesn't really make sense because
- * this function is only called upon successful connection and there
- * should always be a new session in that case. But I don't trust
- * OpenSSL so I'd rather handle this case anyway. */
- ssl_flush_session(stream);
}
}
MSG_PEEK);
}
- /* Grab SSL session information from the cache. */
- if (sslv->type == CLIENT) {
- SSL_SESSION *session = shash_find_data(&client_sessions,
- stream_get_name(stream));
- if (session) {
- SSL_set_session(sslv->ssl, session);
- }
- }
-
retval = (sslv->type == CLIENT
? SSL_connect(sslv->ssl) : SSL_accept(sslv->ssl));
if (retval != 1) {
VLOG_ERR("rejecting SSL connection during bootstrap race window");
return EPROTO;
} else {
- if (sslv->type == CLIENT) {
- ssl_cache_session(stream);
+ /* Statistics. */
+ COVERAGE_INC(ssl_session);
+ if (SSL_session_reused(sslv->ssl)) {
+ COVERAGE_INC(ssl_session_reused);
}
return 0;
}
* background. */
SSL_shutdown(sslv->ssl);
+ ssl_cache_session(stream);
+
/* SSL_shutdown() might have signaled an error, in which case we need to
* flush it out of the OpenSSL error queue or the next OpenSSL operation
* will falsely signal an error. */
free(sslv);
}
+static void
+interpret_queued_ssl_error(const char *function)
+{
+ int queued_error = ERR_get_error();
+ if (queued_error != 0) {
+ VLOG_WARN_RL(&rl, "%s: %s",
+ function, ERR_error_string(queued_error, NULL));
+ } else {
+ VLOG_ERR_RL(&rl, "%s: SSL_ERROR_SSL without queued error", function);
+ }
+}
+
static int
interpret_ssl_error(const char *function, int ret, int error,
int *want)
}
}
- case SSL_ERROR_SSL: {
- int queued_error = ERR_get_error();
- if (queued_error != 0) {
- VLOG_WARN_RL(&rl, "%s: %s",
- function, ERR_error_string(queued_error, NULL));
- } else {
- VLOG_ERR_RL(&rl, "%s: SSL_ERROR_SSL without queued error",
- function);
- }
+ case SSL_ERROR_SSL:
+ interpret_queued_ssl_error(function);
break;
- }
default:
VLOG_ERR_RL(&rl, "%s: bad SSL error code %d", function, error);