#ifndef OPENSSL_NO_SOCK
int DTLSv1_listen(SSL *s, BIO_ADDR *client)
{
- int next, n, ret = 0, clearpkt = 0;
+ int next, n, ret = 0;
unsigned char cookie[DTLS1_COOKIE_LENGTH];
unsigned char seq[SEQ_NUM_SIZE];
const unsigned char *data;
unsigned char *buf, *wbuf;
- size_t fragoff, fraglen, msglen;
+ size_t fragoff, fraglen, msglen, reclen, align = 0;
unsigned int rectype, versmajor, msgseq, msgtype, clientvers, cookielen;
BIO *rbio, *wbio;
BIO_ADDR *tmpclient = NULL;
return -1;
}
- /*
- * We only peek at incoming ClientHello's until we're sure we are going to
- * to respond with a HelloVerifyRequest. If its a ClientHello with a valid
- * cookie then we leave it in the BIO for accept to handle.
- */
- BIO_ctrl(SSL_get_rbio(s), BIO_CTRL_DGRAM_SET_PEEK_MODE, 1, NULL);
-
/*
* Note: This check deliberately excludes DTLS1_BAD_VER because that version
* requires the MAC to be calculated *including* the first ClientHello
}
buf = RECORD_LAYER_get_rbuf(&s->rlayer)->buf;
wbuf = RECORD_LAYER_get_wbuf(&s->rlayer)[0].buf;
+#if defined(SSL3_ALIGN_PAYLOAD)
+# if SSL3_ALIGN_PAYLOAD != 0
+ /*
+ * Using SSL3_RT_HEADER_LENGTH here instead of DTLS1_RT_HEADER_LENGTH for
+ * consistency with ssl3_read_n. In practice it should make no difference
+ * for sensible values of SSL3_ALIGN_PAYLOAD because the difference between
+ * SSL3_RT_HEADER_LENGTH and DTLS1_RT_HEADER_LENGTH is exactly 8
+ */
+ align = (size_t)buf + SSL3_RT_HEADER_LENGTH;
+ align = SSL3_ALIGN_PAYLOAD - 1 - ((align - 1) % SSL3_ALIGN_PAYLOAD);
+# endif
+#endif
+ buf += align;
do {
/* Get a packet */
clear_sys_error();
n = BIO_read(rbio, buf, SSL3_RT_MAX_PLAIN_LENGTH
+ DTLS1_RT_HEADER_LENGTH);
-
if (n <= 0) {
if (BIO_should_retry(rbio)) {
/* Non-blocking IO */
return -1;
}
- /* If we hit any problems we need to clear this packet from the BIO */
- clearpkt = 1;
-
if (!PACKET_buf_init(&pkt, buf, n)) {
SSLerr(SSL_F_DTLSV1_LISTEN, ERR_R_INTERNAL_ERROR);
return -1;
SSLerr(SSL_F_DTLSV1_LISTEN, SSL_R_LENGTH_MISMATCH);
goto end;
}
+ reclen = PACKET_remaining(&msgpkt);
/*
* We allow data remaining at the end of the packet because there could
* be a second record (but we ignore it)
* to resend, we just drop it.
*/
- /*
- * Dump the read packet, we don't need it any more. Ignore return
- * value
- */
- BIO_ctrl(SSL_get_rbio(s), BIO_CTRL_DGRAM_SET_PEEK_MODE, 0, NULL);
- BIO_read(rbio, buf, SSL3_RT_MAX_PLAIN_LENGTH);
- BIO_ctrl(SSL_get_rbio(s), BIO_CTRL_DGRAM_SET_PEEK_MODE, 1, NULL);
-
/* Generate the cookie */
if (s->ctx->app_gen_cookie_cb == NULL ||
s->ctx->app_gen_cookie_cb(s, cookie, &cookielen) == 0 ||
/* Construct the record and message headers */
if (!WPACKET_init_static_len(&wpkt,
wbuf,
- SSL3_RT_MAX_PLAIN_LENGTH
+ ssl_get_max_send_fragment(s)
+ DTLS1_RT_HEADER_LENGTH,
0)
|| !WPACKET_put_bytes_u8(&wpkt, SSL3_RT_HANDSHAKE)
if (BIO_dgram_get_peer(rbio, client) <= 0)
BIO_ADDR_clear(client);
+ /* Buffer the record in the processed_rcds queue */
+ if (!dtls_buffer_listen_record(s, reclen, seq, align))
+ return -1;
ret = 1;
- clearpkt = 0;
end:
BIO_ADDR_free(tmpclient);
- BIO_ctrl(SSL_get_rbio(s), BIO_CTRL_DGRAM_SET_PEEK_MODE, 0, NULL);
- if (clearpkt) {
- /* Dump this packet. Ignore return value */
- BIO_read(rbio, buf, SSL3_RT_MAX_PLAIN_LENGTH);
- }
return ret;
}
#endif