digest_final ( sha1, sha1_ctx, sha1_digest );
}
+/******************************************************************************
+ *
+ * TX state machine transitions
+ *
+ ******************************************************************************
+ */
+
+/**
+ * Resume TX state machine
+ *
+ * @v tls TLS session
+ */
+static void tls_tx_resume ( struct tls_session *tls ) {
+ process_add ( &tls->process );
+}
+
+/**
+ * Enter TX state machine active state
+ *
+ * @v tls TLS session
+ * @v state TX state
+ */
+static void tls_tx_start ( struct tls_session *tls, enum tls_tx_state state ) {
+
+ /* Enter specified state */
+ tls->tx_state = state;
+
+ /* Resume state machine */
+ tls_tx_resume ( tls );
+}
+
+/**
+ * Enter TX state machine idle state
+ *
+ * @v tls TLS session
+ */
+static void tls_tx_none ( struct tls_session *tls ) {
+
+ /* Enter idle state */
+ tls->tx_state = TLS_TX_NONE;
+}
+
+/**
+ * Enter TX state machine data state
+ *
+ * @v tls TLS session
+ */
+static void tls_tx_data ( struct tls_session *tls ) {
+
+ /* Enter data state */
+ tls->tx_state = TLS_TX_DATA;
+
+ /* Send notification of a window change */
+ xfer_window_changed ( &tls->plainstream );
+}
+
/******************************************************************************
*
* Record handling
}
/* Start sending the Client Key Exchange */
- tls->tx_state = TLS_TX_CLIENT_KEY_EXCHANGE;
+ tls_tx_start ( tls, TLS_TX_CLIENT_KEY_EXCHANGE );
return 0;
}
void *data, size_t len ) {
/* FIXME: Handle this properly */
- tls->tx_state = TLS_TX_DATA;
+ tls_tx_data ( tls );
( void ) data;
( void ) len;
- /* Send notification of a window change */
- xfer_window_changed ( &tls->plainstream );
-
return 0;
}
static struct interface_operation tls_cipherstream_ops[] = {
INTF_OP ( xfer_deliver, struct tls_session *,
tls_cipherstream_deliver ),
+ INTF_OP ( xfer_window_changed, struct tls_session *, tls_tx_resume ),
INTF_OP ( intf_close, struct tls_session *, tls_close ),
};
*
* @v tls TLS session
*/
-static void tls_step ( struct tls_session *tls ) {
+static void tls_tx_step ( struct tls_session *tls ) {
int rc;
/* Wait for cipherstream to become ready */
tls, strerror ( rc ) );
goto err;
}
- tls->tx_state = TLS_TX_NONE;
+ tls_tx_none ( tls );
break;
case TLS_TX_CLIENT_KEY_EXCHANGE:
/* Send Client Key Exchange */
"%s\n", tls, strerror ( rc ) );
goto err;
}
- tls->tx_state = TLS_TX_CHANGE_CIPHER;
+ tls_tx_start ( tls, TLS_TX_CHANGE_CIPHER );
break;
case TLS_TX_CHANGE_CIPHER:
/* Send Change Cipher, and then change the cipher in use */
goto err;
}
tls->tx_seq = 0;
- tls->tx_state = TLS_TX_FINISHED;
+ tls_tx_start ( tls, TLS_TX_FINISHED );
break;
case TLS_TX_FINISHED:
/* Send Finished */
tls, strerror ( rc ) );
goto err;
}
- tls->tx_state = TLS_TX_NONE;
+ tls_tx_none ( tls );
break;
case TLS_TX_DATA:
/* Nothing to do */
/** TLS TX process descriptor */
static struct process_descriptor tls_process_desc =
- PROC_DESC ( struct tls_session, process, tls_step );
+ PROC_DESC_ONCE ( struct tls_session, process, tls_tx_step );
/******************************************************************************
*
( sizeof ( tls->pre_master_secret.random ) ) );
digest_init ( &md5_algorithm, tls->handshake_md5_ctx );
digest_init ( &sha1_algorithm, tls->handshake_sha1_ctx );
- tls->tx_state = TLS_TX_CLIENT_HELLO;
- process_init ( &tls->process, &tls_process_desc, &tls->refcnt );
+ process_init_stopped ( &tls->process, &tls_process_desc, &tls->refcnt );
+ tls_tx_start ( tls, TLS_TX_CLIENT_HELLO );
/* Attach to parent interface, mortalise self, and return */
intf_plug_plug ( &tls->plainstream, xfer );