Skip to content

Commit e49d20e

Browse files
committed
Made a missing PONG lead to disconnect
1 parent f954afe commit e49d20e

1 file changed

Lines changed: 52 additions & 4 deletions

File tree

src/main/java/org/digitalmediaserver/cast/Channel.java

Lines changed: 52 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -40,6 +40,7 @@
4040
import java.util.Timer;
4141
import java.util.TimerTask;
4242
import java.util.concurrent.TimeoutException;
43+
import java.util.concurrent.atomic.AtomicInteger;
4344
import java.util.concurrent.atomic.AtomicLong;
4445
import javax.annotation.Nonnull;
4546
import javax.annotation.Nullable;
@@ -188,12 +189,14 @@ public class Channel implements Closeable {
188189
@GuardedBy("socketLock")
189190
protected InputHandler inputHandler;
190191

191-
/**
192-
* Counter for producing request numbers
193-
*/
192+
/** Counter for producing request numbers */
194193
@Nonnull
195194
protected final AtomicLong requestCounter = new AtomicLong(new Random().nextInt(65536) + 1L);
196195

196+
/** Counter for pending {@link Pong}s */
197+
@Nonnull
198+
protected final AtomicInteger pingCounter = new AtomicInteger();
199+
197200
/**
198201
* Processors of requests by their identifiers
199202
*/
@@ -441,6 +444,7 @@ public boolean connect() throws IOException, NoSuchAlgorithmException, KeyManage
441444
pingTimer.cancel();
442445
}
443446
// Start regular pinging
447+
pingCounter.set(0);
444448
PingTask pingTask = new PingTask();
445449
pingTimer = new Timer(remoteName + " PING timer");
446450
pingTimer.schedule(pingTask, 1000, PING_PERIOD);
@@ -2362,19 +2366,48 @@ public PingTask() {
23622366

23632367
@Override
23642368
public void run() {
2369+
int count = pingCounter.get();
2370+
if (count > 0) {
2371+
LOGGER.warn(
2372+
CAST_API_MARKER, "No PONG received for the previous PING from {}, disconnecting", remoteName
2373+
);
2374+
try {
2375+
close();
2376+
} catch (IOException e) {
2377+
LOGGER.debug(
2378+
CAST_API_MARKER,
2379+
"An error occurred while closing {} socket: {}",
2380+
remoteName,
2381+
e.getMessage()
2382+
);
2383+
}
2384+
cancel();
2385+
}
23652386
if (LOGGER.isTraceEnabled(CAST_API_HEARTBEAT_MARKER)) {
23662387
LOGGER.trace(CAST_API_HEARTBEAT_MARKER, "Pinging {}", remoteName);
23672388
}
23682389
try {
23692390
write(message);
2391+
pingCounter.incrementAndGet();
23702392
} catch (IOException e) {
23712393
LOGGER.warn(
23722394
CAST_API_MARKER,
2373-
"An error occurred while sending 'PING' to {}: {}",
2395+
"Disconnecting, because an error occurred while sending 'PING' to {}: {}",
23742396
remoteName,
23752397
e.getMessage()
23762398
);
23772399
LOGGER.trace(CAST_API_MARKER, "", e);
2400+
try {
2401+
close();
2402+
} catch (IOException ioe) {
2403+
LOGGER.debug(
2404+
CAST_API_MARKER,
2405+
"An error occurred while closing {} socket: {}",
2406+
remoteName,
2407+
ioe.getMessage()
2408+
);
2409+
}
2410+
cancel();
23782411
}
23792412
}
23802413
}
@@ -2564,6 +2597,21 @@ public void run() {
25642597
write(pongMessage);
25652598
} else if ("PONG".equals(responseType)) {
25662599
LOGGER.trace(CAST_API_HEARTBEAT_MARKER, "Received PONG from {}", remoteName);
2600+
while (true) {
2601+
int current = pingCounter.get();
2602+
int next = current - 1;
2603+
if (next < 0) {
2604+
LOGGER.warn(
2605+
CAST_API_MARKER,
2606+
"PING PONG mismatch, received more PONGs than sent PINGs from {}",
2607+
remoteName
2608+
);
2609+
break;
2610+
}
2611+
if (pingCounter.compareAndSet(current, next)) {
2612+
break;
2613+
}
2614+
}
25672615
} else {
25682616
LOGGER.trace(
25692617
CAST_API_HEARTBEAT_MARKER,

0 commit comments

Comments
 (0)