Only retransmit on Finished if frag_off == 0.

If the peer fragments Finished into multiple pieces, there is no need to
retransmit multiple times.

Change-Id: Ibf708ad079e1633afd420ff1c9be88a80020cba9
Reviewed-on: https://boringssl-review.googlesource.com/3762
Reviewed-by: Adam Langley <agl@google.com>
This commit is contained in:
David Benjamin 2015-03-02 19:01:16 -05:00 committed by Adam Langley
parent 9d102ddbc0
commit 7eaab4cd57
2 changed files with 25 additions and 5 deletions

View File

@ -840,14 +840,19 @@ start:
struct hm_header_st msg_hdr; struct hm_header_st msg_hdr;
dtls1_get_message_header(&rr->data[rr->off], &msg_hdr); dtls1_get_message_header(&rr->data[rr->off], &msg_hdr);
/* Ignore the Finished, but retransmit our last flight of messages. If the /* Ignore a stray Finished from the previous handshake. */
* peer sends the second Finished, they may not have received ours. */
if (msg_hdr.type == SSL3_MT_FINISHED) { if (msg_hdr.type == SSL3_MT_FINISHED) {
if (dtls1_check_timeout_num(s) < 0) { if (msg_hdr.frag_off == 0) {
return -1; /* Retransmit our last flight of messages. If the peer sends the second
* Finished, they may not have received ours. Only do this for the
* first fragment, in case the Finished was fragmented. */
if (dtls1_check_timeout_num(s) < 0) {
return -1;
}
dtls1_retransmit_buffered_messages(s);
} }
dtls1_retransmit_buffered_messages(s);
rr->length = 0; rr->length = 0;
goto start; goto start;
} }

View File

@ -2846,6 +2846,21 @@ func addDTLSRetransmitTests() {
resumeSession: true, resumeSession: true,
flags: []string{"-async"}, flags: []string{"-async"},
}) })
// Test that the final Finished retransmitting isn't
// duplicated if the peer badly fragments everything.
testCases = append(testCases, testCase{
testType: serverTest,
protocol: dtls,
name: "DTLS-Retransmit-Fragmented",
config: Config{
Bugs: ProtocolBugs{
TimeoutSchedule: []time.Duration{timeouts[0]},
MaxHandshakeRecordLength: 2,
},
},
flags: []string{"-async"},
})
} }
func worker(statusChan chan statusMsg, c chan *testCase, buildDir string, wg *sync.WaitGroup) { func worker(statusChan chan statusMsg, c chan *testCase, buildDir string, wg *sync.WaitGroup) {