mirror of
https://git.tartarus.org/simon/putty.git
synced 2025-01-25 01:02:24 +00:00
Connection sharing: handle reply to cancel-tcpip-forward.
This is another bug that must have been around since connection sharing was introduced, and nobody noticed until I did some unusually thorough testing yesterday. When a sharing downstream asks to set up a remote port forwarding, we pass through the "tcpip-forward" global request, and we also intercept the reply so that we know that the forwarding has been set up (and hence that we should be passing "forwarded-tcpip" channel opens for that port to this downstream). To do that, we set the want-reply flag in the version of the packet we pass to the server, even if it was clear in downstream's version; and we also put an item on a queue local to sshshare.c which reminds us what to do about the reply when it comes back. But when the downstream _cancels_ one of those forwardings, I wrote the code for all parts of that process except adding that queue item. I even wrote the code to _consume_ the queue item, but somehow I completely forgot to generate one in the first place! So the enum value GLOBREQ_CANCEL_TCPIP_FORWARD was declared, tested for, but never actually assigned to anything.
This commit is contained in:
parent
2b54c86e7e
commit
314c8f5270
15
sshshare.c
15
sshshare.c
@ -1146,6 +1146,7 @@ void share_got_pkt_from_server(void *csv, int type,
|
|||||||
case SSH2_MSG_REQUEST_SUCCESS:
|
case SSH2_MSG_REQUEST_SUCCESS:
|
||||||
case SSH2_MSG_REQUEST_FAILURE:
|
case SSH2_MSG_REQUEST_FAILURE:
|
||||||
globreq = cs->globreq_head;
|
globreq = cs->globreq_head;
|
||||||
|
assert(globreq); /* should match the queue in ssh.c */
|
||||||
if (globreq->type == GLOBREQ_TCPIP_FORWARD) {
|
if (globreq->type == GLOBREQ_TCPIP_FORWARD) {
|
||||||
if (type == SSH2_MSG_REQUEST_FAILURE) {
|
if (type == SSH2_MSG_REQUEST_FAILURE) {
|
||||||
share_remove_forwarding(cs, globreq->fwd);
|
share_remove_forwarding(cs, globreq->fwd);
|
||||||
@ -1402,6 +1403,20 @@ static void share_got_pkt_from_downstream(struct ssh_sharing_connstate *cs,
|
|||||||
(cs->parent->ssh, cs->id, type, pkt, pktlen,
|
(cs->parent->ssh, cs->id, type, pkt, pktlen,
|
||||||
orig_wantreply ? NULL : "upstream added want_reply flag");
|
orig_wantreply ? NULL : "upstream added want_reply flag");
|
||||||
ssh_sharing_queue_global_request(cs->parent->ssh, cs);
|
ssh_sharing_queue_global_request(cs->parent->ssh, cs);
|
||||||
|
|
||||||
|
/*
|
||||||
|
* And queue a globreq so that when the reply comes
|
||||||
|
* back we know to cancel it.
|
||||||
|
*/
|
||||||
|
globreq = snew(struct share_globreq);
|
||||||
|
globreq->next = NULL;
|
||||||
|
if (cs->globreq_tail)
|
||||||
|
cs->globreq_tail->next = globreq;
|
||||||
|
else
|
||||||
|
cs->globreq_head = globreq;
|
||||||
|
globreq->fwd = fwd;
|
||||||
|
globreq->want_reply = orig_wantreply;
|
||||||
|
globreq->type = GLOBREQ_CANCEL_TCPIP_FORWARD;
|
||||||
}
|
}
|
||||||
|
|
||||||
sfree(host);
|
sfree(host);
|
||||||
|
Loading…
Reference in New Issue
Block a user