13e81fc971
Although the DTLS transport layer logic drops failed writes on the floor, it is actually set up to work correctly. If an SSL_write fails at the transport, dropping the buffer is fine. Arguably it works better than in TLS because we don't have the weird "half-committed to data" behavior. Likewise, the handshake keeps track of how far its gotten and resumes the message at the right point. This broke when the buffering logic was rewritten because I didn't understand what the DTLS code was doing. The one thing that doesn't work as one might expect is non-fatal write errors during rexmit are not recoverable. The next timeout must fire before we try again. This code is quite badly sprinkled in here, so add tests to guard it against future turbulence. Because of the rexmit issues, the tests need some hacks around calls which may trigger them. It also changes the Go DTLS implementation from being completely strict about sequence numbers to only requiring they be monotonic. The tests also revealed another bug. This one seems to be upstream's fault, not mine. The logic to reset the handshake hash on the second ClientHello (in the HelloVerifyRequest case) was a little overenthusiastic and breaks if the ClientHello took multiple tries to send. Change-Id: I9b38b93fff7ae62faf8e36c4beaf848850b3f4b9 Reviewed-on: https://boringssl-review.googlesource.com/6417 Reviewed-by: Adam Langley <agl@google.com>
46 lines
1.8 KiB
C
46 lines
1.8 KiB
C
/* Copyright (c) 2014, Google Inc.
|
|
*
|
|
* Permission to use, copy, modify, and/or distribute this software for any
|
|
* purpose with or without fee is hereby granted, provided that the above
|
|
* copyright notice and this permission notice appear in all copies.
|
|
*
|
|
* THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL WARRANTIES
|
|
* WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF
|
|
* MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY
|
|
* SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES
|
|
* WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN ACTION
|
|
* OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF OR IN
|
|
* CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE. */
|
|
|
|
#ifndef HEADER_ASYNC_BIO
|
|
#define HEADER_ASYNC_BIO
|
|
|
|
#include <openssl/bio.h>
|
|
|
|
#include "../../crypto/test/scoped_types.h"
|
|
|
|
|
|
// AsyncBioCreate creates a filter BIO for testing asynchronous state
|
|
// machines which consume a stream socket. Reads and writes will fail
|
|
// and return EAGAIN unless explicitly allowed. Each async BIO has a
|
|
// read quota and a write quota. Initially both are zero. As each is
|
|
// incremented, bytes are allowed to flow through the BIO.
|
|
ScopedBIO AsyncBioCreate();
|
|
|
|
// AsyncBioCreateDatagram creates a filter BIO for testing for
|
|
// asynchronous state machines which consume datagram sockets. The read
|
|
// and write quota count in packets rather than bytes.
|
|
ScopedBIO AsyncBioCreateDatagram();
|
|
|
|
// AsyncBioAllowRead increments |bio|'s read quota by |count|.
|
|
void AsyncBioAllowRead(BIO *bio, size_t count);
|
|
|
|
// AsyncBioAllowWrite increments |bio|'s write quota by |count|.
|
|
void AsyncBioAllowWrite(BIO *bio, size_t count);
|
|
|
|
// AsyncBioEnforceWriteQuota configures where |bio| enforces its write quota.
|
|
void AsyncBioEnforceWriteQuota(BIO *bio, bool enforce);
|
|
|
|
|
|
#endif // HEADER_ASYNC_BIO
|