simon-git: putty (main): Simon Tatham
Commits to Tartarus hosted VCS
tartarus-commits at lists.tartarus.org
Sat Jul 26 11:20:32 BST 2025
TL;DR:
0c5fd787 GTK: stop using GDK_CURRENT_TIME.
edce58d4 HTTP proxy: fix misspelled error message (and comment).
b7db1869 More general function to delete toplevel callbacks.
bb8894ff Windows: clear pending netevents when closing a socket.
Repository: https://git.tartarus.org/simon/putty.git
On the web: https://git.tartarus.org/?p=simon/putty.git
Branch updated: main
Committer: Simon Tatham <anakin at pobox.com>
Date: 2025-07-26 11:20:32
commit 0c5fd787135608dc55cc13418ef37cc00236ed64
web diff https://git.tartarus.org/?p=simon/putty.git;a=commitdiff;h=0c5fd787135608dc55cc13418ef37cc00236ed64;hp=26a8ef376daf5f50c441a65691b84f87df49db9b
Author: Simon Tatham <anakin at pobox.com>
Date: Thu Jul 24 08:18:10 2025 +0100
GTK: stop using GDK_CURRENT_TIME.
gtk_get_current_event_time() is better: it returns the X server
timestamp associated with any event currently being handled. And if
there isn't one, it falls back to returning GDK_CURRENT_TIME, so it
doesn't do any worse than hardcoding GDK_CURRENT_TIME did.
unix/askpass.c | 8 ++++----
unix/dialog.c | 2 +-
unix/gtkcompat.h | 1 +
3 files changed, 6 insertions(+), 5 deletions(-)
commit edce58d49dfa17586b2f407fd668dd4dcc41496b
web diff https://git.tartarus.org/?p=simon/putty.git;a=commitdiff;h=edce58d49dfa17586b2f407fd668dd4dcc41496b;hp=0c5fd787135608dc55cc13418ef37cc00236ed64
Author: Simon Tatham <anakin at pobox.com>
Date: Sat Jul 26 09:59:55 2025 +0100
HTTP proxy: fix misspelled error message (and comment).
A 407 response from the proxy is expected to contain at least one
header naming an acceptable authentication method. The header name is
"Proxy-Authenticate". But if no such header is seen, our error message
incorrectly spelled the missing header name as "Proxy-Authorization".
That's a braino rather than a typo: "Proxy-Authorization" is the
header the _client_ sends for an actual attempt to authenticate.
proxy/http.c | 4 ++--
1 file changed, 2 insertions(+), 2 deletions(-)
commit b7db18690b518dc0e9d668bb50c81b485ea449ba
web diff https://git.tartarus.org/?p=simon/putty.git;a=commitdiff;h=b7db18690b518dc0e9d668bb50c81b485ea449ba;hp=edce58d49dfa17586b2f407fd668dd4dcc41496b
Author: Simon Tatham <anakin at pobox.com>
Date: Fri Jul 25 08:28:53 2025 +0100
More general function to delete toplevel callbacks.
For cases where you want a more subtle criterion than "cites this
particular context structure". I'm going to introduce one in the next
commit.
callback.c | 21 +++++++++++++++++----
putty.h | 3 +++
2 files changed, 20 insertions(+), 4 deletions(-)
commit bb8894ff12f9175d8ebc2c0efe2b56a72f091878
web diff https://git.tartarus.org/?p=simon/putty.git;a=commitdiff;h=bb8894ff12f9175d8ebc2c0efe2b56a72f091878;hp=b7db18690b518dc0e9d668bb50c81b485ea449ba
Author: Simon Tatham <anakin at pobox.com>
Date: Thu Jul 24 08:36:36 2025 +0100
Windows: clear pending netevents when closing a socket.
I hope that this fixes http-proxy-auth-wsaenotconn, although I've only
tested it on a hacked-up Python tool that mimics a web proxy only far
enough to reproduce the issue, and haven't confirmed a successful
connection through a working HTTP proxy.
Background: the GUI network tools (both PuTTY and Pageant â anything
that links with select-gui.c) use the WSAAsyncSelect method of
reporting socket activity, which sends a window message to a nominated
HWND when activity happens on a socket. When we receive one of those
messages, we don't handle it synchronously in WndProc: instead we
queue a toplevel callback, and deal with the network activity when the
callbacks are next run from the main loop.
This means that when we _close_ a socket, there are two possible
places where unhandled notifications for the old socket might still be
lurking around. They might be in our window's message queue waiting
for GetMessage to retrieve them, or they might have been moved from
there into the toplevel callback queue.
Either way, this is a source of potential bugs, because WinSock
eagerly reuses numeric socket IDs: it's entirely possible in practice
to close a socket, immediately open another one, and find the new
socket has reused the old one's ID. Then those unhandled notifications
don't just refer to a nonexistent socket any more: instead, they
misleadingly look as if they refer to the _new_ socket, and cause
bugs.
The case of this that comes up in practice, described in
http-proxy-auth-wsaenotconn, involves an HTTP proxy sending a 407
Proxy Authentication Required response with Connection: close. In that
situation, PuTTY wants to try again with authentication, but since
that TCP connection is going away, it must make a fresh connection to
the proxy for the retry. So it does close the socket and open a new
one within the same event handler, and the old socket ID is often
reused for the new socket, and a lingering FD_CLOSE notification from
the old socket causes PuTTY to incorrectly believe that the proxy has
slammed the _new_ connection shut.
According to my diagnostics, this particular FD_CLOSE notification
generally seems to have been moved from the window message queue into
a pending toplevel callback. But the other failure mode is possible in
principle too â perhaps more likely in cases where you close a socket
in response to some other window message. So we should deal with both.
In this commit, I deal with stale toplevel callbacks by using the new
delete_callbacks() function introduced in the previous commit, which
takes a predicate function to decide whether to delete each callback.
That lets me distinguish WM_NETEVENT callbacks citing a particular
socket.
Dealing with stale window messages is harder, because as far as I can
tell, there's no Win32 API to trawl the message queue deleting a
subset of messages of this kind. (GetMessage and PeekMessage both have
wMsgFilterMin and wMsgFilterMax parameters which can filter by the
message type, but to narrow down to just one socket, we would also
need to filter on wParam, and there's no call for that.)
So instead I do a nasty bodge. Wherever we call closesocket(),
select-gui.c posts itself a new custom message WM_DONE_WITH_SOCKET,
which goes on to the end of the message queue, and acts as a dividing
line. Any WM_NETEVENT seen for that socket id _before_
WM_DONE_WITH_SOCKET was already in the queue at the time we called
closesocket(), and therefore refers to the old socket and should be
ignored; but WM_NETEVENTs for the same id _after_ WM_DONE_WITH_SOCKET
must refer to some new socket reusing the id, and should be handled
normally. So select-gui.c keeps a tree234 of "moribund" socket ids:
ones for which we've posted a WM_DONE_WITH_SOCKET message to ourself
but not yet got it back, and therefore, until we do, WM_NETEVENTs
should be ignored.
windows/network.c | 22 ++++++++++++++--------
windows/pageant.c | 3 ++-
windows/platform.h | 6 ++++--
windows/select-cli.c | 4 ++++
windows/select-gui.c | 39 ++++++++++++++++++++++++++++++++++++++-
windows/window.c | 3 ++-
6 files changed, 64 insertions(+), 13 deletions(-)
More information about the tartarus-commits
mailing list