Skip to content

Commit

Permalink
Tarsnap 1.0.9
Browse files Browse the repository at this point in the history
Changes since 1.0.8:
* Linux 2.4 kernel compatibility fix in TCP_CORK code.
* Linux compatibility fix in terminal handling for running tarsnap
  without a controlling terminal (e.g., from cron).
* Linux autoconf fixes for ext2fs header files.
* Workaround for FreeBSD net.inet.ip.portrange.randomized + pf
  interaction.
  • Loading branch information
cperciva authored and gperciva committed Jun 30, 2008
1 parent 815a59c commit 07168b0
Show file tree
Hide file tree
Showing 8 changed files with 78 additions and 11 deletions.
32 changes: 32 additions & 0 deletions actarsnap.m4
Original file line number Diff line number Diff line change
Expand Up @@ -12,3 +12,35 @@ esac
AC_SUBST([BROKEN_TCP_NOPUSH])
])# CHECK_BROKEN_TCP_NOPUSH

# CHECK_FREEBSD_PORTRANGE_BUG
# ---------------------------
AC_DEFUN([CHECK_FREEBSD_PORTRANGE_BUG],
[AC_REQUIRE([AC_CANONICAL_TARGET])
case $target_os in
freebsd*)
AC_DEFINE([FREEBSD_PORTRANGE_BUG], [1],
[Define to 1 if the OS has FreeBSD's randomized portrange bug])
;;
esac
AC_SUBST([FREEBSD_PORTRANGE_BUG])
])# CHECK_FREEBSD_PORTRANGE_BUG

# CHECK_LINUX_EXT2FS
# ---------------------------
AC_DEFUN([CHECK_LINUX_EXT2FS],
[AC_REQUIRE([AC_CANONICAL_TARGET])
case $target_os in
linux*)
AC_CHECK_HEADER(ext2fs/ext2_fs.h,
AC_DEFINE([HAVE_EXT2FS_EXT2_FS_H], [1],
[Define to 1 if you have the <ext2fs/ext2_fs.h> header file.]),
AC_MSG_ERROR([*** ext2fs/ext2_fs.h missing ***]))
;;
esac
AC_SUBST([HAVE_EXT2FS_EXT2_FS_H])
])# CHECK_LINUX_EXT2FS
10 changes: 8 additions & 2 deletions configure.ac
Original file line number Diff line number Diff line change
Expand Up @@ -69,8 +69,8 @@ AM_MAINTAINER_MODE
AC_HEADER_STDC
AC_HEADER_DIRENT
AC_HEADER_SYS_WAIT
AC_CHECK_HEADERS([bzlib.h errno.h ext2fs/ext2_fs.h fcntl.h grp.h])
AC_CHECK_HEADERS([inttypes.h langinfo.h limits.h linux/ext2_fs.h linux/fs.h])
AC_CHECK_HEADERS([bzlib.h errno.h fcntl.h grp.h])
AC_CHECK_HEADERS([inttypes.h langinfo.h limits.h])
# Include inttypes.h into archive.h only if appropriate.
# We can't use the HAVE_INTTYPES_H macro here because archive.h
# gets installed as a system header and then included into client code
Expand Down Expand Up @@ -98,9 +98,15 @@ AC_CHECK_HEADER(openssl/rsa.h,
AC_MSG_ERROR([*** OpenSSL missing ***])),
AC_MSG_ERROR([*** OpenSSL header files missing ***]))

# On Linux, we need ext2fs/ext2_fs.h
CHECK_LINUX_EXT2FS

# Check if we're on an operating system with a broken TCP_NOPUSH
CHECK_BROKEN_TCP_NOPUSH

# Check if we have FreeBSD's randomized TCP source port bug
CHECK_FREEBSD_PORTRANGE_BUG

