瀏覽代碼

[tls] Allow transmitted records to be scheduled independently

Signed-off-by: Michael Brown <mcb30@ipxe.org>
tags/v1.20.1
Michael Brown 13 年之前
父節點
當前提交
56a7981d58
共有 2 個文件被更改,包括 39 次插入93 次删除
  1. 10
    10
      src/include/ipxe/tls.h
  2. 29
    83
      src/net/tls.c

+ 10
- 10
src/include/ipxe/tls.h 查看文件

@@ -84,14 +84,12 @@ enum tls_rx_state {
84 84
 	TLS_RX_DATA,
85 85
 };
86 86
 
87
-/** TLS TX state machine state */
88
-enum tls_tx_state {
89
-	TLS_TX_NONE = 0,
90
-	TLS_TX_CLIENT_HELLO,
91
-	TLS_TX_CLIENT_KEY_EXCHANGE,
92
-	TLS_TX_CHANGE_CIPHER,
93
-	TLS_TX_FINISHED,
94
-	TLS_TX_DATA
87
+/** TLS TX pending flags */
88
+enum tls_tx_pending {
89
+	TLS_TX_CLIENT_HELLO = 0x0001,
90
+	TLS_TX_CLIENT_KEY_EXCHANGE = 0x0002,
91
+	TLS_TX_CHANGE_CIPHER = 0x0004,
92
+	TLS_TX_FINISHED = 0x0008,
95 93
 };
96 94
 
97 95
 /** A TLS cipher specification */
@@ -172,10 +170,12 @@ struct tls_session {
172 170
 
173 171
 	/** TX sequence number */
174 172
 	uint64_t tx_seq;
175
-	/** TX state */
176
-	enum tls_tx_state tx_state;
173
+	/** TX pending transmissions */
174
+	unsigned int tx_pending;
177 175
 	/** TX process */
178 176
 	struct process process;
177
+	/** TX ready for plaintext data */
178
+	int tx_ready;
179 179
 
180 180
 	/** RX sequence number */
181 181
 	uint64_t rx_seq;

+ 29
- 83
src/net/tls.c 查看文件

@@ -596,7 +596,7 @@ static void tls_verify_handshake ( struct tls_session *tls, void *out ) {
596 596
 
597 597
 /******************************************************************************
598 598
  *
599
- * TX state machine transitions
599
+ * Record handling
600 600
  *
601 601
  ******************************************************************************
602 602
  */
@@ -610,53 +610,6 @@ static void tls_tx_resume ( struct tls_session *tls ) {
610 610
 	process_add ( &tls->process );
611 611
 }
612 612
 
613
-/**
614
- * Enter TX state machine active state
615
- *
616
- * @v tls		TLS session
617
- * @v state		TX state
618
- */
619
-static void tls_tx_start ( struct tls_session *tls, enum tls_tx_state state ) {
620
-
621
-	/* Enter specified state */
622
-	tls->tx_state = state;
623
-
624
-	/* Resume state machine */
625
-	tls_tx_resume ( tls );
626
-}
627
-
628
-/**
629
- * Enter TX state machine idle state
630
- *
631
- * @v tls		TLS session
632
- */
633
-static void tls_tx_none ( struct tls_session *tls ) {
634
-
635
-	/* Enter idle state */
636
-	tls->tx_state = TLS_TX_NONE;
637
-}
638
-
639
-/**
640
- * Enter TX state machine data state
641
- *
642
- * @v tls		TLS session
643
- */
644
-static void tls_tx_data ( struct tls_session *tls ) {
645
-
646
-	/* Enter data state */
647
-	tls->tx_state = TLS_TX_DATA;
648
-
649
-	/* Send notification of a window change */
650
-	xfer_window_changed ( &tls->plainstream );
651
-}
652
-
653
-/******************************************************************************
654
- *
655
- * Record handling
656
- *
657
- ******************************************************************************
658
- */
659
-
660 613
 /**
661 614
  * Transmit Handshake record
662 615
  *
@@ -1025,15 +978,11 @@ static int tls_new_server_hello_done ( struct tls_session *tls,
1025 978
 		return -EINVAL;
1026 979
 	}
1027 980
 
1028
-	/* Check that we are ready to send the Client Key Exchange */
1029
-	if ( tls->tx_state != TLS_TX_NONE ) {
1030
-		DBGC ( tls, "TLS %p received Server Hello Done while in "
1031
-		       "TX state %d\n", tls, tls->tx_state );
1032
-		return -EIO;
1033
-	}
1034
-
1035
-	/* Start sending the Client Key Exchange */
1036
-	tls_tx_start ( tls, TLS_TX_CLIENT_KEY_EXCHANGE );
981
+	/* Schedule Client Key Exchange, Change Cipher, and Finished */
982
+	tls->tx_pending |= ( TLS_TX_CLIENT_KEY_EXCHANGE |
983
+			     TLS_TX_CHANGE_CIPHER |
984
+			     TLS_TX_FINISHED );
985
+	tls_tx_resume ( tls );
1037 986
 
1038 987
 	return 0;
1039 988
 }
@@ -1050,10 +999,15 @@ static int tls_new_finished ( struct tls_session *tls,
1050 999
 			      void *data, size_t len ) {
1051 1000
 
1052 1001
 	/* FIXME: Handle this properly */
1053
-	tls_tx_data ( tls );
1054 1002
 	( void ) data;
1055 1003
 	( void ) len;
1056 1004
 
1005
+	/* Mark session as ready to transmit plaintext data */
1006
+	tls->tx_ready = 1;
1007
+
1008
+	/* Send notification of a window change */
1009
+	xfer_window_changed ( &tls->plainstream );
1010
+
1057 1011
 	return 0;
1058 1012
 }
1059 1013
 
@@ -1561,7 +1515,7 @@ static int tls_new_ciphertext ( struct tls_session *tls,
1561 1515
 static size_t tls_plainstream_window ( struct tls_session *tls ) {
1562 1516
 
1563 1517
 	/* Block window unless we are ready to accept data */
1564
-	if ( tls->tx_state != TLS_TX_DATA )
1518
+	if ( ! tls->tx_ready )
1565 1519
 		return 0;
1566 1520
 
1567 1521
 	return xfer_window ( &tls->cipherstream );
@@ -1581,7 +1535,7 @@ static int tls_plainstream_deliver ( struct tls_session *tls,
1581 1535
 	int rc;
1582 1536
 	
1583 1537
 	/* Refuse unless we are ready to accept data */
1584
-	if ( tls->tx_state != TLS_TX_DATA ) {
1538
+	if ( ! tls->tx_ready ) {
1585 1539
 		rc = -ENOTCONN;
1586 1540
 		goto done;
1587 1541
 	}
@@ -1757,29 +1711,24 @@ static void tls_tx_step ( struct tls_session *tls ) {
1757 1711
 	if ( ! xfer_window ( &tls->cipherstream ) )
1758 1712
 		return;
1759 1713
 
1760
-	switch ( tls->tx_state ) {
1761
-	case TLS_TX_NONE:
1762
-		/* Nothing to do */
1763
-		break;
1764
-	case TLS_TX_CLIENT_HELLO:
1714
+	/* Send first pending transmission */
1715
+	if ( tls->tx_pending & TLS_TX_CLIENT_HELLO ) {
1765 1716
 		/* Send Client Hello */
1766 1717
 		if ( ( rc = tls_send_client_hello ( tls ) ) != 0 ) {
1767 1718
 			DBGC ( tls, "TLS %p could not send Client Hello: %s\n",
1768 1719
 			       tls, strerror ( rc ) );
1769 1720
 			goto err;
1770 1721
 		}
1771
-		tls_tx_none ( tls );
1772
-		break;
1773
-	case TLS_TX_CLIENT_KEY_EXCHANGE:
1722
+		tls->tx_pending &= ~TLS_TX_CLIENT_HELLO;
1723
+	} else if ( tls->tx_pending & TLS_TX_CLIENT_KEY_EXCHANGE ) {
1774 1724
 		/* Send Client Key Exchange */
1775 1725
 		if ( ( rc = tls_send_client_key_exchange ( tls ) ) != 0 ) {
1776 1726
 			DBGC ( tls, "TLS %p could send Client Key Exchange: "
1777 1727
 			       "%s\n", tls, strerror ( rc ) );
1778 1728
 			goto err;
1779 1729
 		}
1780
-		tls_tx_start ( tls, TLS_TX_CHANGE_CIPHER );
1781
-		break;
1782
-	case TLS_TX_CHANGE_CIPHER:
1730
+		tls->tx_pending &= ~TLS_TX_CLIENT_KEY_EXCHANGE;
1731
+	} else if ( tls->tx_pending & TLS_TX_CHANGE_CIPHER ) {
1783 1732
 		/* Send Change Cipher, and then change the cipher in use */
1784 1733
 		if ( ( rc = tls_send_change_cipher ( tls ) ) != 0 ) {
1785 1734
 			DBGC ( tls, "TLS %p could not send Change Cipher: "
@@ -1794,24 +1743,21 @@ static void tls_tx_step ( struct tls_session *tls ) {
1794 1743
 			goto err;
1795 1744
 		}
1796 1745
 		tls->tx_seq = 0;
1797
-		tls_tx_start ( tls, TLS_TX_FINISHED );
1798
-		break;
1799
-	case TLS_TX_FINISHED:
1746
+		tls->tx_pending &= ~TLS_TX_CHANGE_CIPHER;
1747
+	} else if ( tls->tx_pending & TLS_TX_FINISHED ) {
1800 1748
 		/* Send Finished */
1801 1749
 		if ( ( rc = tls_send_finished ( tls ) ) != 0 ) {
1802 1750
 			DBGC ( tls, "TLS %p could not send Finished: %s\n",
1803 1751
 			       tls, strerror ( rc ) );
1804 1752
 			goto err;
1805 1753
 		}
1806
-		tls_tx_none ( tls );
1807
-		break;
1808
-	case TLS_TX_DATA:
1809
-		/* Nothing to do */
1810
-		break;
1811
-	default:
1812
-		assert ( 0 );
1754
+		tls->tx_pending &= ~TLS_TX_FINISHED;
1813 1755
 	}
1814 1756
 
1757
+	/* Reschedule process if pending transmissions remain */
1758
+	if ( tls->tx_pending )
1759
+		tls_tx_resume ( tls );
1760
+
1815 1761
 	return;
1816 1762
 
1817 1763
  err:
@@ -1862,8 +1808,8 @@ int add_tls ( struct interface *xfer, const char *name,
1862 1808
 	}
1863 1809
 	digest_init ( &md5_algorithm, tls->handshake_md5_ctx );
1864 1810
 	digest_init ( &sha1_algorithm, tls->handshake_sha1_ctx );
1865
-	process_init_stopped ( &tls->process, &tls_process_desc, &tls->refcnt );
1866
-	tls_tx_start ( tls, TLS_TX_CLIENT_HELLO );
1811
+	tls->tx_pending = TLS_TX_CLIENT_HELLO;
1812
+	process_init ( &tls->process, &tls_process_desc, &tls->refcnt );
1867 1813
 
1868 1814
 	/* Attach to parent interface, mortalise self, and return */
1869 1815
 	intf_plug_plug ( &tls->plainstream, xfer );

Loading…
取消
儲存