2000-10-23 11:55:11 +00:00
|
|
|
/*
|
|
|
|
* Windows networking abstraction.
|
2001-01-07 19:16:16 +00:00
|
|
|
*
|
2004-12-30 16:45:11 +00:00
|
|
|
* For the IPv6 code in here I am indebted to Jeroen Massar and
|
|
|
|
* unfix.org.
|
2000-10-23 11:55:11 +00:00
|
|
|
*/
|
|
|
|
|
2017-02-14 23:19:13 +00:00
|
|
|
#include <winsock2.h> /* need to put this first, for winelib builds */
|
|
|
|
|
2000-10-23 11:55:11 +00:00
|
|
|
#include <stdio.h>
|
2000-10-24 10:47:49 +00:00
|
|
|
#include <stdlib.h>
|
2001-08-25 17:09:23 +00:00
|
|
|
#include <assert.h>
|
2000-10-23 11:55:11 +00:00
|
|
|
|
2017-02-14 23:19:13 +00:00
|
|
|
#define NEED_DECLARATION_OF_SELECT /* in order to initialise it */
|
|
|
|
|
2000-10-23 11:55:11 +00:00
|
|
|
#include "putty.h"
|
|
|
|
#include "network.h"
|
|
|
|
#include "tree234.h"
|
2020-01-29 06:19:30 +00:00
|
|
|
#include "ssh.h"
|
2000-10-23 11:55:11 +00:00
|
|
|
|
2003-10-12 13:46:12 +00:00
|
|
|
#include <ws2tcpip.h>
|
2004-12-30 16:45:11 +00:00
|
|
|
|
|
|
|
#ifndef NO_IPV6
|
2017-02-05 11:19:22 +00:00
|
|
|
#ifdef __clang__
|
|
|
|
#pragma clang diagnostic push
|
|
|
|
#pragma clang diagnostic ignored "-Wmissing-braces"
|
|
|
|
#endif
|
2004-12-30 16:45:11 +00:00
|
|
|
const struct in6_addr in6addr_any = IN6ADDR_ANY_INIT;
|
|
|
|
const struct in6_addr in6addr_loopback = IN6ADDR_LOOPBACK_INIT;
|
2017-02-05 11:19:22 +00:00
|
|
|
#ifdef __clang__
|
|
|
|
#pragma clang diagnostic pop
|
|
|
|
#endif
|
2003-10-12 13:46:12 +00:00
|
|
|
#endif
|
|
|
|
|
2002-12-18 11:39:25 +00:00
|
|
|
#define ipv4_is_loopback(addr) \
|
2019-09-08 19:29:00 +00:00
|
|
|
((p_ntohl(addr.s_addr) & 0xFF000000L) == 0x7F000000L)
|
2002-12-18 11:39:25 +00:00
|
|
|
|
2008-11-08 16:45:45 +00:00
|
|
|
/*
|
|
|
|
* Mutable state that goes with a SockAddr: stores information
|
|
|
|
* about where in the list of candidate IP(v*) addresses we've
|
|
|
|
* currently got to.
|
|
|
|
*/
|
|
|
|
typedef struct SockAddrStep_tag SockAddrStep;
|
|
|
|
struct SockAddrStep_tag {
|
|
|
|
#ifndef NO_IPV6
|
2019-09-08 19:29:00 +00:00
|
|
|
struct addrinfo *ai; /* steps along addr->ais */
|
2008-11-08 16:45:45 +00:00
|
|
|
#endif
|
|
|
|
int curraddr;
|
|
|
|
};
|
|
|
|
|
2018-05-27 08:29:33 +00:00
|
|
|
typedef struct NetSocket NetSocket;
|
|
|
|
struct NetSocket {
|
2015-05-15 10:15:42 +00:00
|
|
|
const char *error;
|
2000-10-23 11:55:11 +00:00
|
|
|
SOCKET s;
|
Get rid of lots of implicit pointer types.
All the main backend structures - Ssh, Telnet, Pty, Serial etc - now
describe structure types themselves rather than pointers to them. The
same goes for the codebase-wide trait types Socket and Plug, and the
supporting types SockAddr and Pinger.
All those things that were typedefed as pointers are older types; the
newer ones have the explicit * at the point of use, because that's
what I now seem to be preferring. But whichever one of those is
better, inconsistently using a mixture of the two styles is worse, so
let's make everything consistent.
A few types are still implicitly pointers, such as Bignum and some of
the GSSAPI types; generally this is either because they have to be
void *, or because they're typedefed differently on different
platforms and aren't always pointers at all. Can't be helped. But I've
got rid of the main ones, at least.
2018-10-04 18:10:23 +00:00
|
|
|
Plug *plug;
|
2001-08-25 17:09:23 +00:00
|
|
|
bufchain output_data;
|
Convert a lot of 'int' variables to 'bool'.
My normal habit these days, in new code, is to treat int and bool as
_almost_ completely separate types. I'm still willing to use C's
implicit test for zero on an integer (e.g. 'if (!blob.len)' is fine,
no need to spell it out as blob.len != 0), but generally, if a
variable is going to be conceptually a boolean, I like to declare it
bool and assign to it using 'true' or 'false' rather than 0 or 1.
PuTTY is an exception, because it predates the C99 bool, and I've
stuck to its existing coding style even when adding new code to it.
But it's been annoying me more and more, so now that I've decided C99
bool is an acceptable thing to require from our toolchain in the first
place, here's a quite thorough trawl through the source doing
'boolification'. Many variables and function parameters are now typed
as bool rather than int; many assignments of 0 or 1 to those variables
are now spelled 'true' or 'false'.
I managed this thorough conversion with the help of a custom clang
plugin that I wrote to trawl the AST and apply heuristics to point out
where things might want changing. So I've even managed to do a decent
job on parts of the code I haven't looked at in years!
To make the plugin's work easier, I pushed platform front ends
generally in the direction of using standard 'bool' in preference to
platform-specific boolean types like Windows BOOL or GTK's gboolean;
I've left the platform booleans in places they _have_ to be for the
platform APIs to work right, but variables only used by my own code
have been converted wherever I found them.
In a few places there are int values that look very like booleans in
_most_ of the places they're used, but have a rarely-used third value,
or a distinction between different nonzero values that most users
don't care about. In these cases, I've _removed_ uses of 'true' and
'false' for the return values, to emphasise that there's something
more subtle going on than a simple boolean answer:
- the 'multisel' field in dialog.h's list box structure, for which
the GTK front end in particular recognises a difference between 1
and 2 but nearly everything else treats as boolean
- the 'urgent' parameter to plug_receive, where 1 vs 2 tells you
something about the specific location of the urgent pointer, but
most clients only care about 0 vs 'something nonzero'
- the return value of wc_match, where -1 indicates a syntax error in
the wildcard.
- the return values from SSH-1 RSA-key loading functions, which use
-1 for 'wrong passphrase' and 0 for all other failures (so any
caller which already knows it's not loading an _encrypted private_
key can treat them as boolean)
- term->esc_query, and the 'query' parameter in toggle_mode in
terminal.c, which _usually_ hold 0 for ESC[123h or 1 for ESC[?123h,
but can also hold -1 for some other intervening character that we
don't support.
In a few places there's an integer that I haven't turned into a bool
even though it really _can_ only take values 0 or 1 (and, as above,
tried to make the call sites consistent in not calling those values
true and false), on the grounds that I thought it would make it more
confusing to imply that the 0 value was in some sense 'negative' or
bad and the 1 positive or good:
- the return value of plug_accepting uses the POSIXish convention of
0=success and nonzero=error; I think if I made it bool then I'd
also want to reverse its sense, and that's a job for a separate
piece of work.
- the 'screen' parameter to lineptr() in terminal.c, where 0 and 1
represent the default and alternate screens. There's no obvious
reason why one of those should be considered 'true' or 'positive'
or 'success' - they're just indices - so I've left it as int.
ssh_scp_recv had particularly confusing semantics for its previous int
return value: its call sites used '<= 0' to check for error, but it
never actually returned a negative number, just 0 or 1. Now the
function and its call sites agree that it's a bool.
In a couple of places I've renamed variables called 'ret', because I
don't like that name any more - it's unclear whether it means the
return value (in preparation) for the _containing_ function or the
return value received from a subroutine call, and occasionally I've
accidentally used the same variable for both and introduced a bug. So
where one of those got in my way, I've renamed it to 'toret' or 'retd'
(the latter short for 'returned') in line with my usual modern
practice, but I haven't done a thorough job of finding all of them.
Finally, one amusing side effect of doing this is that I've had to
separate quite a few chained assignments. It used to be perfectly fine
to write 'a = b = c = TRUE' when a,b,c were int and TRUE was just a
the 'true' defined by stdbool.h, that idiom provokes a warning from
gcc: 'suggest parentheses around assignment used as truth value'!
2018-11-02 19:23:19 +00:00
|
|
|
bool connected;
|
|
|
|
bool writable;
|
|
|
|
bool frozen; /* this causes readability notifications to be ignored */
|
|
|
|
bool frozen_readable; /* this means we missed at least one readability
|
|
|
|
* notification while we were frozen */
|
|
|
|
bool localhost_only; /* for listening sockets */
|
2001-08-25 17:09:23 +00:00
|
|
|
char oobdata[1];
|
2019-02-06 20:42:44 +00:00
|
|
|
size_t sending_oob;
|
Convert a lot of 'int' variables to 'bool'.
My normal habit these days, in new code, is to treat int and bool as
_almost_ completely separate types. I'm still willing to use C's
implicit test for zero on an integer (e.g. 'if (!blob.len)' is fine,
no need to spell it out as blob.len != 0), but generally, if a
variable is going to be conceptually a boolean, I like to declare it
bool and assign to it using 'true' or 'false' rather than 0 or 1.
PuTTY is an exception, because it predates the C99 bool, and I've
stuck to its existing coding style even when adding new code to it.
But it's been annoying me more and more, so now that I've decided C99
bool is an acceptable thing to require from our toolchain in the first
place, here's a quite thorough trawl through the source doing
'boolification'. Many variables and function parameters are now typed
as bool rather than int; many assignments of 0 or 1 to those variables
are now spelled 'true' or 'false'.
I managed this thorough conversion with the help of a custom clang
plugin that I wrote to trawl the AST and apply heuristics to point out
where things might want changing. So I've even managed to do a decent
job on parts of the code I haven't looked at in years!
To make the plugin's work easier, I pushed platform front ends
generally in the direction of using standard 'bool' in preference to
platform-specific boolean types like Windows BOOL or GTK's gboolean;
I've left the platform booleans in places they _have_ to be for the
platform APIs to work right, but variables only used by my own code
have been converted wherever I found them.
In a few places there are int values that look very like booleans in
_most_ of the places they're used, but have a rarely-used third value,
or a distinction between different nonzero values that most users
don't care about. In these cases, I've _removed_ uses of 'true' and
'false' for the return values, to emphasise that there's something
more subtle going on than a simple boolean answer:
- the 'multisel' field in dialog.h's list box structure, for which
the GTK front end in particular recognises a difference between 1
and 2 but nearly everything else treats as boolean
- the 'urgent' parameter to plug_receive, where 1 vs 2 tells you
something about the specific location of the urgent pointer, but
most clients only care about 0 vs 'something nonzero'
- the return value of wc_match, where -1 indicates a syntax error in
the wildcard.
- the return values from SSH-1 RSA-key loading functions, which use
-1 for 'wrong passphrase' and 0 for all other failures (so any
caller which already knows it's not loading an _encrypted private_
key can treat them as boolean)
- term->esc_query, and the 'query' parameter in toggle_mode in
terminal.c, which _usually_ hold 0 for ESC[123h or 1 for ESC[?123h,
but can also hold -1 for some other intervening character that we
don't support.
In a few places there's an integer that I haven't turned into a bool
even though it really _can_ only take values 0 or 1 (and, as above,
tried to make the call sites consistent in not calling those values
true and false), on the grounds that I thought it would make it more
confusing to imply that the 0 value was in some sense 'negative' or
bad and the 1 positive or good:
- the return value of plug_accepting uses the POSIXish convention of
0=success and nonzero=error; I think if I made it bool then I'd
also want to reverse its sense, and that's a job for a separate
piece of work.
- the 'screen' parameter to lineptr() in terminal.c, where 0 and 1
represent the default and alternate screens. There's no obvious
reason why one of those should be considered 'true' or 'positive'
or 'success' - they're just indices - so I've left it as int.
ssh_scp_recv had particularly confusing semantics for its previous int
return value: its call sites used '<= 0' to check for error, but it
never actually returned a negative number, just 0 or 1. Now the
function and its call sites agree that it's a bool.
In a couple of places I've renamed variables called 'ret', because I
don't like that name any more - it's unclear whether it means the
return value (in preparation) for the _containing_ function or the
return value received from a subroutine call, and occasionally I've
accidentally used the same variable for both and introduced a bug. So
where one of those got in my way, I've renamed it to 'toret' or 'retd'
(the latter short for 'returned') in line with my usual modern
practice, but I haven't done a thorough job of finding all of them.
Finally, one amusing side effect of doing this is that I've had to
separate quite a few chained assignments. It used to be perfectly fine
to write 'a = b = c = TRUE' when a,b,c were int and TRUE was just a
the 'true' defined by stdbool.h, that idiom provokes a warning from
gcc: 'suggest parentheses around assignment used as truth value'!
2018-11-02 19:23:19 +00:00
|
|
|
bool oobinline, nodelay, keepalive, privport;
|
2011-09-13 11:44:03 +00:00
|
|
|
enum { EOF_NO, EOF_PENDING, EOF_SENT } outgoingeof;
|
Get rid of lots of implicit pointer types.
All the main backend structures - Ssh, Telnet, Pty, Serial etc - now
describe structure types themselves rather than pointers to them. The
same goes for the codebase-wide trait types Socket and Plug, and the
supporting types SockAddr and Pinger.
All those things that were typedefed as pointers are older types; the
newer ones have the explicit * at the point of use, because that's
what I now seem to be preferring. But whichever one of those is
better, inconsistently using a mixture of the two styles is worse, so
let's make everything consistent.
A few types are still implicitly pointers, such as Bignum and some of
the GSSAPI types; generally this is either because they have to be
void *, or because they're typedefed differently on different
platforms and aren't always pointers at all. Can't be helped. But I've
got rid of the main ones, at least.
2018-10-04 18:10:23 +00:00
|
|
|
SockAddr *addr;
|
2008-11-08 16:45:45 +00:00
|
|
|
SockAddrStep step;
|
2005-01-16 14:29:34 +00:00
|
|
|
int port;
|
Convert a lot of 'int' variables to 'bool'.
My normal habit these days, in new code, is to treat int and bool as
_almost_ completely separate types. I'm still willing to use C's
implicit test for zero on an integer (e.g. 'if (!blob.len)' is fine,
no need to spell it out as blob.len != 0), but generally, if a
variable is going to be conceptually a boolean, I like to declare it
bool and assign to it using 'true' or 'false' rather than 0 or 1.
PuTTY is an exception, because it predates the C99 bool, and I've
stuck to its existing coding style even when adding new code to it.
But it's been annoying me more and more, so now that I've decided C99
bool is an acceptable thing to require from our toolchain in the first
place, here's a quite thorough trawl through the source doing
'boolification'. Many variables and function parameters are now typed
as bool rather than int; many assignments of 0 or 1 to those variables
are now spelled 'true' or 'false'.
I managed this thorough conversion with the help of a custom clang
plugin that I wrote to trawl the AST and apply heuristics to point out
where things might want changing. So I've even managed to do a decent
job on parts of the code I haven't looked at in years!
To make the plugin's work easier, I pushed platform front ends
generally in the direction of using standard 'bool' in preference to
platform-specific boolean types like Windows BOOL or GTK's gboolean;
I've left the platform booleans in places they _have_ to be for the
platform APIs to work right, but variables only used by my own code
have been converted wherever I found them.
In a few places there are int values that look very like booleans in
_most_ of the places they're used, but have a rarely-used third value,
or a distinction between different nonzero values that most users
don't care about. In these cases, I've _removed_ uses of 'true' and
'false' for the return values, to emphasise that there's something
more subtle going on than a simple boolean answer:
- the 'multisel' field in dialog.h's list box structure, for which
the GTK front end in particular recognises a difference between 1
and 2 but nearly everything else treats as boolean
- the 'urgent' parameter to plug_receive, where 1 vs 2 tells you
something about the specific location of the urgent pointer, but
most clients only care about 0 vs 'something nonzero'
- the return value of wc_match, where -1 indicates a syntax error in
the wildcard.
- the return values from SSH-1 RSA-key loading functions, which use
-1 for 'wrong passphrase' and 0 for all other failures (so any
caller which already knows it's not loading an _encrypted private_
key can treat them as boolean)
- term->esc_query, and the 'query' parameter in toggle_mode in
terminal.c, which _usually_ hold 0 for ESC[123h or 1 for ESC[?123h,
but can also hold -1 for some other intervening character that we
don't support.
In a few places there's an integer that I haven't turned into a bool
even though it really _can_ only take values 0 or 1 (and, as above,
tried to make the call sites consistent in not calling those values
true and false), on the grounds that I thought it would make it more
confusing to imply that the 0 value was in some sense 'negative' or
bad and the 1 positive or good:
- the return value of plug_accepting uses the POSIXish convention of
0=success and nonzero=error; I think if I made it bool then I'd
also want to reverse its sense, and that's a job for a separate
piece of work.
- the 'screen' parameter to lineptr() in terminal.c, where 0 and 1
represent the default and alternate screens. There's no obvious
reason why one of those should be considered 'true' or 'positive'
or 'success' - they're just indices - so I've left it as int.
ssh_scp_recv had particularly confusing semantics for its previous int
return value: its call sites used '<= 0' to check for error, but it
never actually returned a negative number, just 0 or 1. Now the
function and its call sites agree that it's a bool.
In a couple of places I've renamed variables called 'ret', because I
don't like that name any more - it's unclear whether it means the
return value (in preparation) for the _containing_ function or the
return value received from a subroutine call, and occasionally I've
accidentally used the same variable for both and introduced a bug. So
where one of those got in my way, I've renamed it to 'toret' or 'retd'
(the latter short for 'returned') in line with my usual modern
practice, but I haven't done a thorough job of finding all of them.
Finally, one amusing side effect of doing this is that I've had to
separate quite a few chained assignments. It used to be perfectly fine
to write 'a = b = c = TRUE' when a,b,c were int and TRUE was just a
the 'true' defined by stdbool.h, that idiom provokes a warning from
gcc: 'suggest parentheses around assignment used as truth value'!
2018-11-02 19:23:19 +00:00
|
|
|
int pending_error; /* in case send() returns error */
|
2005-01-08 14:45:26 +00:00
|
|
|
/*
|
|
|
|
* We sometimes need pairs of Socket structures to be linked:
|
|
|
|
* if we are listening on the same IPv6 and v4 port, for
|
|
|
|
* example. So here we define `parent' and `child' pointers to
|
|
|
|
* track this link.
|
|
|
|
*/
|
2018-05-27 08:29:33 +00:00
|
|
|
NetSocket *parent, *child;
|
|
|
|
|
2018-10-05 06:24:16 +00:00
|
|
|
Socket sock;
|
2000-10-23 11:55:11 +00:00
|
|
|
};
|
|
|
|
|
Get rid of lots of implicit pointer types.
All the main backend structures - Ssh, Telnet, Pty, Serial etc - now
describe structure types themselves rather than pointers to them. The
same goes for the codebase-wide trait types Socket and Plug, and the
supporting types SockAddr and Pinger.
All those things that were typedefed as pointers are older types; the
newer ones have the explicit * at the point of use, because that's
what I now seem to be preferring. But whichever one of those is
better, inconsistently using a mixture of the two styles is worse, so
let's make everything consistent.
A few types are still implicitly pointers, such as Bignum and some of
the GSSAPI types; generally this is either because they have to be
void *, or because they're typedefed differently on different
platforms and aren't always pointers at all. Can't be helped. But I've
got rid of the main ones, at least.
2018-10-04 18:10:23 +00:00
|
|
|
struct SockAddr {
|
2008-11-08 16:58:55 +00:00
|
|
|
int refcount;
|
2000-10-23 11:55:11 +00:00
|
|
|
char *error;
|
Convert a lot of 'int' variables to 'bool'.
My normal habit these days, in new code, is to treat int and bool as
_almost_ completely separate types. I'm still willing to use C's
implicit test for zero on an integer (e.g. 'if (!blob.len)' is fine,
no need to spell it out as blob.len != 0), but generally, if a
variable is going to be conceptually a boolean, I like to declare it
bool and assign to it using 'true' or 'false' rather than 0 or 1.
PuTTY is an exception, because it predates the C99 bool, and I've
stuck to its existing coding style even when adding new code to it.
But it's been annoying me more and more, so now that I've decided C99
bool is an acceptable thing to require from our toolchain in the first
place, here's a quite thorough trawl through the source doing
'boolification'. Many variables and function parameters are now typed
as bool rather than int; many assignments of 0 or 1 to those variables
are now spelled 'true' or 'false'.
I managed this thorough conversion with the help of a custom clang
plugin that I wrote to trawl the AST and apply heuristics to point out
where things might want changing. So I've even managed to do a decent
job on parts of the code I haven't looked at in years!
To make the plugin's work easier, I pushed platform front ends
generally in the direction of using standard 'bool' in preference to
platform-specific boolean types like Windows BOOL or GTK's gboolean;
I've left the platform booleans in places they _have_ to be for the
platform APIs to work right, but variables only used by my own code
have been converted wherever I found them.
In a few places there are int values that look very like booleans in
_most_ of the places they're used, but have a rarely-used third value,
or a distinction between different nonzero values that most users
don't care about. In these cases, I've _removed_ uses of 'true' and
'false' for the return values, to emphasise that there's something
more subtle going on than a simple boolean answer:
- the 'multisel' field in dialog.h's list box structure, for which
the GTK front end in particular recognises a difference between 1
and 2 but nearly everything else treats as boolean
- the 'urgent' parameter to plug_receive, where 1 vs 2 tells you
something about the specific location of the urgent pointer, but
most clients only care about 0 vs 'something nonzero'
- the return value of wc_match, where -1 indicates a syntax error in
the wildcard.
- the return values from SSH-1 RSA-key loading functions, which use
-1 for 'wrong passphrase' and 0 for all other failures (so any
caller which already knows it's not loading an _encrypted private_
key can treat them as boolean)
- term->esc_query, and the 'query' parameter in toggle_mode in
terminal.c, which _usually_ hold 0 for ESC[123h or 1 for ESC[?123h,
but can also hold -1 for some other intervening character that we
don't support.
In a few places there's an integer that I haven't turned into a bool
even though it really _can_ only take values 0 or 1 (and, as above,
tried to make the call sites consistent in not calling those values
true and false), on the grounds that I thought it would make it more
confusing to imply that the 0 value was in some sense 'negative' or
bad and the 1 positive or good:
- the return value of plug_accepting uses the POSIXish convention of
0=success and nonzero=error; I think if I made it bool then I'd
also want to reverse its sense, and that's a job for a separate
piece of work.
- the 'screen' parameter to lineptr() in terminal.c, where 0 and 1
represent the default and alternate screens. There's no obvious
reason why one of those should be considered 'true' or 'positive'
or 'success' - they're just indices - so I've left it as int.
ssh_scp_recv had particularly confusing semantics for its previous int
return value: its call sites used '<= 0' to check for error, but it
never actually returned a negative number, just 0 or 1. Now the
function and its call sites agree that it's a bool.
In a couple of places I've renamed variables called 'ret', because I
don't like that name any more - it's unclear whether it means the
return value (in preparation) for the _containing_ function or the
return value received from a subroutine call, and occasionally I've
accidentally used the same variable for both and introduced a bug. So
where one of those got in my way, I've renamed it to 'toret' or 'retd'
(the latter short for 'returned') in line with my usual modern
practice, but I haven't done a thorough job of finding all of them.
Finally, one amusing side effect of doing this is that I've had to
separate quite a few chained assignments. It used to be perfectly fine
to write 'a = b = c = TRUE' when a,b,c were int and TRUE was just a
the 'true' defined by stdbool.h, that idiom provokes a warning from
gcc: 'suggest parentheses around assignment used as truth value'!
2018-11-02 19:23:19 +00:00
|
|
|
bool resolved;
|
|
|
|
bool namedpipe; /* indicates that this SockAddr is phony, holding a Windows
|
|
|
|
* named pipe pathname instead of a network address */
|
2004-12-30 16:45:11 +00:00
|
|
|
#ifndef NO_IPV6
|
2019-09-08 19:29:00 +00:00
|
|
|
struct addrinfo *ais; /* Addresses IPv6 style. */
|
2001-01-07 19:16:16 +00:00
|
|
|
#endif
|
2019-09-08 19:29:00 +00:00
|
|
|
unsigned long *addresses; /* Addresses IPv4 style. */
|
2008-11-08 16:45:45 +00:00
|
|
|
int naddresses;
|
2019-09-08 19:29:00 +00:00
|
|
|
char hostname[512]; /* Store an unresolved host name. */
|
2000-10-23 11:55:11 +00:00
|
|
|
};
|
|
|
|
|
2008-11-08 16:45:45 +00:00
|
|
|
/*
|
|
|
|
* Which address family this address belongs to. AF_INET for IPv4;
|
|
|
|
* AF_INET6 for IPv6; AF_UNSPEC indicates that name resolution has
|
|
|
|
* not been done and a simple host name is held in this SockAddr
|
|
|
|
* structure.
|
|
|
|
*/
|
|
|
|
#ifndef NO_IPV6
|
|
|
|
#define SOCKADDR_FAMILY(addr, step) \
|
|
|
|
(!(addr)->resolved ? AF_UNSPEC : \
|
|
|
|
(step).ai ? (step).ai->ai_family : AF_INET)
|
|
|
|
#else
|
|
|
|
#define SOCKADDR_FAMILY(addr, step) \
|
|
|
|
(!(addr)->resolved ? AF_UNSPEC : AF_INET)
|
|
|
|
#endif
|
|
|
|
|
|
|
|
/*
|
|
|
|
* Start a SockAddrStep structure to step through multiple
|
|
|
|
* addresses.
|
|
|
|
*/
|
|
|
|
#ifndef NO_IPV6
|
|
|
|
#define START_STEP(addr, step) \
|
|
|
|
((step).ai = (addr)->ais, (step).curraddr = 0)
|
|
|
|
#else
|
|
|
|
#define START_STEP(addr, step) \
|
|
|
|
((step).curraddr = 0)
|
|
|
|
#endif
|
|
|
|
|
2000-10-23 11:55:11 +00:00
|
|
|
static tree234 *sktree;
|
|
|
|
|
2001-05-06 14:35:20 +00:00
|
|
|
static int cmpfortree(void *av, void *bv)
|
|
|
|
{
|
2018-05-27 08:29:33 +00:00
|
|
|
NetSocket *a = (NetSocket *)av, *b = (NetSocket *)bv;
|
2019-08-09 18:24:20 +00:00
|
|
|
uintptr_t as = (uintptr_t) a->s, bs = (uintptr_t) b->s;
|
2001-05-06 14:35:20 +00:00
|
|
|
if (as < bs)
|
2019-09-08 19:29:00 +00:00
|
|
|
return -1;
|
2001-05-06 14:35:20 +00:00
|
|
|
if (as > bs)
|
2019-09-08 19:29:00 +00:00
|
|
|
return +1;
|
2007-11-26 21:09:54 +00:00
|
|
|
if (a < b)
|
2019-09-08 19:29:00 +00:00
|
|
|
return -1;
|
2007-11-26 21:09:54 +00:00
|
|
|
if (a > b)
|
2019-09-08 19:29:00 +00:00
|
|
|
return +1;
|
2000-10-23 11:55:11 +00:00
|
|
|
return 0;
|
|
|
|
}
|
|
|
|
|
2001-05-06 14:35:20 +00:00
|
|
|
static int cmpforsearch(void *av, void *bv)
|
|
|
|
{
|
2018-05-27 08:29:33 +00:00
|
|
|
NetSocket *b = (NetSocket *)bv;
|
2015-08-11 12:01:02 +00:00
|
|
|
uintptr_t as = (uintptr_t) av, bs = (uintptr_t) b->s;
|
2001-05-06 14:35:20 +00:00
|
|
|
if (as < bs)
|
2019-09-08 19:29:00 +00:00
|
|
|
return -1;
|
2001-05-06 14:35:20 +00:00
|
|
|
if (as > bs)
|
2019-09-08 19:29:00 +00:00
|
|
|
return +1;
|
2000-10-23 11:55:11 +00:00
|
|
|
return 0;
|
|
|
|
}
|
|
|
|
|
2009-11-08 18:47:41 +00:00
|
|
|
DECL_WINDOWS_FUNCTION(static, int, WSAStartup, (WORD, LPWSADATA));
|
|
|
|
DECL_WINDOWS_FUNCTION(static, int, WSACleanup, (void));
|
|
|
|
DECL_WINDOWS_FUNCTION(static, int, closesocket, (SOCKET));
|
|
|
|
DECL_WINDOWS_FUNCTION(static, u_long, ntohl, (u_long));
|
|
|
|
DECL_WINDOWS_FUNCTION(static, u_long, htonl, (u_long));
|
|
|
|
DECL_WINDOWS_FUNCTION(static, u_short, htons, (u_short));
|
|
|
|
DECL_WINDOWS_FUNCTION(static, u_short, ntohs, (u_short));
|
|
|
|
DECL_WINDOWS_FUNCTION(static, int, gethostname, (char *, int));
|
|
|
|
DECL_WINDOWS_FUNCTION(static, struct hostent FAR *, gethostbyname,
|
2019-09-08 19:29:00 +00:00
|
|
|
(const char FAR *));
|
2009-11-08 18:47:41 +00:00
|
|
|
DECL_WINDOWS_FUNCTION(static, struct servent FAR *, getservbyname,
|
2019-09-08 19:29:00 +00:00
|
|
|
(const char FAR *, const char FAR *));
|
2009-11-08 18:47:41 +00:00
|
|
|
DECL_WINDOWS_FUNCTION(static, unsigned long, inet_addr, (const char FAR *));
|
|
|
|
DECL_WINDOWS_FUNCTION(static, char FAR *, inet_ntoa, (struct in_addr));
|
2015-05-18 12:57:45 +00:00
|
|
|
DECL_WINDOWS_FUNCTION(static, const char FAR *, inet_ntop,
|
|
|
|
(int, void FAR *, char *, size_t));
|
2009-11-08 18:47:41 +00:00
|
|
|
DECL_WINDOWS_FUNCTION(static, int, connect,
|
2019-09-08 19:29:00 +00:00
|
|
|
(SOCKET, const struct sockaddr FAR *, int));
|
2009-11-08 18:47:41 +00:00
|
|
|
DECL_WINDOWS_FUNCTION(static, int, bind,
|
2019-09-08 19:29:00 +00:00
|
|
|
(SOCKET, const struct sockaddr FAR *, int));
|
2009-11-08 18:47:41 +00:00
|
|
|
DECL_WINDOWS_FUNCTION(static, int, setsockopt,
|
2019-09-08 19:29:00 +00:00
|
|
|
(SOCKET, int, int, const char FAR *, int));
|
2009-11-08 18:47:41 +00:00
|
|
|
DECL_WINDOWS_FUNCTION(static, SOCKET, socket, (int, int, int));
|
|
|
|
DECL_WINDOWS_FUNCTION(static, int, listen, (SOCKET, int));
|
|
|
|
DECL_WINDOWS_FUNCTION(static, int, send, (SOCKET, const char FAR *, int, int));
|
2011-09-13 11:44:03 +00:00
|
|
|
DECL_WINDOWS_FUNCTION(static, int, shutdown, (SOCKET, int));
|
2009-11-08 18:47:41 +00:00
|
|
|
DECL_WINDOWS_FUNCTION(static, int, ioctlsocket,
|
2019-09-08 19:29:00 +00:00
|
|
|
(SOCKET, long, u_long FAR *));
|
2009-11-08 18:47:41 +00:00
|
|
|
DECL_WINDOWS_FUNCTION(static, SOCKET, accept,
|
2019-09-08 19:29:00 +00:00
|
|
|
(SOCKET, struct sockaddr FAR *, int FAR *));
|
2015-05-18 12:57:45 +00:00
|
|
|
DECL_WINDOWS_FUNCTION(static, int, getpeername,
|
2019-09-08 19:29:00 +00:00
|
|
|
(SOCKET, struct sockaddr FAR *, int FAR *));
|
2009-11-08 18:47:41 +00:00
|
|
|
DECL_WINDOWS_FUNCTION(static, int, recv, (SOCKET, char FAR *, int, int));
|
|
|
|
DECL_WINDOWS_FUNCTION(static, int, WSAIoctl,
|
2019-09-08 19:29:00 +00:00
|
|
|
(SOCKET, DWORD, LPVOID, DWORD, LPVOID, DWORD,
|
|
|
|
LPDWORD, LPWSAOVERLAPPED,
|
|
|
|
LPWSAOVERLAPPED_COMPLETION_ROUTINE));
|
2005-01-16 14:29:34 +00:00
|
|
|
#ifndef NO_IPV6
|
2009-11-08 18:47:41 +00:00
|
|
|
DECL_WINDOWS_FUNCTION(static, int, getaddrinfo,
|
2019-09-08 19:29:00 +00:00
|
|
|
(const char *nodename, const char *servname,
|
|
|
|
const struct addrinfo *hints, struct addrinfo **res));
|
2009-11-08 18:47:41 +00:00
|
|
|
DECL_WINDOWS_FUNCTION(static, void, freeaddrinfo, (struct addrinfo *res));
|
|
|
|
DECL_WINDOWS_FUNCTION(static, int, getnameinfo,
|
2019-09-08 19:29:00 +00:00
|
|
|
(const struct sockaddr FAR * sa, socklen_t salen,
|
|
|
|
char FAR * host, DWORD hostlen, char FAR * serv,
|
|
|
|
DWORD servlen, int flags));
|
2009-11-08 18:47:41 +00:00
|
|
|
DECL_WINDOWS_FUNCTION(static, char *, gai_strerror, (int ecode));
|
|
|
|
DECL_WINDOWS_FUNCTION(static, int, WSAAddressToStringA,
|
2019-09-08 19:29:00 +00:00
|
|
|
(LPSOCKADDR, DWORD, LPWSAPROTOCOL_INFO,
|
|
|
|
LPSTR, LPDWORD));
|
2005-01-16 14:29:34 +00:00
|
|
|
#endif
|
2003-10-12 13:46:12 +00:00
|
|
|
|
2006-12-23 09:04:27 +00:00
|
|
|
static HMODULE winsock_module = NULL;
|
|
|
|
static WSADATA wsadata;
|
2005-01-16 14:29:34 +00:00
|
|
|
#ifndef NO_IPV6
|
2006-12-23 09:04:27 +00:00
|
|
|
static HMODULE winsock2_module = NULL;
|
|
|
|
static HMODULE wship6_module = NULL;
|
2005-01-16 14:29:34 +00:00
|
|
|
#endif
|
2003-10-12 13:46:12 +00:00
|
|
|
|
2018-11-03 08:25:28 +00:00
|
|
|
static bool sk_startup(int hi, int lo)
|
2001-05-06 14:35:20 +00:00
|
|
|
{
|
2003-10-12 13:46:12 +00:00
|
|
|
WORD winsock_ver;
|
|
|
|
|
2006-12-23 09:04:27 +00:00
|
|
|
winsock_ver = MAKEWORD(hi, lo);
|
|
|
|
|
|
|
|
if (p_WSAStartup(winsock_ver, &wsadata)) {
|
2019-09-08 19:29:00 +00:00
|
|
|
return false;
|
2006-12-23 09:04:27 +00:00
|
|
|
}
|
|
|
|
|
|
|
|
if (LOBYTE(wsadata.wVersion) != LOBYTE(winsock_ver)) {
|
2019-09-08 19:29:00 +00:00
|
|
|
return false;
|
2006-12-23 09:04:27 +00:00
|
|
|
}
|
|
|
|
|
2018-10-29 19:50:29 +00:00
|
|
|
return true;
|
2006-12-23 09:04:27 +00:00
|
|
|
}
|
|
|
|
|
2020-02-02 10:00:43 +00:00
|
|
|
DEF_WINDOWS_FUNCTION(WSAAsyncSelect);
|
|
|
|
DEF_WINDOWS_FUNCTION(WSAEventSelect);
|
|
|
|
DEF_WINDOWS_FUNCTION(WSAGetLastError);
|
|
|
|
DEF_WINDOWS_FUNCTION(WSAEnumNetworkEvents);
|
|
|
|
DEF_WINDOWS_FUNCTION(select);
|
2017-02-14 23:19:13 +00:00
|
|
|
|
2006-12-23 09:04:27 +00:00
|
|
|
void sk_init(void)
|
|
|
|
{
|
2007-01-05 18:43:58 +00:00
|
|
|
#ifndef NO_IPV6
|
|
|
|
winsock2_module =
|
|
|
|
#endif
|
2010-09-13 08:29:45 +00:00
|
|
|
winsock_module = load_system32_dll("ws2_32.dll");
|
2003-10-12 13:46:12 +00:00
|
|
|
if (!winsock_module) {
|
2019-09-08 19:29:00 +00:00
|
|
|
winsock_module = load_system32_dll("wsock32.dll");
|
2003-10-12 13:46:12 +00:00
|
|
|
}
|
|
|
|
if (!winsock_module)
|
2019-09-08 19:29:00 +00:00
|
|
|
modalfatalbox("Unable to load any WinSock library");
|
2003-10-12 13:46:12 +00:00
|
|
|
|
2005-01-16 14:29:34 +00:00
|
|
|
#ifndef NO_IPV6
|
2006-12-23 09:04:27 +00:00
|
|
|
/* Check if we have getaddrinfo in Winsock */
|
|
|
|
if (GetProcAddress(winsock_module, "getaddrinfo") != NULL) {
|
2019-09-08 19:29:00 +00:00
|
|
|
GET_WINDOWS_FUNCTION(winsock_module, getaddrinfo);
|
|
|
|
GET_WINDOWS_FUNCTION(winsock_module, freeaddrinfo);
|
|
|
|
GET_WINDOWS_FUNCTION_NO_TYPECHECK(winsock_module, getnameinfo);
|
Add automatic type-checking to GET_WINDOWS_FUNCTION.
This gives me an extra safety-check against having mistyped one of the
function prototypes that we load at run time from DLLs: we verify that
the typedef we defined based on the prototype in our source code
matches the type of the real function as declared in the Windows
headers.
This was an idea I had while adding a pile of further functions using
this mechanism. It didn't catch any errors (either in the new
functions or in the existing collection), but that's no reason not to
keep it anyway now that I've thought of it!
In VS2015, this automated type-check works for most functions, but a
couple manage to break it. SetCurrentProcessExplicitAppUserModelID in
winjump.c can't be type-checked, because including <shobjidl.h> where
that function is declared would also bring in a load of other stuff
that conflicts with the painful manual COM declarations in winjump.c.
(That stuff could probably be removed now we're on an up-to-date
Visual Studio, on the other hand, but that's a separate chore.) And
gai_strerror, used in winnet.c, does _have_ an implementation in a
DLL, but the header files like to provide an inline version with a
different calling convention, which defeats this error-checking trick.
And in the older VS2003 that we still precautionarily build with,
several more type-checks have to be #ifdeffed out because the
functions they check against just aren't there at all.
2017-04-11 17:56:55 +00:00
|
|
|
/* This function would fail its type-check if we did one,
|
|
|
|
* because the VS header file provides an inline definition
|
|
|
|
* which is __cdecl instead of WINAPI. */
|
|
|
|
GET_WINDOWS_FUNCTION_NO_TYPECHECK(winsock_module, gai_strerror);
|
2006-12-23 09:04:27 +00:00
|
|
|
} else {
|
2019-09-08 19:29:00 +00:00
|
|
|
/* Fall back to wship6.dll for Windows 2000 */
|
|
|
|
wship6_module = load_system32_dll("wship6.dll");
|
|
|
|
if (wship6_module) {
|
|
|
|
GET_WINDOWS_FUNCTION(wship6_module, getaddrinfo);
|
|
|
|
GET_WINDOWS_FUNCTION(wship6_module, freeaddrinfo);
|
Add automatic type-checking to GET_WINDOWS_FUNCTION.
This gives me an extra safety-check against having mistyped one of the
function prototypes that we load at run time from DLLs: we verify that
the typedef we defined based on the prototype in our source code
matches the type of the real function as declared in the Windows
headers.
This was an idea I had while adding a pile of further functions using
this mechanism. It didn't catch any errors (either in the new
functions or in the existing collection), but that's no reason not to
keep it anyway now that I've thought of it!
In VS2015, this automated type-check works for most functions, but a
couple manage to break it. SetCurrentProcessExplicitAppUserModelID in
winjump.c can't be type-checked, because including <shobjidl.h> where
that function is declared would also bring in a load of other stuff
that conflicts with the painful manual COM declarations in winjump.c.
(That stuff could probably be removed now we're on an up-to-date
Visual Studio, on the other hand, but that's a separate chore.) And
gai_strerror, used in winnet.c, does _have_ an implementation in a
DLL, but the header files like to provide an inline version with a
different calling convention, which defeats this error-checking trick.
And in the older VS2003 that we still precautionarily build with,
several more type-checks have to be #ifdeffed out because the
functions they check against just aren't there at all.
2017-04-11 17:56:55 +00:00
|
|
|
/* See comment above about type check */
|
2019-09-08 19:29:00 +00:00
|
|
|
GET_WINDOWS_FUNCTION_NO_TYPECHECK(wship6_module, getnameinfo);
|
Add automatic type-checking to GET_WINDOWS_FUNCTION.
This gives me an extra safety-check against having mistyped one of the
function prototypes that we load at run time from DLLs: we verify that
the typedef we defined based on the prototype in our source code
matches the type of the real function as declared in the Windows
headers.
This was an idea I had while adding a pile of further functions using
this mechanism. It didn't catch any errors (either in the new
functions or in the existing collection), but that's no reason not to
keep it anyway now that I've thought of it!
In VS2015, this automated type-check works for most functions, but a
couple manage to break it. SetCurrentProcessExplicitAppUserModelID in
winjump.c can't be type-checked, because including <shobjidl.h> where
that function is declared would also bring in a load of other stuff
that conflicts with the painful manual COM declarations in winjump.c.
(That stuff could probably be removed now we're on an up-to-date
Visual Studio, on the other hand, but that's a separate chore.) And
gai_strerror, used in winnet.c, does _have_ an implementation in a
DLL, but the header files like to provide an inline version with a
different calling convention, which defeats this error-checking trick.
And in the older VS2003 that we still precautionarily build with,
several more type-checks have to be #ifdeffed out because the
functions they check against just aren't there at all.
2017-04-11 17:56:55 +00:00
|
|
|
GET_WINDOWS_FUNCTION_NO_TYPECHECK(winsock_module, gai_strerror);
|
2019-09-08 19:29:00 +00:00
|
|
|
} else {
|
|
|
|
}
|
2005-01-16 14:29:34 +00:00
|
|
|
}
|
2009-11-08 18:47:41 +00:00
|
|
|
GET_WINDOWS_FUNCTION(winsock2_module, WSAAddressToStringA);
|
2005-01-16 14:29:34 +00:00
|
|
|
#endif
|
|
|
|
|
2009-11-08 18:47:41 +00:00
|
|
|
GET_WINDOWS_FUNCTION(winsock_module, WSAAsyncSelect);
|
|
|
|
GET_WINDOWS_FUNCTION(winsock_module, WSAEventSelect);
|
2018-06-03 20:48:08 +00:00
|
|
|
/* We don't type-check select because at least some MinGW versions
|
|
|
|
* of the Windows API headers seem to disagree with the
|
|
|
|
* documentation on whether the 'struct timeval *' pointer is
|
|
|
|
* const or not. */
|
|
|
|
GET_WINDOWS_FUNCTION_NO_TYPECHECK(winsock_module, select);
|
2009-11-08 18:47:41 +00:00
|
|
|
GET_WINDOWS_FUNCTION(winsock_module, WSAGetLastError);
|
|
|
|
GET_WINDOWS_FUNCTION(winsock_module, WSAEnumNetworkEvents);
|
|
|
|
GET_WINDOWS_FUNCTION(winsock_module, WSAStartup);
|
|
|
|
GET_WINDOWS_FUNCTION(winsock_module, WSACleanup);
|
|
|
|
GET_WINDOWS_FUNCTION(winsock_module, closesocket);
|
|
|
|
GET_WINDOWS_FUNCTION(winsock_module, ntohl);
|
|
|
|
GET_WINDOWS_FUNCTION(winsock_module, htonl);
|
|
|
|
GET_WINDOWS_FUNCTION(winsock_module, htons);
|
|
|
|
GET_WINDOWS_FUNCTION(winsock_module, ntohs);
|
2018-05-27 08:29:33 +00:00
|
|
|
GET_WINDOWS_FUNCTION_NO_TYPECHECK(winsock_module, gethostname);
|
2009-11-08 18:47:41 +00:00
|
|
|
GET_WINDOWS_FUNCTION(winsock_module, gethostbyname);
|
|
|
|
GET_WINDOWS_FUNCTION(winsock_module, getservbyname);
|
|
|
|
GET_WINDOWS_FUNCTION(winsock_module, inet_addr);
|
|
|
|
GET_WINDOWS_FUNCTION(winsock_module, inet_ntoa);
|
2017-04-15 17:13:47 +00:00
|
|
|
/* Older Visual Studio, and MinGW as of Ubuntu 16.04, don't know
|
2020-01-29 06:35:53 +00:00
|
|
|
* about this function at all, so can't type-check it. Also there
|
|
|
|
* seems to be some disagreement in the VS headers about whether
|
|
|
|
* the second argument is void * or const void *, so I omit the
|
|
|
|
* type check. */
|
Add automatic type-checking to GET_WINDOWS_FUNCTION.
This gives me an extra safety-check against having mistyped one of the
function prototypes that we load at run time from DLLs: we verify that
the typedef we defined based on the prototype in our source code
matches the type of the real function as declared in the Windows
headers.
This was an idea I had while adding a pile of further functions using
this mechanism. It didn't catch any errors (either in the new
functions or in the existing collection), but that's no reason not to
keep it anyway now that I've thought of it!
In VS2015, this automated type-check works for most functions, but a
couple manage to break it. SetCurrentProcessExplicitAppUserModelID in
winjump.c can't be type-checked, because including <shobjidl.h> where
that function is declared would also bring in a load of other stuff
that conflicts with the painful manual COM declarations in winjump.c.
(That stuff could probably be removed now we're on an up-to-date
Visual Studio, on the other hand, but that's a separate chore.) And
gai_strerror, used in winnet.c, does _have_ an implementation in a
DLL, but the header files like to provide an inline version with a
different calling convention, which defeats this error-checking trick.
And in the older VS2003 that we still precautionarily build with,
several more type-checks have to be #ifdeffed out because the
functions they check against just aren't there at all.
2017-04-11 17:56:55 +00:00
|
|
|
GET_WINDOWS_FUNCTION_NO_TYPECHECK(winsock_module, inet_ntop);
|
2009-11-08 18:47:41 +00:00
|
|
|
GET_WINDOWS_FUNCTION(winsock_module, connect);
|
|
|
|
GET_WINDOWS_FUNCTION(winsock_module, bind);
|
|
|
|
GET_WINDOWS_FUNCTION(winsock_module, setsockopt);
|
|
|
|
GET_WINDOWS_FUNCTION(winsock_module, socket);
|
|
|
|
GET_WINDOWS_FUNCTION(winsock_module, listen);
|
|
|
|
GET_WINDOWS_FUNCTION(winsock_module, send);
|
2011-09-13 11:44:03 +00:00
|
|
|
GET_WINDOWS_FUNCTION(winsock_module, shutdown);
|
2009-11-08 18:47:41 +00:00
|
|
|
GET_WINDOWS_FUNCTION(winsock_module, ioctlsocket);
|
|
|
|
GET_WINDOWS_FUNCTION(winsock_module, accept);
|
2015-05-18 12:57:45 +00:00
|
|
|
GET_WINDOWS_FUNCTION(winsock_module, getpeername);
|
2009-11-08 18:47:41 +00:00
|
|
|
GET_WINDOWS_FUNCTION(winsock_module, recv);
|
|
|
|
GET_WINDOWS_FUNCTION(winsock_module, WSAIoctl);
|
2003-10-12 13:46:12 +00:00
|
|
|
|
2006-12-23 09:04:27 +00:00
|
|
|
/* Try to get the best WinSock version we can get */
|
|
|
|
if (!sk_startup(2,2) &&
|
2019-09-08 19:29:00 +00:00
|
|
|
!sk_startup(2,0) &&
|
|
|
|
!sk_startup(1,1)) {
|
|
|
|
modalfatalbox("Unable to initialise WinSock");
|
2003-10-12 13:46:12 +00:00
|
|
|
}
|
|
|
|
|
2000-10-23 11:55:11 +00:00
|
|
|
sktree = newtree234(cmpfortree);
|
|
|
|
}
|
|
|
|
|
2002-03-06 20:13:22 +00:00
|
|
|
void sk_cleanup(void)
|
|
|
|
{
|
2018-05-27 08:29:33 +00:00
|
|
|
NetSocket *s;
|
2002-03-06 20:13:22 +00:00
|
|
|
int i;
|
|
|
|
|
|
|
|
if (sktree) {
|
2019-09-08 19:29:00 +00:00
|
|
|
for (i = 0; (s = index234(sktree, i)) != NULL; i++) {
|
|
|
|
p_closesocket(s->s);
|
|
|
|
}
|
|
|
|
freetree234(sktree);
|
|
|
|
sktree = NULL;
|
2002-03-06 20:13:22 +00:00
|
|
|
}
|
2003-10-12 13:46:12 +00:00
|
|
|
|
2009-08-21 20:05:24 +00:00
|
|
|
if (p_WSACleanup)
|
2019-09-08 19:29:00 +00:00
|
|
|
p_WSACleanup();
|
2003-10-12 13:46:12 +00:00
|
|
|
if (winsock_module)
|
2019-09-08 19:29:00 +00:00
|
|
|
FreeLibrary(winsock_module);
|
2005-02-07 12:23:10 +00:00
|
|
|
#ifndef NO_IPV6
|
2005-01-16 14:29:34 +00:00
|
|
|
if (wship6_module)
|
2019-09-08 19:29:00 +00:00
|
|
|
FreeLibrary(wship6_module);
|
2005-02-07 12:23:10 +00:00
|
|
|
#endif
|
2002-03-06 20:13:22 +00:00
|
|
|
}
|
|
|
|
|
2015-05-15 10:15:42 +00:00
|
|
|
const char *winsock_error_string(int error)
|
2001-05-06 14:35:20 +00:00
|
|
|
{
|
2012-11-13 18:36:27 +00:00
|
|
|
/*
|
|
|
|
* Error codes we know about and have historically had reasonably
|
|
|
|
* sensible error messages for.
|
|
|
|
*/
|
2000-12-18 09:20:26 +00:00
|
|
|
switch (error) {
|
2001-05-06 14:35:20 +00:00
|
|
|
case WSAEACCES:
|
2019-09-08 19:29:00 +00:00
|
|
|
return "Network error: Permission denied";
|
2001-05-06 14:35:20 +00:00
|
|
|
case WSAEADDRINUSE:
|
2019-09-08 19:29:00 +00:00
|
|
|
return "Network error: Address already in use";
|
2001-05-06 14:35:20 +00:00
|
|
|
case WSAEADDRNOTAVAIL:
|
2019-09-08 19:29:00 +00:00
|
|
|
return "Network error: Cannot assign requested address";
|
2001-05-06 14:35:20 +00:00
|
|
|
case WSAEAFNOSUPPORT:
|
2019-09-08 19:29:00 +00:00
|
|
|
return
|
|
|
|
"Network error: Address family not supported by protocol family";
|
2001-05-06 14:35:20 +00:00
|
|
|
case WSAEALREADY:
|
2019-09-08 19:29:00 +00:00
|
|
|
return "Network error: Operation already in progress";
|
2001-05-06 14:35:20 +00:00
|
|
|
case WSAECONNABORTED:
|
2019-09-08 19:29:00 +00:00
|
|
|
return "Network error: Software caused connection abort";
|
2001-05-06 14:35:20 +00:00
|
|
|
case WSAECONNREFUSED:
|
2019-09-08 19:29:00 +00:00
|
|
|
return "Network error: Connection refused";
|
2001-05-06 14:35:20 +00:00
|
|
|
case WSAECONNRESET:
|
2019-09-08 19:29:00 +00:00
|
|
|
return "Network error: Connection reset by peer";
|
2001-05-06 14:35:20 +00:00
|
|
|
case WSAEDESTADDRREQ:
|
2019-09-08 19:29:00 +00:00
|
|
|
return "Network error: Destination address required";
|
2001-05-06 14:35:20 +00:00
|
|
|
case WSAEFAULT:
|
2019-09-08 19:29:00 +00:00
|
|
|
return "Network error: Bad address";
|
2001-05-06 14:35:20 +00:00
|
|
|
case WSAEHOSTDOWN:
|
2019-09-08 19:29:00 +00:00
|
|
|
return "Network error: Host is down";
|
2001-05-06 14:35:20 +00:00
|
|
|
case WSAEHOSTUNREACH:
|
2019-09-08 19:29:00 +00:00
|
|
|
return "Network error: No route to host";
|
2001-05-06 14:35:20 +00:00
|
|
|
case WSAEINPROGRESS:
|
2019-09-08 19:29:00 +00:00
|
|
|
return "Network error: Operation now in progress";
|
2001-05-06 14:35:20 +00:00
|
|
|
case WSAEINTR:
|
2019-09-08 19:29:00 +00:00
|
|
|
return "Network error: Interrupted function call";
|
2001-05-06 14:35:20 +00:00
|
|
|
case WSAEINVAL:
|
2019-09-08 19:29:00 +00:00
|
|
|
return "Network error: Invalid argument";
|
2001-05-06 14:35:20 +00:00
|
|
|
case WSAEISCONN:
|
2019-09-08 19:29:00 +00:00
|
|
|
return "Network error: Socket is already connected";
|
2001-05-06 14:35:20 +00:00
|
|
|
case WSAEMFILE:
|
2019-09-08 19:29:00 +00:00
|
|
|
return "Network error: Too many open files";
|
2001-05-06 14:35:20 +00:00
|
|
|
case WSAEMSGSIZE:
|
2019-09-08 19:29:00 +00:00
|
|
|
return "Network error: Message too long";
|
2001-05-06 14:35:20 +00:00
|
|
|
case WSAENETDOWN:
|
2019-09-08 19:29:00 +00:00
|
|
|
return "Network error: Network is down";
|
2001-05-06 14:35:20 +00:00
|
|
|
case WSAENETRESET:
|
2019-09-08 19:29:00 +00:00
|
|
|
return "Network error: Network dropped connection on reset";
|
2001-05-06 14:35:20 +00:00
|
|
|
case WSAENETUNREACH:
|
2019-09-08 19:29:00 +00:00
|
|
|
return "Network error: Network is unreachable";
|
2001-05-06 14:35:20 +00:00
|
|
|
case WSAENOBUFS:
|
2019-09-08 19:29:00 +00:00
|
|
|
return "Network error: No buffer space available";
|
2001-05-06 14:35:20 +00:00
|
|
|
case WSAENOPROTOOPT:
|
2019-09-08 19:29:00 +00:00
|
|
|
return "Network error: Bad protocol option";
|
2001-05-06 14:35:20 +00:00
|
|
|
case WSAENOTCONN:
|
2019-09-08 19:29:00 +00:00
|
|
|
return "Network error: Socket is not connected";
|
2001-05-06 14:35:20 +00:00
|
|
|
case WSAENOTSOCK:
|
2019-09-08 19:29:00 +00:00
|
|
|
return "Network error: Socket operation on non-socket";
|
2001-05-06 14:35:20 +00:00
|
|
|
case WSAEOPNOTSUPP:
|
2019-09-08 19:29:00 +00:00
|
|
|
return "Network error: Operation not supported";
|
2001-05-06 14:35:20 +00:00
|
|
|
case WSAEPFNOSUPPORT:
|
2019-09-08 19:29:00 +00:00
|
|
|
return "Network error: Protocol family not supported";
|
2001-05-06 14:35:20 +00:00
|
|
|
case WSAEPROCLIM:
|
2019-09-08 19:29:00 +00:00
|
|
|
return "Network error: Too many processes";
|
2001-05-06 14:35:20 +00:00
|
|
|
case WSAEPROTONOSUPPORT:
|
2019-09-08 19:29:00 +00:00
|
|
|
return "Network error: Protocol not supported";
|
2001-05-06 14:35:20 +00:00
|
|
|
case WSAEPROTOTYPE:
|
2019-09-08 19:29:00 +00:00
|
|
|
return "Network error: Protocol wrong type for socket";
|
2001-05-06 14:35:20 +00:00
|
|
|
case WSAESHUTDOWN:
|
2019-09-08 19:29:00 +00:00
|
|
|
return "Network error: Cannot send after socket shutdown";
|
2001-05-06 14:35:20 +00:00
|
|
|
case WSAESOCKTNOSUPPORT:
|
2019-09-08 19:29:00 +00:00
|
|
|
return "Network error: Socket type not supported";
|
2001-05-06 14:35:20 +00:00
|
|
|
case WSAETIMEDOUT:
|
2019-09-08 19:29:00 +00:00
|
|
|
return "Network error: Connection timed out";
|
2001-05-06 14:35:20 +00:00
|
|
|
case WSAEWOULDBLOCK:
|
2019-09-08 19:29:00 +00:00
|
|
|
return "Network error: Resource temporarily unavailable";
|
2001-05-06 14:35:20 +00:00
|
|
|
case WSAEDISCON:
|
2019-09-08 19:29:00 +00:00
|
|
|
return "Network error: Graceful shutdown in progress";
|
2000-12-18 09:20:26 +00:00
|
|
|
}
|
2012-11-13 18:36:27 +00:00
|
|
|
|
|
|
|
/*
|
2018-11-03 08:32:25 +00:00
|
|
|
* Handle any other error code by delegating to win_strerror.
|
2012-11-13 18:36:27 +00:00
|
|
|
*/
|
2018-11-03 08:32:25 +00:00
|
|
|
return win_strerror(error);
|
2000-12-18 09:20:26 +00:00
|
|
|
}
|
|
|
|
|
Get rid of lots of implicit pointer types.
All the main backend structures - Ssh, Telnet, Pty, Serial etc - now
describe structure types themselves rather than pointers to them. The
same goes for the codebase-wide trait types Socket and Plug, and the
supporting types SockAddr and Pinger.
All those things that were typedefed as pointers are older types; the
newer ones have the explicit * at the point of use, because that's
what I now seem to be preferring. But whichever one of those is
better, inconsistently using a mixture of the two styles is worse, so
let's make everything consistent.
A few types are still implicitly pointers, such as Bignum and some of
the GSSAPI types; generally this is either because they have to be
void *, or because they're typedefed differently on different
platforms and aren't always pointers at all. Can't be helped. But I've
got rid of the main ones, at least.
2018-10-04 18:10:23 +00:00
|
|
|
SockAddr *sk_namelookup(const char *host, char **canonicalname,
|
|
|
|
int address_family)
|
2001-01-07 19:16:16 +00:00
|
|
|
{
|
Get rid of lots of implicit pointer types.
All the main backend structures - Ssh, Telnet, Pty, Serial etc - now
describe structure types themselves rather than pointers to them. The
same goes for the codebase-wide trait types Socket and Plug, and the
supporting types SockAddr and Pinger.
All those things that were typedefed as pointers are older types; the
newer ones have the explicit * at the point of use, because that's
what I now seem to be preferring. But whichever one of those is
better, inconsistently using a mixture of the two styles is worse, so
let's make everything consistent.
A few types are still implicitly pointers, such as Bignum and some of
the GSSAPI types; generally this is either because they have to be
void *, or because they're typedefed differently on different
platforms and aren't always pointers at all. Can't be helped. But I've
got rid of the main ones, at least.
2018-10-04 18:10:23 +00:00
|
|
|
SockAddr *ret = snew(SockAddr);
|
2000-10-23 11:55:11 +00:00
|
|
|
unsigned long a;
|
2001-05-09 14:01:15 +00:00
|
|
|
char realhost[8192];
|
2008-11-08 16:45:45 +00:00
|
|
|
int hint_family;
|
2000-10-23 11:55:11 +00:00
|
|
|
|
2008-11-08 16:45:45 +00:00
|
|
|
/* Default to IPv4. */
|
|
|
|
hint_family = (address_family == ADDRTYPE_IPV4 ? AF_INET :
|
2004-12-30 16:45:11 +00:00
|
|
|
#ifndef NO_IPV6
|
2019-09-08 19:29:00 +00:00
|
|
|
address_family == ADDRTYPE_IPV6 ? AF_INET6 :
|
2004-12-30 16:45:11 +00:00
|
|
|
#endif
|
2019-09-08 19:29:00 +00:00
|
|
|
AF_UNSPEC);
|
2008-11-08 16:45:45 +00:00
|
|
|
|
|
|
|
/* Clear the structure and default to IPv4. */
|
Get rid of lots of implicit pointer types.
All the main backend structures - Ssh, Telnet, Pty, Serial etc - now
describe structure types themselves rather than pointers to them. The
same goes for the codebase-wide trait types Socket and Plug, and the
supporting types SockAddr and Pinger.
All those things that were typedefed as pointers are older types; the
newer ones have the explicit * at the point of use, because that's
what I now seem to be preferring. But whichever one of those is
better, inconsistently using a mixture of the two styles is worse, so
let's make everything consistent.
A few types are still implicitly pointers, such as Bignum and some of
the GSSAPI types; generally this is either because they have to be
void *, or because they're typedefed differently on different
platforms and aren't always pointers at all. Can't be helped. But I've
got rid of the main ones, at least.
2018-10-04 18:10:23 +00:00
|
|
|
memset(ret, 0, sizeof(SockAddr));
|
2005-02-14 11:43:27 +00:00
|
|
|
#ifndef NO_IPV6
|
2008-11-08 16:45:45 +00:00
|
|
|
ret->ais = NULL;
|
2005-02-14 11:43:27 +00:00
|
|
|
#endif
|
2018-10-29 19:50:29 +00:00
|
|
|
ret->namedpipe = false;
|
2006-08-26 08:37:42 +00:00
|
|
|
ret->addresses = NULL;
|
2018-10-29 19:50:29 +00:00
|
|
|
ret->resolved = false;
|
2008-11-08 16:58:55 +00:00
|
|
|
ret->refcount = 1;
|
2001-05-09 14:01:15 +00:00
|
|
|
*realhost = '\0';
|
2001-01-07 19:16:16 +00:00
|
|
|
|
2003-10-12 13:46:12 +00:00
|
|
|
if ((a = p_inet_addr(host)) == (unsigned long) INADDR_NONE) {
|
2019-09-08 19:29:00 +00:00
|
|
|
struct hostent *h = NULL;
|
|
|
|
int err = 0;
|
2004-12-30 16:45:11 +00:00
|
|
|
#ifndef NO_IPV6
|
2019-09-08 19:29:00 +00:00
|
|
|
/*
|
|
|
|
* Use getaddrinfo when it's available
|
|
|
|
*/
|
|
|
|
if (p_getaddrinfo) {
|
|
|
|
struct addrinfo hints;
|
|
|
|
memset(&hints, 0, sizeof(hints));
|
|
|
|
hints.ai_family = hint_family;
|
|
|
|
hints.ai_flags = AI_CANONNAME;
|
2014-01-25 15:58:54 +00:00
|
|
|
{
|
|
|
|
/* strip [] on IPv6 address literals */
|
|
|
|
char *trimmed_host = host_strduptrim(host);
|
|
|
|
err = p_getaddrinfo(trimmed_host, NULL, &hints, &ret->ais);
|
|
|
|
sfree(trimmed_host);
|
|
|
|
}
|
2019-09-08 19:29:00 +00:00
|
|
|
if (err == 0)
|
|
|
|
ret->resolved = true;
|
|
|
|
} else
|
2001-01-07 19:16:16 +00:00
|
|
|
#endif
|
2019-09-08 19:29:00 +00:00
|
|
|
{
|
|
|
|
/*
|
|
|
|
* Otherwise use the IPv4-only gethostbyname...
|
|
|
|
* (NOTE: we don't use gethostbyname as a fallback!)
|
|
|
|
*/
|
|
|
|
if ( (h = p_gethostbyname(host)) )
|
|
|
|
ret->resolved = true;
|
|
|
|
else
|
|
|
|
err = p_WSAGetLastError();
|
|
|
|
}
|
|
|
|
|
|
|
|
if (!ret->resolved) {
|
|
|
|
ret->error = (err == WSAENETDOWN ? "Network is down" :
|
|
|
|
err == WSAHOST_NOT_FOUND ? "Host does not exist" :
|
|
|
|
err == WSATRY_AGAIN ? "Host not found" :
|
2004-12-30 16:45:11 +00:00
|
|
|
#ifndef NO_IPV6
|
2019-09-08 19:29:00 +00:00
|
|
|
p_getaddrinfo&&p_gai_strerror ? p_gai_strerror(err) :
|
2001-01-07 19:16:16 +00:00
|
|
|
#endif
|
2019-09-08 19:29:00 +00:00
|
|
|
"gethostbyname: unknown error");
|
|
|
|
} else {
|
|
|
|
ret->error = NULL;
|
2001-01-07 19:16:16 +00:00
|
|
|
|
2004-12-30 16:45:11 +00:00
|
|
|
#ifndef NO_IPV6
|
2019-09-08 19:29:00 +00:00
|
|
|
/* If we got an address info use that... */
|
|
|
|
if (ret->ais) {
|
|
|
|
/* Are we in IPv4 fallback mode? */
|
|
|
|
/* We put the IPv4 address into the a variable so we can further-on use the IPv4 code... */
|
|
|
|
if (ret->ais->ai_family == AF_INET)
|
|
|
|
memcpy(&a,
|
|
|
|
(char *) &((SOCKADDR_IN *) ret->ais->
|
|
|
|
ai_addr)->sin_addr, sizeof(a));
|
|
|
|
|
|
|
|
if (ret->ais->ai_canonname)
|
|
|
|
strncpy(realhost, ret->ais->ai_canonname, lenof(realhost));
|
|
|
|
else
|
|
|
|
strncpy(realhost, host, lenof(realhost));
|
|
|
|
}
|
|
|
|
/* We used the IPv4-only gethostbyname()... */
|
|
|
|
else
|
2001-01-07 19:16:16 +00:00
|
|
|
#endif
|
2019-09-08 19:29:00 +00:00
|
|
|
{
|
|
|
|
int n;
|
|
|
|
for (n = 0; h->h_addr_list[n]; n++);
|
|
|
|
ret->addresses = snewn(n, unsigned long);
|
|
|
|
ret->naddresses = n;
|
|
|
|
for (n = 0; n < ret->naddresses; n++) {
|
|
|
|
memcpy(&a, h->h_addr_list[n], sizeof(a));
|
|
|
|
ret->addresses[n] = p_ntohl(a);
|
|
|
|
}
|
|
|
|
memcpy(&a, h->h_addr, sizeof(a));
|
|
|
|
/* This way we are always sure the h->h_name is valid :) */
|
|
|
|
strncpy(realhost, h->h_name, sizeof(realhost));
|
|
|
|
}
|
|
|
|
}
|
2001-05-06 14:35:20 +00:00
|
|
|
} else {
|
2019-09-08 19:29:00 +00:00
|
|
|
/*
|
|
|
|
* This must be a numeric IPv4 address because it caused a
|
|
|
|
* success return from inet_addr.
|
|
|
|
*/
|
|
|
|
ret->addresses = snewn(1, unsigned long);
|
|
|
|
ret->naddresses = 1;
|
|
|
|
ret->addresses[0] = p_ntohl(a);
|
|
|
|
ret->resolved = true;
|
|
|
|
strncpy(realhost, host, sizeof(realhost));
|
2000-10-23 11:55:11 +00:00
|
|
|
}
|
2001-05-09 14:01:15 +00:00
|
|
|
realhost[lenof(realhost)-1] = '\0';
|
2021-01-21 19:57:38 +00:00
|
|
|
*canonicalname = dupstr(realhost);
|
2000-10-23 11:55:11 +00:00
|
|
|
return ret;
|
|
|
|
}
|
|
|
|
|
Get rid of lots of implicit pointer types.
All the main backend structures - Ssh, Telnet, Pty, Serial etc - now
describe structure types themselves rather than pointers to them. The
same goes for the codebase-wide trait types Socket and Plug, and the
supporting types SockAddr and Pinger.
All those things that were typedefed as pointers are older types; the
newer ones have the explicit * at the point of use, because that's
what I now seem to be preferring. But whichever one of those is
better, inconsistently using a mixture of the two styles is worse, so
let's make everything consistent.
A few types are still implicitly pointers, such as Bignum and some of
the GSSAPI types; generally this is either because they have to be
void *, or because they're typedefed differently on different
platforms and aren't always pointers at all. Can't be helped. But I've
got rid of the main ones, at least.
2018-10-04 18:10:23 +00:00
|
|
|
SockAddr *sk_nonamelookup(const char *host)
|
2002-12-18 16:23:11 +00:00
|
|
|
{
|
Get rid of lots of implicit pointer types.
All the main backend structures - Ssh, Telnet, Pty, Serial etc - now
describe structure types themselves rather than pointers to them. The
same goes for the codebase-wide trait types Socket and Plug, and the
supporting types SockAddr and Pinger.
All those things that were typedefed as pointers are older types; the
newer ones have the explicit * at the point of use, because that's
what I now seem to be preferring. But whichever one of those is
better, inconsistently using a mixture of the two styles is worse, so
let's make everything consistent.
A few types are still implicitly pointers, such as Bignum and some of
the GSSAPI types; generally this is either because they have to be
void *, or because they're typedefed differently on different
platforms and aren't always pointers at all. Can't be helped. But I've
got rid of the main ones, at least.
2018-10-04 18:10:23 +00:00
|
|
|
SockAddr *ret = snew(SockAddr);
|
2003-01-02 10:07:50 +00:00
|
|
|
ret->error = NULL;
|
2018-10-29 19:50:29 +00:00
|
|
|
ret->resolved = false;
|
2005-02-14 11:43:27 +00:00
|
|
|
#ifndef NO_IPV6
|
2008-11-08 16:45:45 +00:00
|
|
|
ret->ais = NULL;
|
2005-02-14 11:43:27 +00:00
|
|
|
#endif
|
2018-10-29 19:50:29 +00:00
|
|
|
ret->namedpipe = false;
|
2006-08-26 08:37:42 +00:00
|
|
|
ret->addresses = NULL;
|
2005-02-14 11:43:27 +00:00
|
|
|
ret->naddresses = 0;
|
2008-11-08 16:58:55 +00:00
|
|
|
ret->refcount = 1;
|
2002-12-18 16:23:11 +00:00
|
|
|
strncpy(ret->hostname, host, lenof(ret->hostname));
|
|
|
|
ret->hostname[lenof(ret->hostname)-1] = '\0';
|
|
|
|
return ret;
|
|
|
|
}
|
|
|
|
|
Get rid of lots of implicit pointer types.
All the main backend structures - Ssh, Telnet, Pty, Serial etc - now
describe structure types themselves rather than pointers to them. The
same goes for the codebase-wide trait types Socket and Plug, and the
supporting types SockAddr and Pinger.
All those things that were typedefed as pointers are older types; the
newer ones have the explicit * at the point of use, because that's
what I now seem to be preferring. But whichever one of those is
better, inconsistently using a mixture of the two styles is worse, so
let's make everything consistent.
A few types are still implicitly pointers, such as Bignum and some of
the GSSAPI types; generally this is either because they have to be
void *, or because they're typedefed differently on different
platforms and aren't always pointers at all. Can't be helped. But I've
got rid of the main ones, at least.
2018-10-04 18:10:23 +00:00
|
|
|
SockAddr *sk_namedpipe_addr(const char *pipename)
|
2013-11-17 14:05:41 +00:00
|
|
|
{
|
Get rid of lots of implicit pointer types.
All the main backend structures - Ssh, Telnet, Pty, Serial etc - now
describe structure types themselves rather than pointers to them. The
same goes for the codebase-wide trait types Socket and Plug, and the
supporting types SockAddr and Pinger.
All those things that were typedefed as pointers are older types; the
newer ones have the explicit * at the point of use, because that's
what I now seem to be preferring. But whichever one of those is
better, inconsistently using a mixture of the two styles is worse, so
let's make everything consistent.
A few types are still implicitly pointers, such as Bignum and some of
the GSSAPI types; generally this is either because they have to be
void *, or because they're typedefed differently on different
platforms and aren't always pointers at all. Can't be helped. But I've
got rid of the main ones, at least.
2018-10-04 18:10:23 +00:00
|
|
|
SockAddr *ret = snew(SockAddr);
|
2013-11-17 14:05:41 +00:00
|
|
|
ret->error = NULL;
|
2018-10-29 19:50:29 +00:00
|
|
|
ret->resolved = false;
|
2013-11-17 14:05:41 +00:00
|
|
|
#ifndef NO_IPV6
|
|
|
|
ret->ais = NULL;
|
|
|
|
#endif
|
2018-10-29 19:50:29 +00:00
|
|
|
ret->namedpipe = true;
|
2013-11-17 14:05:41 +00:00
|
|
|
ret->addresses = NULL;
|
|
|
|
ret->naddresses = 0;
|
|
|
|
ret->refcount = 1;
|
|
|
|
strncpy(ret->hostname, pipename, lenof(ret->hostname));
|
|
|
|
ret->hostname[lenof(ret->hostname)-1] = '\0';
|
|
|
|
return ret;
|
|
|
|
}
|
|
|
|
|
2018-11-03 08:25:28 +00:00
|
|
|
static bool sk_nextaddr(SockAddr *addr, SockAddrStep *step)
|
2005-01-16 14:29:34 +00:00
|
|
|
{
|
|
|
|
#ifndef NO_IPV6
|
2008-11-08 16:45:45 +00:00
|
|
|
if (step->ai) {
|
2019-09-08 19:29:00 +00:00
|
|
|
if (step->ai->ai_next) {
|
|
|
|
step->ai = step->ai->ai_next;
|
|
|
|
return true;
|
|
|
|
} else
|
|
|
|
return false;
|
2005-01-16 14:29:34 +00:00
|
|
|
}
|
|
|
|
#endif
|
2008-11-08 16:45:45 +00:00
|
|
|
if (step->curraddr+1 < addr->naddresses) {
|
2019-09-08 19:29:00 +00:00
|
|
|
step->curraddr++;
|
|
|
|
return true;
|
2005-01-16 14:29:34 +00:00
|
|
|
} else {
|
2019-09-08 19:29:00 +00:00
|
|
|
return false;
|
2005-01-16 14:29:34 +00:00
|
|
|
}
|
|
|
|
}
|
|
|
|
|
Get rid of lots of implicit pointer types.
All the main backend structures - Ssh, Telnet, Pty, Serial etc - now
describe structure types themselves rather than pointers to them. The
same goes for the codebase-wide trait types Socket and Plug, and the
supporting types SockAddr and Pinger.
All those things that were typedefed as pointers are older types; the
newer ones have the explicit * at the point of use, because that's
what I now seem to be preferring. But whichever one of those is
better, inconsistently using a mixture of the two styles is worse, so
let's make everything consistent.
A few types are still implicitly pointers, such as Bignum and some of
the GSSAPI types; generally this is either because they have to be
void *, or because they're typedefed differently on different
platforms and aren't always pointers at all. Can't be helped. But I've
got rid of the main ones, at least.
2018-10-04 18:10:23 +00:00
|
|
|
void sk_getaddr(SockAddr *addr, char *buf, int buflen)
|
2001-09-07 22:39:01 +00:00
|
|
|
{
|
2008-11-08 16:45:45 +00:00
|
|
|
SockAddrStep step;
|
|
|
|
START_STEP(addr, step);
|
|
|
|
|
2004-12-30 16:45:11 +00:00
|
|
|
#ifndef NO_IPV6
|
2008-11-08 16:45:45 +00:00
|
|
|
if (step.ai) {
|
2019-09-08 19:29:00 +00:00
|
|
|
int err = 0;
|
|
|
|
if (p_WSAAddressToStringA) {
|
|
|
|
DWORD dwbuflen = buflen;
|
|
|
|
err = p_WSAAddressToStringA(step.ai->ai_addr, step.ai->ai_addrlen,
|
|
|
|
NULL, buf, &dwbuflen);
|
|
|
|
} else
|
|
|
|
err = -1;
|
|
|
|
if (err) {
|
|
|
|
strncpy(buf, addr->hostname, buflen);
|
|
|
|
if (!buf[0])
|
|
|
|
strncpy(buf, "<unknown>", buflen);
|
|
|
|
buf[buflen-1] = '\0';
|
|
|
|
}
|
2002-12-18 16:23:11 +00:00
|
|
|
} else
|
2001-09-07 22:39:01 +00:00
|
|
|
#endif
|
2008-11-08 16:45:45 +00:00
|
|
|
if (SOCKADDR_FAMILY(addr, step) == AF_INET) {
|
2019-09-08 19:29:00 +00:00
|
|
|
struct in_addr a;
|
|
|
|
assert(addr->addresses && step.curraddr < addr->naddresses);
|
|
|
|
a.s_addr = p_htonl(addr->addresses[step.curraddr]);
|
|
|
|
strncpy(buf, p_inet_ntoa(a), buflen);
|
|
|
|
buf[buflen-1] = '\0';
|
2001-09-07 22:39:01 +00:00
|
|
|
} else {
|
2019-09-08 19:29:00 +00:00
|
|
|
strncpy(buf, addr->hostname, buflen);
|
|
|
|
buf[buflen-1] = '\0';
|
2001-09-07 22:39:01 +00:00
|
|
|
}
|
|
|
|
}
|
|
|
|
|
2017-01-28 10:56:19 +00:00
|
|
|
/*
|
|
|
|
* This constructs a SockAddr that points at one specific sub-address
|
|
|
|
* of a parent SockAddr. The returned SockAddr does not own all its
|
|
|
|
* own memory: it points into the old one's data structures, so it
|
|
|
|
* MUST NOT be used after the old one is freed, and it MUST NOT be
|
|
|
|
* passed to sk_addr_free. (The latter is why it's returned by value
|
|
|
|
* rather than dynamically allocated - that should clue in anyone
|
|
|
|
* writing a call to it that something is weird about it.)
|
|
|
|
*/
|
Get rid of lots of implicit pointer types.
All the main backend structures - Ssh, Telnet, Pty, Serial etc - now
describe structure types themselves rather than pointers to them. The
same goes for the codebase-wide trait types Socket and Plug, and the
supporting types SockAddr and Pinger.
All those things that were typedefed as pointers are older types; the
newer ones have the explicit * at the point of use, because that's
what I now seem to be preferring. But whichever one of those is
better, inconsistently using a mixture of the two styles is worse, so
let's make everything consistent.
A few types are still implicitly pointers, such as Bignum and some of
the GSSAPI types; generally this is either because they have to be
void *, or because they're typedefed differently on different
platforms and aren't always pointers at all. Can't be helped. But I've
got rid of the main ones, at least.
2018-10-04 18:10:23 +00:00
|
|
|
static SockAddr sk_extractaddr_tmp(
|
|
|
|
SockAddr *addr, const SockAddrStep *step)
|
2017-01-28 10:56:19 +00:00
|
|
|
{
|
Get rid of lots of implicit pointer types.
All the main backend structures - Ssh, Telnet, Pty, Serial etc - now
describe structure types themselves rather than pointers to them. The
same goes for the codebase-wide trait types Socket and Plug, and the
supporting types SockAddr and Pinger.
All those things that were typedefed as pointers are older types; the
newer ones have the explicit * at the point of use, because that's
what I now seem to be preferring. But whichever one of those is
better, inconsistently using a mixture of the two styles is worse, so
let's make everything consistent.
A few types are still implicitly pointers, such as Bignum and some of
the GSSAPI types; generally this is either because they have to be
void *, or because they're typedefed differently on different
platforms and aren't always pointers at all. Can't be helped. But I've
got rid of the main ones, at least.
2018-10-04 18:10:23 +00:00
|
|
|
SockAddr toret;
|
2017-01-28 10:56:19 +00:00
|
|
|
toret = *addr; /* structure copy */
|
|
|
|
toret.refcount = 1;
|
|
|
|
|
|
|
|
#ifndef NO_IPV6
|
|
|
|
toret.ais = step->ai;
|
|
|
|
#endif
|
|
|
|
if (SOCKADDR_FAMILY(addr, *step) == AF_INET
|
|
|
|
#ifndef NO_IPV6
|
|
|
|
&& !toret.ais
|
|
|
|
#endif
|
|
|
|
)
|
|
|
|
toret.addresses += step->curraddr;
|
|
|
|
|
|
|
|
return toret;
|
|
|
|
}
|
|
|
|
|
Convert a lot of 'int' variables to 'bool'.
My normal habit these days, in new code, is to treat int and bool as
_almost_ completely separate types. I'm still willing to use C's
implicit test for zero on an integer (e.g. 'if (!blob.len)' is fine,
no need to spell it out as blob.len != 0), but generally, if a
variable is going to be conceptually a boolean, I like to declare it
bool and assign to it using 'true' or 'false' rather than 0 or 1.
PuTTY is an exception, because it predates the C99 bool, and I've
stuck to its existing coding style even when adding new code to it.
But it's been annoying me more and more, so now that I've decided C99
bool is an acceptable thing to require from our toolchain in the first
place, here's a quite thorough trawl through the source doing
'boolification'. Many variables and function parameters are now typed
as bool rather than int; many assignments of 0 or 1 to those variables
are now spelled 'true' or 'false'.
I managed this thorough conversion with the help of a custom clang
plugin that I wrote to trawl the AST and apply heuristics to point out
where things might want changing. So I've even managed to do a decent
job on parts of the code I haven't looked at in years!
To make the plugin's work easier, I pushed platform front ends
generally in the direction of using standard 'bool' in preference to
platform-specific boolean types like Windows BOOL or GTK's gboolean;
I've left the platform booleans in places they _have_ to be for the
platform APIs to work right, but variables only used by my own code
have been converted wherever I found them.
In a few places there are int values that look very like booleans in
_most_ of the places they're used, but have a rarely-used third value,
or a distinction between different nonzero values that most users
don't care about. In these cases, I've _removed_ uses of 'true' and
'false' for the return values, to emphasise that there's something
more subtle going on than a simple boolean answer:
- the 'multisel' field in dialog.h's list box structure, for which
the GTK front end in particular recognises a difference between 1
and 2 but nearly everything else treats as boolean
- the 'urgent' parameter to plug_receive, where 1 vs 2 tells you
something about the specific location of the urgent pointer, but
most clients only care about 0 vs 'something nonzero'
- the return value of wc_match, where -1 indicates a syntax error in
the wildcard.
- the return values from SSH-1 RSA-key loading functions, which use
-1 for 'wrong passphrase' and 0 for all other failures (so any
caller which already knows it's not loading an _encrypted private_
key can treat them as boolean)
- term->esc_query, and the 'query' parameter in toggle_mode in
terminal.c, which _usually_ hold 0 for ESC[123h or 1 for ESC[?123h,
but can also hold -1 for some other intervening character that we
don't support.
In a few places there's an integer that I haven't turned into a bool
even though it really _can_ only take values 0 or 1 (and, as above,
tried to make the call sites consistent in not calling those values
true and false), on the grounds that I thought it would make it more
confusing to imply that the 0 value was in some sense 'negative' or
bad and the 1 positive or good:
- the return value of plug_accepting uses the POSIXish convention of
0=success and nonzero=error; I think if I made it bool then I'd
also want to reverse its sense, and that's a job for a separate
piece of work.
- the 'screen' parameter to lineptr() in terminal.c, where 0 and 1
represent the default and alternate screens. There's no obvious
reason why one of those should be considered 'true' or 'positive'
or 'success' - they're just indices - so I've left it as int.
ssh_scp_recv had particularly confusing semantics for its previous int
return value: its call sites used '<= 0' to check for error, but it
never actually returned a negative number, just 0 or 1. Now the
function and its call sites agree that it's a bool.
In a couple of places I've renamed variables called 'ret', because I
don't like that name any more - it's unclear whether it means the
return value (in preparation) for the _containing_ function or the
return value received from a subroutine call, and occasionally I've
accidentally used the same variable for both and introduced a bug. So
where one of those got in my way, I've renamed it to 'toret' or 'retd'
(the latter short for 'returned') in line with my usual modern
practice, but I haven't done a thorough job of finding all of them.
Finally, one amusing side effect of doing this is that I've had to
separate quite a few chained assignments. It used to be perfectly fine
to write 'a = b = c = TRUE' when a,b,c were int and TRUE was just a
the 'true' defined by stdbool.h, that idiom provokes a warning from
gcc: 'suggest parentheses around assignment used as truth value'!
2018-11-02 19:23:19 +00:00
|
|
|
bool sk_addr_needs_port(SockAddr *addr)
|
2013-11-17 14:05:41 +00:00
|
|
|
{
|
Convert a lot of 'int' variables to 'bool'.
My normal habit these days, in new code, is to treat int and bool as
_almost_ completely separate types. I'm still willing to use C's
implicit test for zero on an integer (e.g. 'if (!blob.len)' is fine,
no need to spell it out as blob.len != 0), but generally, if a
variable is going to be conceptually a boolean, I like to declare it
bool and assign to it using 'true' or 'false' rather than 0 or 1.
PuTTY is an exception, because it predates the C99 bool, and I've
stuck to its existing coding style even when adding new code to it.
But it's been annoying me more and more, so now that I've decided C99
bool is an acceptable thing to require from our toolchain in the first
place, here's a quite thorough trawl through the source doing
'boolification'. Many variables and function parameters are now typed
as bool rather than int; many assignments of 0 or 1 to those variables
are now spelled 'true' or 'false'.
I managed this thorough conversion with the help of a custom clang
plugin that I wrote to trawl the AST and apply heuristics to point out
where things might want changing. So I've even managed to do a decent
job on parts of the code I haven't looked at in years!
To make the plugin's work easier, I pushed platform front ends
generally in the direction of using standard 'bool' in preference to
platform-specific boolean types like Windows BOOL or GTK's gboolean;
I've left the platform booleans in places they _have_ to be for the
platform APIs to work right, but variables only used by my own code
have been converted wherever I found them.
In a few places there are int values that look very like booleans in
_most_ of the places they're used, but have a rarely-used third value,
or a distinction between different nonzero values that most users
don't care about. In these cases, I've _removed_ uses of 'true' and
'false' for the return values, to emphasise that there's something
more subtle going on than a simple boolean answer:
- the 'multisel' field in dialog.h's list box structure, for which
the GTK front end in particular recognises a difference between 1
and 2 but nearly everything else treats as boolean
- the 'urgent' parameter to plug_receive, where 1 vs 2 tells you
something about the specific location of the urgent pointer, but
most clients only care about 0 vs 'something nonzero'
- the return value of wc_match, where -1 indicates a syntax error in
the wildcard.
- the return values from SSH-1 RSA-key loading functions, which use
-1 for 'wrong passphrase' and 0 for all other failures (so any
caller which already knows it's not loading an _encrypted private_
key can treat them as boolean)
- term->esc_query, and the 'query' parameter in toggle_mode in
terminal.c, which _usually_ hold 0 for ESC[123h or 1 for ESC[?123h,
but can also hold -1 for some other intervening character that we
don't support.
In a few places there's an integer that I haven't turned into a bool
even though it really _can_ only take values 0 or 1 (and, as above,
tried to make the call sites consistent in not calling those values
true and false), on the grounds that I thought it would make it more
confusing to imply that the 0 value was in some sense 'negative' or
bad and the 1 positive or good:
- the return value of plug_accepting uses the POSIXish convention of
0=success and nonzero=error; I think if I made it bool then I'd
also want to reverse its sense, and that's a job for a separate
piece of work.
- the 'screen' parameter to lineptr() in terminal.c, where 0 and 1
represent the default and alternate screens. There's no obvious
reason why one of those should be considered 'true' or 'positive'
or 'success' - they're just indices - so I've left it as int.
ssh_scp_recv had particularly confusing semantics for its previous int
return value: its call sites used '<= 0' to check for error, but it
never actually returned a negative number, just 0 or 1. Now the
function and its call sites agree that it's a bool.
In a couple of places I've renamed variables called 'ret', because I
don't like that name any more - it's unclear whether it means the
return value (in preparation) for the _containing_ function or the
return value received from a subroutine call, and occasionally I've
accidentally used the same variable for both and introduced a bug. So
where one of those got in my way, I've renamed it to 'toret' or 'retd'
(the latter short for 'returned') in line with my usual modern
practice, but I haven't done a thorough job of finding all of them.
Finally, one amusing side effect of doing this is that I've had to
separate quite a few chained assignments. It used to be perfectly fine
to write 'a = b = c = TRUE' when a,b,c were int and TRUE was just a
the 'true' defined by stdbool.h, that idiom provokes a warning from
gcc: 'suggest parentheses around assignment used as truth value'!
2018-11-02 19:23:19 +00:00
|
|
|
return !addr->namedpipe;
|
2013-11-17 14:05:41 +00:00
|
|
|
}
|
|
|
|
|
Convert a lot of 'int' variables to 'bool'.
My normal habit these days, in new code, is to treat int and bool as
_almost_ completely separate types. I'm still willing to use C's
implicit test for zero on an integer (e.g. 'if (!blob.len)' is fine,
no need to spell it out as blob.len != 0), but generally, if a
variable is going to be conceptually a boolean, I like to declare it
bool and assign to it using 'true' or 'false' rather than 0 or 1.
PuTTY is an exception, because it predates the C99 bool, and I've
stuck to its existing coding style even when adding new code to it.
But it's been annoying me more and more, so now that I've decided C99
bool is an acceptable thing to require from our toolchain in the first
place, here's a quite thorough trawl through the source doing
'boolification'. Many variables and function parameters are now typed
as bool rather than int; many assignments of 0 or 1 to those variables
are now spelled 'true' or 'false'.
I managed this thorough conversion with the help of a custom clang
plugin that I wrote to trawl the AST and apply heuristics to point out
where things might want changing. So I've even managed to do a decent
job on parts of the code I haven't looked at in years!
To make the plugin's work easier, I pushed platform front ends
generally in the direction of using standard 'bool' in preference to
platform-specific boolean types like Windows BOOL or GTK's gboolean;
I've left the platform booleans in places they _have_ to be for the
platform APIs to work right, but variables only used by my own code
have been converted wherever I found them.
In a few places there are int values that look very like booleans in
_most_ of the places they're used, but have a rarely-used third value,
or a distinction between different nonzero values that most users
don't care about. In these cases, I've _removed_ uses of 'true' and
'false' for the return values, to emphasise that there's something
more subtle going on than a simple boolean answer:
- the 'multisel' field in dialog.h's list box structure, for which
the GTK front end in particular recognises a difference between 1
and 2 but nearly everything else treats as boolean
- the 'urgent' parameter to plug_receive, where 1 vs 2 tells you
something about the specific location of the urgent pointer, but
most clients only care about 0 vs 'something nonzero'
- the return value of wc_match, where -1 indicates a syntax error in
the wildcard.
- the return values from SSH-1 RSA-key loading functions, which use
-1 for 'wrong passphrase' and 0 for all other failures (so any
caller which already knows it's not loading an _encrypted private_
key can treat them as boolean)
- term->esc_query, and the 'query' parameter in toggle_mode in
terminal.c, which _usually_ hold 0 for ESC[123h or 1 for ESC[?123h,
but can also hold -1 for some other intervening character that we
don't support.
In a few places there's an integer that I haven't turned into a bool
even though it really _can_ only take values 0 or 1 (and, as above,
tried to make the call sites consistent in not calling those values
true and false), on the grounds that I thought it would make it more
confusing to imply that the 0 value was in some sense 'negative' or
bad and the 1 positive or good:
- the return value of plug_accepting uses the POSIXish convention of
0=success and nonzero=error; I think if I made it bool then I'd
also want to reverse its sense, and that's a job for a separate
piece of work.
- the 'screen' parameter to lineptr() in terminal.c, where 0 and 1
represent the default and alternate screens. There's no obvious
reason why one of those should be considered 'true' or 'positive'
or 'success' - they're just indices - so I've left it as int.
ssh_scp_recv had particularly confusing semantics for its previous int
return value: its call sites used '<= 0' to check for error, but it
never actually returned a negative number, just 0 or 1. Now the
function and its call sites agree that it's a bool.
In a couple of places I've renamed variables called 'ret', because I
don't like that name any more - it's unclear whether it means the
return value (in preparation) for the _containing_ function or the
return value received from a subroutine call, and occasionally I've
accidentally used the same variable for both and introduced a bug. So
where one of those got in my way, I've renamed it to 'toret' or 'retd'
(the latter short for 'returned') in line with my usual modern
practice, but I haven't done a thorough job of finding all of them.
Finally, one amusing side effect of doing this is that I've had to
separate quite a few chained assignments. It used to be perfectly fine
to write 'a = b = c = TRUE' when a,b,c were int and TRUE was just a
the 'true' defined by stdbool.h, that idiom provokes a warning from
gcc: 'suggest parentheses around assignment used as truth value'!
2018-11-02 19:23:19 +00:00
|
|
|
bool sk_hostname_is_local(const char *name)
|
2002-12-18 12:18:54 +00:00
|
|
|
{
|
2009-01-05 02:45:38 +00:00
|
|
|
return !strcmp(name, "localhost") ||
|
2019-09-08 19:29:00 +00:00
|
|
|
!strcmp(name, "::1") ||
|
|
|
|
!strncmp(name, "127.", 4);
|
2002-12-18 12:18:54 +00:00
|
|
|
}
|
|
|
|
|
2003-10-12 14:12:54 +00:00
|
|
|
static INTERFACE_INFO local_interfaces[16];
|
|
|
|
static int n_local_interfaces; /* 0=not yet, -1=failed, >0=number */
|
|
|
|
|
Convert a lot of 'int' variables to 'bool'.
My normal habit these days, in new code, is to treat int and bool as
_almost_ completely separate types. I'm still willing to use C's
implicit test for zero on an integer (e.g. 'if (!blob.len)' is fine,
no need to spell it out as blob.len != 0), but generally, if a
variable is going to be conceptually a boolean, I like to declare it
bool and assign to it using 'true' or 'false' rather than 0 or 1.
PuTTY is an exception, because it predates the C99 bool, and I've
stuck to its existing coding style even when adding new code to it.
But it's been annoying me more and more, so now that I've decided C99
bool is an acceptable thing to require from our toolchain in the first
place, here's a quite thorough trawl through the source doing
'boolification'. Many variables and function parameters are now typed
as bool rather than int; many assignments of 0 or 1 to those variables
are now spelled 'true' or 'false'.
I managed this thorough conversion with the help of a custom clang
plugin that I wrote to trawl the AST and apply heuristics to point out
where things might want changing. So I've even managed to do a decent
job on parts of the code I haven't looked at in years!
To make the plugin's work easier, I pushed platform front ends
generally in the direction of using standard 'bool' in preference to
platform-specific boolean types like Windows BOOL or GTK's gboolean;
I've left the platform booleans in places they _have_ to be for the
platform APIs to work right, but variables only used by my own code
have been converted wherever I found them.
In a few places there are int values that look very like booleans in
_most_ of the places they're used, but have a rarely-used third value,
or a distinction between different nonzero values that most users
don't care about. In these cases, I've _removed_ uses of 'true' and
'false' for the return values, to emphasise that there's something
more subtle going on than a simple boolean answer:
- the 'multisel' field in dialog.h's list box structure, for which
the GTK front end in particular recognises a difference between 1
and 2 but nearly everything else treats as boolean
- the 'urgent' parameter to plug_receive, where 1 vs 2 tells you
something about the specific location of the urgent pointer, but
most clients only care about 0 vs 'something nonzero'
- the return value of wc_match, where -1 indicates a syntax error in
the wildcard.
- the return values from SSH-1 RSA-key loading functions, which use
-1 for 'wrong passphrase' and 0 for all other failures (so any
caller which already knows it's not loading an _encrypted private_
key can treat them as boolean)
- term->esc_query, and the 'query' parameter in toggle_mode in
terminal.c, which _usually_ hold 0 for ESC[123h or 1 for ESC[?123h,
but can also hold -1 for some other intervening character that we
don't support.
In a few places there's an integer that I haven't turned into a bool
even though it really _can_ only take values 0 or 1 (and, as above,
tried to make the call sites consistent in not calling those values
true and false), on the grounds that I thought it would make it more
confusing to imply that the 0 value was in some sense 'negative' or
bad and the 1 positive or good:
- the return value of plug_accepting uses the POSIXish convention of
0=success and nonzero=error; I think if I made it bool then I'd
also want to reverse its sense, and that's a job for a separate
piece of work.
- the 'screen' parameter to lineptr() in terminal.c, where 0 and 1
represent the default and alternate screens. There's no obvious
reason why one of those should be considered 'true' or 'positive'
or 'success' - they're just indices - so I've left it as int.
ssh_scp_recv had particularly confusing semantics for its previous int
return value: its call sites used '<= 0' to check for error, but it
never actually returned a negative number, just 0 or 1. Now the
function and its call sites agree that it's a bool.
In a couple of places I've renamed variables called 'ret', because I
don't like that name any more - it's unclear whether it means the
return value (in preparation) for the _containing_ function or the
return value received from a subroutine call, and occasionally I've
accidentally used the same variable for both and introduced a bug. So
where one of those got in my way, I've renamed it to 'toret' or 'retd'
(the latter short for 'returned') in line with my usual modern
practice, but I haven't done a thorough job of finding all of them.
Finally, one amusing side effect of doing this is that I've had to
separate quite a few chained assignments. It used to be perfectly fine
to write 'a = b = c = TRUE' when a,b,c were int and TRUE was just a
the 'true' defined by stdbool.h, that idiom provokes a warning from
gcc: 'suggest parentheses around assignment used as truth value'!
2018-11-02 19:23:19 +00:00
|
|
|
static bool ipv4_is_local_addr(struct in_addr addr)
|
2003-10-12 14:12:54 +00:00
|
|
|
{
|
|
|
|
if (ipv4_is_loopback(addr))
|
2019-09-08 19:29:00 +00:00
|
|
|
return true; /* loopback addresses are local */
|
2003-10-12 14:12:54 +00:00
|
|
|
if (!n_local_interfaces) {
|
2019-09-08 19:29:00 +00:00
|
|
|
SOCKET s = p_socket(AF_INET, SOCK_DGRAM, 0);
|
|
|
|
DWORD retbytes;
|
2003-10-12 14:12:54 +00:00
|
|
|
|
2019-09-08 19:29:00 +00:00
|
|
|
SetHandleInformation((HANDLE)s, HANDLE_FLAG_INHERIT, 0);
|
2017-02-19 13:49:12 +00:00
|
|
|
|
2019-09-08 19:29:00 +00:00
|
|
|
if (p_WSAIoctl &&
|
|
|
|
p_WSAIoctl(s, SIO_GET_INTERFACE_LIST, NULL, 0,
|
|
|
|
local_interfaces, sizeof(local_interfaces),
|
|
|
|
&retbytes, NULL, NULL) == 0)
|
|
|
|
n_local_interfaces = retbytes / sizeof(INTERFACE_INFO);
|
|
|
|
else
|
Refactor the LogContext type.
LogContext is now the owner of the logevent() function that back ends
and so forth are constantly calling. Previously, logevent was owned by
the Frontend, which would store the message into its list for the GUI
Event Log dialog (or print it to standard error, or whatever) and then
pass it _back_ to LogContext to write to the currently open log file.
Now it's the other way round: LogContext gets the message from the
back end first, writes it to its log file if it feels so inclined, and
communicates it back to the front end.
This means that lots of parts of the back end system no longer need to
have a pointer to a full-on Frontend; the only thing they needed it
for was logging, so now they just have a LogContext (which many of
them had to have anyway, e.g. for logging SSH packets or session
traffic).
LogContext itself also doesn't get a full Frontend pointer any more:
it now talks back to the front end via a little vtable of its own
called LogPolicy, which contains the method that passes Event Log
entries through, the old askappend() function that decides whether to
truncate a pre-existing log file, and an emergency function for
printing an especially prominent message if the log file can't be
created. One minor nice effect of this is that console and GUI apps
can implement that last function subtly differently, so that Unix
console apps can write it with a plain \n instead of the \r\n
(harmless but inelegant) that the old centralised implementation
generated.
One other consequence of this is that the LogContext has to be
provided to backend_init() so that it's available to backends from the
instant of creation, rather than being provided via a separate API
call a couple of function calls later, because backends have typically
started doing things that need logging (like making network
connections) before the call to backend_provide_logctx. Fortunately,
there's no case in the whole code base where we don't already have
logctx by the time we make a backend (so I don't actually remember why
I ever delayed providing one). So that shortens the backend API by one
function, which is always nice.
While I'm tidying up, I've also moved the printf-style logeventf() and
the handy logevent_and_free() into logging.c, instead of having copies
of them scattered around other places. This has also let me remove
some stub functions from a couple of outlying applications like
Pageant. Finally, I've removed the pointless "_tag" at the end of
LogContext's official struct name.
2018-10-10 18:26:18 +00:00
|
|
|
n_local_interfaces = -1;
|
2003-10-12 14:12:54 +00:00
|
|
|
}
|
|
|
|
if (n_local_interfaces > 0) {
|
2019-09-08 19:29:00 +00:00
|
|
|
int i;
|
|
|
|
for (i = 0; i < n_local_interfaces; i++) {
|
|
|
|
SOCKADDR_IN *address =
|
|
|
|
(SOCKADDR_IN *)&local_interfaces[i].iiAddress;
|
|
|
|
if (address->sin_addr.s_addr == addr.s_addr)
|
|
|
|
return true; /* this address is local */
|
|
|
|
}
|
2003-10-12 14:12:54 +00:00
|
|
|
}
|
Convert a lot of 'int' variables to 'bool'.
My normal habit these days, in new code, is to treat int and bool as
_almost_ completely separate types. I'm still willing to use C's
implicit test for zero on an integer (e.g. 'if (!blob.len)' is fine,
no need to spell it out as blob.len != 0), but generally, if a
variable is going to be conceptually a boolean, I like to declare it
bool and assign to it using 'true' or 'false' rather than 0 or 1.
PuTTY is an exception, because it predates the C99 bool, and I've
stuck to its existing coding style even when adding new code to it.
But it's been annoying me more and more, so now that I've decided C99
bool is an acceptable thing to require from our toolchain in the first
place, here's a quite thorough trawl through the source doing
'boolification'. Many variables and function parameters are now typed
as bool rather than int; many assignments of 0 or 1 to those variables
are now spelled 'true' or 'false'.
I managed this thorough conversion with the help of a custom clang
plugin that I wrote to trawl the AST and apply heuristics to point out
where things might want changing. So I've even managed to do a decent
job on parts of the code I haven't looked at in years!
To make the plugin's work easier, I pushed platform front ends
generally in the direction of using standard 'bool' in preference to
platform-specific boolean types like Windows BOOL or GTK's gboolean;
I've left the platform booleans in places they _have_ to be for the
platform APIs to work right, but variables only used by my own code
have been converted wherever I found them.
In a few places there are int values that look very like booleans in
_most_ of the places they're used, but have a rarely-used third value,
or a distinction between different nonzero values that most users
don't care about. In these cases, I've _removed_ uses of 'true' and
'false' for the return values, to emphasise that there's something
more subtle going on than a simple boolean answer:
- the 'multisel' field in dialog.h's list box structure, for which
the GTK front end in particular recognises a difference between 1
and 2 but nearly everything else treats as boolean
- the 'urgent' parameter to plug_receive, where 1 vs 2 tells you
something about the specific location of the urgent pointer, but
most clients only care about 0 vs 'something nonzero'
- the return value of wc_match, where -1 indicates a syntax error in
the wildcard.
- the return values from SSH-1 RSA-key loading functions, which use
-1 for 'wrong passphrase' and 0 for all other failures (so any
caller which already knows it's not loading an _encrypted private_
key can treat them as boolean)
- term->esc_query, and the 'query' parameter in toggle_mode in
terminal.c, which _usually_ hold 0 for ESC[123h or 1 for ESC[?123h,
but can also hold -1 for some other intervening character that we
don't support.
In a few places there's an integer that I haven't turned into a bool
even though it really _can_ only take values 0 or 1 (and, as above,
tried to make the call sites consistent in not calling those values
true and false), on the grounds that I thought it would make it more
confusing to imply that the 0 value was in some sense 'negative' or
bad and the 1 positive or good:
- the return value of plug_accepting uses the POSIXish convention of
0=success and nonzero=error; I think if I made it bool then I'd
also want to reverse its sense, and that's a job for a separate
piece of work.
- the 'screen' parameter to lineptr() in terminal.c, where 0 and 1
represent the default and alternate screens. There's no obvious
reason why one of those should be considered 'true' or 'positive'
or 'success' - they're just indices - so I've left it as int.
ssh_scp_recv had particularly confusing semantics for its previous int
return value: its call sites used '<= 0' to check for error, but it
never actually returned a negative number, just 0 or 1. Now the
function and its call sites agree that it's a bool.
In a couple of places I've renamed variables called 'ret', because I
don't like that name any more - it's unclear whether it means the
return value (in preparation) for the _containing_ function or the
return value received from a subroutine call, and occasionally I've
accidentally used the same variable for both and introduced a bug. So
where one of those got in my way, I've renamed it to 'toret' or 'retd'
(the latter short for 'returned') in line with my usual modern
practice, but I haven't done a thorough job of finding all of them.
Finally, one amusing side effect of doing this is that I've had to
separate quite a few chained assignments. It used to be perfectly fine
to write 'a = b = c = TRUE' when a,b,c were int and TRUE was just a
the 'true' defined by stdbool.h, that idiom provokes a warning from
gcc: 'suggest parentheses around assignment used as truth value'!
2018-11-02 19:23:19 +00:00
|
|
|
return false; /* this address is not local */
|
2003-10-12 14:12:54 +00:00
|
|
|
}
|
|
|
|
|
Convert a lot of 'int' variables to 'bool'.
My normal habit these days, in new code, is to treat int and bool as
_almost_ completely separate types. I'm still willing to use C's
implicit test for zero on an integer (e.g. 'if (!blob.len)' is fine,
no need to spell it out as blob.len != 0), but generally, if a
variable is going to be conceptually a boolean, I like to declare it
bool and assign to it using 'true' or 'false' rather than 0 or 1.
PuTTY is an exception, because it predates the C99 bool, and I've
stuck to its existing coding style even when adding new code to it.
But it's been annoying me more and more, so now that I've decided C99
bool is an acceptable thing to require from our toolchain in the first
place, here's a quite thorough trawl through the source doing
'boolification'. Many variables and function parameters are now typed
as bool rather than int; many assignments of 0 or 1 to those variables
are now spelled 'true' or 'false'.
I managed this thorough conversion with the help of a custom clang
plugin that I wrote to trawl the AST and apply heuristics to point out
where things might want changing. So I've even managed to do a decent
job on parts of the code I haven't looked at in years!
To make the plugin's work easier, I pushed platform front ends
generally in the direction of using standard 'bool' in preference to
platform-specific boolean types like Windows BOOL or GTK's gboolean;
I've left the platform booleans in places they _have_ to be for the
platform APIs to work right, but variables only used by my own code
have been converted wherever I found them.
In a few places there are int values that look very like booleans in
_most_ of the places they're used, but have a rarely-used third value,
or a distinction between different nonzero values that most users
don't care about. In these cases, I've _removed_ uses of 'true' and
'false' for the return values, to emphasise that there's something
more subtle going on than a simple boolean answer:
- the 'multisel' field in dialog.h's list box structure, for which
the GTK front end in particular recognises a difference between 1
and 2 but nearly everything else treats as boolean
- the 'urgent' parameter to plug_receive, where 1 vs 2 tells you
something about the specific location of the urgent pointer, but
most clients only care about 0 vs 'something nonzero'
- the return value of wc_match, where -1 indicates a syntax error in
the wildcard.
- the return values from SSH-1 RSA-key loading functions, which use
-1 for 'wrong passphrase' and 0 for all other failures (so any
caller which already knows it's not loading an _encrypted private_
key can treat them as boolean)
- term->esc_query, and the 'query' parameter in toggle_mode in
terminal.c, which _usually_ hold 0 for ESC[123h or 1 for ESC[?123h,
but can also hold -1 for some other intervening character that we
don't support.
In a few places there's an integer that I haven't turned into a bool
even though it really _can_ only take values 0 or 1 (and, as above,
tried to make the call sites consistent in not calling those values
true and false), on the grounds that I thought it would make it more
confusing to imply that the 0 value was in some sense 'negative' or
bad and the 1 positive or good:
- the return value of plug_accepting uses the POSIXish convention of
0=success and nonzero=error; I think if I made it bool then I'd
also want to reverse its sense, and that's a job for a separate
piece of work.
- the 'screen' parameter to lineptr() in terminal.c, where 0 and 1
represent the default and alternate screens. There's no obvious
reason why one of those should be considered 'true' or 'positive'
or 'success' - they're just indices - so I've left it as int.
ssh_scp_recv had particularly confusing semantics for its previous int
return value: its call sites used '<= 0' to check for error, but it
never actually returned a negative number, just 0 or 1. Now the
function and its call sites agree that it's a bool.
In a couple of places I've renamed variables called 'ret', because I
don't like that name any more - it's unclear whether it means the
return value (in preparation) for the _containing_ function or the
return value received from a subroutine call, and occasionally I've
accidentally used the same variable for both and introduced a bug. So
where one of those got in my way, I've renamed it to 'toret' or 'retd'
(the latter short for 'returned') in line with my usual modern
practice, but I haven't done a thorough job of finding all of them.
Finally, one amusing side effect of doing this is that I've had to
separate quite a few chained assignments. It used to be perfectly fine
to write 'a = b = c = TRUE' when a,b,c were int and TRUE was just a
the 'true' defined by stdbool.h, that idiom provokes a warning from
gcc: 'suggest parentheses around assignment used as truth value'!
2018-11-02 19:23:19 +00:00
|
|
|
bool sk_address_is_local(SockAddr *addr)
|
2002-12-18 12:18:54 +00:00
|
|
|
{
|
2008-11-08 16:45:45 +00:00
|
|
|
SockAddrStep step;
|
|
|
|
int family;
|
|
|
|
START_STEP(addr, step);
|
|
|
|
family = SOCKADDR_FAMILY(addr, step);
|
|
|
|
|
2004-12-30 16:45:11 +00:00
|
|
|
#ifndef NO_IPV6
|
2008-11-08 16:45:45 +00:00
|
|
|
if (family == AF_INET6) {
|
2019-09-08 19:29:00 +00:00
|
|
|
return IN6_IS_ADDR_LOOPBACK(&((const struct sockaddr_in6 *)step.ai->ai_addr)->sin6_addr);
|
2002-12-18 16:23:11 +00:00
|
|
|
} else
|
2002-12-18 12:18:54 +00:00
|
|
|
#endif
|
2008-11-08 16:45:45 +00:00
|
|
|
if (family == AF_INET) {
|
2005-04-01 08:46:26 +00:00
|
|
|
#ifndef NO_IPV6
|
2019-09-08 19:29:00 +00:00
|
|
|
if (step.ai) {
|
|
|
|
return ipv4_is_local_addr(((struct sockaddr_in *)step.ai->ai_addr)
|
|
|
|
->sin_addr);
|
|
|
|
} else
|
2005-04-01 08:46:26 +00:00
|
|
|
#endif
|
2019-09-08 19:29:00 +00:00
|
|
|
{
|
|
|
|
struct in_addr a;
|
|
|
|
assert(addr->addresses && step.curraddr < addr->naddresses);
|
|
|
|
a.s_addr = p_htonl(addr->addresses[step.curraddr]);
|
|
|
|
return ipv4_is_local_addr(a);
|
|
|
|
}
|
2002-12-18 12:18:54 +00:00
|
|
|
} else {
|
2019-09-08 19:29:00 +00:00
|
|
|
assert(family == AF_UNSPEC);
|
|
|
|
return false; /* we don't know; assume not */
|
2002-12-18 12:18:54 +00:00
|
|
|
}
|
|
|
|
}
|
|
|
|
|
Convert a lot of 'int' variables to 'bool'.
My normal habit these days, in new code, is to treat int and bool as
_almost_ completely separate types. I'm still willing to use C's
implicit test for zero on an integer (e.g. 'if (!blob.len)' is fine,
no need to spell it out as blob.len != 0), but generally, if a
variable is going to be conceptually a boolean, I like to declare it
bool and assign to it using 'true' or 'false' rather than 0 or 1.
PuTTY is an exception, because it predates the C99 bool, and I've
stuck to its existing coding style even when adding new code to it.
But it's been annoying me more and more, so now that I've decided C99
bool is an acceptable thing to require from our toolchain in the first
place, here's a quite thorough trawl through the source doing
'boolification'. Many variables and function parameters are now typed
as bool rather than int; many assignments of 0 or 1 to those variables
are now spelled 'true' or 'false'.
I managed this thorough conversion with the help of a custom clang
plugin that I wrote to trawl the AST and apply heuristics to point out
where things might want changing. So I've even managed to do a decent
job on parts of the code I haven't looked at in years!
To make the plugin's work easier, I pushed platform front ends
generally in the direction of using standard 'bool' in preference to
platform-specific boolean types like Windows BOOL or GTK's gboolean;
I've left the platform booleans in places they _have_ to be for the
platform APIs to work right, but variables only used by my own code
have been converted wherever I found them.
In a few places there are int values that look very like booleans in
_most_ of the places they're used, but have a rarely-used third value,
or a distinction between different nonzero values that most users
don't care about. In these cases, I've _removed_ uses of 'true' and
'false' for the return values, to emphasise that there's something
more subtle going on than a simple boolean answer:
- the 'multisel' field in dialog.h's list box structure, for which
the GTK front end in particular recognises a difference between 1
and 2 but nearly everything else treats as boolean
- the 'urgent' parameter to plug_receive, where 1 vs 2 tells you
something about the specific location of the urgent pointer, but
most clients only care about 0 vs 'something nonzero'
- the return value of wc_match, where -1 indicates a syntax error in
the wildcard.
- the return values from SSH-1 RSA-key loading functions, which use
-1 for 'wrong passphrase' and 0 for all other failures (so any
caller which already knows it's not loading an _encrypted private_
key can treat them as boolean)
- term->esc_query, and the 'query' parameter in toggle_mode in
terminal.c, which _usually_ hold 0 for ESC[123h or 1 for ESC[?123h,
but can also hold -1 for some other intervening character that we
don't support.
In a few places there's an integer that I haven't turned into a bool
even though it really _can_ only take values 0 or 1 (and, as above,
tried to make the call sites consistent in not calling those values
true and false), on the grounds that I thought it would make it more
confusing to imply that the 0 value was in some sense 'negative' or
bad and the 1 positive or good:
- the return value of plug_accepting uses the POSIXish convention of
0=success and nonzero=error; I think if I made it bool then I'd
also want to reverse its sense, and that's a job for a separate
piece of work.
- the 'screen' parameter to lineptr() in terminal.c, where 0 and 1
represent the default and alternate screens. There's no obvious
reason why one of those should be considered 'true' or 'positive'
or 'success' - they're just indices - so I've left it as int.
ssh_scp_recv had particularly confusing semantics for its previous int
return value: its call sites used '<= 0' to check for error, but it
never actually returned a negative number, just 0 or 1. Now the
function and its call sites agree that it's a bool.
In a couple of places I've renamed variables called 'ret', because I
don't like that name any more - it's unclear whether it means the
return value (in preparation) for the _containing_ function or the
return value received from a subroutine call, and occasionally I've
accidentally used the same variable for both and introduced a bug. So
where one of those got in my way, I've renamed it to 'toret' or 'retd'
(the latter short for 'returned') in line with my usual modern
practice, but I haven't done a thorough job of finding all of them.
Finally, one amusing side effect of doing this is that I've had to
separate quite a few chained assignments. It used to be perfectly fine
to write 'a = b = c = TRUE' when a,b,c were int and TRUE was just a
the 'true' defined by stdbool.h, that idiom provokes a warning from
gcc: 'suggest parentheses around assignment used as truth value'!
2018-11-02 19:23:19 +00:00
|
|
|
bool sk_address_is_special_local(SockAddr *addr)
|
2012-10-16 20:15:51 +00:00
|
|
|
{
|
Convert a lot of 'int' variables to 'bool'.
My normal habit these days, in new code, is to treat int and bool as
_almost_ completely separate types. I'm still willing to use C's
implicit test for zero on an integer (e.g. 'if (!blob.len)' is fine,
no need to spell it out as blob.len != 0), but generally, if a
variable is going to be conceptually a boolean, I like to declare it
bool and assign to it using 'true' or 'false' rather than 0 or 1.
PuTTY is an exception, because it predates the C99 bool, and I've
stuck to its existing coding style even when adding new code to it.
But it's been annoying me more and more, so now that I've decided C99
bool is an acceptable thing to require from our toolchain in the first
place, here's a quite thorough trawl through the source doing
'boolification'. Many variables and function parameters are now typed
as bool rather than int; many assignments of 0 or 1 to those variables
are now spelled 'true' or 'false'.
I managed this thorough conversion with the help of a custom clang
plugin that I wrote to trawl the AST and apply heuristics to point out
where things might want changing. So I've even managed to do a decent
job on parts of the code I haven't looked at in years!
To make the plugin's work easier, I pushed platform front ends
generally in the direction of using standard 'bool' in preference to
platform-specific boolean types like Windows BOOL or GTK's gboolean;
I've left the platform booleans in places they _have_ to be for the
platform APIs to work right, but variables only used by my own code
have been converted wherever I found them.
In a few places there are int values that look very like booleans in
_most_ of the places they're used, but have a rarely-used third value,
or a distinction between different nonzero values that most users
don't care about. In these cases, I've _removed_ uses of 'true' and
'false' for the return values, to emphasise that there's something
more subtle going on than a simple boolean answer:
- the 'multisel' field in dialog.h's list box structure, for which
the GTK front end in particular recognises a difference between 1
and 2 but nearly everything else treats as boolean
- the 'urgent' parameter to plug_receive, where 1 vs 2 tells you
something about the specific location of the urgent pointer, but
most clients only care about 0 vs 'something nonzero'
- the return value of wc_match, where -1 indicates a syntax error in
the wildcard.
- the return values from SSH-1 RSA-key loading functions, which use
-1 for 'wrong passphrase' and 0 for all other failures (so any
caller which already knows it's not loading an _encrypted private_
key can treat them as boolean)
- term->esc_query, and the 'query' parameter in toggle_mode in
terminal.c, which _usually_ hold 0 for ESC[123h or 1 for ESC[?123h,
but can also hold -1 for some other intervening character that we
don't support.
In a few places there's an integer that I haven't turned into a bool
even though it really _can_ only take values 0 or 1 (and, as above,
tried to make the call sites consistent in not calling those values
true and false), on the grounds that I thought it would make it more
confusing to imply that the 0 value was in some sense 'negative' or
bad and the 1 positive or good:
- the return value of plug_accepting uses the POSIXish convention of
0=success and nonzero=error; I think if I made it bool then I'd
also want to reverse its sense, and that's a job for a separate
piece of work.
- the 'screen' parameter to lineptr() in terminal.c, where 0 and 1
represent the default and alternate screens. There's no obvious
reason why one of those should be considered 'true' or 'positive'
or 'success' - they're just indices - so I've left it as int.
ssh_scp_recv had particularly confusing semantics for its previous int
return value: its call sites used '<= 0' to check for error, but it
never actually returned a negative number, just 0 or 1. Now the
function and its call sites agree that it's a bool.
In a couple of places I've renamed variables called 'ret', because I
don't like that name any more - it's unclear whether it means the
return value (in preparation) for the _containing_ function or the
return value received from a subroutine call, and occasionally I've
accidentally used the same variable for both and introduced a bug. So
where one of those got in my way, I've renamed it to 'toret' or 'retd'
(the latter short for 'returned') in line with my usual modern
practice, but I haven't done a thorough job of finding all of them.
Finally, one amusing side effect of doing this is that I've had to
separate quite a few chained assignments. It used to be perfectly fine
to write 'a = b = c = TRUE' when a,b,c were int and TRUE was just a
the 'true' defined by stdbool.h, that idiom provokes a warning from
gcc: 'suggest parentheses around assignment used as truth value'!
2018-11-02 19:23:19 +00:00
|
|
|
return false; /* no Unix-domain socket analogue here */
|
2012-10-16 20:15:51 +00:00
|
|
|
}
|
|
|
|
|
Get rid of lots of implicit pointer types.
All the main backend structures - Ssh, Telnet, Pty, Serial etc - now
describe structure types themselves rather than pointers to them. The
same goes for the codebase-wide trait types Socket and Plug, and the
supporting types SockAddr and Pinger.
All those things that were typedefed as pointers are older types; the
newer ones have the explicit * at the point of use, because that's
what I now seem to be preferring. But whichever one of those is
better, inconsistently using a mixture of the two styles is worse, so
let's make everything consistent.
A few types are still implicitly pointers, such as Bignum and some of
the GSSAPI types; generally this is either because they have to be
void *, or because they're typedefed differently on different
platforms and aren't always pointers at all. Can't be helped. But I've
got rid of the main ones, at least.
2018-10-04 18:10:23 +00:00
|
|
|
int sk_addrtype(SockAddr *addr)
|
2002-04-27 15:01:18 +00:00
|
|
|
{
|
2008-11-08 16:45:45 +00:00
|
|
|
SockAddrStep step;
|
|
|
|
int family;
|
|
|
|
START_STEP(addr, step);
|
|
|
|
family = SOCKADDR_FAMILY(addr, step);
|
|
|
|
|
|
|
|
return (family == AF_INET ? ADDRTYPE_IPV4 :
|
2004-12-30 16:45:11 +00:00
|
|
|
#ifndef NO_IPV6
|
2019-09-08 19:29:00 +00:00
|
|
|
family == AF_INET6 ? ADDRTYPE_IPV6 :
|
2002-12-18 16:23:11 +00:00
|
|
|
#endif
|
2019-09-08 19:29:00 +00:00
|
|
|
ADDRTYPE_NAME);
|
2002-04-27 15:01:18 +00:00
|
|
|
}
|
|
|
|
|
Get rid of lots of implicit pointer types.
All the main backend structures - Ssh, Telnet, Pty, Serial etc - now
describe structure types themselves rather than pointers to them. The
same goes for the codebase-wide trait types Socket and Plug, and the
supporting types SockAddr and Pinger.
All those things that were typedefed as pointers are older types; the
newer ones have the explicit * at the point of use, because that's
what I now seem to be preferring. But whichever one of those is
better, inconsistently using a mixture of the two styles is worse, so
let's make everything consistent.
A few types are still implicitly pointers, such as Bignum and some of
the GSSAPI types; generally this is either because they have to be
void *, or because they're typedefed differently on different
platforms and aren't always pointers at all. Can't be helped. But I've
got rid of the main ones, at least.
2018-10-04 18:10:23 +00:00
|
|
|
void sk_addrcopy(SockAddr *addr, char *buf)
|
2002-04-27 15:01:18 +00:00
|
|
|
{
|
2008-11-08 16:45:45 +00:00
|
|
|
SockAddrStep step;
|
|
|
|
int family;
|
|
|
|
START_STEP(addr, step);
|
|
|
|
family = SOCKADDR_FAMILY(addr, step);
|
|
|
|
|
|
|
|
assert(family != AF_UNSPEC);
|
2004-12-30 16:45:11 +00:00
|
|
|
#ifndef NO_IPV6
|
2008-11-08 16:45:45 +00:00
|
|
|
if (step.ai) {
|
2019-09-08 19:29:00 +00:00
|
|
|
if (family == AF_INET)
|
|
|
|
memcpy(buf, &((struct sockaddr_in *)step.ai->ai_addr)->sin_addr,
|
|
|
|
sizeof(struct in_addr));
|
|
|
|
else if (family == AF_INET6)
|
|
|
|
memcpy(buf, &((struct sockaddr_in6 *)step.ai->ai_addr)->sin6_addr,
|
|
|
|
sizeof(struct in6_addr));
|
|
|
|
else
|
|
|
|
unreachable("bad address family in sk_addrcopy");
|
2002-12-18 16:23:11 +00:00
|
|
|
} else
|
2002-04-27 15:01:18 +00:00
|
|
|
#endif
|
2008-11-08 16:45:45 +00:00
|
|
|
if (family == AF_INET) {
|
2019-09-08 19:29:00 +00:00
|
|
|
struct in_addr a;
|
|
|
|
assert(addr->addresses && step.curraddr < addr->naddresses);
|
|
|
|
a.s_addr = p_htonl(addr->addresses[step.curraddr]);
|
|
|
|
memcpy(buf, (char*) &a.s_addr, 4);
|
2002-04-27 15:01:18 +00:00
|
|
|
}
|
|
|
|
}
|
|
|
|
|
Get rid of lots of implicit pointer types.
All the main backend structures - Ssh, Telnet, Pty, Serial etc - now
describe structure types themselves rather than pointers to them. The
same goes for the codebase-wide trait types Socket and Plug, and the
supporting types SockAddr and Pinger.
All those things that were typedefed as pointers are older types; the
newer ones have the explicit * at the point of use, because that's
what I now seem to be preferring. But whichever one of those is
better, inconsistently using a mixture of the two styles is worse, so
let's make everything consistent.
A few types are still implicitly pointers, such as Bignum and some of
the GSSAPI types; generally this is either because they have to be
void *, or because they're typedefed differently on different
platforms and aren't always pointers at all. Can't be helped. But I've
got rid of the main ones, at least.
2018-10-04 18:10:23 +00:00
|
|
|
void sk_addr_free(SockAddr *addr)
|
2001-05-06 14:35:20 +00:00
|
|
|
{
|
2008-11-08 16:58:55 +00:00
|
|
|
if (--addr->refcount > 0)
|
2019-09-08 19:29:00 +00:00
|
|
|
return;
|
2005-01-16 14:29:34 +00:00
|
|
|
#ifndef NO_IPV6
|
|
|
|
if (addr->ais && p_freeaddrinfo)
|
2019-09-08 19:29:00 +00:00
|
|
|
p_freeaddrinfo(addr->ais);
|
2005-01-16 14:29:34 +00:00
|
|
|
#endif
|
|
|
|
if (addr->addresses)
|
2019-09-08 19:29:00 +00:00
|
|
|
sfree(addr->addresses);
|
2000-10-23 11:55:11 +00:00
|
|
|
sfree(addr);
|
|
|
|
}
|
|
|
|
|
Get rid of lots of implicit pointer types.
All the main backend structures - Ssh, Telnet, Pty, Serial etc - now
describe structure types themselves rather than pointers to them. The
same goes for the codebase-wide trait types Socket and Plug, and the
supporting types SockAddr and Pinger.
All those things that were typedefed as pointers are older types; the
newer ones have the explicit * at the point of use, because that's
what I now seem to be preferring. But whichever one of those is
better, inconsistently using a mixture of the two styles is worse, so
let's make everything consistent.
A few types are still implicitly pointers, such as Bignum and some of
the GSSAPI types; generally this is either because they have to be
void *, or because they're typedefed differently on different
platforms and aren't always pointers at all. Can't be helped. But I've
got rid of the main ones, at least.
2018-10-04 18:10:23 +00:00
|
|
|
SockAddr *sk_addr_dup(SockAddr *addr)
|
2008-11-08 16:58:55 +00:00
|
|
|
{
|
|
|
|
addr->refcount++;
|
|
|
|
return addr;
|
|
|
|
}
|
|
|
|
|
Get rid of lots of implicit pointer types.
All the main backend structures - Ssh, Telnet, Pty, Serial etc - now
describe structure types themselves rather than pointers to them. The
same goes for the codebase-wide trait types Socket and Plug, and the
supporting types SockAddr and Pinger.
All those things that were typedefed as pointers are older types; the
newer ones have the explicit * at the point of use, because that's
what I now seem to be preferring. But whichever one of those is
better, inconsistently using a mixture of the two styles is worse, so
let's make everything consistent.
A few types are still implicitly pointers, such as Bignum and some of
the GSSAPI types; generally this is either because they have to be
void *, or because they're typedefed differently on different
platforms and aren't always pointers at all. Can't be helped. But I've
got rid of the main ones, at least.
2018-10-04 18:10:23 +00:00
|
|
|
static Plug *sk_net_plug(Socket *sock, Plug *p)
|
2001-05-06 14:35:20 +00:00
|
|
|
{
|
2018-10-05 22:49:08 +00:00
|
|
|
NetSocket *s = container_of(sock, NetSocket, sock);
|
Get rid of lots of implicit pointer types.
All the main backend structures - Ssh, Telnet, Pty, Serial etc - now
describe structure types themselves rather than pointers to them. The
same goes for the codebase-wide trait types Socket and Plug, and the
supporting types SockAddr and Pinger.
All those things that were typedefed as pointers are older types; the
newer ones have the explicit * at the point of use, because that's
what I now seem to be preferring. But whichever one of those is
better, inconsistently using a mixture of the two styles is worse, so
let's make everything consistent.
A few types are still implicitly pointers, such as Bignum and some of
the GSSAPI types; generally this is either because they have to be
void *, or because they're typedefed differently on different
platforms and aren't always pointers at all. Can't be helped. But I've
got rid of the main ones, at least.
2018-10-04 18:10:23 +00:00
|
|
|
Plug *ret = s->plug;
|
2001-05-06 14:35:20 +00:00
|
|
|
if (p)
|
2019-09-08 19:29:00 +00:00
|
|
|
s->plug = p;
|
2001-03-13 10:22:45 +00:00
|
|
|
return ret;
|
|
|
|
}
|
|
|
|
|
Get rid of lots of implicit pointer types.
All the main backend structures - Ssh, Telnet, Pty, Serial etc - now
describe structure types themselves rather than pointers to them. The
same goes for the codebase-wide trait types Socket and Plug, and the
supporting types SockAddr and Pinger.
All those things that were typedefed as pointers are older types; the
newer ones have the explicit * at the point of use, because that's
what I now seem to be preferring. But whichever one of those is
better, inconsistently using a mixture of the two styles is worse, so
let's make everything consistent.
A few types are still implicitly pointers, such as Bignum and some of
the GSSAPI types; generally this is either because they have to be
void *, or because they're typedefed differently on different
platforms and aren't always pointers at all. Can't be helped. But I've
got rid of the main ones, at least.
2018-10-04 18:10:23 +00:00
|
|
|
static void sk_net_close(Socket *s);
|
2019-02-06 20:42:44 +00:00
|
|
|
static size_t sk_net_write(Socket *s, const void *data, size_t len);
|
|
|
|
static size_t sk_net_write_oob(Socket *s, const void *data, size_t len);
|
Get rid of lots of implicit pointer types.
All the main backend structures - Ssh, Telnet, Pty, Serial etc - now
describe structure types themselves rather than pointers to them. The
same goes for the codebase-wide trait types Socket and Plug, and the
supporting types SockAddr and Pinger.
All those things that were typedefed as pointers are older types; the
newer ones have the explicit * at the point of use, because that's
what I now seem to be preferring. But whichever one of those is
better, inconsistently using a mixture of the two styles is worse, so
let's make everything consistent.
A few types are still implicitly pointers, such as Bignum and some of
the GSSAPI types; generally this is either because they have to be
void *, or because they're typedefed differently on different
platforms and aren't always pointers at all. Can't be helped. But I've
got rid of the main ones, at least.
2018-10-04 18:10:23 +00:00
|
|
|
static void sk_net_write_eof(Socket *s);
|
Convert a lot of 'int' variables to 'bool'.
My normal habit these days, in new code, is to treat int and bool as
_almost_ completely separate types. I'm still willing to use C's
implicit test for zero on an integer (e.g. 'if (!blob.len)' is fine,
no need to spell it out as blob.len != 0), but generally, if a
variable is going to be conceptually a boolean, I like to declare it
bool and assign to it using 'true' or 'false' rather than 0 or 1.
PuTTY is an exception, because it predates the C99 bool, and I've
stuck to its existing coding style even when adding new code to it.
But it's been annoying me more and more, so now that I've decided C99
bool is an acceptable thing to require from our toolchain in the first
place, here's a quite thorough trawl through the source doing
'boolification'. Many variables and function parameters are now typed
as bool rather than int; many assignments of 0 or 1 to those variables
are now spelled 'true' or 'false'.
I managed this thorough conversion with the help of a custom clang
plugin that I wrote to trawl the AST and apply heuristics to point out
where things might want changing. So I've even managed to do a decent
job on parts of the code I haven't looked at in years!
To make the plugin's work easier, I pushed platform front ends
generally in the direction of using standard 'bool' in preference to
platform-specific boolean types like Windows BOOL or GTK's gboolean;
I've left the platform booleans in places they _have_ to be for the
platform APIs to work right, but variables only used by my own code
have been converted wherever I found them.
In a few places there are int values that look very like booleans in
_most_ of the places they're used, but have a rarely-used third value,
or a distinction between different nonzero values that most users
don't care about. In these cases, I've _removed_ uses of 'true' and
'false' for the return values, to emphasise that there's something
more subtle going on than a simple boolean answer:
- the 'multisel' field in dialog.h's list box structure, for which
the GTK front end in particular recognises a difference between 1
and 2 but nearly everything else treats as boolean
- the 'urgent' parameter to plug_receive, where 1 vs 2 tells you
something about the specific location of the urgent pointer, but
most clients only care about 0 vs 'something nonzero'
- the return value of wc_match, where -1 indicates a syntax error in
the wildcard.
- the return values from SSH-1 RSA-key loading functions, which use
-1 for 'wrong passphrase' and 0 for all other failures (so any
caller which already knows it's not loading an _encrypted private_
key can treat them as boolean)
- term->esc_query, and the 'query' parameter in toggle_mode in
terminal.c, which _usually_ hold 0 for ESC[123h or 1 for ESC[?123h,
but can also hold -1 for some other intervening character that we
don't support.
In a few places there's an integer that I haven't turned into a bool
even though it really _can_ only take values 0 or 1 (and, as above,
tried to make the call sites consistent in not calling those values
true and false), on the grounds that I thought it would make it more
confusing to imply that the 0 value was in some sense 'negative' or
bad and the 1 positive or good:
- the return value of plug_accepting uses the POSIXish convention of
0=success and nonzero=error; I think if I made it bool then I'd
also want to reverse its sense, and that's a job for a separate
piece of work.
- the 'screen' parameter to lineptr() in terminal.c, where 0 and 1
represent the default and alternate screens. There's no obvious
reason why one of those should be considered 'true' or 'positive'
or 'success' - they're just indices - so I've left it as int.
ssh_scp_recv had particularly confusing semantics for its previous int
return value: its call sites used '<= 0' to check for error, but it
never actually returned a negative number, just 0 or 1. Now the
function and its call sites agree that it's a bool.
In a couple of places I've renamed variables called 'ret', because I
don't like that name any more - it's unclear whether it means the
return value (in preparation) for the _containing_ function or the
return value received from a subroutine call, and occasionally I've
accidentally used the same variable for both and introduced a bug. So
where one of those got in my way, I've renamed it to 'toret' or 'retd'
(the latter short for 'returned') in line with my usual modern
practice, but I haven't done a thorough job of finding all of them.
Finally, one amusing side effect of doing this is that I've had to
separate quite a few chained assignments. It used to be perfectly fine
to write 'a = b = c = TRUE' when a,b,c were int and TRUE was just a
the 'true' defined by stdbool.h, that idiom provokes a warning from
gcc: 'suggest parentheses around assignment used as truth value'!
2018-11-02 19:23:19 +00:00
|
|
|
static void sk_net_set_frozen(Socket *s, bool is_frozen);
|
Get rid of lots of implicit pointer types.
All the main backend structures - Ssh, Telnet, Pty, Serial etc - now
describe structure types themselves rather than pointers to them. The
same goes for the codebase-wide trait types Socket and Plug, and the
supporting types SockAddr and Pinger.
All those things that were typedefed as pointers are older types; the
newer ones have the explicit * at the point of use, because that's
what I now seem to be preferring. But whichever one of those is
better, inconsistently using a mixture of the two styles is worse, so
let's make everything consistent.
A few types are still implicitly pointers, such as Bignum and some of
the GSSAPI types; generally this is either because they have to be
void *, or because they're typedefed differently on different
platforms and aren't always pointers at all. Can't be helped. But I've
got rid of the main ones, at least.
2018-10-04 18:10:23 +00:00
|
|
|
static const char *sk_net_socket_error(Socket *s);
|
2018-10-18 19:06:42 +00:00
|
|
|
static SocketPeerInfo *sk_net_peer_info(Socket *s);
|
2001-03-13 10:22:45 +00:00
|
|
|
|
2018-10-05 06:03:46 +00:00
|
|
|
static const SocketVtable NetSocket_sockvt = {
|
Change vtable defs to use C99 designated initialisers.
This is a sweeping change applied across the whole code base by a spot
of Emacs Lisp. Now, everywhere I declare a vtable filled with function
pointers (and the occasional const data member), all the members of
the vtable structure are initialised by name using the '.fieldname =
value' syntax introduced in C99.
We were already using this syntax for a handful of things in the new
key-generation progress report system, so it's not new to the code
base as a whole.
The advantage is that now, when a vtable only declares a subset of the
available fields, I can initialise the rest to NULL or zero just by
leaving them out. This is most dramatic in a couple of the outlying
vtables in things like psocks (which has a ConnectionLayerVtable
containing only one non-NULL method), but less dramatically, it means
that the new 'flags' field in BackendVtable can be completely left out
of every backend definition except for the SUPDUP one which defines it
to a nonzero value. Similarly, the test_for_upstream method only used
by SSH doesn't have to be mentioned in the rest of the backends;
network Plugs for listening sockets don't have to explicitly null out
'receive' and 'sent', and vice versa for 'accepting', and so on.
While I'm at it, I've normalised the declarations so they don't use
the unnecessarily verbose 'struct' keyword. Also a handful of them
weren't const; now they are.
2020-03-10 21:06:29 +00:00
|
|
|
.plug = sk_net_plug,
|
|
|
|
.close = sk_net_close,
|
|
|
|
.write = sk_net_write,
|
|
|
|
.write_oob = sk_net_write_oob,
|
|
|
|
.write_eof = sk_net_write_eof,
|
|
|
|
.set_frozen = sk_net_set_frozen,
|
|
|
|
.socket_error = sk_net_socket_error,
|
|
|
|
.peer_info = sk_net_peer_info,
|
2018-05-27 08:29:33 +00:00
|
|
|
};
|
2001-08-08 20:44:35 +00:00
|
|
|
|
Get rid of lots of implicit pointer types.
All the main backend structures - Ssh, Telnet, Pty, Serial etc - now
describe structure types themselves rather than pointers to them. The
same goes for the codebase-wide trait types Socket and Plug, and the
supporting types SockAddr and Pinger.
All those things that were typedefed as pointers are older types; the
newer ones have the explicit * at the point of use, because that's
what I now seem to be preferring. But whichever one of those is
better, inconsistently using a mixture of the two styles is worse, so
let's make everything consistent.
A few types are still implicitly pointers, such as Bignum and some of
the GSSAPI types; generally this is either because they have to be
void *, or because they're typedefed differently on different
platforms and aren't always pointers at all. Can't be helped. But I've
got rid of the main ones, at least.
2018-10-04 18:10:23 +00:00
|
|
|
static Socket *sk_net_accept(accept_ctx_t ctx, Plug *plug)
|
2018-05-27 08:29:33 +00:00
|
|
|
{
|
2001-08-08 20:44:35 +00:00
|
|
|
DWORD err;
|
2020-01-01 15:46:59 +00:00
|
|
|
const char *errstr;
|
2018-05-27 08:29:33 +00:00
|
|
|
NetSocket *ret;
|
2001-08-08 20:44:35 +00:00
|
|
|
|
|
|
|
/*
|
2018-05-27 08:29:33 +00:00
|
|
|
* Create NetSocket structure.
|
2001-08-08 20:44:35 +00:00
|
|
|
*/
|
2018-05-27 08:29:33 +00:00
|
|
|
ret = snew(NetSocket);
|
2018-10-05 06:24:16 +00:00
|
|
|
ret->sock.vt = &NetSocket_sockvt;
|
2001-08-08 20:44:35 +00:00
|
|
|
ret->error = NULL;
|
|
|
|
ret->plug = plug;
|
2001-08-25 17:09:23 +00:00
|
|
|
bufchain_init(&ret->output_data);
|
Convert a lot of 'int' variables to 'bool'.
My normal habit these days, in new code, is to treat int and bool as
_almost_ completely separate types. I'm still willing to use C's
implicit test for zero on an integer (e.g. 'if (!blob.len)' is fine,
no need to spell it out as blob.len != 0), but generally, if a
variable is going to be conceptually a boolean, I like to declare it
bool and assign to it using 'true' or 'false' rather than 0 or 1.
PuTTY is an exception, because it predates the C99 bool, and I've
stuck to its existing coding style even when adding new code to it.
But it's been annoying me more and more, so now that I've decided C99
bool is an acceptable thing to require from our toolchain in the first
place, here's a quite thorough trawl through the source doing
'boolification'. Many variables and function parameters are now typed
as bool rather than int; many assignments of 0 or 1 to those variables
are now spelled 'true' or 'false'.
I managed this thorough conversion with the help of a custom clang
plugin that I wrote to trawl the AST and apply heuristics to point out
where things might want changing. So I've even managed to do a decent
job on parts of the code I haven't looked at in years!
To make the plugin's work easier, I pushed platform front ends
generally in the direction of using standard 'bool' in preference to
platform-specific boolean types like Windows BOOL or GTK's gboolean;
I've left the platform booleans in places they _have_ to be for the
platform APIs to work right, but variables only used by my own code
have been converted wherever I found them.
In a few places there are int values that look very like booleans in
_most_ of the places they're used, but have a rarely-used third value,
or a distinction between different nonzero values that most users
don't care about. In these cases, I've _removed_ uses of 'true' and
'false' for the return values, to emphasise that there's something
more subtle going on than a simple boolean answer:
- the 'multisel' field in dialog.h's list box structure, for which
the GTK front end in particular recognises a difference between 1
and 2 but nearly everything else treats as boolean
- the 'urgent' parameter to plug_receive, where 1 vs 2 tells you
something about the specific location of the urgent pointer, but
most clients only care about 0 vs 'something nonzero'
- the return value of wc_match, where -1 indicates a syntax error in
the wildcard.
- the return values from SSH-1 RSA-key loading functions, which use
-1 for 'wrong passphrase' and 0 for all other failures (so any
caller which already knows it's not loading an _encrypted private_
key can treat them as boolean)
- term->esc_query, and the 'query' parameter in toggle_mode in
terminal.c, which _usually_ hold 0 for ESC[123h or 1 for ESC[?123h,
but can also hold -1 for some other intervening character that we
don't support.
In a few places there's an integer that I haven't turned into a bool
even though it really _can_ only take values 0 or 1 (and, as above,
tried to make the call sites consistent in not calling those values
true and false), on the grounds that I thought it would make it more
confusing to imply that the 0 value was in some sense 'negative' or
bad and the 1 positive or good:
- the return value of plug_accepting uses the POSIXish convention of
0=success and nonzero=error; I think if I made it bool then I'd
also want to reverse its sense, and that's a job for a separate
piece of work.
- the 'screen' parameter to lineptr() in terminal.c, where 0 and 1
represent the default and alternate screens. There's no obvious
reason why one of those should be considered 'true' or 'positive'
or 'success' - they're just indices - so I've left it as int.
ssh_scp_recv had particularly confusing semantics for its previous int
return value: its call sites used '<= 0' to check for error, but it
never actually returned a negative number, just 0 or 1. Now the
function and its call sites agree that it's a bool.
In a couple of places I've renamed variables called 'ret', because I
don't like that name any more - it's unclear whether it means the
return value (in preparation) for the _containing_ function or the
return value received from a subroutine call, and occasionally I've
accidentally used the same variable for both and introduced a bug. So
where one of those got in my way, I've renamed it to 'toret' or 'retd'
(the latter short for 'returned') in line with my usual modern
practice, but I haven't done a thorough job of finding all of them.
Finally, one amusing side effect of doing this is that I've had to
separate quite a few chained assignments. It used to be perfectly fine
to write 'a = b = c = TRUE' when a,b,c were int and TRUE was just a
the 'true' defined by stdbool.h, that idiom provokes a warning from
gcc: 'suggest parentheses around assignment used as truth value'!
2018-11-02 19:23:19 +00:00
|
|
|
ret->writable = true; /* to start with */
|
2001-08-08 20:44:35 +00:00
|
|
|
ret->sending_oob = 0;
|
2011-09-13 11:44:03 +00:00
|
|
|
ret->outgoingeof = EOF_NO;
|
Convert a lot of 'int' variables to 'bool'.
My normal habit these days, in new code, is to treat int and bool as
_almost_ completely separate types. I'm still willing to use C's
implicit test for zero on an integer (e.g. 'if (!blob.len)' is fine,
no need to spell it out as blob.len != 0), but generally, if a
variable is going to be conceptually a boolean, I like to declare it
bool and assign to it using 'true' or 'false' rather than 0 or 1.
PuTTY is an exception, because it predates the C99 bool, and I've
stuck to its existing coding style even when adding new code to it.
But it's been annoying me more and more, so now that I've decided C99
bool is an acceptable thing to require from our toolchain in the first
place, here's a quite thorough trawl through the source doing
'boolification'. Many variables and function parameters are now typed
as bool rather than int; many assignments of 0 or 1 to those variables
are now spelled 'true' or 'false'.
I managed this thorough conversion with the help of a custom clang
plugin that I wrote to trawl the AST and apply heuristics to point out
where things might want changing. So I've even managed to do a decent
job on parts of the code I haven't looked at in years!
To make the plugin's work easier, I pushed platform front ends
generally in the direction of using standard 'bool' in preference to
platform-specific boolean types like Windows BOOL or GTK's gboolean;
I've left the platform booleans in places they _have_ to be for the
platform APIs to work right, but variables only used by my own code
have been converted wherever I found them.
In a few places there are int values that look very like booleans in
_most_ of the places they're used, but have a rarely-used third value,
or a distinction between different nonzero values that most users
don't care about. In these cases, I've _removed_ uses of 'true' and
'false' for the return values, to emphasise that there's something
more subtle going on than a simple boolean answer:
- the 'multisel' field in dialog.h's list box structure, for which
the GTK front end in particular recognises a difference between 1
and 2 but nearly everything else treats as boolean
- the 'urgent' parameter to plug_receive, where 1 vs 2 tells you
something about the specific location of the urgent pointer, but
most clients only care about 0 vs 'something nonzero'
- the return value of wc_match, where -1 indicates a syntax error in
the wildcard.
- the return values from SSH-1 RSA-key loading functions, which use
-1 for 'wrong passphrase' and 0 for all other failures (so any
caller which already knows it's not loading an _encrypted private_
key can treat them as boolean)
- term->esc_query, and the 'query' parameter in toggle_mode in
terminal.c, which _usually_ hold 0 for ESC[123h or 1 for ESC[?123h,
but can also hold -1 for some other intervening character that we
don't support.
In a few places there's an integer that I haven't turned into a bool
even though it really _can_ only take values 0 or 1 (and, as above,
tried to make the call sites consistent in not calling those values
true and false), on the grounds that I thought it would make it more
confusing to imply that the 0 value was in some sense 'negative' or
bad and the 1 positive or good:
- the return value of plug_accepting uses the POSIXish convention of
0=success and nonzero=error; I think if I made it bool then I'd
also want to reverse its sense, and that's a job for a separate
piece of work.
- the 'screen' parameter to lineptr() in terminal.c, where 0 and 1
represent the default and alternate screens. There's no obvious
reason why one of those should be considered 'true' or 'positive'
or 'success' - they're just indices - so I've left it as int.
ssh_scp_recv had particularly confusing semantics for its previous int
return value: its call sites used '<= 0' to check for error, but it
never actually returned a negative number, just 0 or 1. Now the
function and its call sites agree that it's a bool.
In a couple of places I've renamed variables called 'ret', because I
don't like that name any more - it's unclear whether it means the
return value (in preparation) for the _containing_ function or the
return value received from a subroutine call, and occasionally I've
accidentally used the same variable for both and introduced a bug. So
where one of those got in my way, I've renamed it to 'toret' or 'retd'
(the latter short for 'returned') in line with my usual modern
practice, but I haven't done a thorough job of finding all of them.
Finally, one amusing side effect of doing this is that I've had to
separate quite a few chained assignments. It used to be perfectly fine
to write 'a = b = c = TRUE' when a,b,c were int and TRUE was just a
the 'true' defined by stdbool.h, that idiom provokes a warning from
gcc: 'suggest parentheses around assignment used as truth value'!
2018-11-02 19:23:19 +00:00
|
|
|
ret->frozen = true;
|
|
|
|
ret->frozen_readable = false;
|
|
|
|
ret->localhost_only = false; /* unused, but best init anyway */
|
2001-10-28 09:57:47 +00:00
|
|
|
ret->pending_error = 0;
|
2005-01-08 14:45:26 +00:00
|
|
|
ret->parent = ret->child = NULL;
|
2005-01-16 14:29:34 +00:00
|
|
|
ret->addr = NULL;
|
2001-08-08 20:44:35 +00:00
|
|
|
|
2013-11-17 14:03:55 +00:00
|
|
|
ret->s = (SOCKET)ctx.p;
|
2001-08-08 20:44:35 +00:00
|
|
|
|
|
|
|
if (ret->s == INVALID_SOCKET) {
|
2019-09-08 19:29:00 +00:00
|
|
|
err = p_WSAGetLastError();
|
|
|
|
ret->error = winsock_error_string(err);
|
|
|
|
return &ret->sock;
|
2001-08-08 20:44:35 +00:00
|
|
|
}
|
|
|
|
|
Convert a lot of 'int' variables to 'bool'.
My normal habit these days, in new code, is to treat int and bool as
_almost_ completely separate types. I'm still willing to use C's
implicit test for zero on an integer (e.g. 'if (!blob.len)' is fine,
no need to spell it out as blob.len != 0), but generally, if a
variable is going to be conceptually a boolean, I like to declare it
bool and assign to it using 'true' or 'false' rather than 0 or 1.
PuTTY is an exception, because it predates the C99 bool, and I've
stuck to its existing coding style even when adding new code to it.
But it's been annoying me more and more, so now that I've decided C99
bool is an acceptable thing to require from our toolchain in the first
place, here's a quite thorough trawl through the source doing
'boolification'. Many variables and function parameters are now typed
as bool rather than int; many assignments of 0 or 1 to those variables
are now spelled 'true' or 'false'.
I managed this thorough conversion with the help of a custom clang
plugin that I wrote to trawl the AST and apply heuristics to point out
where things might want changing. So I've even managed to do a decent
job on parts of the code I haven't looked at in years!
To make the plugin's work easier, I pushed platform front ends
generally in the direction of using standard 'bool' in preference to
platform-specific boolean types like Windows BOOL or GTK's gboolean;
I've left the platform booleans in places they _have_ to be for the
platform APIs to work right, but variables only used by my own code
have been converted wherever I found them.
In a few places there are int values that look very like booleans in
_most_ of the places they're used, but have a rarely-used third value,
or a distinction between different nonzero values that most users
don't care about. In these cases, I've _removed_ uses of 'true' and
'false' for the return values, to emphasise that there's something
more subtle going on than a simple boolean answer:
- the 'multisel' field in dialog.h's list box structure, for which
the GTK front end in particular recognises a difference between 1
and 2 but nearly everything else treats as boolean
- the 'urgent' parameter to plug_receive, where 1 vs 2 tells you
something about the specific location of the urgent pointer, but
most clients only care about 0 vs 'something nonzero'
- the return value of wc_match, where -1 indicates a syntax error in
the wildcard.
- the return values from SSH-1 RSA-key loading functions, which use
-1 for 'wrong passphrase' and 0 for all other failures (so any
caller which already knows it's not loading an _encrypted private_
key can treat them as boolean)
- term->esc_query, and the 'query' parameter in toggle_mode in
terminal.c, which _usually_ hold 0 for ESC[123h or 1 for ESC[?123h,
but can also hold -1 for some other intervening character that we
don't support.
In a few places there's an integer that I haven't turned into a bool
even though it really _can_ only take values 0 or 1 (and, as above,
tried to make the call sites consistent in not calling those values
true and false), on the grounds that I thought it would make it more
confusing to imply that the 0 value was in some sense 'negative' or
bad and the 1 positive or good:
- the return value of plug_accepting uses the POSIXish convention of
0=success and nonzero=error; I think if I made it bool then I'd
also want to reverse its sense, and that's a job for a separate
piece of work.
- the 'screen' parameter to lineptr() in terminal.c, where 0 and 1
represent the default and alternate screens. There's no obvious
reason why one of those should be considered 'true' or 'positive'
or 'success' - they're just indices - so I've left it as int.
ssh_scp_recv had particularly confusing semantics for its previous int
return value: its call sites used '<= 0' to check for error, but it
never actually returned a negative number, just 0 or 1. Now the
function and its call sites agree that it's a bool.
In a couple of places I've renamed variables called 'ret', because I
don't like that name any more - it's unclear whether it means the
return value (in preparation) for the _containing_ function or the
return value received from a subroutine call, and occasionally I've
accidentally used the same variable for both and introduced a bug. So
where one of those got in my way, I've renamed it to 'toret' or 'retd'
(the latter short for 'returned') in line with my usual modern
practice, but I haven't done a thorough job of finding all of them.
Finally, one amusing side effect of doing this is that I've had to
separate quite a few chained assignments. It used to be perfectly fine
to write 'a = b = c = TRUE' when a,b,c were int and TRUE was just a
the 'true' defined by stdbool.h, that idiom provokes a warning from
gcc: 'suggest parentheses around assignment used as truth value'!
2018-11-02 19:23:19 +00:00
|
|
|
ret->oobinline = false;
|
2001-08-08 20:44:35 +00:00
|
|
|
|
|
|
|
/* Set up a select mechanism. This could be an AsyncSelect on a
|
|
|
|
* window, or an EventSelect on an event object. */
|
Convert a lot of 'int' variables to 'bool'.
My normal habit these days, in new code, is to treat int and bool as
_almost_ completely separate types. I'm still willing to use C's
implicit test for zero on an integer (e.g. 'if (!blob.len)' is fine,
no need to spell it out as blob.len != 0), but generally, if a
variable is going to be conceptually a boolean, I like to declare it
bool and assign to it using 'true' or 'false' rather than 0 or 1.
PuTTY is an exception, because it predates the C99 bool, and I've
stuck to its existing coding style even when adding new code to it.
But it's been annoying me more and more, so now that I've decided C99
bool is an acceptable thing to require from our toolchain in the first
place, here's a quite thorough trawl through the source doing
'boolification'. Many variables and function parameters are now typed
as bool rather than int; many assignments of 0 or 1 to those variables
are now spelled 'true' or 'false'.
I managed this thorough conversion with the help of a custom clang
plugin that I wrote to trawl the AST and apply heuristics to point out
where things might want changing. So I've even managed to do a decent
job on parts of the code I haven't looked at in years!
To make the plugin's work easier, I pushed platform front ends
generally in the direction of using standard 'bool' in preference to
platform-specific boolean types like Windows BOOL or GTK's gboolean;
I've left the platform booleans in places they _have_ to be for the
platform APIs to work right, but variables only used by my own code
have been converted wherever I found them.
In a few places there are int values that look very like booleans in
_most_ of the places they're used, but have a rarely-used third value,
or a distinction between different nonzero values that most users
don't care about. In these cases, I've _removed_ uses of 'true' and
'false' for the return values, to emphasise that there's something
more subtle going on than a simple boolean answer:
- the 'multisel' field in dialog.h's list box structure, for which
the GTK front end in particular recognises a difference between 1
and 2 but nearly everything else treats as boolean
- the 'urgent' parameter to plug_receive, where 1 vs 2 tells you
something about the specific location of the urgent pointer, but
most clients only care about 0 vs 'something nonzero'
- the return value of wc_match, where -1 indicates a syntax error in
the wildcard.
- the return values from SSH-1 RSA-key loading functions, which use
-1 for 'wrong passphrase' and 0 for all other failures (so any
caller which already knows it's not loading an _encrypted private_
key can treat them as boolean)
- term->esc_query, and the 'query' parameter in toggle_mode in
terminal.c, which _usually_ hold 0 for ESC[123h or 1 for ESC[?123h,
but can also hold -1 for some other intervening character that we
don't support.
In a few places there's an integer that I haven't turned into a bool
even though it really _can_ only take values 0 or 1 (and, as above,
tried to make the call sites consistent in not calling those values
true and false), on the grounds that I thought it would make it more
confusing to imply that the 0 value was in some sense 'negative' or
bad and the 1 positive or good:
- the return value of plug_accepting uses the POSIXish convention of
0=success and nonzero=error; I think if I made it bool then I'd
also want to reverse its sense, and that's a job for a separate
piece of work.
- the 'screen' parameter to lineptr() in terminal.c, where 0 and 1
represent the default and alternate screens. There's no obvious
reason why one of those should be considered 'true' or 'positive'
or 'success' - they're just indices - so I've left it as int.
ssh_scp_recv had particularly confusing semantics for its previous int
return value: its call sites used '<= 0' to check for error, but it
never actually returned a negative number, just 0 or 1. Now the
function and its call sites agree that it's a bool.
In a couple of places I've renamed variables called 'ret', because I
don't like that name any more - it's unclear whether it means the
return value (in preparation) for the _containing_ function or the
return value received from a subroutine call, and occasionally I've
accidentally used the same variable for both and introduced a bug. So
where one of those got in my way, I've renamed it to 'toret' or 'retd'
(the latter short for 'returned') in line with my usual modern
practice, but I haven't done a thorough job of finding all of them.
Finally, one amusing side effect of doing this is that I've had to
separate quite a few chained assignments. It used to be perfectly fine
to write 'a = b = c = TRUE' when a,b,c were int and TRUE was just a
the 'true' defined by stdbool.h, that idiom provokes a warning from
gcc: 'suggest parentheses around assignment used as truth value'!
2018-11-02 19:23:19 +00:00
|
|
|
errstr = do_select(ret->s, true);
|
2001-08-08 20:44:35 +00:00
|
|
|
if (errstr) {
|
2019-09-08 19:29:00 +00:00
|
|
|
ret->error = errstr;
|
|
|
|
return &ret->sock;
|
2001-08-08 20:44:35 +00:00
|
|
|
}
|
|
|
|
|
|
|
|
add234(sktree, ret);
|
|
|
|
|
2018-10-05 06:24:16 +00:00
|
|
|
return &ret->sock;
|
2001-08-08 20:44:35 +00:00
|
|
|
}
|
|
|
|
|
2018-05-27 08:29:33 +00:00
|
|
|
static DWORD try_connect(NetSocket *sock)
|
2001-03-13 10:22:45 +00:00
|
|
|
{
|
2000-10-23 11:55:11 +00:00
|
|
|
SOCKET s;
|
2004-12-30 16:45:11 +00:00
|
|
|
#ifndef NO_IPV6
|
2001-01-07 19:16:16 +00:00
|
|
|
SOCKADDR_IN6 a6;
|
|
|
|
#endif
|
2000-10-23 11:55:11 +00:00
|
|
|
SOCKADDR_IN a;
|
|
|
|
DWORD err;
|
2020-01-01 15:46:59 +00:00
|
|
|
const char *errstr;
|
2001-01-19 10:10:37 +00:00
|
|
|
short localport;
|
2005-01-16 14:29:34 +00:00
|
|
|
int family;
|
2000-10-23 11:55:11 +00:00
|
|
|
|
2005-01-16 14:29:34 +00:00
|
|
|
if (sock->s != INVALID_SOCKET) {
|
2019-09-08 19:29:00 +00:00
|
|
|
do_select(sock->s, false);
|
2005-01-16 14:29:34 +00:00
|
|
|
p_closesocket(sock->s);
|
|
|
|
}
|
|
|
|
|
2017-01-28 10:56:19 +00:00
|
|
|
{
|
Get rid of lots of implicit pointer types.
All the main backend structures - Ssh, Telnet, Pty, Serial etc - now
describe structure types themselves rather than pointers to them. The
same goes for the codebase-wide trait types Socket and Plug, and the
supporting types SockAddr and Pinger.
All those things that were typedefed as pointers are older types; the
newer ones have the explicit * at the point of use, because that's
what I now seem to be preferring. But whichever one of those is
better, inconsistently using a mixture of the two styles is worse, so
let's make everything consistent.
A few types are still implicitly pointers, such as Bignum and some of
the GSSAPI types; generally this is either because they have to be
void *, or because they're typedefed differently on different
platforms and aren't always pointers at all. Can't be helped. But I've
got rid of the main ones, at least.
2018-10-04 18:10:23 +00:00
|
|
|
SockAddr thisaddr = sk_extractaddr_tmp(
|
2017-01-28 10:56:19 +00:00
|
|
|
sock->addr, &sock->step);
|
2020-02-07 19:17:45 +00:00
|
|
|
plug_log(sock->plug, PLUGLOG_CONNECT_TRYING,
|
|
|
|
&thisaddr, sock->port, NULL, 0);
|
2017-01-28 10:56:19 +00:00
|
|
|
}
|
2000-10-23 11:55:11 +00:00
|
|
|
|
|
|
|
/*
|
|
|
|
* Open socket.
|
|
|
|
*/
|
2008-11-08 16:45:45 +00:00
|
|
|
family = SOCKADDR_FAMILY(sock->addr, sock->step);
|
2005-01-16 14:29:34 +00:00
|
|
|
|
2007-11-26 21:09:54 +00:00
|
|
|
/*
|
|
|
|
* Remove the socket from the tree before we overwrite its
|
|
|
|
* internal socket id, because that forms part of the tree's
|
|
|
|
* sorting criterion. We'll add it back before exiting this
|
|
|
|
* function, whether we changed anything or not.
|
|
|
|
*/
|
|
|
|
del234(sktree, sock);
|
|
|
|
|
2005-01-16 14:29:34 +00:00
|
|
|
s = p_socket(family, SOCK_STREAM, 0);
|
|
|
|
sock->s = s;
|
2000-10-23 11:55:11 +00:00
|
|
|
|
|
|
|
if (s == INVALID_SOCKET) {
|
2019-09-08 19:29:00 +00:00
|
|
|
err = p_WSAGetLastError();
|
|
|
|
sock->error = winsock_error_string(err);
|
|
|
|
goto ret;
|
2000-10-23 11:55:11 +00:00
|
|
|
}
|
2001-02-01 14:11:04 +00:00
|
|
|
|
2019-09-08 19:29:00 +00:00
|
|
|
SetHandleInformation((HANDLE)s, HANDLE_FLAG_INHERIT, 0);
|
2017-02-19 13:49:12 +00:00
|
|
|
|
2005-01-16 14:29:34 +00:00
|
|
|
if (sock->oobinline) {
|
2019-09-08 19:29:00 +00:00
|
|
|
BOOL b = true;
|
|
|
|
p_setsockopt(s, SOL_SOCKET, SO_OOBINLINE, (void *) &b, sizeof(b));
|
2001-01-29 14:49:21 +00:00
|
|
|
}
|
2000-10-23 11:55:11 +00:00
|
|
|
|
2005-01-16 14:29:34 +00:00
|
|
|
if (sock->nodelay) {
|
2019-09-08 19:29:00 +00:00
|
|
|
BOOL b = true;
|
|
|
|
p_setsockopt(s, IPPROTO_TCP, TCP_NODELAY, (void *) &b, sizeof(b));
|
2001-11-29 21:47:11 +00:00
|
|
|
}
|
|
|
|
|
2005-01-16 14:29:34 +00:00
|
|
|
if (sock->keepalive) {
|
2019-09-08 19:29:00 +00:00
|
|
|
BOOL b = true;
|
|
|
|
p_setsockopt(s, SOL_SOCKET, SO_KEEPALIVE, (void *) &b, sizeof(b));
|
2004-06-20 17:07:38 +00:00
|
|
|
}
|
|
|
|
|
2000-10-23 11:55:11 +00:00
|
|
|
/*
|
|
|
|
* Bind to local address.
|
|
|
|
*/
|
2005-01-16 14:29:34 +00:00
|
|
|
if (sock->privport)
|
2019-09-08 19:29:00 +00:00
|
|
|
localport = 1023; /* count from 1023 downwards */
|
2001-01-07 19:16:16 +00:00
|
|
|
else
|
2019-09-08 19:29:00 +00:00
|
|
|
localport = 0; /* just use port 0 (ie winsock picks) */
|
2001-01-19 10:10:37 +00:00
|
|
|
|
|
|
|
/* Loop round trying to bind */
|
|
|
|
while (1) {
|
2019-09-08 19:29:00 +00:00
|
|
|
int sockcode;
|
2001-01-19 10:10:37 +00:00
|
|
|
|
2004-12-30 16:45:11 +00:00
|
|
|
#ifndef NO_IPV6
|
2019-09-08 19:29:00 +00:00
|
|
|
if (family == AF_INET6) {
|
|
|
|
memset(&a6, 0, sizeof(a6));
|
|
|
|
a6.sin6_family = AF_INET6;
|
2004-12-30 16:45:11 +00:00
|
|
|
/*a6.sin6_addr = in6addr_any; */ /* == 0 done by memset() */
|
2019-09-08 19:29:00 +00:00
|
|
|
a6.sin6_port = p_htons(localport);
|
|
|
|
} else
|
2001-01-07 19:16:16 +00:00
|
|
|
#endif
|
2019-09-08 19:29:00 +00:00
|
|
|
{
|
|
|
|
a.sin_family = AF_INET;
|
|
|
|
a.sin_addr.s_addr = p_htonl(INADDR_ANY);
|
|
|
|
a.sin_port = p_htons(localport);
|
|
|
|
}
|
2004-12-30 16:45:11 +00:00
|
|
|
#ifndef NO_IPV6
|
2019-09-08 19:29:00 +00:00
|
|
|
sockcode = p_bind(s, (family == AF_INET6 ?
|
|
|
|
(struct sockaddr *) &a6 :
|
|
|
|
(struct sockaddr *) &a),
|
|
|
|
(family == AF_INET6 ? sizeof(a6) : sizeof(a)));
|
2001-01-07 19:16:16 +00:00
|
|
|
#else
|
2019-09-08 19:29:00 +00:00
|
|
|
sockcode = p_bind(s, (struct sockaddr *) &a, sizeof(a));
|
2001-01-07 19:16:16 +00:00
|
|
|
#endif
|
2019-09-08 19:29:00 +00:00
|
|
|
if (sockcode != SOCKET_ERROR) {
|
|
|
|
err = 0;
|
|
|
|
break; /* done */
|
|
|
|
} else {
|
|
|
|
err = p_WSAGetLastError();
|
|
|
|
if (err != WSAEADDRINUSE) /* failed, for a bad reason */
|
|
|
|
break;
|
|
|
|
}
|
|
|
|
|
|
|
|
if (localport == 0)
|
|
|
|
break; /* we're only looping once */
|
|
|
|
localport--;
|
|
|
|
if (localport == 0)
|
|
|
|
break; /* we might have got to the end */
|
2001-01-19 10:10:37 +00:00
|
|
|
}
|
|
|
|
|
2001-05-06 14:35:20 +00:00
|
|
|
if (err) {
|
2019-09-08 19:29:00 +00:00
|
|
|
sock->error = winsock_error_string(err);
|
|
|
|
goto ret;
|
2000-10-23 11:55:11 +00:00
|
|
|
}
|
|
|
|
|
|
|
|
/*
|
|
|
|
* Connect to remote address.
|
|
|
|
*/
|
2004-12-30 16:45:11 +00:00
|
|
|
#ifndef NO_IPV6
|
2008-11-08 16:45:45 +00:00
|
|
|
if (sock->step.ai) {
|
2019-09-08 19:29:00 +00:00
|
|
|
if (family == AF_INET6) {
|
|
|
|
a6.sin6_family = AF_INET6;
|
|
|
|
a6.sin6_port = p_htons((short) sock->port);
|
|
|
|
a6.sin6_addr =
|
|
|
|
((struct sockaddr_in6 *) sock->step.ai->ai_addr)->sin6_addr;
|
|
|
|
a6.sin6_flowinfo = ((struct sockaddr_in6 *) sock->step.ai->ai_addr)->sin6_flowinfo;
|
|
|
|
a6.sin6_scope_id = ((struct sockaddr_in6 *) sock->step.ai->ai_addr)->sin6_scope_id;
|
|
|
|
} else {
|
|
|
|
a.sin_family = AF_INET;
|
|
|
|
a.sin_addr =
|
|
|
|
((struct sockaddr_in *) sock->step.ai->ai_addr)->sin_addr;
|
|
|
|
a.sin_port = p_htons((short) sock->port);
|
|
|
|
}
|
2001-05-06 14:35:20 +00:00
|
|
|
} else
|
2001-01-07 19:16:16 +00:00
|
|
|
#endif
|
2001-05-06 14:35:20 +00:00
|
|
|
{
|
2019-09-08 19:29:00 +00:00
|
|
|
assert(sock->addr->addresses && sock->step.curraddr < sock->addr->naddresses);
|
|
|
|
a.sin_family = AF_INET;
|
|
|
|
a.sin_addr.s_addr = p_htonl(sock->addr->addresses[sock->step.curraddr]);
|
|
|
|
a.sin_port = p_htons((short) sock->port);
|
2001-01-07 19:16:16 +00:00
|
|
|
}
|
2001-09-07 22:39:01 +00:00
|
|
|
|
|
|
|
/* Set up a select mechanism. This could be an AsyncSelect on a
|
|
|
|
* window, or an EventSelect on an event object. */
|
Convert a lot of 'int' variables to 'bool'.
My normal habit these days, in new code, is to treat int and bool as
_almost_ completely separate types. I'm still willing to use C's
implicit test for zero on an integer (e.g. 'if (!blob.len)' is fine,
no need to spell it out as blob.len != 0), but generally, if a
variable is going to be conceptually a boolean, I like to declare it
bool and assign to it using 'true' or 'false' rather than 0 or 1.
PuTTY is an exception, because it predates the C99 bool, and I've
stuck to its existing coding style even when adding new code to it.
But it's been annoying me more and more, so now that I've decided C99
bool is an acceptable thing to require from our toolchain in the first
place, here's a quite thorough trawl through the source doing
'boolification'. Many variables and function parameters are now typed
as bool rather than int; many assignments of 0 or 1 to those variables
are now spelled 'true' or 'false'.
I managed this thorough conversion with the help of a custom clang
plugin that I wrote to trawl the AST and apply heuristics to point out
where things might want changing. So I've even managed to do a decent
job on parts of the code I haven't looked at in years!
To make the plugin's work easier, I pushed platform front ends
generally in the direction of using standard 'bool' in preference to
platform-specific boolean types like Windows BOOL or GTK's gboolean;
I've left the platform booleans in places they _have_ to be for the
platform APIs to work right, but variables only used by my own code
have been converted wherever I found them.
In a few places there are int values that look very like booleans in
_most_ of the places they're used, but have a rarely-used third value,
or a distinction between different nonzero values that most users
don't care about. In these cases, I've _removed_ uses of 'true' and
'false' for the return values, to emphasise that there's something
more subtle going on than a simple boolean answer:
- the 'multisel' field in dialog.h's list box structure, for which
the GTK front end in particular recognises a difference between 1
and 2 but nearly everything else treats as boolean
- the 'urgent' parameter to plug_receive, where 1 vs 2 tells you
something about the specific location of the urgent pointer, but
most clients only care about 0 vs 'something nonzero'
- the return value of wc_match, where -1 indicates a syntax error in
the wildcard.
- the return values from SSH-1 RSA-key loading functions, which use
-1 for 'wrong passphrase' and 0 for all other failures (so any
caller which already knows it's not loading an _encrypted private_
key can treat them as boolean)
- term->esc_query, and the 'query' parameter in toggle_mode in
terminal.c, which _usually_ hold 0 for ESC[123h or 1 for ESC[?123h,
but can also hold -1 for some other intervening character that we
don't support.
In a few places there's an integer that I haven't turned into a bool
even though it really _can_ only take values 0 or 1 (and, as above,
tried to make the call sites consistent in not calling those values
true and false), on the grounds that I thought it would make it more
confusing to imply that the 0 value was in some sense 'negative' or
bad and the 1 positive or good:
- the return value of plug_accepting uses the POSIXish convention of
0=success and nonzero=error; I think if I made it bool then I'd
also want to reverse its sense, and that's a job for a separate
piece of work.
- the 'screen' parameter to lineptr() in terminal.c, where 0 and 1
represent the default and alternate screens. There's no obvious
reason why one of those should be considered 'true' or 'positive'
or 'success' - they're just indices - so I've left it as int.
ssh_scp_recv had particularly confusing semantics for its previous int
return value: its call sites used '<= 0' to check for error, but it
never actually returned a negative number, just 0 or 1. Now the
function and its call sites agree that it's a bool.
In a couple of places I've renamed variables called 'ret', because I
don't like that name any more - it's unclear whether it means the
return value (in preparation) for the _containing_ function or the
return value received from a subroutine call, and occasionally I've
accidentally used the same variable for both and introduced a bug. So
where one of those got in my way, I've renamed it to 'toret' or 'retd'
(the latter short for 'returned') in line with my usual modern
practice, but I haven't done a thorough job of finding all of them.
Finally, one amusing side effect of doing this is that I've had to
separate quite a few chained assignments. It used to be perfectly fine
to write 'a = b = c = TRUE' when a,b,c were int and TRUE was just a
the 'true' defined by stdbool.h, that idiom provokes a warning from
gcc: 'suggest parentheses around assignment used as truth value'!
2018-11-02 19:23:19 +00:00
|
|
|
errstr = do_select(s, true);
|
2001-09-07 22:39:01 +00:00
|
|
|
if (errstr) {
|
2019-09-08 19:29:00 +00:00
|
|
|
sock->error = errstr;
|
|
|
|
err = 1;
|
|
|
|
goto ret;
|
2001-09-07 22:39:01 +00:00
|
|
|
}
|
|
|
|
|
2001-05-06 14:35:20 +00:00
|
|
|
if ((
|
2004-12-30 16:45:11 +00:00
|
|
|
#ifndef NO_IPV6
|
2019-09-08 19:29:00 +00:00
|
|
|
p_connect(s,
|
|
|
|
((family == AF_INET6) ? (struct sockaddr *) &a6 :
|
|
|
|
(struct sockaddr *) &a),
|
|
|
|
(family == AF_INET6) ? sizeof(a6) : sizeof(a))
|
2001-01-07 19:16:16 +00:00
|
|
|
#else
|
2019-09-08 19:29:00 +00:00
|
|
|
p_connect(s, (struct sockaddr *) &a, sizeof(a))
|
2001-01-07 19:16:16 +00:00
|
|
|
#endif
|
2019-09-08 19:29:00 +00:00
|
|
|
) == SOCKET_ERROR) {
|
|
|
|
err = p_WSAGetLastError();
|
|
|
|
/*
|
|
|
|
* We expect a potential EWOULDBLOCK here, because the
|
|
|
|
* chances are the front end has done a select for
|
|
|
|
* FD_CONNECT, so that connect() will complete
|
|
|
|
* asynchronously.
|
|
|
|
*/
|
|
|
|
if ( err != WSAEWOULDBLOCK ) {
|
|
|
|
sock->error = winsock_error_string(err);
|
|
|
|
goto ret;
|
|
|
|
}
|
2001-09-07 22:39:01 +00:00
|
|
|
} else {
|
2019-09-08 19:29:00 +00:00
|
|
|
/*
|
|
|
|
* If we _don't_ get EWOULDBLOCK, the connect has completed
|
|
|
|
* and we should set the socket as writable.
|
|
|
|
*/
|
|
|
|
sock->writable = true;
|
2020-02-07 19:18:50 +00:00
|
|
|
SockAddr thisaddr = sk_extractaddr_tmp(sock->addr, &sock->step);
|
|
|
|
plug_log(sock->plug, PLUGLOG_CONNECT_SUCCESS,
|
|
|
|
&thisaddr, sock->port, NULL, 0);
|
2000-10-23 11:55:11 +00:00
|
|
|
}
|
|
|
|
|
2005-01-16 14:29:34 +00:00
|
|
|
err = 0;
|
|
|
|
|
|
|
|
ret:
|
2007-11-26 21:09:54 +00:00
|
|
|
|
|
|
|
/*
|
|
|
|
* No matter what happened, put the socket back in the tree.
|
|
|
|
*/
|
|
|
|
add234(sktree, sock);
|
|
|
|
|
2017-01-28 10:56:19 +00:00
|
|
|
if (err) {
|
Get rid of lots of implicit pointer types.
All the main backend structures - Ssh, Telnet, Pty, Serial etc - now
describe structure types themselves rather than pointers to them. The
same goes for the codebase-wide trait types Socket and Plug, and the
supporting types SockAddr and Pinger.
All those things that were typedefed as pointers are older types; the
newer ones have the explicit * at the point of use, because that's
what I now seem to be preferring. But whichever one of those is
better, inconsistently using a mixture of the two styles is worse, so
let's make everything consistent.
A few types are still implicitly pointers, such as Bignum and some of
the GSSAPI types; generally this is either because they have to be
void *, or because they're typedefed differently on different
platforms and aren't always pointers at all. Can't be helped. But I've
got rid of the main ones, at least.
2018-10-04 18:10:23 +00:00
|
|
|
SockAddr thisaddr = sk_extractaddr_tmp(
|
2017-01-28 10:56:19 +00:00
|
|
|
sock->addr, &sock->step);
|
2020-02-07 19:17:45 +00:00
|
|
|
plug_log(sock->plug, PLUGLOG_CONNECT_FAILED,
|
|
|
|
&thisaddr, sock->port, sock->error, err);
|
2017-01-28 10:56:19 +00:00
|
|
|
}
|
2005-01-16 14:29:34 +00:00
|
|
|
return err;
|
|
|
|
}
|
|
|
|
|
Convert a lot of 'int' variables to 'bool'.
My normal habit these days, in new code, is to treat int and bool as
_almost_ completely separate types. I'm still willing to use C's
implicit test for zero on an integer (e.g. 'if (!blob.len)' is fine,
no need to spell it out as blob.len != 0), but generally, if a
variable is going to be conceptually a boolean, I like to declare it
bool and assign to it using 'true' or 'false' rather than 0 or 1.
PuTTY is an exception, because it predates the C99 bool, and I've
stuck to its existing coding style even when adding new code to it.
But it's been annoying me more and more, so now that I've decided C99
bool is an acceptable thing to require from our toolchain in the first
place, here's a quite thorough trawl through the source doing
'boolification'. Many variables and function parameters are now typed
as bool rather than int; many assignments of 0 or 1 to those variables
are now spelled 'true' or 'false'.
I managed this thorough conversion with the help of a custom clang
plugin that I wrote to trawl the AST and apply heuristics to point out
where things might want changing. So I've even managed to do a decent
job on parts of the code I haven't looked at in years!
To make the plugin's work easier, I pushed platform front ends
generally in the direction of using standard 'bool' in preference to
platform-specific boolean types like Windows BOOL or GTK's gboolean;
I've left the platform booleans in places they _have_ to be for the
platform APIs to work right, but variables only used by my own code
have been converted wherever I found them.
In a few places there are int values that look very like booleans in
_most_ of the places they're used, but have a rarely-used third value,
or a distinction between different nonzero values that most users
don't care about. In these cases, I've _removed_ uses of 'true' and
'false' for the return values, to emphasise that there's something
more subtle going on than a simple boolean answer:
- the 'multisel' field in dialog.h's list box structure, for which
the GTK front end in particular recognises a difference between 1
and 2 but nearly everything else treats as boolean
- the 'urgent' parameter to plug_receive, where 1 vs 2 tells you
something about the specific location of the urgent pointer, but
most clients only care about 0 vs 'something nonzero'
- the return value of wc_match, where -1 indicates a syntax error in
the wildcard.
- the return values from SSH-1 RSA-key loading functions, which use
-1 for 'wrong passphrase' and 0 for all other failures (so any
caller which already knows it's not loading an _encrypted private_
key can treat them as boolean)
- term->esc_query, and the 'query' parameter in toggle_mode in
terminal.c, which _usually_ hold 0 for ESC[123h or 1 for ESC[?123h,
but can also hold -1 for some other intervening character that we
don't support.
In a few places there's an integer that I haven't turned into a bool
even though it really _can_ only take values 0 or 1 (and, as above,
tried to make the call sites consistent in not calling those values
true and false), on the grounds that I thought it would make it more
confusing to imply that the 0 value was in some sense 'negative' or
bad and the 1 positive or good:
- the return value of plug_accepting uses the POSIXish convention of
0=success and nonzero=error; I think if I made it bool then I'd
also want to reverse its sense, and that's a job for a separate
piece of work.
- the 'screen' parameter to lineptr() in terminal.c, where 0 and 1
represent the default and alternate screens. There's no obvious
reason why one of those should be considered 'true' or 'positive'
or 'success' - they're just indices - so I've left it as int.
ssh_scp_recv had particularly confusing semantics for its previous int
return value: its call sites used '<= 0' to check for error, but it
never actually returned a negative number, just 0 or 1. Now the
function and its call sites agree that it's a bool.
In a couple of places I've renamed variables called 'ret', because I
don't like that name any more - it's unclear whether it means the
return value (in preparation) for the _containing_ function or the
return value received from a subroutine call, and occasionally I've
accidentally used the same variable for both and introduced a bug. So
where one of those got in my way, I've renamed it to 'toret' or 'retd'
(the latter short for 'returned') in line with my usual modern
practice, but I haven't done a thorough job of finding all of them.
Finally, one amusing side effect of doing this is that I've had to
separate quite a few chained assignments. It used to be perfectly fine
to write 'a = b = c = TRUE' when a,b,c were int and TRUE was just a
the 'true' defined by stdbool.h, that idiom provokes a warning from
gcc: 'suggest parentheses around assignment used as truth value'!
2018-11-02 19:23:19 +00:00
|
|
|
Socket *sk_new(SockAddr *addr, int port, bool privport, bool oobinline,
|
|
|
|
bool nodelay, bool keepalive, Plug *plug)
|
2005-01-16 14:29:34 +00:00
|
|
|
{
|
2018-05-27 08:29:33 +00:00
|
|
|
NetSocket *ret;
|
2005-01-16 14:29:34 +00:00
|
|
|
DWORD err;
|
|
|
|
|
|
|
|
/*
|
2018-05-27 08:29:33 +00:00
|
|
|
* Create NetSocket structure.
|
2005-01-16 14:29:34 +00:00
|
|
|
*/
|
2018-05-27 08:29:33 +00:00
|
|
|
ret = snew(NetSocket);
|
2018-10-05 06:24:16 +00:00
|
|
|
ret->sock.vt = &NetSocket_sockvt;
|
2005-01-16 14:29:34 +00:00
|
|
|
ret->error = NULL;
|
|
|
|
ret->plug = plug;
|
|
|
|
bufchain_init(&ret->output_data);
|
Convert a lot of 'int' variables to 'bool'.
My normal habit these days, in new code, is to treat int and bool as
_almost_ completely separate types. I'm still willing to use C's
implicit test for zero on an integer (e.g. 'if (!blob.len)' is fine,
no need to spell it out as blob.len != 0), but generally, if a
variable is going to be conceptually a boolean, I like to declare it
bool and assign to it using 'true' or 'false' rather than 0 or 1.
PuTTY is an exception, because it predates the C99 bool, and I've
stuck to its existing coding style even when adding new code to it.
But it's been annoying me more and more, so now that I've decided C99
bool is an acceptable thing to require from our toolchain in the first
place, here's a quite thorough trawl through the source doing
'boolification'. Many variables and function parameters are now typed
as bool rather than int; many assignments of 0 or 1 to those variables
are now spelled 'true' or 'false'.
I managed this thorough conversion with the help of a custom clang
plugin that I wrote to trawl the AST and apply heuristics to point out
where things might want changing. So I've even managed to do a decent
job on parts of the code I haven't looked at in years!
To make the plugin's work easier, I pushed platform front ends
generally in the direction of using standard 'bool' in preference to
platform-specific boolean types like Windows BOOL or GTK's gboolean;
I've left the platform booleans in places they _have_ to be for the
platform APIs to work right, but variables only used by my own code
have been converted wherever I found them.
In a few places there are int values that look very like booleans in
_most_ of the places they're used, but have a rarely-used third value,
or a distinction between different nonzero values that most users
don't care about. In these cases, I've _removed_ uses of 'true' and
'false' for the return values, to emphasise that there's something
more subtle going on than a simple boolean answer:
- the 'multisel' field in dialog.h's list box structure, for which
the GTK front end in particular recognises a difference between 1
and 2 but nearly everything else treats as boolean
- the 'urgent' parameter to plug_receive, where 1 vs 2 tells you
something about the specific location of the urgent pointer, but
most clients only care about 0 vs 'something nonzero'
- the return value of wc_match, where -1 indicates a syntax error in
the wildcard.
- the return values from SSH-1 RSA-key loading functions, which use
-1 for 'wrong passphrase' and 0 for all other failures (so any
caller which already knows it's not loading an _encrypted private_
key can treat them as boolean)
- term->esc_query, and the 'query' parameter in toggle_mode in
terminal.c, which _usually_ hold 0 for ESC[123h or 1 for ESC[?123h,
but can also hold -1 for some other intervening character that we
don't support.
In a few places there's an integer that I haven't turned into a bool
even though it really _can_ only take values 0 or 1 (and, as above,
tried to make the call sites consistent in not calling those values
true and false), on the grounds that I thought it would make it more
confusing to imply that the 0 value was in some sense 'negative' or
bad and the 1 positive or good:
- the return value of plug_accepting uses the POSIXish convention of
0=success and nonzero=error; I think if I made it bool then I'd
also want to reverse its sense, and that's a job for a separate
piece of work.
- the 'screen' parameter to lineptr() in terminal.c, where 0 and 1
represent the default and alternate screens. There's no obvious
reason why one of those should be considered 'true' or 'positive'
or 'success' - they're just indices - so I've left it as int.
ssh_scp_recv had particularly confusing semantics for its previous int
return value: its call sites used '<= 0' to check for error, but it
never actually returned a negative number, just 0 or 1. Now the
function and its call sites agree that it's a bool.
In a couple of places I've renamed variables called 'ret', because I
don't like that name any more - it's unclear whether it means the
return value (in preparation) for the _containing_ function or the
return value received from a subroutine call, and occasionally I've
accidentally used the same variable for both and introduced a bug. So
where one of those got in my way, I've renamed it to 'toret' or 'retd'
(the latter short for 'returned') in line with my usual modern
practice, but I haven't done a thorough job of finding all of them.
Finally, one amusing side effect of doing this is that I've had to
separate quite a few chained assignments. It used to be perfectly fine
to write 'a = b = c = TRUE' when a,b,c were int and TRUE was just a
the 'true' defined by stdbool.h, that idiom provokes a warning from
gcc: 'suggest parentheses around assignment used as truth value'!
2018-11-02 19:23:19 +00:00
|
|
|
ret->connected = false; /* to start with */
|
|
|
|
ret->writable = false; /* to start with */
|
2005-01-16 14:29:34 +00:00
|
|
|
ret->sending_oob = 0;
|
2011-09-13 11:44:03 +00:00
|
|
|
ret->outgoingeof = EOF_NO;
|
Convert a lot of 'int' variables to 'bool'.
My normal habit these days, in new code, is to treat int and bool as
_almost_ completely separate types. I'm still willing to use C's
implicit test for zero on an integer (e.g. 'if (!blob.len)' is fine,
no need to spell it out as blob.len != 0), but generally, if a
variable is going to be conceptually a boolean, I like to declare it
bool and assign to it using 'true' or 'false' rather than 0 or 1.
PuTTY is an exception, because it predates the C99 bool, and I've
stuck to its existing coding style even when adding new code to it.
But it's been annoying me more and more, so now that I've decided C99
bool is an acceptable thing to require from our toolchain in the first
place, here's a quite thorough trawl through the source doing
'boolification'. Many variables and function parameters are now typed
as bool rather than int; many assignments of 0 or 1 to those variables
are now spelled 'true' or 'false'.
I managed this thorough conversion with the help of a custom clang
plugin that I wrote to trawl the AST and apply heuristics to point out
where things might want changing. So I've even managed to do a decent
job on parts of the code I haven't looked at in years!
To make the plugin's work easier, I pushed platform front ends
generally in the direction of using standard 'bool' in preference to
platform-specific boolean types like Windows BOOL or GTK's gboolean;
I've left the platform booleans in places they _have_ to be for the
platform APIs to work right, but variables only used by my own code
have been converted wherever I found them.
In a few places there are int values that look very like booleans in
_most_ of the places they're used, but have a rarely-used third value,
or a distinction between different nonzero values that most users
don't care about. In these cases, I've _removed_ uses of 'true' and
'false' for the return values, to emphasise that there's something
more subtle going on than a simple boolean answer:
- the 'multisel' field in dialog.h's list box structure, for which
the GTK front end in particular recognises a difference between 1
and 2 but nearly everything else treats as boolean
- the 'urgent' parameter to plug_receive, where 1 vs 2 tells you
something about the specific location of the urgent pointer, but
most clients only care about 0 vs 'something nonzero'
- the return value of wc_match, where -1 indicates a syntax error in
the wildcard.
- the return values from SSH-1 RSA-key loading functions, which use
-1 for 'wrong passphrase' and 0 for all other failures (so any
caller which already knows it's not loading an _encrypted private_
key can treat them as boolean)
- term->esc_query, and the 'query' parameter in toggle_mode in
terminal.c, which _usually_ hold 0 for ESC[123h or 1 for ESC[?123h,
but can also hold -1 for some other intervening character that we
don't support.
In a few places there's an integer that I haven't turned into a bool
even though it really _can_ only take values 0 or 1 (and, as above,
tried to make the call sites consistent in not calling those values
true and false), on the grounds that I thought it would make it more
confusing to imply that the 0 value was in some sense 'negative' or
bad and the 1 positive or good:
- the return value of plug_accepting uses the POSIXish convention of
0=success and nonzero=error; I think if I made it bool then I'd
also want to reverse its sense, and that's a job for a separate
piece of work.
- the 'screen' parameter to lineptr() in terminal.c, where 0 and 1
represent the default and alternate screens. There's no obvious
reason why one of those should be considered 'true' or 'positive'
or 'success' - they're just indices - so I've left it as int.
ssh_scp_recv had particularly confusing semantics for its previous int
return value: its call sites used '<= 0' to check for error, but it
never actually returned a negative number, just 0 or 1. Now the
function and its call sites agree that it's a bool.
In a couple of places I've renamed variables called 'ret', because I
don't like that name any more - it's unclear whether it means the
return value (in preparation) for the _containing_ function or the
return value received from a subroutine call, and occasionally I've
accidentally used the same variable for both and introduced a bug. So
where one of those got in my way, I've renamed it to 'toret' or 'retd'
(the latter short for 'returned') in line with my usual modern
practice, but I haven't done a thorough job of finding all of them.
Finally, one amusing side effect of doing this is that I've had to
separate quite a few chained assignments. It used to be perfectly fine
to write 'a = b = c = TRUE' when a,b,c were int and TRUE was just a
the 'true' defined by stdbool.h, that idiom provokes a warning from
gcc: 'suggest parentheses around assignment used as truth value'!
2018-11-02 19:23:19 +00:00
|
|
|
ret->frozen = false;
|
|
|
|
ret->frozen_readable = false;
|
|
|
|
ret->localhost_only = false; /* unused, but best init anyway */
|
2005-01-16 14:29:34 +00:00
|
|
|
ret->pending_error = 0;
|
|
|
|
ret->parent = ret->child = NULL;
|
|
|
|
ret->oobinline = oobinline;
|
|
|
|
ret->nodelay = nodelay;
|
|
|
|
ret->keepalive = keepalive;
|
|
|
|
ret->privport = privport;
|
|
|
|
ret->port = port;
|
|
|
|
ret->addr = addr;
|
2008-11-08 16:45:45 +00:00
|
|
|
START_STEP(ret->addr, ret->step);
|
2005-01-16 14:29:34 +00:00
|
|
|
ret->s = INVALID_SOCKET;
|
|
|
|
|
|
|
|
err = 0;
|
|
|
|
do {
|
|
|
|
err = try_connect(ret);
|
2008-11-08 16:45:45 +00:00
|
|
|
} while (err && sk_nextaddr(ret->addr, &ret->step));
|
2003-08-07 16:04:33 +00:00
|
|
|
|
2018-10-05 06:24:16 +00:00
|
|
|
return &ret->sock;
|
2000-10-23 11:55:11 +00:00
|
|
|
}
|
|
|
|
|
Get rid of lots of implicit pointer types.
All the main backend structures - Ssh, Telnet, Pty, Serial etc - now
describe structure types themselves rather than pointers to them. The
same goes for the codebase-wide trait types Socket and Plug, and the
supporting types SockAddr and Pinger.
All those things that were typedefed as pointers are older types; the
newer ones have the explicit * at the point of use, because that's
what I now seem to be preferring. But whichever one of those is
better, inconsistently using a mixture of the two styles is worse, so
let's make everything consistent.
A few types are still implicitly pointers, such as Bignum and some of
the GSSAPI types; generally this is either because they have to be
void *, or because they're typedefed differently on different
platforms and aren't always pointers at all. Can't be helped. But I've
got rid of the main ones, at least.
2018-10-04 18:10:23 +00:00
|
|
|
Socket *sk_newlistener(const char *srcaddr, int port, Plug *plug,
|
Convert a lot of 'int' variables to 'bool'.
My normal habit these days, in new code, is to treat int and bool as
_almost_ completely separate types. I'm still willing to use C's
implicit test for zero on an integer (e.g. 'if (!blob.len)' is fine,
no need to spell it out as blob.len != 0), but generally, if a
variable is going to be conceptually a boolean, I like to declare it
bool and assign to it using 'true' or 'false' rather than 0 or 1.
PuTTY is an exception, because it predates the C99 bool, and I've
stuck to its existing coding style even when adding new code to it.
But it's been annoying me more and more, so now that I've decided C99
bool is an acceptable thing to require from our toolchain in the first
place, here's a quite thorough trawl through the source doing
'boolification'. Many variables and function parameters are now typed
as bool rather than int; many assignments of 0 or 1 to those variables
are now spelled 'true' or 'false'.
I managed this thorough conversion with the help of a custom clang
plugin that I wrote to trawl the AST and apply heuristics to point out
where things might want changing. So I've even managed to do a decent
job on parts of the code I haven't looked at in years!
To make the plugin's work easier, I pushed platform front ends
generally in the direction of using standard 'bool' in preference to
platform-specific boolean types like Windows BOOL or GTK's gboolean;
I've left the platform booleans in places they _have_ to be for the
platform APIs to work right, but variables only used by my own code
have been converted wherever I found them.
In a few places there are int values that look very like booleans in
_most_ of the places they're used, but have a rarely-used third value,
or a distinction between different nonzero values that most users
don't care about. In these cases, I've _removed_ uses of 'true' and
'false' for the return values, to emphasise that there's something
more subtle going on than a simple boolean answer:
- the 'multisel' field in dialog.h's list box structure, for which
the GTK front end in particular recognises a difference between 1
and 2 but nearly everything else treats as boolean
- the 'urgent' parameter to plug_receive, where 1 vs 2 tells you
something about the specific location of the urgent pointer, but
most clients only care about 0 vs 'something nonzero'
- the return value of wc_match, where -1 indicates a syntax error in
the wildcard.
- the return values from SSH-1 RSA-key loading functions, which use
-1 for 'wrong passphrase' and 0 for all other failures (so any
caller which already knows it's not loading an _encrypted private_
key can treat them as boolean)
- term->esc_query, and the 'query' parameter in toggle_mode in
terminal.c, which _usually_ hold 0 for ESC[123h or 1 for ESC[?123h,
but can also hold -1 for some other intervening character that we
don't support.
In a few places there's an integer that I haven't turned into a bool
even though it really _can_ only take values 0 or 1 (and, as above,
tried to make the call sites consistent in not calling those values
true and false), on the grounds that I thought it would make it more
confusing to imply that the 0 value was in some sense 'negative' or
bad and the 1 positive or good:
- the return value of plug_accepting uses the POSIXish convention of
0=success and nonzero=error; I think if I made it bool then I'd
also want to reverse its sense, and that's a job for a separate
piece of work.
- the 'screen' parameter to lineptr() in terminal.c, where 0 and 1
represent the default and alternate screens. There's no obvious
reason why one of those should be considered 'true' or 'positive'
or 'success' - they're just indices - so I've left it as int.
ssh_scp_recv had particularly confusing semantics for its previous int
return value: its call sites used '<= 0' to check for error, but it
never actually returned a negative number, just 0 or 1. Now the
function and its call sites agree that it's a bool.
In a couple of places I've renamed variables called 'ret', because I
don't like that name any more - it's unclear whether it means the
return value (in preparation) for the _containing_ function or the
return value received from a subroutine call, and occasionally I've
accidentally used the same variable for both and introduced a bug. So
where one of those got in my way, I've renamed it to 'toret' or 'retd'
(the latter short for 'returned') in line with my usual modern
practice, but I haven't done a thorough job of finding all of them.
Finally, one amusing side effect of doing this is that I've had to
separate quite a few chained assignments. It used to be perfectly fine
to write 'a = b = c = TRUE' when a,b,c were int and TRUE was just a
the 'true' defined by stdbool.h, that idiom provokes a warning from
gcc: 'suggest parentheses around assignment used as truth value'!
2018-11-02 19:23:19 +00:00
|
|
|
bool local_host_only, int orig_address_family)
|
2001-08-08 20:44:35 +00:00
|
|
|
{
|
|
|
|
SOCKET s;
|
2004-12-30 16:45:11 +00:00
|
|
|
#ifndef NO_IPV6
|
2001-08-08 20:44:35 +00:00
|
|
|
SOCKADDR_IN6 a6;
|
|
|
|
#endif
|
|
|
|
SOCKADDR_IN a;
|
2004-12-30 16:45:11 +00:00
|
|
|
|
2001-08-08 20:44:35 +00:00
|
|
|
DWORD err;
|
2020-01-01 15:46:59 +00:00
|
|
|
const char *errstr;
|
2018-05-27 08:29:33 +00:00
|
|
|
NetSocket *ret;
|
2001-08-08 20:44:35 +00:00
|
|
|
int retcode;
|
|
|
|
|
2005-01-08 14:45:26 +00:00
|
|
|
int address_family;
|
|
|
|
|
2001-08-08 20:44:35 +00:00
|
|
|
/*
|
2018-05-27 08:29:33 +00:00
|
|
|
* Create NetSocket structure.
|
2001-08-08 20:44:35 +00:00
|
|
|
*/
|
2018-05-27 08:29:33 +00:00
|
|
|
ret = snew(NetSocket);
|
2018-10-05 06:24:16 +00:00
|
|
|
ret->sock.vt = &NetSocket_sockvt;
|
2001-08-08 20:44:35 +00:00
|
|
|
ret->error = NULL;
|
|
|
|
ret->plug = plug;
|
2001-08-25 17:09:23 +00:00
|
|
|
bufchain_init(&ret->output_data);
|
Convert a lot of 'int' variables to 'bool'.
My normal habit these days, in new code, is to treat int and bool as
_almost_ completely separate types. I'm still willing to use C's
implicit test for zero on an integer (e.g. 'if (!blob.len)' is fine,
no need to spell it out as blob.len != 0), but generally, if a
variable is going to be conceptually a boolean, I like to declare it
bool and assign to it using 'true' or 'false' rather than 0 or 1.
PuTTY is an exception, because it predates the C99 bool, and I've
stuck to its existing coding style even when adding new code to it.
But it's been annoying me more and more, so now that I've decided C99
bool is an acceptable thing to require from our toolchain in the first
place, here's a quite thorough trawl through the source doing
'boolification'. Many variables and function parameters are now typed
as bool rather than int; many assignments of 0 or 1 to those variables
are now spelled 'true' or 'false'.
I managed this thorough conversion with the help of a custom clang
plugin that I wrote to trawl the AST and apply heuristics to point out
where things might want changing. So I've even managed to do a decent
job on parts of the code I haven't looked at in years!
To make the plugin's work easier, I pushed platform front ends
generally in the direction of using standard 'bool' in preference to
platform-specific boolean types like Windows BOOL or GTK's gboolean;
I've left the platform booleans in places they _have_ to be for the
platform APIs to work right, but variables only used by my own code
have been converted wherever I found them.
In a few places there are int values that look very like booleans in
_most_ of the places they're used, but have a rarely-used third value,
or a distinction between different nonzero values that most users
don't care about. In these cases, I've _removed_ uses of 'true' and
'false' for the return values, to emphasise that there's something
more subtle going on than a simple boolean answer:
- the 'multisel' field in dialog.h's list box structure, for which
the GTK front end in particular recognises a difference between 1
and 2 but nearly everything else treats as boolean
- the 'urgent' parameter to plug_receive, where 1 vs 2 tells you
something about the specific location of the urgent pointer, but
most clients only care about 0 vs 'something nonzero'
- the return value of wc_match, where -1 indicates a syntax error in
the wildcard.
- the return values from SSH-1 RSA-key loading functions, which use
-1 for 'wrong passphrase' and 0 for all other failures (so any
caller which already knows it's not loading an _encrypted private_
key can treat them as boolean)
- term->esc_query, and the 'query' parameter in toggle_mode in
terminal.c, which _usually_ hold 0 for ESC[123h or 1 for ESC[?123h,
but can also hold -1 for some other intervening character that we
don't support.
In a few places there's an integer that I haven't turned into a bool
even though it really _can_ only take values 0 or 1 (and, as above,
tried to make the call sites consistent in not calling those values
true and false), on the grounds that I thought it would make it more
confusing to imply that the 0 value was in some sense 'negative' or
bad and the 1 positive or good:
- the return value of plug_accepting uses the POSIXish convention of
0=success and nonzero=error; I think if I made it bool then I'd
also want to reverse its sense, and that's a job for a separate
piece of work.
- the 'screen' parameter to lineptr() in terminal.c, where 0 and 1
represent the default and alternate screens. There's no obvious
reason why one of those should be considered 'true' or 'positive'
or 'success' - they're just indices - so I've left it as int.
ssh_scp_recv had particularly confusing semantics for its previous int
return value: its call sites used '<= 0' to check for error, but it
never actually returned a negative number, just 0 or 1. Now the
function and its call sites agree that it's a bool.
In a couple of places I've renamed variables called 'ret', because I
don't like that name any more - it's unclear whether it means the
return value (in preparation) for the _containing_ function or the
return value received from a subroutine call, and occasionally I've
accidentally used the same variable for both and introduced a bug. So
where one of those got in my way, I've renamed it to 'toret' or 'retd'
(the latter short for 'returned') in line with my usual modern
practice, but I haven't done a thorough job of finding all of them.
Finally, one amusing side effect of doing this is that I've had to
separate quite a few chained assignments. It used to be perfectly fine
to write 'a = b = c = TRUE' when a,b,c were int and TRUE was just a
the 'true' defined by stdbool.h, that idiom provokes a warning from
gcc: 'suggest parentheses around assignment used as truth value'!
2018-11-02 19:23:19 +00:00
|
|
|
ret->writable = false; /* to start with */
|
2001-08-08 20:44:35 +00:00
|
|
|
ret->sending_oob = 0;
|
2011-09-13 11:44:03 +00:00
|
|
|
ret->outgoingeof = EOF_NO;
|
Convert a lot of 'int' variables to 'bool'.
My normal habit these days, in new code, is to treat int and bool as
_almost_ completely separate types. I'm still willing to use C's
implicit test for zero on an integer (e.g. 'if (!blob.len)' is fine,
no need to spell it out as blob.len != 0), but generally, if a
variable is going to be conceptually a boolean, I like to declare it
bool and assign to it using 'true' or 'false' rather than 0 or 1.
PuTTY is an exception, because it predates the C99 bool, and I've
stuck to its existing coding style even when adding new code to it.
But it's been annoying me more and more, so now that I've decided C99
bool is an acceptable thing to require from our toolchain in the first
place, here's a quite thorough trawl through the source doing
'boolification'. Many variables and function parameters are now typed
as bool rather than int; many assignments of 0 or 1 to those variables
are now spelled 'true' or 'false'.
I managed this thorough conversion with the help of a custom clang
plugin that I wrote to trawl the AST and apply heuristics to point out
where things might want changing. So I've even managed to do a decent
job on parts of the code I haven't looked at in years!
To make the plugin's work easier, I pushed platform front ends
generally in the direction of using standard 'bool' in preference to
platform-specific boolean types like Windows BOOL or GTK's gboolean;
I've left the platform booleans in places they _have_ to be for the
platform APIs to work right, but variables only used by my own code
have been converted wherever I found them.
In a few places there are int values that look very like booleans in
_most_ of the places they're used, but have a rarely-used third value,
or a distinction between different nonzero values that most users
don't care about. In these cases, I've _removed_ uses of 'true' and
'false' for the return values, to emphasise that there's something
more subtle going on than a simple boolean answer:
- the 'multisel' field in dialog.h's list box structure, for which
the GTK front end in particular recognises a difference between 1
and 2 but nearly everything else treats as boolean
- the 'urgent' parameter to plug_receive, where 1 vs 2 tells you
something about the specific location of the urgent pointer, but
most clients only care about 0 vs 'something nonzero'
- the return value of wc_match, where -1 indicates a syntax error in
the wildcard.
- the return values from SSH-1 RSA-key loading functions, which use
-1 for 'wrong passphrase' and 0 for all other failures (so any
caller which already knows it's not loading an _encrypted private_
key can treat them as boolean)
- term->esc_query, and the 'query' parameter in toggle_mode in
terminal.c, which _usually_ hold 0 for ESC[123h or 1 for ESC[?123h,
but can also hold -1 for some other intervening character that we
don't support.
In a few places there's an integer that I haven't turned into a bool
even though it really _can_ only take values 0 or 1 (and, as above,
tried to make the call sites consistent in not calling those values
true and false), on the grounds that I thought it would make it more
confusing to imply that the 0 value was in some sense 'negative' or
bad and the 1 positive or good:
- the return value of plug_accepting uses the POSIXish convention of
0=success and nonzero=error; I think if I made it bool then I'd
also want to reverse its sense, and that's a job for a separate
piece of work.
- the 'screen' parameter to lineptr() in terminal.c, where 0 and 1
represent the default and alternate screens. There's no obvious
reason why one of those should be considered 'true' or 'positive'
or 'success' - they're just indices - so I've left it as int.
ssh_scp_recv had particularly confusing semantics for its previous int
return value: its call sites used '<= 0' to check for error, but it
never actually returned a negative number, just 0 or 1. Now the
function and its call sites agree that it's a bool.
In a couple of places I've renamed variables called 'ret', because I
don't like that name any more - it's unclear whether it means the
return value (in preparation) for the _containing_ function or the
return value received from a subroutine call, and occasionally I've
accidentally used the same variable for both and introduced a bug. So
where one of those got in my way, I've renamed it to 'toret' or 'retd'
(the latter short for 'returned') in line with my usual modern
practice, but I haven't done a thorough job of finding all of them.
Finally, one amusing side effect of doing this is that I've had to
separate quite a few chained assignments. It used to be perfectly fine
to write 'a = b = c = TRUE' when a,b,c were int and TRUE was just a
the 'true' defined by stdbool.h, that idiom provokes a warning from
gcc: 'suggest parentheses around assignment used as truth value'!
2018-11-02 19:23:19 +00:00
|
|
|
ret->frozen = false;
|
|
|
|
ret->frozen_readable = false;
|
2001-10-12 19:32:13 +00:00
|
|
|
ret->localhost_only = local_host_only;
|
2001-10-28 09:57:47 +00:00
|
|
|
ret->pending_error = 0;
|
2005-01-08 14:45:26 +00:00
|
|
|
ret->parent = ret->child = NULL;
|
2005-01-16 14:29:34 +00:00
|
|
|
ret->addr = NULL;
|
2001-08-08 20:44:35 +00:00
|
|
|
|
2004-12-30 16:45:11 +00:00
|
|
|
/*
|
|
|
|
* Translate address_family from platform-independent constants
|
|
|
|
* into local reality.
|
|
|
|
*/
|
2005-01-08 14:45:26 +00:00
|
|
|
address_family = (orig_address_family == ADDRTYPE_IPV4 ? AF_INET :
|
2004-12-30 16:45:11 +00:00
|
|
|
#ifndef NO_IPV6
|
2019-09-08 19:29:00 +00:00
|
|
|
orig_address_family == ADDRTYPE_IPV6 ? AF_INET6 :
|
2004-12-30 16:45:11 +00:00
|
|
|
#endif
|
2019-09-08 19:29:00 +00:00
|
|
|
AF_UNSPEC);
|
2005-01-08 14:45:26 +00:00
|
|
|
|
|
|
|
/*
|
|
|
|
* Our default, if passed the `don't care' value
|
|
|
|
* ADDRTYPE_UNSPEC, is to listen on IPv4. If IPv6 is supported,
|
|
|
|
* we will also set up a second socket listening on IPv6, but
|
|
|
|
* the v4 one is primary since that ought to work even on
|
|
|
|
* non-v6-supporting systems.
|
|
|
|
*/
|
|
|
|
if (address_family == AF_UNSPEC) address_family = AF_INET;
|
2004-12-30 16:45:11 +00:00
|
|
|
|
2001-08-08 20:44:35 +00:00
|
|
|
/*
|
|
|
|
* Open socket.
|
|
|
|
*/
|
2004-12-30 16:45:11 +00:00
|
|
|
s = p_socket(address_family, SOCK_STREAM, 0);
|
2001-08-08 20:44:35 +00:00
|
|
|
ret->s = s;
|
|
|
|
|
|
|
|
if (s == INVALID_SOCKET) {
|
2019-09-08 19:29:00 +00:00
|
|
|
err = p_WSAGetLastError();
|
|
|
|
ret->error = winsock_error_string(err);
|
|
|
|
return &ret->sock;
|
2001-08-08 20:44:35 +00:00
|
|
|
}
|
|
|
|
|
2018-05-27 08:29:33 +00:00
|
|
|
SetHandleInformation((HANDLE)s, HANDLE_FLAG_INHERIT, 0);
|
2017-02-19 13:49:12 +00:00
|
|
|
|
Convert a lot of 'int' variables to 'bool'.
My normal habit these days, in new code, is to treat int and bool as
_almost_ completely separate types. I'm still willing to use C's
implicit test for zero on an integer (e.g. 'if (!blob.len)' is fine,
no need to spell it out as blob.len != 0), but generally, if a
variable is going to be conceptually a boolean, I like to declare it
bool and assign to it using 'true' or 'false' rather than 0 or 1.
PuTTY is an exception, because it predates the C99 bool, and I've
stuck to its existing coding style even when adding new code to it.
But it's been annoying me more and more, so now that I've decided C99
bool is an acceptable thing to require from our toolchain in the first
place, here's a quite thorough trawl through the source doing
'boolification'. Many variables and function parameters are now typed
as bool rather than int; many assignments of 0 or 1 to those variables
are now spelled 'true' or 'false'.
I managed this thorough conversion with the help of a custom clang
plugin that I wrote to trawl the AST and apply heuristics to point out
where things might want changing. So I've even managed to do a decent
job on parts of the code I haven't looked at in years!
To make the plugin's work easier, I pushed platform front ends
generally in the direction of using standard 'bool' in preference to
platform-specific boolean types like Windows BOOL or GTK's gboolean;
I've left the platform booleans in places they _have_ to be for the
platform APIs to work right, but variables only used by my own code
have been converted wherever I found them.
In a few places there are int values that look very like booleans in
_most_ of the places they're used, but have a rarely-used third value,
or a distinction between different nonzero values that most users
don't care about. In these cases, I've _removed_ uses of 'true' and
'false' for the return values, to emphasise that there's something
more subtle going on than a simple boolean answer:
- the 'multisel' field in dialog.h's list box structure, for which
the GTK front end in particular recognises a difference between 1
and 2 but nearly everything else treats as boolean
- the 'urgent' parameter to plug_receive, where 1 vs 2 tells you
something about the specific location of the urgent pointer, but
most clients only care about 0 vs 'something nonzero'
- the return value of wc_match, where -1 indicates a syntax error in
the wildcard.
- the return values from SSH-1 RSA-key loading functions, which use
-1 for 'wrong passphrase' and 0 for all other failures (so any
caller which already knows it's not loading an _encrypted private_
key can treat them as boolean)
- term->esc_query, and the 'query' parameter in toggle_mode in
terminal.c, which _usually_ hold 0 for ESC[123h or 1 for ESC[?123h,
but can also hold -1 for some other intervening character that we
don't support.
In a few places there's an integer that I haven't turned into a bool
even though it really _can_ only take values 0 or 1 (and, as above,
tried to make the call sites consistent in not calling those values
true and false), on the grounds that I thought it would make it more
confusing to imply that the 0 value was in some sense 'negative' or
bad and the 1 positive or good:
- the return value of plug_accepting uses the POSIXish convention of
0=success and nonzero=error; I think if I made it bool then I'd
also want to reverse its sense, and that's a job for a separate
piece of work.
- the 'screen' parameter to lineptr() in terminal.c, where 0 and 1
represent the default and alternate screens. There's no obvious
reason why one of those should be considered 'true' or 'positive'
or 'success' - they're just indices - so I've left it as int.
ssh_scp_recv had particularly confusing semantics for its previous int
return value: its call sites used '<= 0' to check for error, but it
never actually returned a negative number, just 0 or 1. Now the
function and its call sites agree that it's a bool.
In a couple of places I've renamed variables called 'ret', because I
don't like that name any more - it's unclear whether it means the
return value (in preparation) for the _containing_ function or the
return value received from a subroutine call, and occasionally I've
accidentally used the same variable for both and introduced a bug. So
where one of those got in my way, I've renamed it to 'toret' or 'retd'
(the latter short for 'returned') in line with my usual modern
practice, but I haven't done a thorough job of finding all of them.
Finally, one amusing side effect of doing this is that I've had to
separate quite a few chained assignments. It used to be perfectly fine
to write 'a = b = c = TRUE' when a,b,c were int and TRUE was just a
the 'true' defined by stdbool.h, that idiom provokes a warning from
gcc: 'suggest parentheses around assignment used as truth value'!
2018-11-02 19:23:19 +00:00
|
|
|
ret->oobinline = false;
|
2001-08-08 20:44:35 +00:00
|
|
|
|
winnet: use SO_EXCLUSIVEADDRUSE for listening sockets.
Thanks to Patrick Stekovic for pointing out that, unlike sensible IP
stacks, Windows requires a non-default socket option to prevent a
second application from binding to a port you were already listening
on, causing some of your incoming connections to be diverted.
This replaces the previous setsockopt that enabled SO_REUSEADDR, which
I put there a long time ago in order to fix an annoying behaviour if
you used the same listening socket twice in rapid succession (e.g. for
successive PuTTYs forwarding the same port) and the second one failed
to bind the listening port because a left-over connection from the
first one was still in TIME_WAIT and causing the port number to be
marked as used.
As far as I can see, SO_EXCLUSIVEADDRUSE and SO_REUSEADDR are mutually
exclusive - if I try to set both, either way round, then setsockopt
returns failure on the second one - so if I have to set the former
then I _can't_ set the latter. And fortunately, re-testing on Windows
10, the TIME_WAIT problem that SO_REUSEADDR was supposed to solve
doesn't seem to exist any more: I deliberately tried listening on a
port that had a TIME_WAIT connection sitting on it, and it worked for
me even without SO_REUSEADDR.
(I can't remember now whether I definitely confirmed the TIME_WAIT
problem on a previous version of Windows, or whether I just assumed it
would happen on Windows in the same way as Linux, where I definitely
do remember observing it.)
While I'm changing that setsockopt call, I've also fixed its 'on'
parameter so that it's a BOOL rather than an int, in accordance with
the docs for WinSock setsockopt.
2019-08-03 17:22:08 +00:00
|
|
|
{
|
|
|
|
BOOL on = true;
|
|
|
|
p_setsockopt(s, SOL_SOCKET, SO_EXCLUSIVEADDRUSE,
|
|
|
|
(const char *)&on, sizeof(on));
|
|
|
|
}
|
2001-08-08 20:44:35 +00:00
|
|
|
|
2004-12-30 16:45:11 +00:00
|
|
|
#ifndef NO_IPV6
|
2019-09-08 19:29:00 +00:00
|
|
|
if (address_family == AF_INET6) {
|
|
|
|
memset(&a6, 0, sizeof(a6));
|
|
|
|
a6.sin6_family = AF_INET6;
|
|
|
|
if (local_host_only)
|
|
|
|
a6.sin6_addr = in6addr_loopback;
|
|
|
|
else
|
|
|
|
a6.sin6_addr = in6addr_any;
|
2014-01-25 15:58:59 +00:00
|
|
|
if (srcaddr != NULL && p_getaddrinfo) {
|
|
|
|
struct addrinfo hints;
|
|
|
|
struct addrinfo *ai;
|
|
|
|
int err;
|
|
|
|
|
|
|
|
memset(&hints, 0, sizeof(hints));
|
|
|
|
hints.ai_family = AF_INET6;
|
|
|
|
hints.ai_flags = 0;
|
|
|
|
{
|
|
|
|
/* strip [] on IPv6 address literals */
|
|
|
|
char *trimmed_addr = host_strduptrim(srcaddr);
|
|
|
|
err = p_getaddrinfo(trimmed_addr, NULL, &hints, &ai);
|
|
|
|
sfree(trimmed_addr);
|
|
|
|
}
|
|
|
|
if (err == 0 && ai->ai_family == AF_INET6) {
|
|
|
|
a6.sin6_addr =
|
|
|
|
((struct sockaddr_in6 *)ai->ai_addr)->sin6_addr;
|
|
|
|
}
|
|
|
|
}
|
2019-09-08 19:29:00 +00:00
|
|
|
a6.sin6_port = p_htons(port);
|
|
|
|
} else
|
2001-08-08 20:44:35 +00:00
|
|
|
#endif
|
2019-09-08 19:29:00 +00:00
|
|
|
{
|
Convert a lot of 'int' variables to 'bool'.
My normal habit these days, in new code, is to treat int and bool as
_almost_ completely separate types. I'm still willing to use C's
implicit test for zero on an integer (e.g. 'if (!blob.len)' is fine,
no need to spell it out as blob.len != 0), but generally, if a
variable is going to be conceptually a boolean, I like to declare it
bool and assign to it using 'true' or 'false' rather than 0 or 1.
PuTTY is an exception, because it predates the C99 bool, and I've
stuck to its existing coding style even when adding new code to it.
But it's been annoying me more and more, so now that I've decided C99
bool is an acceptable thing to require from our toolchain in the first
place, here's a quite thorough trawl through the source doing
'boolification'. Many variables and function parameters are now typed
as bool rather than int; many assignments of 0 or 1 to those variables
are now spelled 'true' or 'false'.
I managed this thorough conversion with the help of a custom clang
plugin that I wrote to trawl the AST and apply heuristics to point out
where things might want changing. So I've even managed to do a decent
job on parts of the code I haven't looked at in years!
To make the plugin's work easier, I pushed platform front ends
generally in the direction of using standard 'bool' in preference to
platform-specific boolean types like Windows BOOL or GTK's gboolean;
I've left the platform booleans in places they _have_ to be for the
platform APIs to work right, but variables only used by my own code
have been converted wherever I found them.
In a few places there are int values that look very like booleans in
_most_ of the places they're used, but have a rarely-used third value,
or a distinction between different nonzero values that most users
don't care about. In these cases, I've _removed_ uses of 'true' and
'false' for the return values, to emphasise that there's something
more subtle going on than a simple boolean answer:
- the 'multisel' field in dialog.h's list box structure, for which
the GTK front end in particular recognises a difference between 1
and 2 but nearly everything else treats as boolean
- the 'urgent' parameter to plug_receive, where 1 vs 2 tells you
something about the specific location of the urgent pointer, but
most clients only care about 0 vs 'something nonzero'
- the return value of wc_match, where -1 indicates a syntax error in
the wildcard.
- the return values from SSH-1 RSA-key loading functions, which use
-1 for 'wrong passphrase' and 0 for all other failures (so any
caller which already knows it's not loading an _encrypted private_
key can treat them as boolean)
- term->esc_query, and the 'query' parameter in toggle_mode in
terminal.c, which _usually_ hold 0 for ESC[123h or 1 for ESC[?123h,
but can also hold -1 for some other intervening character that we
don't support.
In a few places there's an integer that I haven't turned into a bool
even though it really _can_ only take values 0 or 1 (and, as above,
tried to make the call sites consistent in not calling those values
true and false), on the grounds that I thought it would make it more
confusing to imply that the 0 value was in some sense 'negative' or
bad and the 1 positive or good:
- the return value of plug_accepting uses the POSIXish convention of
0=success and nonzero=error; I think if I made it bool then I'd
also want to reverse its sense, and that's a job for a separate
piece of work.
- the 'screen' parameter to lineptr() in terminal.c, where 0 and 1
represent the default and alternate screens. There's no obvious
reason why one of those should be considered 'true' or 'positive'
or 'success' - they're just indices - so I've left it as int.
ssh_scp_recv had particularly confusing semantics for its previous int
return value: its call sites used '<= 0' to check for error, but it
never actually returned a negative number, just 0 or 1. Now the
function and its call sites agree that it's a bool.
In a couple of places I've renamed variables called 'ret', because I
don't like that name any more - it's unclear whether it means the
return value (in preparation) for the _containing_ function or the
return value received from a subroutine call, and occasionally I've
accidentally used the same variable for both and introduced a bug. So
where one of those got in my way, I've renamed it to 'toret' or 'retd'
(the latter short for 'returned') in line with my usual modern
practice, but I haven't done a thorough job of finding all of them.
Finally, one amusing side effect of doing this is that I've had to
separate quite a few chained assignments. It used to be perfectly fine
to write 'a = b = c = TRUE' when a,b,c were int and TRUE was just a
the 'true' defined by stdbool.h, that idiom provokes a warning from
gcc: 'suggest parentheses around assignment used as truth value'!
2018-11-02 19:23:19 +00:00
|
|
|
bool got_addr = false;
|
2019-09-08 19:29:00 +00:00
|
|
|
a.sin_family = AF_INET;
|
|
|
|
|
|
|
|
/*
|
|
|
|
* Bind to source address. First try an explicitly
|
|
|
|
* specified one...
|
|
|
|
*/
|
|
|
|
if (srcaddr) {
|
|
|
|
a.sin_addr.s_addr = p_inet_addr(srcaddr);
|
|
|
|
if (a.sin_addr.s_addr != INADDR_NONE) {
|
|
|
|
/* Override localhost_only with specified listen addr. */
|
|
|
|
ret->localhost_only = ipv4_is_loopback(a.sin_addr);
|
|
|
|
got_addr = true;
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
|
|
|
/*
|
|
|
|
* ... and failing that, go with one of the standard ones.
|
|
|
|
*/
|
|
|
|
if (!got_addr) {
|
|
|
|
if (local_host_only)
|
|
|
|
a.sin_addr.s_addr = p_htonl(INADDR_LOOPBACK);
|
|
|
|
else
|
|
|
|
a.sin_addr.s_addr = p_htonl(INADDR_ANY);
|
|
|
|
}
|
|
|
|
|
|
|
|
a.sin_port = p_htons((short)port);
|
|
|
|
}
|
2004-12-30 16:45:11 +00:00
|
|
|
#ifndef NO_IPV6
|
2019-09-08 19:29:00 +00:00
|
|
|
retcode = p_bind(s, (address_family == AF_INET6 ?
|
|
|
|
(struct sockaddr *) &a6 :
|
|
|
|
(struct sockaddr *) &a),
|
|
|
|
(address_family ==
|
|
|
|
AF_INET6 ? sizeof(a6) : sizeof(a)));
|
2001-08-08 20:44:35 +00:00
|
|
|
#else
|
2019-09-08 19:29:00 +00:00
|
|
|
retcode = p_bind(s, (struct sockaddr *) &a, sizeof(a));
|
2001-08-08 20:44:35 +00:00
|
|
|
#endif
|
2019-09-08 19:29:00 +00:00
|
|
|
if (retcode != SOCKET_ERROR) {
|
|
|
|
err = 0;
|
|
|
|
} else {
|
|
|
|
err = p_WSAGetLastError();
|
|
|
|
}
|
2001-08-08 20:44:35 +00:00
|
|
|
|
|
|
|
if (err) {
|
2019-09-08 19:29:00 +00:00
|
|
|
p_closesocket(s);
|
|
|
|
ret->error = winsock_error_string(err);
|
|
|
|
return &ret->sock;
|
2001-08-08 20:44:35 +00:00
|
|
|
}
|
|
|
|
|
|
|
|
|
2003-10-12 13:46:12 +00:00
|
|
|
if (p_listen(s, SOMAXCONN) == SOCKET_ERROR) {
|
|
|
|
p_closesocket(s);
|
2019-09-08 19:29:00 +00:00
|
|
|
ret->error = winsock_error_string(p_WSAGetLastError());
|
|
|
|
return &ret->sock;
|
2001-08-08 20:44:35 +00:00
|
|
|
}
|
|
|
|
|
|
|
|
/* Set up a select mechanism. This could be an AsyncSelect on a
|
|
|
|
* window, or an EventSelect on an event object. */
|
Convert a lot of 'int' variables to 'bool'.
My normal habit these days, in new code, is to treat int and bool as
_almost_ completely separate types. I'm still willing to use C's
implicit test for zero on an integer (e.g. 'if (!blob.len)' is fine,
no need to spell it out as blob.len != 0), but generally, if a
variable is going to be conceptually a boolean, I like to declare it
bool and assign to it using 'true' or 'false' rather than 0 or 1.
PuTTY is an exception, because it predates the C99 bool, and I've
stuck to its existing coding style even when adding new code to it.
But it's been annoying me more and more, so now that I've decided C99
bool is an acceptable thing to require from our toolchain in the first
place, here's a quite thorough trawl through the source doing
'boolification'. Many variables and function parameters are now typed
as bool rather than int; many assignments of 0 or 1 to those variables
are now spelled 'true' or 'false'.
I managed this thorough conversion with the help of a custom clang
plugin that I wrote to trawl the AST and apply heuristics to point out
where things might want changing. So I've even managed to do a decent
job on parts of the code I haven't looked at in years!
To make the plugin's work easier, I pushed platform front ends
generally in the direction of using standard 'bool' in preference to
platform-specific boolean types like Windows BOOL or GTK's gboolean;
I've left the platform booleans in places they _have_ to be for the
platform APIs to work right, but variables only used by my own code
have been converted wherever I found them.
In a few places there are int values that look very like booleans in
_most_ of the places they're used, but have a rarely-used third value,
or a distinction between different nonzero values that most users
don't care about. In these cases, I've _removed_ uses of 'true' and
'false' for the return values, to emphasise that there's something
more subtle going on than a simple boolean answer:
- the 'multisel' field in dialog.h's list box structure, for which
the GTK front end in particular recognises a difference between 1
and 2 but nearly everything else treats as boolean
- the 'urgent' parameter to plug_receive, where 1 vs 2 tells you
something about the specific location of the urgent pointer, but
most clients only care about 0 vs 'something nonzero'
- the return value of wc_match, where -1 indicates a syntax error in
the wildcard.
- the return values from SSH-1 RSA-key loading functions, which use
-1 for 'wrong passphrase' and 0 for all other failures (so any
caller which already knows it's not loading an _encrypted private_
key can treat them as boolean)
- term->esc_query, and the 'query' parameter in toggle_mode in
terminal.c, which _usually_ hold 0 for ESC[123h or 1 for ESC[?123h,
but can also hold -1 for some other intervening character that we
don't support.
In a few places there's an integer that I haven't turned into a bool
even though it really _can_ only take values 0 or 1 (and, as above,
tried to make the call sites consistent in not calling those values
true and false), on the grounds that I thought it would make it more
confusing to imply that the 0 value was in some sense 'negative' or
bad and the 1 positive or good:
- the return value of plug_accepting uses the POSIXish convention of
0=success and nonzero=error; I think if I made it bool then I'd
also want to reverse its sense, and that's a job for a separate
piece of work.
- the 'screen' parameter to lineptr() in terminal.c, where 0 and 1
represent the default and alternate screens. There's no obvious
reason why one of those should be considered 'true' or 'positive'
or 'success' - they're just indices - so I've left it as int.
ssh_scp_recv had particularly confusing semantics for its previous int
return value: its call sites used '<= 0' to check for error, but it
never actually returned a negative number, just 0 or 1. Now the
function and its call sites agree that it's a bool.
In a couple of places I've renamed variables called 'ret', because I
don't like that name any more - it's unclear whether it means the
return value (in preparation) for the _containing_ function or the
return value received from a subroutine call, and occasionally I've
accidentally used the same variable for both and introduced a bug. So
where one of those got in my way, I've renamed it to 'toret' or 'retd'
(the latter short for 'returned') in line with my usual modern
practice, but I haven't done a thorough job of finding all of them.
Finally, one amusing side effect of doing this is that I've had to
separate quite a few chained assignments. It used to be perfectly fine
to write 'a = b = c = TRUE' when a,b,c were int and TRUE was just a
the 'true' defined by stdbool.h, that idiom provokes a warning from
gcc: 'suggest parentheses around assignment used as truth value'!
2018-11-02 19:23:19 +00:00
|
|
|
errstr = do_select(s, true);
|
2001-08-08 20:44:35 +00:00
|
|
|
if (errstr) {
|
2019-09-08 19:29:00 +00:00
|
|
|
p_closesocket(s);
|
|
|
|
ret->error = errstr;
|
|
|
|
return &ret->sock;
|
2001-08-08 20:44:35 +00:00
|
|
|
}
|
|
|
|
|
|
|
|
add234(sktree, ret);
|
|
|
|
|
2005-01-08 14:45:26 +00:00
|
|
|
#ifndef NO_IPV6
|
|
|
|
/*
|
|
|
|
* If we were given ADDRTYPE_UNSPEC, we must also create an
|
|
|
|
* IPv6 listening socket and link it to this one.
|
|
|
|
*/
|
|
|
|
if (address_family == AF_INET && orig_address_family == ADDRTYPE_UNSPEC) {
|
2019-09-08 19:29:00 +00:00
|
|
|
Socket *other = sk_newlistener(srcaddr, port, plug,
|
Get rid of lots of implicit pointer types.
All the main backend structures - Ssh, Telnet, Pty, Serial etc - now
describe structure types themselves rather than pointers to them. The
same goes for the codebase-wide trait types Socket and Plug, and the
supporting types SockAddr and Pinger.
All those things that were typedefed as pointers are older types; the
newer ones have the explicit * at the point of use, because that's
what I now seem to be preferring. But whichever one of those is
better, inconsistently using a mixture of the two styles is worse, so
let's make everything consistent.
A few types are still implicitly pointers, such as Bignum and some of
the GSSAPI types; generally this is either because they have to be
void *, or because they're typedefed differently on different
platforms and aren't always pointers at all. Can't be helped. But I've
got rid of the main ones, at least.
2018-10-04 18:10:23 +00:00
|
|
|
local_host_only, ADDRTYPE_IPV6);
|
2005-01-08 14:45:26 +00:00
|
|
|
|
2019-09-08 19:29:00 +00:00
|
|
|
if (other) {
|
2018-10-05 22:49:08 +00:00
|
|
|
NetSocket *ns = container_of(other, NetSocket, sock);
|
2019-09-08 19:29:00 +00:00
|
|
|
if (!ns->error) {
|
|
|
|
ns->parent = ret;
|
|
|
|
ret->child = ns;
|
|
|
|
} else {
|
|
|
|
sfree(ns);
|
|
|
|
}
|
|
|
|
}
|
2005-01-08 14:45:26 +00:00
|
|
|
}
|
|
|
|
#endif
|
|
|
|
|
2018-10-05 06:24:16 +00:00
|
|
|
return &ret->sock;
|
2001-08-08 20:44:35 +00:00
|
|
|
}
|
|
|
|
|
Get rid of lots of implicit pointer types.
All the main backend structures - Ssh, Telnet, Pty, Serial etc - now
describe structure types themselves rather than pointers to them. The
same goes for the codebase-wide trait types Socket and Plug, and the
supporting types SockAddr and Pinger.
All those things that were typedefed as pointers are older types; the
newer ones have the explicit * at the point of use, because that's
what I now seem to be preferring. But whichever one of those is
better, inconsistently using a mixture of the two styles is worse, so
let's make everything consistent.
A few types are still implicitly pointers, such as Bignum and some of
the GSSAPI types; generally this is either because they have to be
void *, or because they're typedefed differently on different
platforms and aren't always pointers at all. Can't be helped. But I've
got rid of the main ones, at least.
2018-10-04 18:10:23 +00:00
|
|
|
static void sk_net_close(Socket *sock)
|
2001-05-06 14:35:20 +00:00
|
|
|
{
|
2018-10-05 22:49:08 +00:00
|
|
|
NetSocket *s = container_of(sock, NetSocket, sock);
|
2001-01-22 11:34:52 +00:00
|
|
|
|
2005-01-08 14:45:26 +00:00
|
|
|
if (s->child)
|
2019-09-08 19:29:00 +00:00
|
|
|
sk_net_close(&s->child->sock);
|
2005-01-08 14:45:26 +00:00
|
|
|
|
2019-01-29 20:13:47 +00:00
|
|
|
bufchain_clear(&s->output_data);
|
|
|
|
|
2000-10-23 11:55:11 +00:00
|
|
|
del234(sktree, s);
|
Convert a lot of 'int' variables to 'bool'.
My normal habit these days, in new code, is to treat int and bool as
_almost_ completely separate types. I'm still willing to use C's
implicit test for zero on an integer (e.g. 'if (!blob.len)' is fine,
no need to spell it out as blob.len != 0), but generally, if a
variable is going to be conceptually a boolean, I like to declare it
bool and assign to it using 'true' or 'false' rather than 0 or 1.
PuTTY is an exception, because it predates the C99 bool, and I've
stuck to its existing coding style even when adding new code to it.
But it's been annoying me more and more, so now that I've decided C99
bool is an acceptable thing to require from our toolchain in the first
place, here's a quite thorough trawl through the source doing
'boolification'. Many variables and function parameters are now typed
as bool rather than int; many assignments of 0 or 1 to those variables
are now spelled 'true' or 'false'.
I managed this thorough conversion with the help of a custom clang
plugin that I wrote to trawl the AST and apply heuristics to point out
where things might want changing. So I've even managed to do a decent
job on parts of the code I haven't looked at in years!
To make the plugin's work easier, I pushed platform front ends
generally in the direction of using standard 'bool' in preference to
platform-specific boolean types like Windows BOOL or GTK's gboolean;
I've left the platform booleans in places they _have_ to be for the
platform APIs to work right, but variables only used by my own code
have been converted wherever I found them.
In a few places there are int values that look very like booleans in
_most_ of the places they're used, but have a rarely-used third value,
or a distinction between different nonzero values that most users
don't care about. In these cases, I've _removed_ uses of 'true' and
'false' for the return values, to emphasise that there's something
more subtle going on than a simple boolean answer:
- the 'multisel' field in dialog.h's list box structure, for which
the GTK front end in particular recognises a difference between 1
and 2 but nearly everything else treats as boolean
- the 'urgent' parameter to plug_receive, where 1 vs 2 tells you
something about the specific location of the urgent pointer, but
most clients only care about 0 vs 'something nonzero'
- the return value of wc_match, where -1 indicates a syntax error in
the wildcard.
- the return values from SSH-1 RSA-key loading functions, which use
-1 for 'wrong passphrase' and 0 for all other failures (so any
caller which already knows it's not loading an _encrypted private_
key can treat them as boolean)
- term->esc_query, and the 'query' parameter in toggle_mode in
terminal.c, which _usually_ hold 0 for ESC[123h or 1 for ESC[?123h,
but can also hold -1 for some other intervening character that we
don't support.
In a few places there's an integer that I haven't turned into a bool
even though it really _can_ only take values 0 or 1 (and, as above,
tried to make the call sites consistent in not calling those values
true and false), on the grounds that I thought it would make it more
confusing to imply that the 0 value was in some sense 'negative' or
bad and the 1 positive or good:
- the return value of plug_accepting uses the POSIXish convention of
0=success and nonzero=error; I think if I made it bool then I'd
also want to reverse its sense, and that's a job for a separate
piece of work.
- the 'screen' parameter to lineptr() in terminal.c, where 0 and 1
represent the default and alternate screens. There's no obvious
reason why one of those should be considered 'true' or 'positive'
or 'success' - they're just indices - so I've left it as int.
ssh_scp_recv had particularly confusing semantics for its previous int
return value: its call sites used '<= 0' to check for error, but it
never actually returned a negative number, just 0 or 1. Now the
function and its call sites agree that it's a bool.
In a couple of places I've renamed variables called 'ret', because I
don't like that name any more - it's unclear whether it means the
return value (in preparation) for the _containing_ function or the
return value received from a subroutine call, and occasionally I've
accidentally used the same variable for both and introduced a bug. So
where one of those got in my way, I've renamed it to 'toret' or 'retd'
(the latter short for 'returned') in line with my usual modern
practice, but I haven't done a thorough job of finding all of them.
Finally, one amusing side effect of doing this is that I've had to
separate quite a few chained assignments. It used to be perfectly fine
to write 'a = b = c = TRUE' when a,b,c were int and TRUE was just a
the 'true' defined by stdbool.h, that idiom provokes a warning from
gcc: 'suggest parentheses around assignment used as truth value'!
2018-11-02 19:23:19 +00:00
|
|
|
do_select(s->s, false);
|
2003-10-12 13:46:12 +00:00
|
|
|
p_closesocket(s->s);
|
2005-01-16 14:29:34 +00:00
|
|
|
if (s->addr)
|
2019-09-08 19:29:00 +00:00
|
|
|
sk_addr_free(s->addr);
|
2019-04-20 07:20:34 +00:00
|
|
|
delete_callbacks_for_context(s);
|
2000-12-12 10:33:13 +00:00
|
|
|
sfree(s);
|
2000-10-23 11:55:11 +00:00
|
|
|
}
|
|
|
|
|
2013-08-17 16:06:27 +00:00
|
|
|
/*
|
|
|
|
* Deal with socket errors detected in try_send().
|
|
|
|
*/
|
|
|
|
static void socket_error_callback(void *vs)
|
|
|
|
{
|
2018-05-27 08:29:33 +00:00
|
|
|
NetSocket *s = (NetSocket *)vs;
|
2013-08-17 16:06:27 +00:00
|
|
|
|
|
|
|
/*
|
|
|
|
* Just in case other socket work has caused this socket to vanish
|
|
|
|
* or become somehow non-erroneous before this callback arrived...
|
|
|
|
*/
|
|
|
|
if (!find234(sktree, s, NULL) || !s->pending_error)
|
|
|
|
return;
|
|
|
|
|
|
|
|
/*
|
|
|
|
* An error has occurred on this socket. Pass it to the plug.
|
|
|
|
*/
|
2013-10-09 18:36:56 +00:00
|
|
|
plug_closing(s->plug, winsock_error_string(s->pending_error),
|
|
|
|
s->pending_error, 0);
|
2013-08-17 16:06:27 +00:00
|
|
|
}
|
|
|
|
|
2000-10-23 11:55:11 +00:00
|
|
|
/*
|
|
|
|
* The function which tries to send on a socket once it's deemed
|
|
|
|
* writable.
|
|
|
|
*/
|
2018-05-27 08:29:33 +00:00
|
|
|
void try_send(NetSocket *s)
|
2001-05-06 14:35:20 +00:00
|
|
|
{
|
2001-08-25 17:09:23 +00:00
|
|
|
while (s->sending_oob || bufchain_size(&s->output_data) > 0) {
|
2019-09-08 19:29:00 +00:00
|
|
|
int nsent;
|
|
|
|
DWORD err;
|
|
|
|
const void *data;
|
|
|
|
size_t len;
|
2019-02-06 20:42:44 +00:00
|
|
|
int urgentflag;
|
2001-05-06 14:35:20 +00:00
|
|
|
|
2019-09-08 19:29:00 +00:00
|
|
|
if (s->sending_oob) {
|
|
|
|
urgentflag = MSG_OOB;
|
|
|
|
len = s->sending_oob;
|
|
|
|
data = &s->oobdata;
|
|
|
|
} else {
|
|
|
|
urgentflag = 0;
|
2019-02-06 20:46:45 +00:00
|
|
|
ptrlen bufdata = bufchain_prefix(&s->output_data);
|
|
|
|
data = bufdata.ptr;
|
|
|
|
len = bufdata.len;
|
2019-09-08 19:29:00 +00:00
|
|
|
}
|
2019-02-06 20:42:44 +00:00
|
|
|
len = min(len, INT_MAX); /* WinSock send() takes an int */
|
2019-09-08 19:29:00 +00:00
|
|
|
nsent = p_send(s->s, data, len, urgentflag);
|
|
|
|
noise_ultralight(NOISE_SOURCE_IOLEN, nsent);
|
|
|
|
if (nsent <= 0) {
|
|
|
|
err = (nsent < 0 ? p_WSAGetLastError() : 0);
|
|
|
|
if ((err < WSABASEERR && nsent < 0) || err == WSAEWOULDBLOCK) {
|
|
|
|
/*
|
|
|
|
* Perfectly normal: we've sent all we can for the moment.
|
|
|
|
*
|
|
|
|
* (Some WinSock send() implementations can return
|
|
|
|
* <0 but leave no sensible error indication -
|
|
|
|
* WSAGetLastError() is called but returns zero or
|
|
|
|
* a small number - so we check that case and treat
|
|
|
|
* it just like WSAEWOULDBLOCK.)
|
|
|
|
*/
|
|
|
|
s->writable = false;
|
|
|
|
return;
|
|
|
|
} else {
|
|
|
|
/*
|
|
|
|
* If send() returns a socket error, we unfortunately
|
|
|
|
* can't just call plug_closing(), because it's quite
|
|
|
|
* likely that we're currently _in_ a call from the
|
|
|
|
* code we'd be calling back to, so we'd have to make
|
|
|
|
* half the SSH code reentrant. Instead we flag a
|
|
|
|
* pending error on the socket, to be dealt with (by
|
|
|
|
* calling plug_closing()) at some suitable future
|
|
|
|
* moment.
|
|
|
|
*/
|
|
|
|
s->pending_error = err;
|
2013-08-17 16:06:27 +00:00
|
|
|
queue_toplevel_callback(socket_error_callback, s);
|
2019-09-08 19:29:00 +00:00
|
|
|
return;
|
|
|
|
}
|
|
|
|
} else {
|
|
|
|
if (s->sending_oob) {
|
|
|
|
if (nsent < len) {
|
|
|
|
memmove(s->oobdata, s->oobdata+nsent, len-nsent);
|
|
|
|
s->sending_oob = len - nsent;
|
|
|
|
} else {
|
|
|
|
s->sending_oob = 0;
|
|
|
|
}
|
|
|
|
} else {
|
|
|
|
bufchain_consume(&s->output_data, nsent);
|
|
|
|
}
|
|
|
|
}
|
2000-10-23 11:55:11 +00:00
|
|
|
}
|
2011-09-13 11:44:03 +00:00
|
|
|
|
|
|
|
/*
|
|
|
|
* If we reach here, we've finished sending everything we might
|
|
|
|
* have needed to send. Send EOF, if we need to.
|
|
|
|
*/
|
|
|
|
if (s->outgoingeof == EOF_PENDING) {
|
|
|
|
p_shutdown(s->s, SD_SEND);
|
|
|
|
s->outgoingeof = EOF_SENT;
|
|
|
|
}
|
2000-10-23 11:55:11 +00:00
|
|
|
}
|
|
|
|
|
2019-02-06 20:42:44 +00:00
|
|
|
static size_t sk_net_write(Socket *sock, const void *buf, size_t len)
|
2001-05-06 14:35:20 +00:00
|
|
|
{
|
2018-10-05 22:49:08 +00:00
|
|
|
NetSocket *s = container_of(sock, NetSocket, sock);
|
2001-03-13 10:22:45 +00:00
|
|
|
|
2011-09-13 11:44:03 +00:00
|
|
|
assert(s->outgoingeof == EOF_NO);
|
|
|
|
|
2000-10-23 11:55:11 +00:00
|
|
|
/*
|
|
|
|
* Add the data to the buffer list on the socket.
|
|
|
|
*/
|
2001-08-25 17:09:23 +00:00
|
|
|
bufchain_add(&s->output_data, buf, len);
|
2000-10-23 11:55:11 +00:00
|
|
|
|
|
|
|
/*
|
|
|
|
* Now try sending from the start of the buffer list.
|
|
|
|
*/
|
|
|
|
if (s->writable)
|
2019-09-08 19:29:00 +00:00
|
|
|
try_send(s);
|
2001-08-25 17:09:23 +00:00
|
|
|
|
|
|
|
return bufchain_size(&s->output_data);
|
2000-10-23 11:55:11 +00:00
|
|
|
}
|
|
|
|
|
2019-02-06 20:42:44 +00:00
|
|
|
static size_t sk_net_write_oob(Socket *sock, const void *buf, size_t len)
|
2001-05-06 14:35:20 +00:00
|
|
|
{
|
2018-10-05 22:49:08 +00:00
|
|
|
NetSocket *s = container_of(sock, NetSocket, sock);
|
2001-03-13 10:22:45 +00:00
|
|
|
|
2011-09-13 11:44:03 +00:00
|
|
|
assert(s->outgoingeof == EOF_NO);
|
|
|
|
|
2000-10-23 11:55:11 +00:00
|
|
|
/*
|
|
|
|
* Replace the buffer list on the socket with the data.
|
|
|
|
*/
|
2001-08-25 17:09:23 +00:00
|
|
|
bufchain_clear(&s->output_data);
|
|
|
|
assert(len <= sizeof(s->oobdata));
|
|
|
|
memcpy(s->oobdata, buf, len);
|
2000-10-23 11:55:11 +00:00
|
|
|
s->sending_oob = len;
|
|
|
|
|
|
|
|
/*
|
|
|
|
* Now try sending from the start of the buffer list.
|
|
|
|
*/
|
|
|
|
if (s->writable)
|
2019-09-08 19:29:00 +00:00
|
|
|
try_send(s);
|
2001-08-25 17:09:23 +00:00
|
|
|
|
|
|
|
return s->sending_oob;
|
2000-10-23 11:55:11 +00:00
|
|
|
}
|
|
|
|
|
Get rid of lots of implicit pointer types.
All the main backend structures - Ssh, Telnet, Pty, Serial etc - now
describe structure types themselves rather than pointers to them. The
same goes for the codebase-wide trait types Socket and Plug, and the
supporting types SockAddr and Pinger.
All those things that were typedefed as pointers are older types; the
newer ones have the explicit * at the point of use, because that's
what I now seem to be preferring. But whichever one of those is
better, inconsistently using a mixture of the two styles is worse, so
let's make everything consistent.
A few types are still implicitly pointers, such as Bignum and some of
the GSSAPI types; generally this is either because they have to be
void *, or because they're typedefed differently on different
platforms and aren't always pointers at all. Can't be helped. But I've
got rid of the main ones, at least.
2018-10-04 18:10:23 +00:00
|
|
|
static void sk_net_write_eof(Socket *sock)
|
2011-09-13 11:44:03 +00:00
|
|
|
{
|
2018-10-05 22:49:08 +00:00
|
|
|
NetSocket *s = container_of(sock, NetSocket, sock);
|
2011-09-13 11:44:03 +00:00
|
|
|
|
|
|
|
assert(s->outgoingeof == EOF_NO);
|
|
|
|
|
|
|
|
/*
|
|
|
|
* Mark the socket as pending outgoing EOF.
|
|
|
|
*/
|
|
|
|
s->outgoingeof = EOF_PENDING;
|
|
|
|
|
|
|
|
/*
|
|
|
|
* Now try sending from the start of the buffer list.
|
|
|
|
*/
|
|
|
|
if (s->writable)
|
2019-09-08 19:29:00 +00:00
|
|
|
try_send(s);
|
2011-09-13 11:44:03 +00:00
|
|
|
}
|
|
|
|
|
2016-06-02 21:38:36 +00:00
|
|
|
void select_result(WPARAM wParam, LPARAM lParam)
|
2001-05-06 14:35:20 +00:00
|
|
|
{
|
2016-06-02 21:38:36 +00:00
|
|
|
int ret;
|
2000-10-23 11:55:11 +00:00
|
|
|
DWORD err;
|
2019-09-08 19:29:00 +00:00
|
|
|
char buf[20480]; /* nice big buffer for plenty of speed */
|
2018-05-27 08:29:33 +00:00
|
|
|
NetSocket *s;
|
Convert a lot of 'int' variables to 'bool'.
My normal habit these days, in new code, is to treat int and bool as
_almost_ completely separate types. I'm still willing to use C's
implicit test for zero on an integer (e.g. 'if (!blob.len)' is fine,
no need to spell it out as blob.len != 0), but generally, if a
variable is going to be conceptually a boolean, I like to declare it
bool and assign to it using 'true' or 'false' rather than 0 or 1.
PuTTY is an exception, because it predates the C99 bool, and I've
stuck to its existing coding style even when adding new code to it.
But it's been annoying me more and more, so now that I've decided C99
bool is an acceptable thing to require from our toolchain in the first
place, here's a quite thorough trawl through the source doing
'boolification'. Many variables and function parameters are now typed
as bool rather than int; many assignments of 0 or 1 to those variables
are now spelled 'true' or 'false'.
I managed this thorough conversion with the help of a custom clang
plugin that I wrote to trawl the AST and apply heuristics to point out
where things might want changing. So I've even managed to do a decent
job on parts of the code I haven't looked at in years!
To make the plugin's work easier, I pushed platform front ends
generally in the direction of using standard 'bool' in preference to
platform-specific boolean types like Windows BOOL or GTK's gboolean;
I've left the platform booleans in places they _have_ to be for the
platform APIs to work right, but variables only used by my own code
have been converted wherever I found them.
In a few places there are int values that look very like booleans in
_most_ of the places they're used, but have a rarely-used third value,
or a distinction between different nonzero values that most users
don't care about. In these cases, I've _removed_ uses of 'true' and
'false' for the return values, to emphasise that there's something
more subtle going on than a simple boolean answer:
- the 'multisel' field in dialog.h's list box structure, for which
the GTK front end in particular recognises a difference between 1
and 2 but nearly everything else treats as boolean
- the 'urgent' parameter to plug_receive, where 1 vs 2 tells you
something about the specific location of the urgent pointer, but
most clients only care about 0 vs 'something nonzero'
- the return value of wc_match, where -1 indicates a syntax error in
the wildcard.
- the return values from SSH-1 RSA-key loading functions, which use
-1 for 'wrong passphrase' and 0 for all other failures (so any
caller which already knows it's not loading an _encrypted private_
key can treat them as boolean)
- term->esc_query, and the 'query' parameter in toggle_mode in
terminal.c, which _usually_ hold 0 for ESC[123h or 1 for ESC[?123h,
but can also hold -1 for some other intervening character that we
don't support.
In a few places there's an integer that I haven't turned into a bool
even though it really _can_ only take values 0 or 1 (and, as above,
tried to make the call sites consistent in not calling those values
true and false), on the grounds that I thought it would make it more
confusing to imply that the 0 value was in some sense 'negative' or
bad and the 1 positive or good:
- the return value of plug_accepting uses the POSIXish convention of
0=success and nonzero=error; I think if I made it bool then I'd
also want to reverse its sense, and that's a job for a separate
piece of work.
- the 'screen' parameter to lineptr() in terminal.c, where 0 and 1
represent the default and alternate screens. There's no obvious
reason why one of those should be considered 'true' or 'positive'
or 'success' - they're just indices - so I've left it as int.
ssh_scp_recv had particularly confusing semantics for its previous int
return value: its call sites used '<= 0' to check for error, but it
never actually returned a negative number, just 0 or 1. Now the
function and its call sites agree that it's a bool.
In a couple of places I've renamed variables called 'ret', because I
don't like that name any more - it's unclear whether it means the
return value (in preparation) for the _containing_ function or the
return value received from a subroutine call, and occasionally I've
accidentally used the same variable for both and introduced a bug. So
where one of those got in my way, I've renamed it to 'toret' or 'retd'
(the latter short for 'returned') in line with my usual modern
practice, but I haven't done a thorough job of finding all of them.
Finally, one amusing side effect of doing this is that I've had to
separate quite a few chained assignments. It used to be perfectly fine
to write 'a = b = c = TRUE' when a,b,c were int and TRUE was just a
the 'true' defined by stdbool.h, that idiom provokes a warning from
gcc: 'suggest parentheses around assignment used as truth value'!
2018-11-02 19:23:19 +00:00
|
|
|
bool atmark;
|
2000-10-23 11:55:11 +00:00
|
|
|
|
|
|
|
/* wParam is the socket itself */
|
2002-12-08 11:00:47 +00:00
|
|
|
|
2003-01-09 19:26:12 +00:00
|
|
|
if (wParam == 0)
|
2019-09-08 19:29:00 +00:00
|
|
|
return; /* boggle */
|
2002-12-08 11:00:47 +00:00
|
|
|
|
2001-05-06 14:35:20 +00:00
|
|
|
s = find234(sktree, (void *) wParam, cmpforsearch);
|
2000-10-23 11:55:11 +00:00
|
|
|
if (!s)
|
2019-09-08 19:29:00 +00:00
|
|
|
return; /* boggle */
|
2000-10-23 11:55:11 +00:00
|
|
|
|
|
|
|
if ((err = WSAGETSELECTERROR(lParam)) != 0) {
|
2019-09-08 19:29:00 +00:00
|
|
|
/*
|
|
|
|
* An error has occurred on this socket. Pass it to the
|
|
|
|
* plug.
|
|
|
|
*/
|
|
|
|
if (s->addr) {
|
Get rid of lots of implicit pointer types.
All the main backend structures - Ssh, Telnet, Pty, Serial etc - now
describe structure types themselves rather than pointers to them. The
same goes for the codebase-wide trait types Socket and Plug, and the
supporting types SockAddr and Pinger.
All those things that were typedefed as pointers are older types; the
newer ones have the explicit * at the point of use, because that's
what I now seem to be preferring. But whichever one of those is
better, inconsistently using a mixture of the two styles is worse, so
let's make everything consistent.
A few types are still implicitly pointers, such as Bignum and some of
the GSSAPI types; generally this is either because they have to be
void *, or because they're typedefed differently on different
platforms and aren't always pointers at all. Can't be helped. But I've
got rid of the main ones, at least.
2018-10-04 18:10:23 +00:00
|
|
|
SockAddr thisaddr = sk_extractaddr_tmp(
|
2017-01-28 10:56:19 +00:00
|
|
|
s->addr, &s->step);
|
2020-02-07 19:17:45 +00:00
|
|
|
plug_log(s->plug, PLUGLOG_CONNECT_FAILED, &thisaddr, s->port,
|
2019-09-08 19:29:00 +00:00
|
|
|
winsock_error_string(err), err);
|
|
|
|
while (err && s->addr && sk_nextaddr(s->addr, &s->step)) {
|
|
|
|
err = try_connect(s);
|
|
|
|
}
|
|
|
|
}
|
|
|
|
if (err != 0)
|
|
|
|
plug_closing(s->plug, winsock_error_string(err), err, 0);
|
|
|
|
return;
|
2000-10-23 11:55:11 +00:00
|
|
|
}
|
|
|
|
|
2019-01-22 18:25:54 +00:00
|
|
|
noise_ultralight(NOISE_SOURCE_IOID, wParam);
|
2000-10-23 15:20:05 +00:00
|
|
|
|
2000-10-23 11:55:11 +00:00
|
|
|
switch (WSAGETSELECTEVENT(lParam)) {
|
2001-09-07 22:39:01 +00:00
|
|
|
case FD_CONNECT:
|
2019-09-08 19:29:00 +00:00
|
|
|
s->connected = true;
|
Convert a lot of 'int' variables to 'bool'.
My normal habit these days, in new code, is to treat int and bool as
_almost_ completely separate types. I'm still willing to use C's
implicit test for zero on an integer (e.g. 'if (!blob.len)' is fine,
no need to spell it out as blob.len != 0), but generally, if a
variable is going to be conceptually a boolean, I like to declare it
bool and assign to it using 'true' or 'false' rather than 0 or 1.
PuTTY is an exception, because it predates the C99 bool, and I've
stuck to its existing coding style even when adding new code to it.
But it's been annoying me more and more, so now that I've decided C99
bool is an acceptable thing to require from our toolchain in the first
place, here's a quite thorough trawl through the source doing
'boolification'. Many variables and function parameters are now typed
as bool rather than int; many assignments of 0 or 1 to those variables
are now spelled 'true' or 'false'.
I managed this thorough conversion with the help of a custom clang
plugin that I wrote to trawl the AST and apply heuristics to point out
where things might want changing. So I've even managed to do a decent
job on parts of the code I haven't looked at in years!
To make the plugin's work easier, I pushed platform front ends
generally in the direction of using standard 'bool' in preference to
platform-specific boolean types like Windows BOOL or GTK's gboolean;
I've left the platform booleans in places they _have_ to be for the
platform APIs to work right, but variables only used by my own code
have been converted wherever I found them.
In a few places there are int values that look very like booleans in
_most_ of the places they're used, but have a rarely-used third value,
or a distinction between different nonzero values that most users
don't care about. In these cases, I've _removed_ uses of 'true' and
'false' for the return values, to emphasise that there's something
more subtle going on than a simple boolean answer:
- the 'multisel' field in dialog.h's list box structure, for which
the GTK front end in particular recognises a difference between 1
and 2 but nearly everything else treats as boolean
- the 'urgent' parameter to plug_receive, where 1 vs 2 tells you
something about the specific location of the urgent pointer, but
most clients only care about 0 vs 'something nonzero'
- the return value of wc_match, where -1 indicates a syntax error in
the wildcard.
- the return values from SSH-1 RSA-key loading functions, which use
-1 for 'wrong passphrase' and 0 for all other failures (so any
caller which already knows it's not loading an _encrypted private_
key can treat them as boolean)
- term->esc_query, and the 'query' parameter in toggle_mode in
terminal.c, which _usually_ hold 0 for ESC[123h or 1 for ESC[?123h,
but can also hold -1 for some other intervening character that we
don't support.
In a few places there's an integer that I haven't turned into a bool
even though it really _can_ only take values 0 or 1 (and, as above,
tried to make the call sites consistent in not calling those values
true and false), on the grounds that I thought it would make it more
confusing to imply that the 0 value was in some sense 'negative' or
bad and the 1 positive or good:
- the return value of plug_accepting uses the POSIXish convention of
0=success and nonzero=error; I think if I made it bool then I'd
also want to reverse its sense, and that's a job for a separate
piece of work.
- the 'screen' parameter to lineptr() in terminal.c, where 0 and 1
represent the default and alternate screens. There's no obvious
reason why one of those should be considered 'true' or 'positive'
or 'success' - they're just indices - so I've left it as int.
ssh_scp_recv had particularly confusing semantics for its previous int
return value: its call sites used '<= 0' to check for error, but it
never actually returned a negative number, just 0 or 1. Now the
function and its call sites agree that it's a bool.
In a couple of places I've renamed variables called 'ret', because I
don't like that name any more - it's unclear whether it means the
return value (in preparation) for the _containing_ function or the
return value received from a subroutine call, and occasionally I've
accidentally used the same variable for both and introduced a bug. So
where one of those got in my way, I've renamed it to 'toret' or 'retd'
(the latter short for 'returned') in line with my usual modern
practice, but I haven't done a thorough job of finding all of them.
Finally, one amusing side effect of doing this is that I've had to
separate quite a few chained assignments. It used to be perfectly fine
to write 'a = b = c = TRUE' when a,b,c were int and TRUE was just a
the 'true' defined by stdbool.h, that idiom provokes a warning from
gcc: 'suggest parentheses around assignment used as truth value'!
2018-11-02 19:23:19 +00:00
|
|
|
s->writable = true;
|
2020-02-07 19:18:50 +00:00
|
|
|
|
2019-09-08 19:29:00 +00:00
|
|
|
/*
|
2020-02-07 19:18:50 +00:00
|
|
|
* Once a socket is connected, we can stop falling back
|
|
|
|
* through the candidate addresses to connect to. But first,
|
|
|
|
* let the plug know we were successful.
|
2019-09-08 19:29:00 +00:00
|
|
|
*/
|
|
|
|
if (s->addr) {
|
2020-02-07 19:18:50 +00:00
|
|
|
SockAddr thisaddr = sk_extractaddr_tmp(
|
|
|
|
s->addr, &s->step);
|
|
|
|
plug_log(s->plug, PLUGLOG_CONNECT_SUCCESS,
|
|
|
|
&thisaddr, s->port, NULL, 0);
|
|
|
|
|
2019-09-08 19:29:00 +00:00
|
|
|
sk_addr_free(s->addr);
|
|
|
|
s->addr = NULL;
|
|
|
|
}
|
|
|
|
break;
|
2000-10-23 11:55:11 +00:00
|
|
|
case FD_READ:
|
2019-09-08 19:29:00 +00:00
|
|
|
/* In the case the socket is still frozen, we don't even bother */
|
|
|
|
if (s->frozen) {
|
|
|
|
s->frozen_readable = true;
|
|
|
|
break;
|
|
|
|
}
|
|
|
|
|
|
|
|
/*
|
|
|
|
* We have received data on the socket. For an oobinline
|
|
|
|
* socket, this might be data _before_ an urgent pointer,
|
|
|
|
* in which case we send it to the back end with type==1
|
|
|
|
* (data prior to urgent).
|
|
|
|
*/
|
|
|
|
if (s->oobinline) {
|
Convert a lot of 'int' variables to 'bool'.
My normal habit these days, in new code, is to treat int and bool as
_almost_ completely separate types. I'm still willing to use C's
implicit test for zero on an integer (e.g. 'if (!blob.len)' is fine,
no need to spell it out as blob.len != 0), but generally, if a
variable is going to be conceptually a boolean, I like to declare it
bool and assign to it using 'true' or 'false' rather than 0 or 1.
PuTTY is an exception, because it predates the C99 bool, and I've
stuck to its existing coding style even when adding new code to it.
But it's been annoying me more and more, so now that I've decided C99
bool is an acceptable thing to require from our toolchain in the first
place, here's a quite thorough trawl through the source doing
'boolification'. Many variables and function parameters are now typed
as bool rather than int; many assignments of 0 or 1 to those variables
are now spelled 'true' or 'false'.
I managed this thorough conversion with the help of a custom clang
plugin that I wrote to trawl the AST and apply heuristics to point out
where things might want changing. So I've even managed to do a decent
job on parts of the code I haven't looked at in years!
To make the plugin's work easier, I pushed platform front ends
generally in the direction of using standard 'bool' in preference to
platform-specific boolean types like Windows BOOL or GTK's gboolean;
I've left the platform booleans in places they _have_ to be for the
platform APIs to work right, but variables only used by my own code
have been converted wherever I found them.
In a few places there are int values that look very like booleans in
_most_ of the places they're used, but have a rarely-used third value,
or a distinction between different nonzero values that most users
don't care about. In these cases, I've _removed_ uses of 'true' and
'false' for the return values, to emphasise that there's something
more subtle going on than a simple boolean answer:
- the 'multisel' field in dialog.h's list box structure, for which
the GTK front end in particular recognises a difference between 1
and 2 but nearly everything else treats as boolean
- the 'urgent' parameter to plug_receive, where 1 vs 2 tells you
something about the specific location of the urgent pointer, but
most clients only care about 0 vs 'something nonzero'
- the return value of wc_match, where -1 indicates a syntax error in
the wildcard.
- the return values from SSH-1 RSA-key loading functions, which use
-1 for 'wrong passphrase' and 0 for all other failures (so any
caller which already knows it's not loading an _encrypted private_
key can treat them as boolean)
- term->esc_query, and the 'query' parameter in toggle_mode in
terminal.c, which _usually_ hold 0 for ESC[123h or 1 for ESC[?123h,
but can also hold -1 for some other intervening character that we
don't support.
In a few places there's an integer that I haven't turned into a bool
even though it really _can_ only take values 0 or 1 (and, as above,
tried to make the call sites consistent in not calling those values
true and false), on the grounds that I thought it would make it more
confusing to imply that the 0 value was in some sense 'negative' or
bad and the 1 positive or good:
- the return value of plug_accepting uses the POSIXish convention of
0=success and nonzero=error; I think if I made it bool then I'd
also want to reverse its sense, and that's a job for a separate
piece of work.
- the 'screen' parameter to lineptr() in terminal.c, where 0 and 1
represent the default and alternate screens. There's no obvious
reason why one of those should be considered 'true' or 'positive'
or 'success' - they're just indices - so I've left it as int.
ssh_scp_recv had particularly confusing semantics for its previous int
return value: its call sites used '<= 0' to check for error, but it
never actually returned a negative number, just 0 or 1. Now the
function and its call sites agree that it's a bool.
In a couple of places I've renamed variables called 'ret', because I
don't like that name any more - it's unclear whether it means the
return value (in preparation) for the _containing_ function or the
return value received from a subroutine call, and occasionally I've
accidentally used the same variable for both and introduced a bug. So
where one of those got in my way, I've renamed it to 'toret' or 'retd'
(the latter short for 'returned') in line with my usual modern
practice, but I haven't done a thorough job of finding all of them.
Finally, one amusing side effect of doing this is that I've had to
separate quite a few chained assignments. It used to be perfectly fine
to write 'a = b = c = TRUE' when a,b,c were int and TRUE was just a
the 'true' defined by stdbool.h, that idiom provokes a warning from
gcc: 'suggest parentheses around assignment used as truth value'!
2018-11-02 19:23:19 +00:00
|
|
|
u_long atmark_from_ioctl = 1;
|
2019-09-08 19:29:00 +00:00
|
|
|
p_ioctlsocket(s->s, SIOCATMARK, &atmark_from_ioctl);
|
|
|
|
/*
|
|
|
|
* Avoid checking the return value from ioctlsocket(),
|
|
|
|
* on the grounds that some WinSock wrappers don't
|
|
|
|
* support it. If it does nothing, we get atmark==1,
|
|
|
|
* which is equivalent to `no OOB pending', so the
|
|
|
|
* effect will be to non-OOB-ify any OOB data.
|
|
|
|
*/
|
Convert a lot of 'int' variables to 'bool'.
My normal habit these days, in new code, is to treat int and bool as
_almost_ completely separate types. I'm still willing to use C's
implicit test for zero on an integer (e.g. 'if (!blob.len)' is fine,
no need to spell it out as blob.len != 0), but generally, if a
variable is going to be conceptually a boolean, I like to declare it
bool and assign to it using 'true' or 'false' rather than 0 or 1.
PuTTY is an exception, because it predates the C99 bool, and I've
stuck to its existing coding style even when adding new code to it.
But it's been annoying me more and more, so now that I've decided C99
bool is an acceptable thing to require from our toolchain in the first
place, here's a quite thorough trawl through the source doing
'boolification'. Many variables and function parameters are now typed
as bool rather than int; many assignments of 0 or 1 to those variables
are now spelled 'true' or 'false'.
I managed this thorough conversion with the help of a custom clang
plugin that I wrote to trawl the AST and apply heuristics to point out
where things might want changing. So I've even managed to do a decent
job on parts of the code I haven't looked at in years!
To make the plugin's work easier, I pushed platform front ends
generally in the direction of using standard 'bool' in preference to
platform-specific boolean types like Windows BOOL or GTK's gboolean;
I've left the platform booleans in places they _have_ to be for the
platform APIs to work right, but variables only used by my own code
have been converted wherever I found them.
In a few places there are int values that look very like booleans in
_most_ of the places they're used, but have a rarely-used third value,
or a distinction between different nonzero values that most users
don't care about. In these cases, I've _removed_ uses of 'true' and
'false' for the return values, to emphasise that there's something
more subtle going on than a simple boolean answer:
- the 'multisel' field in dialog.h's list box structure, for which
the GTK front end in particular recognises a difference between 1
and 2 but nearly everything else treats as boolean
- the 'urgent' parameter to plug_receive, where 1 vs 2 tells you
something about the specific location of the urgent pointer, but
most clients only care about 0 vs 'something nonzero'
- the return value of wc_match, where -1 indicates a syntax error in
the wildcard.
- the return values from SSH-1 RSA-key loading functions, which use
-1 for 'wrong passphrase' and 0 for all other failures (so any
caller which already knows it's not loading an _encrypted private_
key can treat them as boolean)
- term->esc_query, and the 'query' parameter in toggle_mode in
terminal.c, which _usually_ hold 0 for ESC[123h or 1 for ESC[?123h,
but can also hold -1 for some other intervening character that we
don't support.
In a few places there's an integer that I haven't turned into a bool
even though it really _can_ only take values 0 or 1 (and, as above,
tried to make the call sites consistent in not calling those values
true and false), on the grounds that I thought it would make it more
confusing to imply that the 0 value was in some sense 'negative' or
bad and the 1 positive or good:
- the return value of plug_accepting uses the POSIXish convention of
0=success and nonzero=error; I think if I made it bool then I'd
also want to reverse its sense, and that's a job for a separate
piece of work.
- the 'screen' parameter to lineptr() in terminal.c, where 0 and 1
represent the default and alternate screens. There's no obvious
reason why one of those should be considered 'true' or 'positive'
or 'success' - they're just indices - so I've left it as int.
ssh_scp_recv had particularly confusing semantics for its previous int
return value: its call sites used '<= 0' to check for error, but it
never actually returned a negative number, just 0 or 1. Now the
function and its call sites agree that it's a bool.
In a couple of places I've renamed variables called 'ret', because I
don't like that name any more - it's unclear whether it means the
return value (in preparation) for the _containing_ function or the
return value received from a subroutine call, and occasionally I've
accidentally used the same variable for both and introduced a bug. So
where one of those got in my way, I've renamed it to 'toret' or 'retd'
(the latter short for 'returned') in line with my usual modern
practice, but I haven't done a thorough job of finding all of them.
Finally, one amusing side effect of doing this is that I've had to
separate quite a few chained assignments. It used to be perfectly fine
to write 'a = b = c = TRUE' when a,b,c were int and TRUE was just a
the 'true' defined by stdbool.h, that idiom provokes a warning from
gcc: 'suggest parentheses around assignment used as truth value'!
2018-11-02 19:23:19 +00:00
|
|
|
atmark = atmark_from_ioctl;
|
2019-09-08 19:29:00 +00:00
|
|
|
} else
|
|
|
|
atmark = true;
|
|
|
|
|
|
|
|
ret = p_recv(s->s, buf, sizeof(buf), 0);
|
|
|
|
noise_ultralight(NOISE_SOURCE_IOLEN, ret);
|
|
|
|
if (ret < 0) {
|
|
|
|
err = p_WSAGetLastError();
|
|
|
|
if (err == WSAEWOULDBLOCK) {
|
|
|
|
break;
|
|
|
|
}
|
|
|
|
}
|
|
|
|
if (ret < 0) {
|
|
|
|
plug_closing(s->plug, winsock_error_string(err), err, 0);
|
|
|
|
} else if (0 == ret) {
|
|
|
|
plug_closing(s->plug, NULL, 0, 0);
|
|
|
|
} else {
|
|
|
|
plug_receive(s->plug, atmark ? 0 : 1, buf, ret);
|
|
|
|
}
|
|
|
|
break;
|
2000-10-23 11:55:11 +00:00
|
|
|
case FD_OOB:
|
2019-09-08 19:29:00 +00:00
|
|
|
/*
|
|
|
|
* This will only happen on a non-oobinline socket. It
|
|
|
|
* indicates that we can immediately perform an OOB read
|
|
|
|
* and get back OOB data, which we will send to the back
|
|
|
|
* end with type==2 (urgent data).
|
|
|
|
*/
|
|
|
|
ret = p_recv(s->s, buf, sizeof(buf), MSG_OOB);
|
|
|
|
noise_ultralight(NOISE_SOURCE_IOLEN, ret);
|
|
|
|
if (ret <= 0) {
|
2017-11-26 17:43:02 +00:00
|
|
|
int err = p_WSAGetLastError();
|
2019-09-08 19:29:00 +00:00
|
|
|
plug_closing(s->plug, winsock_error_string(err), err, 0);
|
|
|
|
} else {
|
|
|
|
plug_receive(s->plug, 2, buf, ret);
|
|
|
|
}
|
|
|
|
break;
|
Formatting change to braces around one case of a switch.
Sometimes, within a switch statement, you want to declare local
variables specific to the handler for one particular case. Until now
I've mostly been writing this in the form
switch (discriminant) {
case SIMPLE:
do stuff;
break;
case COMPLICATED:
{
declare variables;
do stuff;
}
break;
}
which is ugly because the two pieces of essentially similar code
appear at different indent levels, and also inconvenient because you
have less horizontal space available to write the complicated case
handler in - particuarly undesirable because _complicated_ case
handlers are the ones most likely to need all the space they can get!
After encountering a rather nicer idiom in the LLVM source code, and
after a bit of hackery this morning figuring out how to persuade
Emacs's auto-indent to do what I wanted with it, I've decided to move
to an idiom in which the open brace comes right after the case
statement, and the code within it is indented the same as it would
have been without the brace. Then the whole case handler (including
the break) lives inside those braces, and you get something that looks
more like this:
switch (discriminant) {
case SIMPLE:
do stuff;
break;
case COMPLICATED: {
declare variables;
do stuff;
break;
}
}
This commit is a big-bang change that reformats all the complicated
case handlers I could find into the new layout. This is particularly
nice in the Pageant main function, in which almost _every_ case
handler had a bundle of variables and was long and complicated. (In
fact that's what motivated me to get round to this.) Some of the
innermost parts of the terminal escape-sequence handling are also
breathing a bit easier now the horizontal pressure on them is
relieved.
(Also, in a few cases, I was able to remove the extra braces
completely, because the only variable local to the case handler was a
loop variable which our new C99 policy allows me to move into the
initialiser clause of its for statement.)
Viewed with whitespace ignored, this is not too disruptive a change.
Downstream patches that conflict with it may need to be reapplied
using --ignore-whitespace or similar.
2020-02-16 07:49:52 +00:00
|
|
|
case FD_WRITE: {
|
|
|
|
int bufsize_before, bufsize_after;
|
|
|
|
s->writable = true;
|
|
|
|
bufsize_before = s->sending_oob + bufchain_size(&s->output_data);
|
|
|
|
try_send(s);
|
|
|
|
bufsize_after = s->sending_oob + bufchain_size(&s->output_data);
|
|
|
|
if (bufsize_after < bufsize_before)
|
|
|
|
plug_sent(s->plug, bufsize_after);
|
2019-09-08 19:29:00 +00:00
|
|
|
break;
|
Formatting change to braces around one case of a switch.
Sometimes, within a switch statement, you want to declare local
variables specific to the handler for one particular case. Until now
I've mostly been writing this in the form
switch (discriminant) {
case SIMPLE:
do stuff;
break;
case COMPLICATED:
{
declare variables;
do stuff;
}
break;
}
which is ugly because the two pieces of essentially similar code
appear at different indent levels, and also inconvenient because you
have less horizontal space available to write the complicated case
handler in - particuarly undesirable because _complicated_ case
handlers are the ones most likely to need all the space they can get!
After encountering a rather nicer idiom in the LLVM source code, and
after a bit of hackery this morning figuring out how to persuade
Emacs's auto-indent to do what I wanted with it, I've decided to move
to an idiom in which the open brace comes right after the case
statement, and the code within it is indented the same as it would
have been without the brace. Then the whole case handler (including
the break) lives inside those braces, and you get something that looks
more like this:
switch (discriminant) {
case SIMPLE:
do stuff;
break;
case COMPLICATED: {
declare variables;
do stuff;
break;
}
}
This commit is a big-bang change that reformats all the complicated
case handlers I could find into the new layout. This is particularly
nice in the Pageant main function, in which almost _every_ case
handler had a bundle of variables and was long and complicated. (In
fact that's what motivated me to get round to this.) Some of the
innermost parts of the terminal escape-sequence handling are also
breathing a bit easier now the horizontal pressure on them is
relieved.
(Also, in a few cases, I was able to remove the extra braces
completely, because the only variable local to the case handler was a
loop variable which our new C99 policy allows me to move into the
initialiser clause of its for statement.)
Viewed with whitespace ignored, this is not too disruptive a change.
Downstream patches that conflict with it may need to be reapplied
using --ignore-whitespace or similar.
2020-02-16 07:49:52 +00:00
|
|
|
}
|
2000-10-23 11:55:11 +00:00
|
|
|
case FD_CLOSE:
|
2019-09-08 19:29:00 +00:00
|
|
|
/* Signal a close on the socket. First read any outstanding data. */
|
|
|
|
do {
|
|
|
|
ret = p_recv(s->s, buf, sizeof(buf), 0);
|
|
|
|
if (ret < 0) {
|
|
|
|
err = p_WSAGetLastError();
|
|
|
|
if (err == WSAEWOULDBLOCK)
|
|
|
|
break;
|
|
|
|
plug_closing(s->plug, winsock_error_string(err), err, 0);
|
|
|
|
} else {
|
|
|
|
if (ret)
|
|
|
|
plug_receive(s->plug, 0, buf, ret);
|
|
|
|
else
|
|
|
|
plug_closing(s->plug, NULL, 0, 0);
|
|
|
|
}
|
|
|
|
} while (ret > 0);
|
|
|
|
return;
|
Formatting change to braces around one case of a switch.
Sometimes, within a switch statement, you want to declare local
variables specific to the handler for one particular case. Until now
I've mostly been writing this in the form
switch (discriminant) {
case SIMPLE:
do stuff;
break;
case COMPLICATED:
{
declare variables;
do stuff;
}
break;
}
which is ugly because the two pieces of essentially similar code
appear at different indent levels, and also inconvenient because you
have less horizontal space available to write the complicated case
handler in - particuarly undesirable because _complicated_ case
handlers are the ones most likely to need all the space they can get!
After encountering a rather nicer idiom in the LLVM source code, and
after a bit of hackery this morning figuring out how to persuade
Emacs's auto-indent to do what I wanted with it, I've decided to move
to an idiom in which the open brace comes right after the case
statement, and the code within it is indented the same as it would
have been without the brace. Then the whole case handler (including
the break) lives inside those braces, and you get something that looks
more like this:
switch (discriminant) {
case SIMPLE:
do stuff;
break;
case COMPLICATED: {
declare variables;
do stuff;
break;
}
}
This commit is a big-bang change that reformats all the complicated
case handlers I could find into the new layout. This is particularly
nice in the Pageant main function, in which almost _every_ case
handler had a bundle of variables and was long and complicated. (In
fact that's what motivated me to get round to this.) Some of the
innermost parts of the terminal escape-sequence handling are also
breathing a bit easier now the horizontal pressure on them is
relieved.
(Also, in a few cases, I was able to remove the extra braces
completely, because the only variable local to the case handler was a
loop variable which our new C99 policy allows me to move into the
initialiser clause of its for statement.)
Viewed with whitespace ignored, this is not too disruptive a change.
Downstream patches that conflict with it may need to be reapplied
using --ignore-whitespace or similar.
2020-02-16 07:49:52 +00:00
|
|
|
case FD_ACCEPT: {
|
2004-12-30 16:45:11 +00:00
|
|
|
#ifdef NO_IPV6
|
Formatting change to braces around one case of a switch.
Sometimes, within a switch statement, you want to declare local
variables specific to the handler for one particular case. Until now
I've mostly been writing this in the form
switch (discriminant) {
case SIMPLE:
do stuff;
break;
case COMPLICATED:
{
declare variables;
do stuff;
}
break;
}
which is ugly because the two pieces of essentially similar code
appear at different indent levels, and also inconvenient because you
have less horizontal space available to write the complicated case
handler in - particuarly undesirable because _complicated_ case
handlers are the ones most likely to need all the space they can get!
After encountering a rather nicer idiom in the LLVM source code, and
after a bit of hackery this morning figuring out how to persuade
Emacs's auto-indent to do what I wanted with it, I've decided to move
to an idiom in which the open brace comes right after the case
statement, and the code within it is indented the same as it would
have been without the brace. Then the whole case handler (including
the break) lives inside those braces, and you get something that looks
more like this:
switch (discriminant) {
case SIMPLE:
do stuff;
break;
case COMPLICATED: {
declare variables;
do stuff;
break;
}
}
This commit is a big-bang change that reformats all the complicated
case handlers I could find into the new layout. This is particularly
nice in the Pageant main function, in which almost _every_ case
handler had a bundle of variables and was long and complicated. (In
fact that's what motivated me to get round to this.) Some of the
innermost parts of the terminal escape-sequence handling are also
breathing a bit easier now the horizontal pressure on them is
relieved.
(Also, in a few cases, I was able to remove the extra braces
completely, because the only variable local to the case handler was a
loop variable which our new C99 policy allows me to move into the
initialiser clause of its for statement.)
Viewed with whitespace ignored, this is not too disruptive a change.
Downstream patches that conflict with it may need to be reapplied
using --ignore-whitespace or similar.
2020-02-16 07:49:52 +00:00
|
|
|
struct sockaddr_in isa;
|
2004-12-30 16:45:11 +00:00
|
|
|
#else
|
Formatting change to braces around one case of a switch.
Sometimes, within a switch statement, you want to declare local
variables specific to the handler for one particular case. Until now
I've mostly been writing this in the form
switch (discriminant) {
case SIMPLE:
do stuff;
break;
case COMPLICATED:
{
declare variables;
do stuff;
}
break;
}
which is ugly because the two pieces of essentially similar code
appear at different indent levels, and also inconvenient because you
have less horizontal space available to write the complicated case
handler in - particuarly undesirable because _complicated_ case
handlers are the ones most likely to need all the space they can get!
After encountering a rather nicer idiom in the LLVM source code, and
after a bit of hackery this morning figuring out how to persuade
Emacs's auto-indent to do what I wanted with it, I've decided to move
to an idiom in which the open brace comes right after the case
statement, and the code within it is indented the same as it would
have been without the brace. Then the whole case handler (including
the break) lives inside those braces, and you get something that looks
more like this:
switch (discriminant) {
case SIMPLE:
do stuff;
break;
case COMPLICATED: {
declare variables;
do stuff;
break;
}
}
This commit is a big-bang change that reformats all the complicated
case handlers I could find into the new layout. This is particularly
nice in the Pageant main function, in which almost _every_ case
handler had a bundle of variables and was long and complicated. (In
fact that's what motivated me to get round to this.) Some of the
innermost parts of the terminal escape-sequence handling are also
breathing a bit easier now the horizontal pressure on them is
relieved.
(Also, in a few cases, I was able to remove the extra braces
completely, because the only variable local to the case handler was a
loop variable which our new C99 policy allows me to move into the
initialiser clause of its for statement.)
Viewed with whitespace ignored, this is not too disruptive a change.
Downstream patches that conflict with it may need to be reapplied
using --ignore-whitespace or similar.
2020-02-16 07:49:52 +00:00
|
|
|
struct sockaddr_storage isa;
|
2004-12-30 16:45:11 +00:00
|
|
|
#endif
|
Formatting change to braces around one case of a switch.
Sometimes, within a switch statement, you want to declare local
variables specific to the handler for one particular case. Until now
I've mostly been writing this in the form
switch (discriminant) {
case SIMPLE:
do stuff;
break;
case COMPLICATED:
{
declare variables;
do stuff;
}
break;
}
which is ugly because the two pieces of essentially similar code
appear at different indent levels, and also inconvenient because you
have less horizontal space available to write the complicated case
handler in - particuarly undesirable because _complicated_ case
handlers are the ones most likely to need all the space they can get!
After encountering a rather nicer idiom in the LLVM source code, and
after a bit of hackery this morning figuring out how to persuade
Emacs's auto-indent to do what I wanted with it, I've decided to move
to an idiom in which the open brace comes right after the case
statement, and the code within it is indented the same as it would
have been without the brace. Then the whole case handler (including
the break) lives inside those braces, and you get something that looks
more like this:
switch (discriminant) {
case SIMPLE:
do stuff;
break;
case COMPLICATED: {
declare variables;
do stuff;
break;
}
}
This commit is a big-bang change that reformats all the complicated
case handlers I could find into the new layout. This is particularly
nice in the Pageant main function, in which almost _every_ case
handler had a bundle of variables and was long and complicated. (In
fact that's what motivated me to get round to this.) Some of the
innermost parts of the terminal escape-sequence handling are also
breathing a bit easier now the horizontal pressure on them is
relieved.
(Also, in a few cases, I was able to remove the extra braces
completely, because the only variable local to the case handler was a
loop variable which our new C99 policy allows me to move into the
initialiser clause of its for statement.)
Viewed with whitespace ignored, this is not too disruptive a change.
Downstream patches that conflict with it may need to be reapplied
using --ignore-whitespace or similar.
2020-02-16 07:49:52 +00:00
|
|
|
int addrlen = sizeof(isa);
|
|
|
|
SOCKET t; /* socket of connection */
|
|
|
|
accept_ctx_t actx;
|
|
|
|
|
|
|
|
memset(&isa, 0, sizeof(isa));
|
|
|
|
err = 0;
|
|
|
|
t = p_accept(s->s,(struct sockaddr *)&isa,&addrlen);
|
|
|
|
if (t == INVALID_SOCKET)
|
|
|
|
{
|
|
|
|
err = p_WSAGetLastError();
|
|
|
|
if (err == WSATRY_AGAIN)
|
|
|
|
break;
|
|
|
|
}
|
2013-11-17 14:03:55 +00:00
|
|
|
|
Formatting change to braces around one case of a switch.
Sometimes, within a switch statement, you want to declare local
variables specific to the handler for one particular case. Until now
I've mostly been writing this in the form
switch (discriminant) {
case SIMPLE:
do stuff;
break;
case COMPLICATED:
{
declare variables;
do stuff;
}
break;
}
which is ugly because the two pieces of essentially similar code
appear at different indent levels, and also inconvenient because you
have less horizontal space available to write the complicated case
handler in - particuarly undesirable because _complicated_ case
handlers are the ones most likely to need all the space they can get!
After encountering a rather nicer idiom in the LLVM source code, and
after a bit of hackery this morning figuring out how to persuade
Emacs's auto-indent to do what I wanted with it, I've decided to move
to an idiom in which the open brace comes right after the case
statement, and the code within it is indented the same as it would
have been without the brace. Then the whole case handler (including
the break) lives inside those braces, and you get something that looks
more like this:
switch (discriminant) {
case SIMPLE:
do stuff;
break;
case COMPLICATED: {
declare variables;
do stuff;
break;
}
}
This commit is a big-bang change that reformats all the complicated
case handlers I could find into the new layout. This is particularly
nice in the Pageant main function, in which almost _every_ case
handler had a bundle of variables and was long and complicated. (In
fact that's what motivated me to get round to this.) Some of the
innermost parts of the terminal escape-sequence handling are also
breathing a bit easier now the horizontal pressure on them is
relieved.
(Also, in a few cases, I was able to remove the extra braces
completely, because the only variable local to the case handler was a
loop variable which our new C99 policy allows me to move into the
initialiser clause of its for statement.)
Viewed with whitespace ignored, this is not too disruptive a change.
Downstream patches that conflict with it may need to be reapplied
using --ignore-whitespace or similar.
2020-02-16 07:49:52 +00:00
|
|
|
actx.p = (void *)t;
|
2013-11-17 14:03:55 +00:00
|
|
|
|
2004-12-30 16:45:11 +00:00
|
|
|
#ifndef NO_IPV6
|
Formatting change to braces around one case of a switch.
Sometimes, within a switch statement, you want to declare local
variables specific to the handler for one particular case. Until now
I've mostly been writing this in the form
switch (discriminant) {
case SIMPLE:
do stuff;
break;
case COMPLICATED:
{
declare variables;
do stuff;
}
break;
}
which is ugly because the two pieces of essentially similar code
appear at different indent levels, and also inconvenient because you
have less horizontal space available to write the complicated case
handler in - particuarly undesirable because _complicated_ case
handlers are the ones most likely to need all the space they can get!
After encountering a rather nicer idiom in the LLVM source code, and
after a bit of hackery this morning figuring out how to persuade
Emacs's auto-indent to do what I wanted with it, I've decided to move
to an idiom in which the open brace comes right after the case
statement, and the code within it is indented the same as it would
have been without the brace. Then the whole case handler (including
the break) lives inside those braces, and you get something that looks
more like this:
switch (discriminant) {
case SIMPLE:
do stuff;
break;
case COMPLICATED: {
declare variables;
do stuff;
break;
}
}
This commit is a big-bang change that reformats all the complicated
case handlers I could find into the new layout. This is particularly
nice in the Pageant main function, in which almost _every_ case
handler had a bundle of variables and was long and complicated. (In
fact that's what motivated me to get round to this.) Some of the
innermost parts of the terminal escape-sequence handling are also
breathing a bit easier now the horizontal pressure on them is
relieved.
(Also, in a few cases, I was able to remove the extra braces
completely, because the only variable local to the case handler was a
loop variable which our new C99 policy allows me to move into the
initialiser clause of its for statement.)
Viewed with whitespace ignored, this is not too disruptive a change.
Downstream patches that conflict with it may need to be reapplied
using --ignore-whitespace or similar.
2020-02-16 07:49:52 +00:00
|
|
|
if (isa.ss_family == AF_INET &&
|
|
|
|
s->localhost_only &&
|
|
|
|
!ipv4_is_local_addr(((struct sockaddr_in *)&isa)->sin_addr))
|
2004-12-30 16:45:11 +00:00
|
|
|
#else
|
Formatting change to braces around one case of a switch.
Sometimes, within a switch statement, you want to declare local
variables specific to the handler for one particular case. Until now
I've mostly been writing this in the form
switch (discriminant) {
case SIMPLE:
do stuff;
break;
case COMPLICATED:
{
declare variables;
do stuff;
}
break;
}
which is ugly because the two pieces of essentially similar code
appear at different indent levels, and also inconvenient because you
have less horizontal space available to write the complicated case
handler in - particuarly undesirable because _complicated_ case
handlers are the ones most likely to need all the space they can get!
After encountering a rather nicer idiom in the LLVM source code, and
after a bit of hackery this morning figuring out how to persuade
Emacs's auto-indent to do what I wanted with it, I've decided to move
to an idiom in which the open brace comes right after the case
statement, and the code within it is indented the same as it would
have been without the brace. Then the whole case handler (including
the break) lives inside those braces, and you get something that looks
more like this:
switch (discriminant) {
case SIMPLE:
do stuff;
break;
case COMPLICATED: {
declare variables;
do stuff;
break;
}
}
This commit is a big-bang change that reformats all the complicated
case handlers I could find into the new layout. This is particularly
nice in the Pageant main function, in which almost _every_ case
handler had a bundle of variables and was long and complicated. (In
fact that's what motivated me to get round to this.) Some of the
innermost parts of the terminal escape-sequence handling are also
breathing a bit easier now the horizontal pressure on them is
relieved.
(Also, in a few cases, I was able to remove the extra braces
completely, because the only variable local to the case handler was a
loop variable which our new C99 policy allows me to move into the
initialiser clause of its for statement.)
Viewed with whitespace ignored, this is not too disruptive a change.
Downstream patches that conflict with it may need to be reapplied
using --ignore-whitespace or similar.
2020-02-16 07:49:52 +00:00
|
|
|
if (s->localhost_only && !ipv4_is_local_addr(isa.sin_addr))
|
2004-12-30 16:45:11 +00:00
|
|
|
#endif
|
Formatting change to braces around one case of a switch.
Sometimes, within a switch statement, you want to declare local
variables specific to the handler for one particular case. Until now
I've mostly been writing this in the form
switch (discriminant) {
case SIMPLE:
do stuff;
break;
case COMPLICATED:
{
declare variables;
do stuff;
}
break;
}
which is ugly because the two pieces of essentially similar code
appear at different indent levels, and also inconvenient because you
have less horizontal space available to write the complicated case
handler in - particuarly undesirable because _complicated_ case
handlers are the ones most likely to need all the space they can get!
After encountering a rather nicer idiom in the LLVM source code, and
after a bit of hackery this morning figuring out how to persuade
Emacs's auto-indent to do what I wanted with it, I've decided to move
to an idiom in which the open brace comes right after the case
statement, and the code within it is indented the same as it would
have been without the brace. Then the whole case handler (including
the break) lives inside those braces, and you get something that looks
more like this:
switch (discriminant) {
case SIMPLE:
do stuff;
break;
case COMPLICATED: {
declare variables;
do stuff;
break;
}
}
This commit is a big-bang change that reformats all the complicated
case handlers I could find into the new layout. This is particularly
nice in the Pageant main function, in which almost _every_ case
handler had a bundle of variables and was long and complicated. (In
fact that's what motivated me to get round to this.) Some of the
innermost parts of the terminal escape-sequence handling are also
breathing a bit easier now the horizontal pressure on them is
relieved.
(Also, in a few cases, I was able to remove the extra braces
completely, because the only variable local to the case handler was a
loop variable which our new C99 policy allows me to move into the
initialiser clause of its for statement.)
Viewed with whitespace ignored, this is not too disruptive a change.
Downstream patches that conflict with it may need to be reapplied
using --ignore-whitespace or similar.
2020-02-16 07:49:52 +00:00
|
|
|
{
|
|
|
|
p_closesocket(t); /* dodgy WinSock let nonlocal through */
|
|
|
|
} else if (plug_accepting(s->plug, sk_net_accept, actx)) {
|
|
|
|
p_closesocket(t); /* denied or error */
|
2019-09-08 19:29:00 +00:00
|
|
|
}
|
Formatting change to braces around one case of a switch.
Sometimes, within a switch statement, you want to declare local
variables specific to the handler for one particular case. Until now
I've mostly been writing this in the form
switch (discriminant) {
case SIMPLE:
do stuff;
break;
case COMPLICATED:
{
declare variables;
do stuff;
}
break;
}
which is ugly because the two pieces of essentially similar code
appear at different indent levels, and also inconvenient because you
have less horizontal space available to write the complicated case
handler in - particuarly undesirable because _complicated_ case
handlers are the ones most likely to need all the space they can get!
After encountering a rather nicer idiom in the LLVM source code, and
after a bit of hackery this morning figuring out how to persuade
Emacs's auto-indent to do what I wanted with it, I've decided to move
to an idiom in which the open brace comes right after the case
statement, and the code within it is indented the same as it would
have been without the brace. Then the whole case handler (including
the break) lives inside those braces, and you get something that looks
more like this:
switch (discriminant) {
case SIMPLE:
do stuff;
break;
case COMPLICATED: {
declare variables;
do stuff;
break;
}
}
This commit is a big-bang change that reformats all the complicated
case handlers I could find into the new layout. This is particularly
nice in the Pageant main function, in which almost _every_ case
handler had a bundle of variables and was long and complicated. (In
fact that's what motivated me to get round to this.) Some of the
innermost parts of the terminal escape-sequence handling are also
breathing a bit easier now the horizontal pressure on them is
relieved.
(Also, in a few cases, I was able to remove the extra braces
completely, because the only variable local to the case handler was a
loop variable which our new C99 policy allows me to move into the
initialiser clause of its for statement.)
Viewed with whitespace ignored, this is not too disruptive a change.
Downstream patches that conflict with it may need to be reapplied
using --ignore-whitespace or similar.
2020-02-16 07:49:52 +00:00
|
|
|
break;
|
|
|
|
}
|
2000-10-23 11:55:11 +00:00
|
|
|
}
|
|
|
|
}
|
|
|
|
|
|
|
|
/*
|
|
|
|
* Special error values are returned from sk_namelookup and sk_new
|
|
|
|
* if there's a problem. These functions extract an error message,
|
|
|
|
* or return NULL if there's no problem.
|
|
|
|
*/
|
Get rid of lots of implicit pointer types.
All the main backend structures - Ssh, Telnet, Pty, Serial etc - now
describe structure types themselves rather than pointers to them. The
same goes for the codebase-wide trait types Socket and Plug, and the
supporting types SockAddr and Pinger.
All those things that were typedefed as pointers are older types; the
newer ones have the explicit * at the point of use, because that's
what I now seem to be preferring. But whichever one of those is
better, inconsistently using a mixture of the two styles is worse, so
let's make everything consistent.
A few types are still implicitly pointers, such as Bignum and some of
the GSSAPI types; generally this is either because they have to be
void *, or because they're typedefed differently on different
platforms and aren't always pointers at all. Can't be helped. But I've
got rid of the main ones, at least.
2018-10-04 18:10:23 +00:00
|
|
|
const char *sk_addr_error(SockAddr *addr)
|
2001-05-06 14:35:20 +00:00
|
|
|
{
|
2000-10-23 11:55:11 +00:00
|
|
|
return addr->error;
|
|
|
|
}
|
Get rid of lots of implicit pointer types.
All the main backend structures - Ssh, Telnet, Pty, Serial etc - now
describe structure types themselves rather than pointers to them. The
same goes for the codebase-wide trait types Socket and Plug, and the
supporting types SockAddr and Pinger.
All those things that were typedefed as pointers are older types; the
newer ones have the explicit * at the point of use, because that's
what I now seem to be preferring. But whichever one of those is
better, inconsistently using a mixture of the two styles is worse, so
let's make everything consistent.
A few types are still implicitly pointers, such as Bignum and some of
the GSSAPI types; generally this is either because they have to be
void *, or because they're typedefed differently on different
platforms and aren't always pointers at all. Can't be helped. But I've
got rid of the main ones, at least.
2018-10-04 18:10:23 +00:00
|
|
|
static const char *sk_net_socket_error(Socket *sock)
|
2001-05-06 14:35:20 +00:00
|
|
|
{
|
2018-10-05 22:49:08 +00:00
|
|
|
NetSocket *s = container_of(sock, NetSocket, sock);
|
2000-10-23 11:55:11 +00:00
|
|
|
return s->error;
|
|
|
|
}
|
|
|
|
|
2018-10-18 19:06:42 +00:00
|
|
|
static SocketPeerInfo *sk_net_peer_info(Socket *sock)
|
2015-05-18 12:57:45 +00:00
|
|
|
{
|
2018-10-05 22:49:08 +00:00
|
|
|
NetSocket *s = container_of(sock, NetSocket, sock);
|
2015-05-18 12:57:45 +00:00
|
|
|
#ifdef NO_IPV6
|
|
|
|
struct sockaddr_in addr;
|
|
|
|
#else
|
|
|
|
struct sockaddr_storage addr;
|
2016-12-11 22:27:40 +00:00
|
|
|
char buf[INET6_ADDRSTRLEN];
|
2015-05-18 12:57:45 +00:00
|
|
|
#endif
|
|
|
|
int addrlen = sizeof(addr);
|
2018-10-18 19:06:42 +00:00
|
|
|
SocketPeerInfo *pi;
|
2015-05-18 12:57:45 +00:00
|
|
|
|
|
|
|
if (p_getpeername(s->s, (struct sockaddr *)&addr, &addrlen) < 0)
|
|
|
|
return NULL;
|
|
|
|
|
2018-10-18 19:06:42 +00:00
|
|
|
pi = snew(SocketPeerInfo);
|
|
|
|
pi->addressfamily = ADDRTYPE_UNSPEC;
|
|
|
|
pi->addr_text = NULL;
|
|
|
|
pi->port = -1;
|
|
|
|
pi->log_text = NULL;
|
|
|
|
|
2015-05-18 12:57:45 +00:00
|
|
|
if (((struct sockaddr *)&addr)->sa_family == AF_INET) {
|
2018-10-18 19:06:42 +00:00
|
|
|
pi->addressfamily = ADDRTYPE_IPV4;
|
|
|
|
memcpy(pi->addr_bin.ipv4, &((struct sockaddr_in *)&addr)->sin_addr, 4);
|
|
|
|
pi->port = p_ntohs(((struct sockaddr_in *)&addr)->sin_port);
|
|
|
|
pi->addr_text = dupstr(
|
|
|
|
p_inet_ntoa(((struct sockaddr_in *)&addr)->sin_addr));
|
|
|
|
pi->log_text = dupprintf("%s:%d", pi->addr_text, pi->port);
|
|
|
|
|
2015-05-18 12:57:45 +00:00
|
|
|
#ifndef NO_IPV6
|
|
|
|
} else if (((struct sockaddr *)&addr)->sa_family == AF_INET6) {
|
2018-10-18 19:06:42 +00:00
|
|
|
pi->addressfamily = ADDRTYPE_IPV6;
|
|
|
|
memcpy(pi->addr_bin.ipv6,
|
|
|
|
&((struct sockaddr_in6 *)&addr)->sin6_addr, 16);
|
|
|
|
pi->port = p_ntohs(((struct sockaddr_in6 *)&addr)->sin6_port);
|
|
|
|
pi->addr_text = dupstr(
|
|
|
|
p_inet_ntop(AF_INET6, &((struct sockaddr_in6 *)&addr)->sin6_addr,
|
|
|
|
buf, sizeof(buf)));
|
|
|
|
pi->log_text = dupprintf("[%s]:%d", pi->addr_text, pi->port);
|
|
|
|
|
2015-05-18 12:57:45 +00:00
|
|
|
#endif
|
|
|
|
} else {
|
2018-10-18 19:06:42 +00:00
|
|
|
sfree(pi);
|
2015-05-18 12:57:45 +00:00
|
|
|
return NULL;
|
|
|
|
}
|
2018-10-18 19:06:42 +00:00
|
|
|
|
|
|
|
return pi;
|
2015-05-18 12:57:45 +00:00
|
|
|
}
|
|
|
|
|
Convert a lot of 'int' variables to 'bool'.
My normal habit these days, in new code, is to treat int and bool as
_almost_ completely separate types. I'm still willing to use C's
implicit test for zero on an integer (e.g. 'if (!blob.len)' is fine,
no need to spell it out as blob.len != 0), but generally, if a
variable is going to be conceptually a boolean, I like to declare it
bool and assign to it using 'true' or 'false' rather than 0 or 1.
PuTTY is an exception, because it predates the C99 bool, and I've
stuck to its existing coding style even when adding new code to it.
But it's been annoying me more and more, so now that I've decided C99
bool is an acceptable thing to require from our toolchain in the first
place, here's a quite thorough trawl through the source doing
'boolification'. Many variables and function parameters are now typed
as bool rather than int; many assignments of 0 or 1 to those variables
are now spelled 'true' or 'false'.
I managed this thorough conversion with the help of a custom clang
plugin that I wrote to trawl the AST and apply heuristics to point out
where things might want changing. So I've even managed to do a decent
job on parts of the code I haven't looked at in years!
To make the plugin's work easier, I pushed platform front ends
generally in the direction of using standard 'bool' in preference to
platform-specific boolean types like Windows BOOL or GTK's gboolean;
I've left the platform booleans in places they _have_ to be for the
platform APIs to work right, but variables only used by my own code
have been converted wherever I found them.
In a few places there are int values that look very like booleans in
_most_ of the places they're used, but have a rarely-used third value,
or a distinction between different nonzero values that most users
don't care about. In these cases, I've _removed_ uses of 'true' and
'false' for the return values, to emphasise that there's something
more subtle going on than a simple boolean answer:
- the 'multisel' field in dialog.h's list box structure, for which
the GTK front end in particular recognises a difference between 1
and 2 but nearly everything else treats as boolean
- the 'urgent' parameter to plug_receive, where 1 vs 2 tells you
something about the specific location of the urgent pointer, but
most clients only care about 0 vs 'something nonzero'
- the return value of wc_match, where -1 indicates a syntax error in
the wildcard.
- the return values from SSH-1 RSA-key loading functions, which use
-1 for 'wrong passphrase' and 0 for all other failures (so any
caller which already knows it's not loading an _encrypted private_
key can treat them as boolean)
- term->esc_query, and the 'query' parameter in toggle_mode in
terminal.c, which _usually_ hold 0 for ESC[123h or 1 for ESC[?123h,
but can also hold -1 for some other intervening character that we
don't support.
In a few places there's an integer that I haven't turned into a bool
even though it really _can_ only take values 0 or 1 (and, as above,
tried to make the call sites consistent in not calling those values
true and false), on the grounds that I thought it would make it more
confusing to imply that the 0 value was in some sense 'negative' or
bad and the 1 positive or good:
- the return value of plug_accepting uses the POSIXish convention of
0=success and nonzero=error; I think if I made it bool then I'd
also want to reverse its sense, and that's a job for a separate
piece of work.
- the 'screen' parameter to lineptr() in terminal.c, where 0 and 1
represent the default and alternate screens. There's no obvious
reason why one of those should be considered 'true' or 'positive'
or 'success' - they're just indices - so I've left it as int.
ssh_scp_recv had particularly confusing semantics for its previous int
return value: its call sites used '<= 0' to check for error, but it
never actually returned a negative number, just 0 or 1. Now the
function and its call sites agree that it's a bool.
In a couple of places I've renamed variables called 'ret', because I
don't like that name any more - it's unclear whether it means the
return value (in preparation) for the _containing_ function or the
return value received from a subroutine call, and occasionally I've
accidentally used the same variable for both and introduced a bug. So
where one of those got in my way, I've renamed it to 'toret' or 'retd'
(the latter short for 'returned') in line with my usual modern
practice, but I haven't done a thorough job of finding all of them.
Finally, one amusing side effect of doing this is that I've had to
separate quite a few chained assignments. It used to be perfectly fine
to write 'a = b = c = TRUE' when a,b,c were int and TRUE was just a
the 'true' defined by stdbool.h, that idiom provokes a warning from
gcc: 'suggest parentheses around assignment used as truth value'!
2018-11-02 19:23:19 +00:00
|
|
|
static void sk_net_set_frozen(Socket *sock, bool is_frozen)
|
2001-08-08 20:44:35 +00:00
|
|
|
{
|
2018-10-05 22:49:08 +00:00
|
|
|
NetSocket *s = container_of(sock, NetSocket, sock);
|
2001-08-25 17:09:23 +00:00
|
|
|
if (s->frozen == is_frozen)
|
2019-09-08 19:29:00 +00:00
|
|
|
return;
|
2001-08-08 20:44:35 +00:00
|
|
|
s->frozen = is_frozen;
|
2005-03-18 19:47:21 +00:00
|
|
|
if (!is_frozen) {
|
2019-09-08 19:29:00 +00:00
|
|
|
do_select(s->s, true);
|
|
|
|
if (s->frozen_readable) {
|
|
|
|
char c;
|
|
|
|
p_recv(s->s, &c, 1, MSG_PEEK);
|
|
|
|
}
|
2001-08-08 20:44:35 +00:00
|
|
|
}
|
Convert a lot of 'int' variables to 'bool'.
My normal habit these days, in new code, is to treat int and bool as
_almost_ completely separate types. I'm still willing to use C's
implicit test for zero on an integer (e.g. 'if (!blob.len)' is fine,
no need to spell it out as blob.len != 0), but generally, if a
variable is going to be conceptually a boolean, I like to declare it
bool and assign to it using 'true' or 'false' rather than 0 or 1.
PuTTY is an exception, because it predates the C99 bool, and I've
stuck to its existing coding style even when adding new code to it.
But it's been annoying me more and more, so now that I've decided C99
bool is an acceptable thing to require from our toolchain in the first
place, here's a quite thorough trawl through the source doing
'boolification'. Many variables and function parameters are now typed
as bool rather than int; many assignments of 0 or 1 to those variables
are now spelled 'true' or 'false'.
I managed this thorough conversion with the help of a custom clang
plugin that I wrote to trawl the AST and apply heuristics to point out
where things might want changing. So I've even managed to do a decent
job on parts of the code I haven't looked at in years!
To make the plugin's work easier, I pushed platform front ends
generally in the direction of using standard 'bool' in preference to
platform-specific boolean types like Windows BOOL or GTK's gboolean;
I've left the platform booleans in places they _have_ to be for the
platform APIs to work right, but variables only used by my own code
have been converted wherever I found them.
In a few places there are int values that look very like booleans in
_most_ of the places they're used, but have a rarely-used third value,
or a distinction between different nonzero values that most users
don't care about. In these cases, I've _removed_ uses of 'true' and
'false' for the return values, to emphasise that there's something
more subtle going on than a simple boolean answer:
- the 'multisel' field in dialog.h's list box structure, for which
the GTK front end in particular recognises a difference between 1
and 2 but nearly everything else treats as boolean
- the 'urgent' parameter to plug_receive, where 1 vs 2 tells you
something about the specific location of the urgent pointer, but
most clients only care about 0 vs 'something nonzero'
- the return value of wc_match, where -1 indicates a syntax error in
the wildcard.
- the return values from SSH-1 RSA-key loading functions, which use
-1 for 'wrong passphrase' and 0 for all other failures (so any
caller which already knows it's not loading an _encrypted private_
key can treat them as boolean)
- term->esc_query, and the 'query' parameter in toggle_mode in
terminal.c, which _usually_ hold 0 for ESC[123h or 1 for ESC[?123h,
but can also hold -1 for some other intervening character that we
don't support.
In a few places there's an integer that I haven't turned into a bool
even though it really _can_ only take values 0 or 1 (and, as above,
tried to make the call sites consistent in not calling those values
true and false), on the grounds that I thought it would make it more
confusing to imply that the 0 value was in some sense 'negative' or
bad and the 1 positive or good:
- the return value of plug_accepting uses the POSIXish convention of
0=success and nonzero=error; I think if I made it bool then I'd
also want to reverse its sense, and that's a job for a separate
piece of work.
- the 'screen' parameter to lineptr() in terminal.c, where 0 and 1
represent the default and alternate screens. There's no obvious
reason why one of those should be considered 'true' or 'positive'
or 'success' - they're just indices - so I've left it as int.
ssh_scp_recv had particularly confusing semantics for its previous int
return value: its call sites used '<= 0' to check for error, but it
never actually returned a negative number, just 0 or 1. Now the
function and its call sites agree that it's a bool.
In a couple of places I've renamed variables called 'ret', because I
don't like that name any more - it's unclear whether it means the
return value (in preparation) for the _containing_ function or the
return value received from a subroutine call, and occasionally I've
accidentally used the same variable for both and introduced a bug. So
where one of those got in my way, I've renamed it to 'toret' or 'retd'
(the latter short for 'returned') in line with my usual modern
practice, but I haven't done a thorough job of finding all of them.
Finally, one amusing side effect of doing this is that I've had to
separate quite a few chained assignments. It used to be perfectly fine
to write 'a = b = c = TRUE' when a,b,c were int and TRUE was just a
the 'true' defined by stdbool.h, that idiom provokes a warning from
gcc: 'suggest parentheses around assignment used as truth value'!
2018-11-02 19:23:19 +00:00
|
|
|
s->frozen_readable = false;
|
2001-08-08 20:44:35 +00:00
|
|
|
}
|
|
|
|
|
2007-01-08 19:38:39 +00:00
|
|
|
void socket_reselect_all(void)
|
|
|
|
{
|
2018-05-27 08:29:33 +00:00
|
|
|
NetSocket *s;
|
2007-01-08 19:38:39 +00:00
|
|
|
int i;
|
|
|
|
|
|
|
|
for (i = 0; (s = index234(sktree, i)) != NULL; i++) {
|
2019-09-08 19:29:00 +00:00
|
|
|
if (!s->frozen)
|
|
|
|
do_select(s->s, true);
|
2007-01-08 19:38:39 +00:00
|
|
|
}
|
|
|
|
}
|
|
|
|
|
2000-10-23 11:55:11 +00:00
|
|
|
/*
|
|
|
|
* For Plink: enumerate all sockets currently active.
|
|
|
|
*/
|
2001-05-06 14:35:20 +00:00
|
|
|
SOCKET first_socket(int *state)
|
|
|
|
{
|
2018-05-27 08:29:33 +00:00
|
|
|
NetSocket *s;
|
2001-04-16 17:18:24 +00:00
|
|
|
*state = 0;
|
|
|
|
s = index234(sktree, (*state)++);
|
2000-10-23 11:55:11 +00:00
|
|
|
return s ? s->s : INVALID_SOCKET;
|
|
|
|
}
|
2001-05-06 14:35:20 +00:00
|
|
|
|
|
|
|
SOCKET next_socket(int *state)
|
|
|
|
{
|
2018-05-27 08:29:33 +00:00
|
|
|
NetSocket *s = index234(sktree, (*state)++);
|
2000-10-23 11:55:11 +00:00
|
|
|
return s ? s->s : INVALID_SOCKET;
|
|
|
|
}
|
2002-10-30 17:57:31 +00:00
|
|
|
|
2018-11-03 10:06:33 +00:00
|
|
|
bool socket_writable(SOCKET skt)
|
2004-11-27 13:20:21 +00:00
|
|
|
{
|
2018-05-27 08:29:33 +00:00
|
|
|
NetSocket *s = find234(sktree, (void *)skt, cmpforsearch);
|
2004-11-27 13:20:21 +00:00
|
|
|
|
|
|
|
if (s)
|
2019-09-08 19:29:00 +00:00
|
|
|
return bufchain_size(&s->output_data) > 0;
|
2004-11-27 13:20:21 +00:00
|
|
|
else
|
2019-09-08 19:29:00 +00:00
|
|
|
return false;
|
2004-11-27 13:20:21 +00:00
|
|
|
}
|
|
|
|
|
2002-10-30 17:57:31 +00:00
|
|
|
int net_service_lookup(char *service)
|
|
|
|
{
|
|
|
|
struct servent *se;
|
2003-10-12 13:46:12 +00:00
|
|
|
se = p_getservbyname(service, NULL);
|
2002-10-30 17:57:31 +00:00
|
|
|
if (se != NULL)
|
2019-09-08 19:29:00 +00:00
|
|
|
return p_ntohs(se->s_port);
|
2002-10-30 17:57:31 +00:00
|
|
|
else
|
2019-09-08 19:29:00 +00:00
|
|
|
return 0;
|
2002-10-30 17:57:31 +00:00
|
|
|
}
|
2004-05-31 14:01:52 +00:00
|
|
|
|
Since r8305, Unix PuTTY has always "upgraded" an X11 display like "localhost:0"
to a Unix-domain socket. This typically works fine when PuTTY is run on the
same machine as the X server, but it's broken multi-hop X forwarding through
OpenSSH; when OpenSSH creates a proxy X server "localhost:10", it only listens
on TCP, not on a Unix-domain socket.
Instead, when deciding on the details of the display, we actively probe to see
if there's a Unix-domain socket we can use instead, and only use it if it's
there, falling back to the specified IP "localhost" if not.
Independently, when looking for local auth details in Xauthority for a
"localhost" TCP display, we prefer a matching Unix-domain entry, but will fall
back to an IP "localhost" entry (which would be unusual, but we don't trust a
Windows X server not to do it) -- this is a generalisation of the special case
added in r2538 (but removed in r8305, as the automatic upgrade masked the need
for it).
(This is now done in platform-independent code, so a side-effect is that
get_hostname() is now part of the networking abstraction on all platforms.)
[originally from svn r8462]
[r2538 == fda998324345ba50a913655754303ce8f0a4cfde]
[r8305 == ca6fc3a4daf51166a15693feffc967bee9e3f59a]
2009-02-24 01:01:23 +00:00
|
|
|
char *get_hostname(void)
|
|
|
|
{
|
2019-02-28 19:58:24 +00:00
|
|
|
char hostbuf[256]; /* MSDN docs for gethostname() promise this is enough */
|
|
|
|
if (p_gethostname(hostbuf, sizeof(hostbuf)) < 0)
|
|
|
|
return NULL;
|
|
|
|
return dupstr(hostbuf);
|
Since r8305, Unix PuTTY has always "upgraded" an X11 display like "localhost:0"
to a Unix-domain socket. This typically works fine when PuTTY is run on the
same machine as the X server, but it's broken multi-hop X forwarding through
OpenSSH; when OpenSSH creates a proxy X server "localhost:10", it only listens
on TCP, not on a Unix-domain socket.
Instead, when deciding on the details of the display, we actively probe to see
if there's a Unix-domain socket we can use instead, and only use it if it's
there, falling back to the specified IP "localhost" if not.
Independently, when looking for local auth details in Xauthority for a
"localhost" TCP display, we prefer a matching Unix-domain entry, but will fall
back to an IP "localhost" entry (which would be unusual, but we don't trust a
Windows X server not to do it) -- this is a generalisation of the special case
added in r2538 (but removed in r8305, as the automatic upgrade masked the need
for it).
(This is now done in platform-independent code, so a side-effect is that
get_hostname() is now part of the networking abstraction on all platforms.)
[originally from svn r8462]
[r2538 == fda998324345ba50a913655754303ce8f0a4cfde]
[r8305 == ca6fc3a4daf51166a15693feffc967bee9e3f59a]
2009-02-24 01:01:23 +00:00
|
|
|
}
|
|
|
|
|
2020-01-29 06:13:41 +00:00
|
|
|
SockAddr *platform_get_x11_unix_address(const char *display, int displaynum)
|
2004-05-31 14:01:52 +00:00
|
|
|
{
|
Get rid of lots of implicit pointer types.
All the main backend structures - Ssh, Telnet, Pty, Serial etc - now
describe structure types themselves rather than pointers to them. The
same goes for the codebase-wide trait types Socket and Plug, and the
supporting types SockAddr and Pinger.
All those things that were typedefed as pointers are older types; the
newer ones have the explicit * at the point of use, because that's
what I now seem to be preferring. But whichever one of those is
better, inconsistently using a mixture of the two styles is worse, so
let's make everything consistent.
A few types are still implicitly pointers, such as Bignum and some of
the GSSAPI types; generally this is either because they have to be
void *, or because they're typedefed differently on different
platforms and aren't always pointers at all. Can't be helped. But I've
got rid of the main ones, at least.
2018-10-04 18:10:23 +00:00
|
|
|
SockAddr *ret = snew(SockAddr);
|
|
|
|
memset(ret, 0, sizeof(SockAddr));
|
2004-05-31 14:01:52 +00:00
|
|
|
ret->error = "unix sockets not supported on this platform";
|
2008-11-08 16:58:55 +00:00
|
|
|
ret->refcount = 1;
|
2004-05-31 14:01:52 +00:00
|
|
|
return ret;
|
|
|
|
}
|