mirror of https://github.com/wolfSSL/wolfssh.git
Drop a forward the peer refused twice
A cancel refusal leaves the forward standing, since the peer keeps a listener it would not drop. There is no listener to keep when the setup was refused too, so FwdRemoteSettle() unwinds a registration nothing establishes and nothing is still owed an answer on, rather than leaving it unconfirmed and unmatchable until the session ends. - A cancel refusal unlinks an unconfirmed forward with no setup queued - Test refuses a want-reply setup and the cancel behind it, and checks the registration is gonepull/1214/head
parent
f6126898e0
commit
a88404cb88
|
|
@ -4097,7 +4097,11 @@ static void FwdRemoteSettle(WOLFSSH* ssh, WOLFSSH_FWD_REMOTE* entry,
|
|||
if (isCancel) {
|
||||
if (!success) {
|
||||
/* The peer kept the listener, so the forward stands and matching
|
||||
* resumes unless a later cancel is outstanding. */
|
||||
* resumes unless a later cancel is outstanding. An unconfirmed
|
||||
* forward has no listener to keep, though: its setup was refused
|
||||
* too, and with none still queued nothing will ever bind it. */
|
||||
if (!entry->confirmed && !FwdReplyHasSetup(ssh, entry))
|
||||
FwdRemoteUnlink(ssh, ssh->ctx->heap, entry);
|
||||
return;
|
||||
}
|
||||
|
||||
|
|
|
|||
|
|
@ -4051,6 +4051,36 @@ static void TestForwardedTcpipCancelBeforeSetupReply(void)
|
|||
FreeChannelOpenHarness(&harness);
|
||||
}
|
||||
|
||||
/* The same overlap with both requests refused. The setup bound no listener,
|
||||
* so the cancel's refusal is only the peer saying it has none to drop, and
|
||||
* nothing is left to hold the registration open. */
|
||||
static void TestForwardedTcpipSetupAndCancelBothRefusedDrops(void)
|
||||
{
|
||||
ChannelOpenHarness harness;
|
||||
|
||||
InitFwdRemoteHarness(&harness);
|
||||
|
||||
AssertIntEQ(wolfSSH_FwdRemoteSetup(harness.ssh, "127.0.0.1", 8080, 1),
|
||||
WS_SUCCESS);
|
||||
AssertIntEQ(wolfSSH_FwdRemoteCancel(harness.ssh, "127.0.0.1", 8080, 1),
|
||||
WS_SUCCESS);
|
||||
|
||||
/* The setup is refused, but the queued cancel still names the forward, so
|
||||
* it is held for that answer. */
|
||||
FeedRequestFailure(&harness);
|
||||
AssertNotNull(harness.ssh->fwdRemoteList);
|
||||
|
||||
/* The cancel is refused too. Nothing establishes the forward and nothing
|
||||
* is owed an answer on it, so it goes rather than sitting unmatchable
|
||||
* until the session ends. */
|
||||
FeedRequestFailure(&harness);
|
||||
AssertNull(harness.ssh->fwdRemoteList);
|
||||
|
||||
AssertForwardedOpenRefused(&harness, "127.0.0.1", 8080);
|
||||
|
||||
FreeChannelOpenHarness(&harness);
|
||||
}
|
||||
|
||||
/* The same overlap, but with a second forward outstanding behind it. The
|
||||
* cancelled forward's reply must not be spent on the one still waiting. */
|
||||
static void TestForwardedTcpipCancelBeforeSetupReplyKeepsOther(void)
|
||||
|
|
@ -10800,6 +10830,7 @@ int main(int argc, char** argv)
|
|||
TestForwardedTcpipUnmatchedCancelKeepsForward();
|
||||
TestForwardedTcpipCancelBeforeSetupReply();
|
||||
TestForwardedTcpipCancelBeforeSetupReplyKeepsOther();
|
||||
TestForwardedTcpipSetupAndCancelBothRefusedDrops();
|
||||
TestForwardedTcpipDuplicateSetupIsOneForward();
|
||||
TestForwardedTcpipDuplicateSetupRefusalKeepsForward();
|
||||
TestForwardedTcpipDuplicateSetupLaterSuccessBinds();
|
||||
|
|
|
|||
Loading…
Reference in New Issue