SSL *ssl;
struct ofpbuf *rxbuf;
struct ofpbuf *txbuf;
- struct poll_waiter *tx_waiter;
/* rx_want and tx_want record the result of the last call to SSL_read()
* and SSL_write(), respectively:
static void ssl_clear_txbuf(struct ssl_vconn *);
static int interpret_ssl_error(const char *function, int ret, int error,
int *want);
-static void ssl_tx_poll_callback(int fd, short int revents, void *vconn_);
static DH *tmp_dh_callback(SSL *ssl, int is_export UNUSED, int keylength);
static void log_ca_cert(const char *file_name, X509 *cert);
/* Create and return the ssl_vconn. */
sslv = xmalloc(sizeof *sslv);
- vconn_init(&sslv->vconn, &ssl_vconn_class, EAGAIN, name, true);
+ vconn_init(&sslv->vconn, &ssl_vconn_class, EAGAIN, name);
vconn_set_remote_ip(&sslv->vconn, remote->sin_addr.s_addr);
vconn_set_remote_port(&sslv->vconn, remote->sin_port);
vconn_set_local_ip(&sslv->vconn, local.sin_addr.s_addr);
sslv->ssl = ssl;
sslv->rxbuf = NULL;
sslv->txbuf = NULL;
- sslv->tx_waiter = NULL;
sslv->rx_want = sslv->tx_want = SSL_NOTHING;
*vconnp = &sslv->vconn;
return 0;
return error;
}
- error = tcp_open_active(suffix, OFP_SSL_PORT, &sin, &fd);
+ error = inet_open_active(SOCK_STREAM, suffix, OFP_SSL_PORT, &sin, &fd);
if (fd >= 0) {
int state = error ? STATE_TCP_CONNECTING : STATE_SSL_CONNECTING;
return new_ssl_vconn(name, fd, CLIENT, state, &sin, vconnp);
ssl_close(struct vconn *vconn)
{
struct ssl_vconn *sslv = ssl_vconn_cast(vconn);
- poll_cancel(sslv->tx_waiter);
ssl_clear_txbuf(sslv);
ofpbuf_delete(sslv->rxbuf);
SSL_free(sslv->ssl);
ret = SSL_read(sslv->ssl, ofpbuf_tail(rx), want_bytes);
if (old_state != SSL_get_state(sslv->ssl)) {
sslv->tx_want = SSL_NOTHING;
- if (sslv->tx_waiter) {
- poll_cancel(sslv->tx_waiter);
- ssl_tx_poll_callback(sslv->fd, POLLIN, vconn);
- }
}
sslv->rx_want = SSL_NOTHING;
{
ofpbuf_delete(sslv->txbuf);
sslv->txbuf = NULL;
- sslv->tx_waiter = NULL;
-}
-
-static void
-ssl_register_tx_waiter(struct vconn *vconn)
-{
- struct ssl_vconn *sslv = ssl_vconn_cast(vconn);
- sslv->tx_waiter = poll_fd_callback(sslv->fd,
- want_to_poll_events(sslv->tx_want),
- ssl_tx_poll_callback, vconn);
}
static int
}
}
-static void
-ssl_tx_poll_callback(int fd UNUSED, short int revents UNUSED, void *vconn_)
-{
- struct vconn *vconn = vconn_;
- struct ssl_vconn *sslv = ssl_vconn_cast(vconn);
- int error = ssl_do_tx(vconn);
- if (error != EAGAIN) {
- ssl_clear_txbuf(sslv);
- } else {
- ssl_register_tx_waiter(vconn);
- }
-}
-
static int
ssl_send(struct vconn *vconn, struct ofpbuf *buffer)
{
return 0;
case EAGAIN:
leak_checker_claim(buffer);
- ssl_register_tx_waiter(vconn);
return 0;
default:
sslv->txbuf = NULL;
}
}
+static void
+ssl_run(struct vconn *vconn)
+{
+ struct ssl_vconn *sslv = ssl_vconn_cast(vconn);
+
+ if (sslv->txbuf && ssl_do_tx(vconn) != EAGAIN) {
+ ssl_clear_txbuf(sslv);
+ }
+}
+
+static void
+ssl_run_wait(struct vconn *vconn)
+{
+ struct ssl_vconn *sslv = ssl_vconn_cast(vconn);
+
+ if (sslv->tx_want != SSL_NOTHING) {
+ poll_fd_wait(sslv->fd, want_to_poll_events(sslv->tx_want));
+ }
+}
+
static void
ssl_wait(struct vconn *vconn, enum vconn_wait_type wait)
{
/* We have room in our tx queue. */
poll_immediate_wake();
} else {
- /* The call to ssl_tx_poll_callback() will wake us up. */
+ /* vconn_run_wait() will do the right thing; don't bother with
+ * redundancy. */
}
break;
ssl_connect, /* connect */
ssl_recv, /* recv */
ssl_send, /* send */
+ ssl_run, /* run */
+ ssl_run_wait, /* run_wait */
ssl_wait, /* wait */
};
\f
return retval;
}
- fd = tcp_open_passive(suffix, OFP_SSL_PORT);
+ fd = inet_open_passive(SOCK_STREAM, suffix, OFP_SSL_PORT);
if (fd < 0) {
return -fd;
}