... when referring to a function's parameter or a struct/union's
member.
The idea of using FOO comes from the GNU coding standards:
The comment on a function is much clearer if you use the argument
names to speak about the argument values. The variable name
itself should be lower case, but write it in upper case when you
are speaking about the value rather than the variable itself.
Thus, "the inode number NODE_NUM" rather than "an inode".
Upcasing names is problematic for a case-sensitive language like C,
because it can create ambiguity. Moreover, it's too much shouting for
my taste.
GTK-Doc's convention to prefix the identifier with @ makes references
to variables stand out nicely. The rest of the GTK-Doc conventions
make no sense for us, however.
Signed-off-by: Markus Armbruster <armbru@pond.sub.org>
Leaks one file descriptor per configured IPv6 address, which should be
pretty harmless. Broken in commit da154ff, v4.3.31.
Signed-off-by: Markus Armbruster <armbru@pond.sub.org>
OpenBSD refuses to implement IPV6_V6ONLY, in violation of RFC 3493.
RFC 4038 frowningly recognizes this practice. The only way to bind
both IPv4 and IPv4 there is two separate sockets. Requires more
surgery than I can do now.
Since we can't have both IPv6 and IPv6 on OpenBSD with our single
socket, prefer IPv4, but if that doesn't work, do IPv6.
To prefer IPv6 instead, put 'listen_addr "::"' into econfig. Document
that in listen_addr's doc string.
We rely on AF_INET6 wildcard bind() binding the AF_INET port, too,
i.e. IPV6_V6ONLY off. This should be the default according to RFC
3493 section 5.3, but isn't on Windows and BSD. RFC 4038 recognizes
this fact in section 4.2.
When IPV6_V6ONLY is on, an AF_INET6 wildcard bind only accepts
connections from IPv6 addresses. Thus, IPv4 doesn't work when
getaddrinfo() returns an AF_INET6 address first (which it should do
when the system has an IPv6 address configured).
Switch off IPV6_V6ONLY explicitly instead of relying on the default.
This makes IPv6 work on systems where IPV6_V6ONLY is on by default,
such as Windows and BSD.
Except for OpenBSD, which does not support switching it off. To be
addressed in the next commit.
Shouldn't fail. If it fails, but bind() works, the failure doesn't
matter. If bind() fails, we can just as well report that failure
instead of setsockopt()'s.
We seed it with value of time(). It's the traditional way, but it
provides only a few bits of effective entropy when an attacker has a
rough idea when the program started.
Instead, seed with a kernel random number. If we can't get one, fall
back to a hash of gettimeofday() and getpid(). This should happen
only on old systems or Windows. Far worse than a kernel random
number, but far better than using time().
Note that fairland used to seed with time() + getpid() until commit
331aac2a (v4.2.20) dropped the getpid(), claiming it didn't improve
the randomness. Perhaps it didn't under Windows then, but it
certainly did elsewhere, so it was a regression.
random() may yield different pseudo-random number sequences for the
same seed on another system. For instance, at least some versions of
MinGW provide a random() in -liberty that differs from traditional BSD
(see commit c8231b12). Rather inconvenient for regression testing.
MT19937 Mersenne Twister is a proven, high-quality PRNG. Actual code
is reference code provided by the inventors[*]. Quick tests show
performance comparable to random().
Like random(), MT is not cryptographically secure: observing enough of
its output permits guessing its state, and thus its future output. I
don't think players can do that.
Drop the copy of BSD random() we added for Windows.
Like the previous commit, this changes the server's die rolls, and
makes fairland create a different random map for the same seed. Update
expected smoke test results accordingly.
[*] mt19937ar.sep.tgz downloaded from
http://www.math.sci.hiroshima-u.ac.jp/~m-mat/MT/MT2002/emt19937ar.html
"random() % n" is sound only when n is a power of two. The error is
hardly relevant in Empire, because random() yields 31 bits, and our n
are always much smaller than 2^31. Fix it anyway.
Use smallest the 2^m >= n instead of n, and discard numbers exceeding
n.
Bonus: faster for me even in the worst case n = 2^m+1.
Like the recent change to damage(), this changes some of the server's
die rolls, only this time the effect is pretty pervasive. Worse,
fairland now creates a completely different random map for the same
seed. Update expected smoke test results accordingly.
Why upgrade? I'm not a lawyer, but here's my take on the differences
to version 2:
* Software patents: better protection against abuse of patents to
prevent users from exercising the rights under the GPL. I doubt
we'll get hit with a patent suit, but it's a good move just on
general principles.
* License compatibility: compatible with more free licenses, i.e. can
"steal" more free software for use in Empire. I don't expect to steal
much, but it's nice to have the option.
* Definition of "source code": modernization of some details for today's
networked world, to make it easier to distribute the software. Not
really relevant to us now, as we normally distribute full source code.
* Tivoization: this is about putting GPL-licensed software in hardware,
then make the hardware refuse to run modified software. "Neat" trick
to effectively deny its users their rights under the GPL. Abuse was
"pioneered" by TiVo (popular digital video recorders). GPLv3 forbids
it. Unlikely to become a problem for us.
* Internationalization: more careful wording, to harden the license
outside the US. The lawyers tell us it better be done that way.
* License violations: friendlier way to deal with license violations.
This has come out of past experience enforcing the GPL.
* Additional permissions: Probably not relevant to us.
Also include myself in the list of principal authors.
The previous commit's message claims the race can lead to duplicated
output, use after free, then double-free. That's correct only up to
the use after free. There is no double-free.
Heap corruption (double-free?) has been observed in Changeling,
though. Player logged in (still in sanctuary), map #, crashed within
removecc()'s free(io->data). Partial backtrace:
raise () from /lib64/libc.so.6
abort () from /lib64/libc.so.6
__libc_message () from /lib64/libc.so.6
malloc_printerr () from /lib64/libc.so.6
removecc (ioq=0x251fd10, cc=468) at ../src/lib/gen/ioqueue.c:350
ioq_dequeue (ioq=0x251fd10, cc=468) at ../src/lib/gen/ioqueue.c:135
io_output (iop=0x251fc90, wait=1) at ../src/lib/empthread/io.c:231
recvclient (cmd=0x258d8e0 "", size=1024) at ../src/lib/player/recvclient.c:82
getcommand (combufp=0x2557068 "map #1") at ../src/lib/player/empdis.c:84
I haven't been able to reproduce.
To hopefully catch ioqueue going south earlier, make ioq_dequeue()
oops when it can't dequeue as many bytes as requested.
Local analysis can now easily find out what's up. Before, inter-
procedural analysis was required. The Clang Static Analyzer
complained about a dereference of res that is actually fine.
Local analysis can now easily find out what's up. Before,
whole-program analysis was required. The Clang Static Analyzer
complained about code that is actually fine.
Change oops() to call the new oops_handler function pointer instead of
offering a fixed set of actions. Change server's main() to install a
handler for the action requested by -E.
Three options: abort, crash-dump, nothing. crash-dump works by
aborting a fork. It isn't implemented for Windows.
The oops action is no longer tied to daemon mode, but -d still implies
-E abort for convenience.
read_builtin_tables() wanted to run in builtindir, and
read_custom_tables() wanted to run in configdir. Bothersome. Use new
fopenat() to relax those requirements.
The chdir() satisfying them are now superflous, remove them.
File names in econfig need to be interpreted relative to configdir.
This wasn't the case everywhere for keys data and info.
Fix this by changing variables gamedir and infodir to hold absolute
names. Change builtindir likewise, for consistency. Store the values
from econfig in gamedir_conf, infodir_conf and builtindir_conf.
Uses new fnameat() to derive absolute names from possibly relative
ones.
Until now, they tried to recover and continue (debug off). That's
appropriate only for the server. The server could be told to abort
instead (debug on, selected by option -d), but not the utility
programs.
Change debug to be on by default, and switch it off early in the
server's main(). No functional change for the server.
Move stuff to untangle the ugly cyclic dependencies between the
archives built for selected subdirectories of src/lib/:
* Move common/io.c to empthread/ because it requires empthread stuff
* Move parts of subs/nstr.c to common/nstreval.c to satisfy
common/ef_verify.o
* Move getstarg.c getstring.c onearg.c from gen/ to subs/ because they
require stuff from there
* Move bridgefall.c check.c damage.c empobj.c journal.c maps.c
sectdamage.c from common/ to subs/ because they require stuff from
there
* Move cnumb.c from subs/ to common/ to satisfy common/type.o
* Move log.c fsize.c from common/ to gen/ because they really belong
there
* Move emp_config.c mapdist.c from gen/ to common/ because they really
belong there, and require stuff from libglobal.a
Also package as/ as libas.a to satisfy common/path.o.
Remaining dependencies:
lib needs
--------------------------------------------
libas.a libglobal.a
libcommon.a libas.a libglobal.a libgen.a
libgen.a
libglobal.a
liblwp.a libgen.a
libw32.a[*] libgen.a
[*] Except for service.o, which can only be linked into the server
Link order now: liblwp.a libcommon.a libas.a libgen.a libglobal.a
libw32.a. The position of libw32.a is not quite right, but works
anyway.
The function that gave its name to this file is long gone, the file's
description is bogus, and it contains just one definition. Move that
to ../subs/border.c, and delete the file.