[RFC 0/3] Refactor the options system
Michael Witten
mfwitten at gmail.com
Thu Jul 20 10:17:15 AWST 2017
On Thu, 20 Jul 2017 00:31:25 +0800, Matt Johnston wrote:
> I'm less keen on this options patch series. I don't really
> think they add much clarity, and any widespread change is
> going to cause extra work for people with their own forks.
> (Yes the move to localoptions.h is also disruptive, but I
> think it has a clear benefit).
> It's pretty clear already which options are expected to be
> overridden - they're the ones in default_options.h !
> The line between options in sysoptions.h and
> default_options.h is kind of vague anyway, something like
> KEX_REKEY_TIMEOUT could really go in either, but I've kept
> it in sysoptions.h just to try and avoid too many knobs to
> fiddle with. The main reason I went with a DROPBEAR_ prefix
> is to avoid namespace clashes - CUSTOM_ doesn't really do
> that.
Allow me to push back a bit.
This switch to `localoptions.h' is already a flag day, so it
would probably be prudent to stuff into that flag day as much
irritating cleanup as possible.
* Sure, nitpicky refactoring is a bit of bikeshedding, but it
can be valuable to spend time figuring out which paint color
for the bikeshed is actually the most pleasing to look at
every day; the choice of color can be very important to
those who haven't yet spent over a decade staring at it.
This includes decisions that are small, but worthwhile
with respect to consistency; for instance, to me, it seems
that the file name should be at least `local_options.h'
rather than `localoptions.h' (or, maybe, there should be
`defaultoptions.h' rather than `default_options.h', as there
is already a `sysoptions.h' rather than a `sys_options.h').
Why `local', anyway? That's kind of an archaic term; I mean,
one might as well choose `site', like in the old days.
Something like `custom_options.h' or `configured_options.h'
or `config_options.h' or `user_options.h' carries a lot more
information at first glance.
What does `sysoptions.h' tell anyone? How does it help structure
the thoughts of people who are working with the source code?
Indeed, as you already noted, the reasoning for where an option
should go is often so nebulous as to be almost arbitrary; that
suggests there is something wrong (or at least useless) in the
way that the source code is organized.
How can we organize it better? Can organization be based around
*technical* reasons?
* There are 2 kinds of options:
* Fundamental constants in the Dropbear Universe.
* Variables that can be set by the user.
(Hey! what about `variable_options.h.in'?! I kid, I kid...
... but I'm kind of not kidding...)
That's starting to look like a hard-nosed, conceptual, technical
basis for where certain macros should be defined:
Can reasonable people disagree on the value of this macro?
Yes! Then it belongs in `config_options.h.in'! (or whatever)
No! Then it belongs elsewhere! (and shouldn't be in an `#ifndef' block)
Can reasonable people disagree on the value of `KEX_REKEY_TIMEOUT'?
Yes! Then it belongs in `user_options.h.in'! (or whatever)
Can reasonable people disagree on the value of `DROPBEAR_VERSION'?
No! This is the Dropbear project, and if you change this to something
custom, then you've effectively forked the project.
Thus, it belongs in `constant_options.h' and shouldn't be
in an `#ifndef' block.
Can reasonable people disagree on the value of `MD5_HASH_SIZE'?
No! Blasphemy! The Gods of Crypto handed that one down from their
glissening Tower of Ivory, when hackers were hackers and
Dennis Ritchie still walked amongst us.
Thus, it belongs in... WHERE?
Actually, where should `MD5_HASH_SIZE' go, anyway? You'll notice that
it's only used in one file:
$ git grep -l MD5_HASH_SIZE | grep -v sysoptions.h
signkey.c
So, why isn't `MD5_HASH_SIZE' just defined in that one file? Indeed,
if it were defined in that file, then there probably wouldn't even need
to be a qualifying pseudo-namespace, like `DROPBEAR_'.
As you can see, some kind of purposeful organizational structure is
already beginning to emerge.
* Speaking of the qualifying prefix `DROPBEAR_', note that without this
refactoring patch series, there are still quite a few option macros
that are not yet qualified:
$ clean() { awk '{print $2}' | sort -u; }
$ filter_options() { git grep -P '^#define\s+(?!DROPBEAR_)' "$1" | clean; }
$
$ filter_options default_options.h.in
DEFAULT_IDLE_TIMEOUT
DEFAULT_KEEPALIVE
DEFAULT_KEEPALIVE_LIMIT
DEFAULT_PATH
DEFAULT_RECV_WINDOW
DO_HOST_LOOKUP
DO_MOTD
DSS_PRIV_FILENAME
ECDSA_PRIV_FILENAME
INETD_MODE
LOG_COMMANDS
MAX_AUTH_TRIES
MAX_UNAUTH_CLIENTS
MAX_UNAUTH_PER_IP
MOTD_FILENAME
NON_INETD_MODE
RECV_MAX_PAYLOAD_LEN
RSA_PRIV_FILENAME
SFTPSERVER_PATH
TRANS_MAX_PAYLOAD_LEN
XAUTH_COMMAND
$
$
$ filter_options sysoptions.h
AUTH_TIMEOUT
ENABLE_CONNECT_UNIX
ENV_SIZE
IS_DROPBEAR_CLIENT
IS_DROPBEAR_SERVER
KEXHASHBUF_MAX_INTS
KEX_REKEY_DATA
KEX_REKEY_TIMEOUT
LOCAL_IDENT
LTM_DESC
MAX_BANNER_LINES
MAX_BANNER_SIZE
MAX_CHANNELS
MAX_CMD_LEN
MAX_ECC_SIZE
MAX_HASH_SIZE
MAX_HOSTKEYS
MAX_HOST_LEN
MAX_IP_LEN
MAX_IV_LEN
MAX_KEY_LEN
MAX_LISTEN_ADDR
MAX_MAC_LEN
MAX_NAME_LEN
MAX_PRIVKEY_SIZE
MAX_PROPOSED_ALGO
MAX_PUBKEY_SIZE
MAX_RECV_WINDOW
MAX_STRING_LEN
MAX_TERM_LEN
MD5_HASH_SIZE
MIN_DSS_KEYLEN
MIN_PACKET_LEN
MIN_RSA_KEYLEN
PROGNAME
RECV_MAX_PACKET_LEN
RECV_WINDOWEXTEND
SHA1_HASH_SIZE
TRANS_MAX_WINDOW
TRANS_MAX_WIN_INCR
_PATH_CP
_PATH_TTY
Surely, for the sake of consistency, and to avoid clashes, these macros
should also be prefixed with `DROPBEAR_' (or moved to a more relevant
file), especially now that there is already going to be a flag day.
And, if they are going to be altered, then why not also institute some
kind of differentiator that indicates whether the macro in question
represents either a Dropbear-defined constant or a user-defined variable?
This may seem trivial, but it might also be very useful to be able to
see right in the very code, at the very point of use, that a particular
value represents input from the user; it would be a more explicit way
to identify exactly where the user interfaces with the Dropbear source
code.
This differentiator doesn't have to be `CUSTOM_'; it could instead be
`DROPBEAR_USER_'.
Certainly, it might help people who fork the code identify what exactly
is considered acceptable to manipulate without the consensus of the
wider userbase; if a user manipulates something that is not explicitly
presented as being user-definable, then that user is acknowledging
the risk that he might have to deal with source-code conflicts in the
future.
* Even those users who have forked the code will likely have major
difficulties only with one file (`options.h'), and with one aspect
of the source code (how user-defined options are specified).
This will already be the case, regardless of the refactoring; it hardly
counts against refactoring in general.
* Even with heavy refactoring, it seems like it should be possible to
help users convert to the new system in a way that would be seamless
for most cases.
Rather than using `options.h' for the new system, the file to use
should instead be, say, `all_options.h'; not only would this be named
consistently with the related files (`default_options.h.in', and, say,
`constant_options.h'), but it would allow for keeping around the old
(untouched) `options.h' file (and perhaps also the old `sysoptions.h'),
so that a user's file manipulations can still occur without conflict.
Then, when `make' is run as usual, if the user has not yet supplied
a `custom_options.h' (or whatever), a new `custom_options.h' can be
created by converting the old options into the new options; perhaps the
conversion could be affected by whether any old file has actually been
altered.
There could also be a warning printed on `stderr', and a 20 second pause
in the build process, to warn a user that the old way of doing things
is being abandoned, and to explain that a `custom_options.h' has been
created automatically, and to point out any discrepancies that might
exist due to this conversion process (if there are any worth mentioning).
A user who builds Dropbear as part of a larger, automated building
process should receive such a notification if the `stderr' output is
being logged for later review.
In short, this is potentially a great opportunity to clean up the source
code, establishing a more solid foundation for future development.
Sincerely,
Michael Witten
More information about the Dropbear
mailing list