Use an explicit lock object instead of method synchronization
@@ -95,6 +95,7 @@ private static void sendDatagram(DatagramSender sender, byte[] record)
private final DatagramTransport transport;
private final ByteQueue recordQueue = new ByteQueue();
+ private final Object writeLock = new Object();
private volatile boolean closed = false;
private volatile boolean failed = false;
@@ -757,13 +758,12 @@ private void sendHeartbeatMessage(HeartbeatMessage heartbeatMessage)
}
/*
- * Currently synchronized here to ensure heartbeat sends and application data sends don't
+ * Currently uses synchronization to ensure heartbeat sends and application data sends don't
* interfere with each other. It may be overly cautious; the sequence number allocation is
* atomic, and if we synchronize only on the datagram send instead, then the only effect should
* be possible reordering of records (which might surprise a reliable transport implementation).
*/
- private synchronized void sendRecord(short contentType, byte[] buf, int off, int len)
- throws IOException
+ private void sendRecord(short contentType, byte[] buf, int off, int len) throws IOException
{
// Never send anything until a valid ClientHello has been received
if (writeVersion == null)
@@ -785,11 +785,12 @@ private synchronized void sendRecord(short contentType, byte[] buf, int off, int
throw new TlsFatalAlert(AlertDescription.internal_error);
}
+ synchronized (writeLock)
+ {
int recordEpoch = writeEpoch.getEpoch();
long recordSequenceNumber = writeEpoch.allocateSequenceNumber();
-
- byte[] ciphertext = writeEpoch.getCipher().encodePlaintext(
- getMacSequenceNumber(recordEpoch, recordSequenceNumber), contentType, buf, off, len);
+ long macSequenceNumber = getMacSequenceNumber(recordEpoch, recordSequenceNumber);
+ byte[] ciphertext = writeEpoch.getCipher().encodePlaintext(macSequenceNumber, contentType, buf, off, len);
// TODO Check the ciphertext length?
@@ -803,6 +804,7 @@ private synchronized void sendRecord(short contentType, byte[] buf, int off, int
sendDatagram(transport, record);
}
+ }
private static long getMacSequenceNumber(int epoch, long sequence_number)
{
