@@ -1084,7 +1084,11 @@ int dtls1_read_failed(SSL *s, int code)
10841084return code;
10851085 }
108610861087-if ( ! SSL_in_init(s)) /* done, no need to send a retransmit */
1087+#ifndef OPENSSL_NO_HEARTBEATS
1088+if (!SSL_in_init(s) && !s->tlsext_hb_pending) /* done, no need to send a retransmit */
1089+#else
1090+if (!SSL_in_init(s)) /* done, no need to send a retransmit */
1091+#endif
10881092 {
10891093BIO_set_flags(SSL_get_rbio(s), BIO_FLAGS_READ);
10901094return code;
@@ -1438,3 +1442,149 @@ int dtls1_shutdown(SSL *s)
14381442#endif
14391443return ret;
14401444 }
1445+1446+#ifndef OPENSSL_NO_HEARTBEATS
1447+int
1448+dtls1_process_heartbeat(SSL *s)
1449+ {
1450+unsigned char *p = &s->s3->rrec.data[0], *pl;
1451+unsigned short hbtype;
1452+unsigned int payload;
1453+unsigned int padding = 16; /* Use minimum padding */
1454+1455+/* Read type and payload length first */
1456+hbtype = *p++;
1457+n2s(p, payload);
1458+pl = p;
1459+1460+if (s->msg_callback)
1461+s->msg_callback(0, s->version, TLS1_RT_HEARTBEAT,
1462+&s->s3->rrec.data[0], s->s3->rrec.length,
1463+s, s->msg_callback_arg);
1464+1465+if (hbtype == TLS1_HB_REQUEST)
1466+ {
1467+unsigned char *buffer, *bp;
1468+int r;
1469+1470+/* Allocate memory for the response, size is 1 byte
1471+ * message type, plus 2 bytes payload length, plus
1472+ * payload, plus padding
1473+ */
1474+buffer = OPENSSL_malloc(1 + 2 + payload + padding);
1475+bp = buffer;
1476+1477+/* Enter response type, length and copy payload */
1478+*bp++ = TLS1_HB_RESPONSE;
1479+s2n(payload, bp);
1480+memcpy(bp, pl, payload);
1481+/* Random padding */
1482+RAND_pseudo_bytes(p, padding);
1483+1484+r = dtls1_write_bytes(s, TLS1_RT_HEARTBEAT, buffer, 3 + payload + padding);
1485+1486+if (r >= 0 && s->msg_callback)
1487+s->msg_callback(1, s->version, TLS1_RT_HEARTBEAT,
1488+buffer, 3 + payload + padding,
1489+s, s->msg_callback_arg);
1490+1491+OPENSSL_free(buffer);
1492+1493+if (r < 0)
1494+return r;
1495+ }
1496+else if (hbtype == TLS1_HB_RESPONSE)
1497+ {
1498+unsigned int seq;
1499+1500+/* We only send sequence numbers (2 bytes unsigned int),
1501+ * and 16 random bytes, so we just try to read the
1502+ * sequence number */
1503+n2s(pl, seq);
1504+1505+if (payload == 18 && seq == s->tlsext_hb_seq)
1506+ {
1507+dtls1_stop_timer(s);
1508+s->tlsext_hb_seq++;
1509+s->tlsext_hb_pending = 0;
1510+ }
1511+ }
1512+1513+return 0;
1514+ }
1515+1516+int
1517+dtls1_heartbeat(SSL *s)
1518+ {
1519+unsigned char *buf, *p;
1520+int ret;
1521+unsigned int payload = 18; /* Sequence number + random bytes */
1522+unsigned int padding = 16; /* Use minimum padding */
1523+1524+/* Only send if peer supports and accepts HB requests... */
1525+if (!(s->tlsext_heartbeat & SSL_TLSEXT_HB_ENABLED) ||
1526+s->tlsext_heartbeat & SSL_TLSEXT_HB_DONT_SEND_REQUESTS)
1527+ {
1528+SSLerr(SSL_F_DTLS1_HEARTBEAT,SSL_R_TLS_HEARTBEAT_PEER_DOESNT_ACCEPT);
1529+return -1;
1530+ }
1531+1532+/* ...and there is none in flight yet... */
1533+if (s->tlsext_hb_pending)
1534+ {
1535+SSLerr(SSL_F_DTLS1_HEARTBEAT,SSL_R_TLS_HEARTBEAT_PENDING);
1536+return -1;
1537+ }
1538+1539+/* ...and no handshake in progress. */
1540+if (SSL_in_init(s) || s->in_handshake)
1541+ {
1542+SSLerr(SSL_F_DTLS1_HEARTBEAT,SSL_R_UNEXPECTED_MESSAGE);
1543+return -1;
1544+ }
1545+1546+/* Check if padding is too long, payload and padding
1547+ * must not exceed 2^14 - 3 = 16381 bytes in total.
1548+ */
1549+OPENSSL_assert(payload + padding <= 16381);
1550+1551+/* Create HeartBeat message, we just use a sequence number
1552+ * as payload to distuingish different messages and add
1553+ * some random stuff.
1554+ * - Message Type, 1 byte
1555+ * - Payload Length, 2 bytes (unsigned int)
1556+ * - Payload, the sequence number (2 bytes uint)
1557+ * - Payload, random bytes (16 bytes uint)
1558+ * - Padding
1559+ */
1560+buf = OPENSSL_malloc(1 + 2 + payload + padding);
1561+p = buf;
1562+/* Message Type */
1563+*p++ = TLS1_HB_REQUEST;
1564+/* Payload length (18 bytes here) */
1565+s2n(payload, p);
1566+/* Sequence number */
1567+s2n(s->tlsext_hb_seq, p);
1568+/* 16 random bytes */
1569+RAND_pseudo_bytes(p, 16);
1570+p += 16;
1571+/* Random padding */
1572+RAND_pseudo_bytes(p, padding);
1573+1574+ret = dtls1_write_bytes(s, TLS1_RT_HEARTBEAT, buf, 3 + payload + padding);
1575+if (ret >= 0)
1576+ {
1577+if (s->msg_callback)
1578+s->msg_callback(1, s->version, TLS1_RT_HEARTBEAT,
1579+buf, 3 + payload + padding,
1580+s, s->msg_callback_arg);
1581+1582+dtls1_start_timer(s);
1583+s->tlsext_hb_pending = 1;
1584+ }
1585+1586+OPENSSL_free(buf);
1587+1588+return ret;
1589+ }
1590+#endif