Skip to content

Commit 9b6b49d

Browse files
committed
Made a missing PONG lead to disconnect
1 parent f4ed388 commit 9b6b49d

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);
@@ -2410,19 +2414,48 @@ public PingTask() {
24102414

24112415
@Override
24122416
public void run() {
2417+
int count = pingCounter.get();
2418+
if (count > 0) {
2419+
LOGGER.warn(
2420+
CAST_API_MARKER, "No PONG received for the previous PING from {}, disconnecting", remoteName
2421+
);
2422+
try {
2423+
close();
2424+
} catch (IOException e) {
2425+
LOGGER.debug(
2426+
CAST_API_MARKER,
2427+
"An error occurred while closing {} socket: {}",
2428+
remoteName,
2429+
e.getMessage()
2430+
);
2431+
}
2432+
cancel();
2433+
}
24132434
if (LOGGER.isTraceEnabled(CAST_API_HEARTBEAT_MARKER)) {
24142435
LOGGER.trace(CAST_API_HEARTBEAT_MARKER, "Pinging {}", remoteName);
24152436
}
24162437
try {
24172438
write(message);
2439+
pingCounter.incrementAndGet();
24182440
} catch (IOException e) {
24192441
LOGGER.warn(
24202442
CAST_API_MARKER,
2421-
"An error occurred while sending 'PING' to {}: {}",
2443+
"Disconnecting, because an error occurred while sending 'PING' to {}: {}",
24222444
remoteName,
24232445
e.getMessage()
24242446
);
24252447
LOGGER.trace(CAST_API_MARKER, "", e);
2448+
try {
2449+
close();
2450+
} catch (IOException ioe) {
2451+
LOGGER.debug(
2452+
CAST_API_MARKER,
2453+
"An error occurred while closing {} socket: {}",
2454+
remoteName,
2455+
ioe.getMessage()
2456+
);
2457+
}
2458+
cancel();
24262459
}
24272460
}
24282461
}
@@ -2612,6 +2645,21 @@ public void run() {
26122645
write(pongMessage);
26132646
} else if ("PONG".equals(responseType)) {
26142647
LOGGER.trace(CAST_API_HEARTBEAT_MARKER, "Received PONG from {}", remoteName);
2648+
while (true) {
2649+
int current = pingCounter.get();
2650+
int next = current - 1;
2651+
if (next < 0) {
2652+
LOGGER.warn(
2653+
CAST_API_MARKER,
2654+
"PING PONG mismatch, received more PONGs than sent PINGs from {}",
2655+
remoteName
2656+
);
2657+
break;
2658+
}
2659+
if (pingCounter.compareAndSet(current, next)) {
2660+
break;
2661+
}
2662+
}
26152663
} else {
26162664
LOGGER.trace(
26172665
CAST_API_HEARTBEAT_MARKER,

0 commit comments

Comments
 (0)