# Checks for typedefs, structures, and compiler characteristics.
AC_C_CONST
AC_TYPE_UID_T
Expand Down
20 changes: 20 additions & 0 deletions network/network_connect.c
Original file line number Diff line number Diff line change
Expand Up @@ -107,6 +107,26 @@ network_connect(int s, const struct sockaddr * addr, socklen_t addrlen,
(errno == ECONNRESET) ||
(errno == ENETDOWN) ||
(errno == ENETUNREACH) ||
#ifdef FREEBSD_PORTRANGE_BUG
/**
* If FreeBSD's net.inet.ip.portrange.randomized sysctl is set to 1
* (the default value) FreeBSD sometimes reuses a source port faster
* than might naively be expected. This doesn't cause any problems
* except if the pf filewall is running on the source system; said
* firewall detects the packet as belonging to an expired connection
* and drops it. This would be fine, except that the FreeBSD kernel
* doesn't merely drop the packet when a firewall blocks an outgoing
* packet; instead, it reports EPERM back to the userland process
* which was responsible for the packet being sent.
* In short, things interact in wacky ways which make it possible to
* get EPERM back in response to a connect(2) syscall. Work around
* this by handling EPERM the same way as transient network glitches;
* the upstream code will handle this appropriately by retrying the
* connection, at which point a new source port number will be chosen
* and everything will (probably) work fine.
*/
(errno == EPERM) ||
#endif
(errno == EHOSTUNREACH)) {
/*
* The connection attempt has failed. Schedule a callback
Expand Down
10 changes: 7 additions & 3 deletions network/network_cork.c
Original file line number Diff line number Diff line change
Expand Up @@ -80,9 +80,6 @@ int
network_uncork(int fd)
{

/* Set TCP_NODELAY. */
setopt(fd, TCP_NODELAY, 1, err0);

/* Clear TCP_CORK or TCP_NOPUSH as appropriate. */
#ifdef TCP_CORK
setopt(fd, TCP_CORK, 0, err0);
Expand All @@ -94,6 +91,13 @@ network_uncork(int fd)
#endif
#endif

/* Set TCP_NODELAY. */
/*
* For compatibility with Linux 2.4, this must be done after we
* clear TCP_CORK; otherwise it will throw an EINVAL back at us.
*/
setopt(fd, TCP_NODELAY, 1, err0);

/* Success! */
return (0);

Expand Down
2 changes: 1 addition & 1 deletion tar-version
Original file line number Diff line number Diff line change
@@ -1 +1 @@
1.0.8
1.0.9
1 change: 1 addition & 0 deletions tar/config_freebsd.h
Original file line number Diff line number Diff line change
Expand Up @@ -106,3 +106,4 @@
#undef MAJOR_IN_MKDEV
#define STDC_HEADERS 1

#define FREEBSD_PORTRANGE_BUG
7 changes: 4 additions & 3 deletions util/hexify.c
Original file line number Diff line number Diff line change
Expand Up @@ -6,7 +6,7 @@

#include "hexify.h"

static char hexchars[16] ="0123456789abcdef";
static char hexchars[32] ="0123456789abcdef0123456789ABCDEF";

/**
* hexify(in, out, len):
Expand Down Expand Up @@ -41,8 +41,9 @@ unhexify(const char * in, uint8_t * out, size_t len)
goto err0;

for (i = 0; i < len; i++) {
out[i] = ((strchr(hexchars, in[2 * i]) - hexchars) << 4) +
(strchr(hexchars, in[2 * i + 1]) - hexchars);
out[i] = (strchr(hexchars, in[2 * i]) - hexchars) & 0x0f;
out[i] <<= 4;
out[i] += (strchr(hexchars, in[2 * i + 1]) - hexchars) & 0x0f;
}

/* Success! */
Expand Down
7 changes: 5 additions & 2 deletions util/sigquit.c
Original file line number Diff line number Diff line change
Expand Up @@ -70,9 +70,12 @@ sigquit_init(void)
/*
* If stdin isn't a TTY, or doesn't exist (i.e., the other
* end of the pipe was closed) we're not going to remap ^Q
* to SIGQUIT, and we don't need to unmap it on exit.
* to SIGQUIT, and we don't need to unmap it on exit. For
* some reason Linux returns EINVAL if stdin is not a
* terminal, so handle this too.
*/
if ((errno == ENOTTY) || (errno == ENXIO))
if ((errno == ENOTTY) || (errno == ENXIO) ||
(errno == EBADF) || (errno == EINVAL))
goto done;

warnp("tcgetattr(stdin)");
Expand Down

0 comments on commit 07168b0

Please sign in to comment.