unsigned int (*record_minus)(record_t *buf, void *ptr, unsigned int size);
bool invalid_hb_used; //!< Whether heartbleed attack was detected.
+ bool connected; //!< whether the outgoing socket is connected
/*
* Framed-MTU attribute in RADIUS, if present, can also be used to set this
#ifdef WITH_TCP
if (sock->proto == IPPROTO_TCP) {
/*
- * If there are hard-coded worker threads, OR
- * it's a TLS connection, it's blocking.
+ * Woker threads are blocking.
*
* Otherwise, they're non-blocking.
*/
- if (!this->workers
-#ifdef WITH_PROXY
-#ifdef WITH_TLS
- && (this->type == RAD_LISTEN_PROXY) && !this->tls
-#endif
-#endif
- ) {
+ if (!this->workers) {
if (fr_nonblock(this->fd) < 0) {
close(this->fd);
ERROR("Failed setting non-blocking on socket: %s",
talloc_set_destructor(ssn, _tls_session_free);
ssn->ctx = conf->ctx;
+ ssn->mtu = conf->fragment_size;
SSL_CTX_set_mode(ssn->ctx, SSL_MODE_ACCEPT_MOVING_WRITE_BUFFER | SSL_MODE_AUTO_RETRY);
SSL_set_ex_data(ssn->ssl, FR_TLS_EX_INDEX_SSN, (void *)ssn);
SSL_set_fd(ssn->ssl, fd);
ret = SSL_connect(ssn->ssl);
+
+ if (ret < 0) {
+ switch (SSL_get_error(ssn->ssl, ret)) {
+ default:
+ break;
+
+
+
+ case SSL_ERROR_WANT_READ:
+ case SSL_ERROR_WANT_WRITE:
+ ssn->connected = false;
+ return ssn;
+ }
+ }
+
if (ret <= 0) {
tls_error_io_log(NULL, ssn, ret, "Failed in " STRINGIFY(__FUNCTION__) " (SSL_connect)");
talloc_free(ssn);
return NULL;
}
- ssn->mtu = conf->fragment_size;
-
+ ssn->connected = true;
return ssn;
}
return 0;
}
+static int try_connect(tls_session_t *ssn)
+{
+ int ret;
+ ret = SSL_connect(ssn->ssl);
+ if (ret < 0) {
+ switch (SSL_get_error(ssn->ssl, ret)) {
+ default:
+ break;
+
+
+
+ case SSL_ERROR_WANT_READ:
+ case SSL_ERROR_WANT_WRITE:
+ ssn->connected = false;
+ return 0;
+ }
+ }
+
+ if (ret <= 0) {
+ tls_error_io_log(NULL, ssn, ret, "Failed in " STRINGIFY(__FUNCTION__) " (SSL_connect)");
+ talloc_free(ssn);
+
+ return -1;
+ }
+
+ return 1;
+}
+
#ifdef WITH_PROXY
/*
uint8_t *data;
listen_socket_t *sock = listener->data;
+ if (!sock->ssn->connected) {
+ rcode = try_connect(sock->ssn);
+ if (rcode == 0) return 0;
+
+ if (rcode < 0) {
+ SSL_shutdown(sock->ssn->ssl);
+ return -1;
+ }
+
+ sock->ssn->connected = true;
+ }
+
/*
* Get the maximum size of data to receive.
*/
request);
}
+ if (!sock->ssn->connected) {
+ PTHREAD_MUTEX_LOCK(&sock->mutex);
+ rcode = try_connect(sock->ssn);
+ PTHREAD_MUTEX_LOCK(&sock->mutex);
+ if (rcode == 0) return 0;
+
+ if (rcode < 0) {
+ SSL_shutdown(sock->ssn->ssl);
+ return -1;
+ }
+
+ sock->ssn->connected = true;
+ }
+
DEBUG3("Proxy is writing %u bytes to SSL",
(unsigned int) request->proxy->data_len);
PTHREAD_MUTEX_LOCK(&sock->mutex);