51. [`--rsync.priority`](#--rsyncpriority)
53. [`--rsync.retry.count`](#--rsyncretrycount)
54. [`--rsync.retry.interval`](#--rsyncretryinterval)
+ 40. [`--rsync.transfer-timeout`](#--rsynctransfer-timeout)
55. [`--configuration-file`](#--configuration-file)
56. [`rsync.program`](#rsyncprogram)
57. [`rsync.arguments-recursive`](#rsyncarguments-recursive)
[--rsync.priority=<unsigned integer>]
[--rsync.retry.count=<unsigned integer>]
[--rsync.retry.interval=<unsigned integer>]
+ [--rsync.transfer-timeout=<unsigned integer>]
[--http.enabled=true|false]
[--http.priority=<unsigned integer>]
[--http.retry.count=<unsigned integer>]
Period of time (in seconds) to wait between each retry to execute an RSYNC.
+### `--rsync.transfer-timeout`
+
+- **Type:** Integer
+- **Availability:** `argv` and JSON
+- **Default:** 900
+- **Range:** [0, [`UINT_MAX`](http://pubs.opengroup.org/onlinepubs/9699919799/basedefs/limits.h.html)]
+
+Maximum time in seconds that the rsync transfer can last.
+
+Once the connection is established with the server, the request will last a maximum of `rsync.transfer-timeout` seconds. A value of 0 means unlimited time.
+
### `--configuration-file`
- **Type:** String (Path to file)
"<a href="#--rsyncretrycount">count</a>": 1,
"<a href="#--rsyncretryinterval">interval</a>": 4
},
+ "<a href="#--rsynctransfer-timeout">transfer-timeout</a>": 0,
"<a href="#rsyncprogram">program</a>": "rsync",
"<a href="#rsyncarguments-recursive">arguments-recursive</a>": [
"-rtz",
"count": 2,
"interval": 5
},
+ "transfer-timeout": 900,
"program": "rsync",
"arguments-recursive": [
"--recursive",
.RE
.P
+.B \-\-rsync.transfer\-timeout=\fIUNSIGNED_INTEGER\fR
+.RS 4
+Maximum time in seconds that the rsync process can last.
+.P
+Once the connection is established with the server, the request will last a
+maximum of \fBrsync.transfer-timeout\fR seconds. A value of \fI0\fR means
+unlimited time (default value).
+.P
+By default, it has a value of \fI900\fR.
+.RE
+.P
+
.B \-\-output.roa=\fIFILE\fR
.RS 4
File where the ROAs will be printed in the configured format (see
/* Interval (in seconds) between each retry */
unsigned int interval;
} retry;
+ unsigned int transfer_timeout;
char *program;
struct {
struct string_array flat; /* Deprecated */
/* Unlimited */
.max = 0,
.deprecated = true,
+ }, {
+ .id = 3008,
+ .name = "rsync.transfer-timeout",
+ .type = >_uint,
+ .offset = offsetof(struct rpki_config, rsync.transfer_timeout),
+ .doc = "Maximum transfer time before killing the rsync process",
+ .min = 0,
+ .max = UINT_MAX,
},
/* HTTP requests parameters */
rpki_config.rsync.strategy = pstrdup("<deprecated>");
rpki_config.rsync.retry.count = 1;
rpki_config.rsync.retry.interval = 4;
+ rpki_config.rsync.transfer_timeout = 900;
rpki_config.rsync.program = pstrdup("rsync");
string_array_init(&rpki_config.rsync.args.flat,
flat_rsync_args, ARRAY_LEN(flat_rsync_args));
return rpki_config.rsync.retry.interval;
}
+long
+config_get_rsync_transfer_timeout(void)
+{
+ return rpki_config.rsync.transfer_timeout;
+}
+
char *
config_get_rsync_program(void)
{
unsigned int config_get_rsync_priority(void);
unsigned int config_get_rsync_retry_count(void);
unsigned int config_get_rsync_retry_interval(void);
+long config_get_rsync_transfer_timeout(void);
char *config_get_rsync_program(void);
struct string_array const *config_get_rsync_args(void);
bool config_get_http_enabled(void);
#include <errno.h>
#include <fcntl.h>
+#include <poll.h>
#include <signal.h>
#include <sys/wait.h>
#include <syslog.h>
{
char buffer[4096];
ssize_t count;
- int error;
+ struct pollfd pfd[1];
+ int error, nready;
+
+ memset(&pfd, 0, sizeof(pfd));
+ pfd[0].fd = fd_pipe[type][0];
+ pfd[0].events = POLLIN;
while (1) {
- count = read(fd_pipe[type][0], buffer, sizeof(buffer));
- if (count == -1) {
- error = errno;
- if (error == EINTR)
+ nready = poll(pfd, 1, 1000 * config_get_rsync_transfer_timeout());
+ if (nready == 0) {
+ pr_val_err("rsync transfer timeout reached");
+ close(fd_pipe[type][0]);
+ return 1;
+ }
+ if (nready == -1) {
+ if (errno == EINTR)
continue;
- close(fd_pipe[type][0]); /* Close read end */
- pr_val_err("rsync buffer read error: %s",
- strerror(error));
- return -error;
+ pr_val_err("rsync bad poll");
+ close(fd_pipe[type][0]);
+ return 1;
+ }
+ if (pfd[0].revents & (POLLERR|POLLNVAL)) {
+ pr_val_err("rsync bad fd: %i", pfd[0].fd);
+ return 1;
+ } else if (pfd[0].revents & (POLLIN|POLLHUP)) {
+ count = read(fd_pipe[type][0], buffer, sizeof(buffer));
+ if (count == -1) {
+ if (errno == EINTR)
+ continue;
+ error = errno;
+ close(fd_pipe[type][0]); /* Close read end */
+ pr_val_err("rsync buffer read error: %s",
+ strerror(error));
+ return -error;
+ }
+ if (count == 0)
+ break;
}
- if (count == 0)
- break;
log_buffer(buffer, count, type);
}
/* This code is run by us. */
error = read_pipes(fork_fds);
if (error)
- kill(child_pid, SIGCHLD); /* Stop the child */
+ kill(child_pid, SIGTERM); /* Stop the child */
error = waitpid(child_pid, &child_status, 0);
do {