From 1eb40c83287b07ac7428ad2d58504f386fad98f1 Mon Sep 17 00:00:00 2001 From: Dan McGee Date: Thu, 19 Jan 2012 16:21:06 -0600 Subject: Add diskspace checking support for Solaris/Illumos Was able to get my hands on one of these boxes today, so add yet another new way of doing this. I'm glad these calls are so standardized. This was compile tested on Linux and Illumos and seems to still be working in both places. Signed-off-by: Dan McGee --- configure.ac | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-) (limited to 'configure.ac') diff --git a/configure.ac b/configure.ac index 0de908a3..a8b142ea 100644 --- a/configure.ac +++ b/configure.ac @@ -173,7 +173,8 @@ AM_CONDITIONAL([HAVE_LIBGPGME], [test "x$with_gpgme" = "xyes"]) # Checks for header files. AC_CHECK_HEADERS([fcntl.h float.h glob.h libintl.h limits.h locale.h \ - mntent.h stddef.h string.h sys/ioctl.h sys/mount.h \ + mntent.h stddef.h string.h sys/ioctl.h \ + sys/mnttab.h sys/mount.h \ sys/param.h sys/statvfs.h sys/time.h sys/types.h \ sys/ucred.h syslog.h termios.h wchar.h]) -- cgit v1.2.3-54-g00ecf From 44f146f232be5203fb01ad35fdf73122838df97c Mon Sep 17 00:00:00 2001 From: Dave Reisner Date: Sat, 21 Jan 2012 21:31:39 -0500 Subject: lib/dload: enforce usage of TCP keepalives This is particularly important in the case of FTP control connections, which may be closed by rogue NAT/firewall devices detecting idle connections on larger transfers which may take 5-10+ minutes. Signed-off-by: Dave Reisner Signed-off-by: Dan McGee --- configure.ac | 3 ++- lib/libalpm/dload.c | 53 +++++++++++++++++++++++++++++++++++++++++++++++++++++ 2 files changed, 55 insertions(+), 1 deletion(-) (limited to 'configure.ac') diff --git a/configure.ac b/configure.ac index a8b142ea..0bf11e99 100644 --- a/configure.ac +++ b/configure.ac @@ -173,7 +173,8 @@ AM_CONDITIONAL([HAVE_LIBGPGME], [test "x$with_gpgme" = "xyes"]) # Checks for header files. AC_CHECK_HEADERS([fcntl.h float.h glob.h libintl.h limits.h locale.h \ - mntent.h stddef.h string.h sys/ioctl.h \ + mntent.h netinet/in.h netinet/tcp.h \ + stddef.h string.h sys/ioctl.h \ sys/mnttab.h sys/mount.h \ sys/param.h sys/statvfs.h sys/time.h sys/types.h \ sys/ucred.h syslog.h termios.h wchar.h]) diff --git a/lib/libalpm/dload.c b/lib/libalpm/dload.c index 6fe4a323..f5af7c64 100644 --- a/lib/libalpm/dload.c +++ b/lib/libalpm/dload.c @@ -25,11 +25,19 @@ #include #include #include +#include /* setsockopt, SO_KEEPALIVE */ #include #include #include #include +#ifdef HAVE_NETINET_IN_H +#include /* IPPROTO_TCP */ +#endif +#ifdef HAVE_NETINET_TCP_H +#include /* TCP_KEEPINTVL, TCP_KEEPIDLE */ +#endif + #ifdef HAVE_LIBCURL #include #endif @@ -217,6 +225,47 @@ static size_t parse_headers(void *ptr, size_t size, size_t nmemb, void *user) return realsize; } +static int dload_sockopt_cb(void *userdata, curl_socket_t curlfd, + curlsocktype purpose) +{ + alpm_handle_t *handle = userdata; + int optval = 1; + + /* this whole method is to prevent FTP control connections from going sour + * during a long data transfer; crappy firewalls love to drop otherwise idle + * connections if there is no traffic. */ + if(purpose != CURLSOCKTYPE_IPCXN) { + return 0; + } + + /* don't abort operation if any setsockopt fails, just log to debug */ + if(setsockopt(curlfd, SOL_SOCKET, SO_KEEPALIVE, (void *)&optval, + sizeof(optval)) < 0) { + _alpm_log(handle, ALPM_LOG_DEBUG, + "Failed to set SO_KEEPALIVE on fd %d\n", curlfd); + } + else { +#ifdef TCP_KEEPIDLE + optval = 60; + if(setsockopt(curlfd, IPPROTO_TCP, TCP_KEEPIDLE, (void *)&optval, + sizeof(optval)) < 0) { + _alpm_log(handle, ALPM_LOG_DEBUG, + "Failed to set TCP_KEEPIDLE on fd %d\n", curlfd); + } +#endif +#ifdef TCP_KEEPINTVL + optval = 60; + if(setsockopt(curlfd, IPPROTO_TCP, TCP_KEEPINTVL, (void *)&optval, + sizeof(optval)) < 0) { + _alpm_log(handle, ALPM_LOG_DEBUG, + "Failed to set TCP_KEEPINTVL on fd %d\n", curlfd); + } +#endif + } + + return 0; +} + static void curl_set_handle_opts(struct dload_payload *payload, CURL *curl, char *error_buffer) { @@ -241,6 +290,8 @@ static void curl_set_handle_opts(struct dload_payload *payload, curl_easy_setopt(curl, CURLOPT_HEADERFUNCTION, parse_headers); curl_easy_setopt(curl, CURLOPT_WRITEHEADER, (void *)payload); curl_easy_setopt(curl, CURLOPT_NETRC, CURL_NETRC_OPTIONAL); + curl_easy_setopt(curl, CURLOPT_SOCKOPTFUNCTION, dload_sockopt_cb); + curl_easy_setopt(curl, CURLOPT_SOCKOPTDATA, (void *)handle); _alpm_log(handle, ALPM_LOG_DEBUG, "url: %s\n", payload->fileurl); @@ -392,6 +443,8 @@ static int curl_download_internal(struct dload_payload *payload, /* perform transfer */ payload->curlerr = curl_easy_perform(curl); + _alpm_log(handle, ALPM_LOG_DEBUG, "curl returned error %d from transfer\n", + payload->curlerr); /* disconnect relationships from the curl handle for things that might go out * of scope, but could still be touched on connection teardown. This really -- cgit v1.2.3-54-g00ecf