saned: Cancel scan if data connection appears to have gone away

The data connection timeout default to 4000ms but is configurable
in saned.conf.

See Alioth 315765
merge-requests/1/head
Farid Benamrouche 2017-07-22 21:34:00 +09:00 zatwierdzone przez Olaf Meeuwissen
rodzic 0a62202e95
commit 1f68d8d8c4
2 zmienionych plików z 94 dodań i 5 usunięć

Wyświetl plik

@ -102,6 +102,13 @@ may have performance issues. Use this option if your \fBsaned\fP
server is sitting behind a firewall. If that firewall is a Linux
machine, we strongly recommend using the Netfilter
\fInf_conntrack_sane\fP module instead.
.TP
\fBdata_connect_timeout\fP = \fItimeout\fP
Specify the time in milliseconds that saned will wait for a data
connection. Without this option, if the data connection is not done
before the scanner reaches the end of scan, the scanner will continue
to scan past the end and may damage it depending on the
backend. Specify zero to have the old behavior. The default is 4000ms.
.PP
The access list is a list of host names, IP addresses or IP subnets
(CIDR notation) that are permitted to use local SANE devices. IPv6

Wyświetl plik

@ -251,6 +251,7 @@ static Wire wire;
static int num_handles;
static int debug;
static int run_mode;
static int data_connect_timeout = 4000;
static Handle *handle;
static char *bind_addr;
static union
@ -1734,6 +1735,7 @@ do_scan (Wire * w, int h, int data_fd)
DBG (DBG_ERR, "do_scan: write failed (%s)\n",
strerror (errno));
status = SANE_STATUS_CANCELLED;
handle[h].docancel = 1;
break;
}
bytes_in_buf -= nwritten;
@ -1799,13 +1801,19 @@ do_scan (Wire * w, int h, int data_fd)
{
DBG (DBG_MSG,
"do_scan: processing RPC request on fd %d\n", w->io.fd);
process_request (w);
if(process_request (w) < 0)
handle[h].docancel = 1;
if (handle[h].docancel)
break;
}
}
while (status == SANE_STATUS_GOOD || bytes_in_buf > 0 || status_dirty);
DBG (DBG_MSG, "do_scan: done, status=%s\n", sane_strstatus (status));
if(handle[h].docancel)
sane_cancel (handle[h].handle);
handle[h].docancel = 0;
handle[h].scanning = 0;
}
@ -2062,7 +2070,7 @@ process_request (Wire * w)
case SANE_NET_START:
{
SANE_Start_Reply reply;
int fd = -1, data_fd;
int fd = -1, data_fd = -1;
h = decode_handle (w, "start");
if (h < 0)
@ -2087,9 +2095,36 @@ process_request (Wire * w)
char text_addr[64];
int len;
int error;
struct pollfd fds[1];
int ret;
DBG (DBG_MSG, "process_request: waiting for data connection\n");
data_fd = accept (fd, 0, 0);
fds->fd = fd;
fds->events = POLLIN;
DBG (DBG_MSG, "process_request: waiting 4s for data connection\n");
if(data_connect_timeout)
{
while (1)
{
ret = poll (fds, 1, data_connect_timeout);
if (ret < 0)
{
if (errno == EINTR)
continue;
else
{
DBG (DBG_ERR, "run_standalone: poll failed: %s\n",
strerror (errno));
}
break;
}
break;
}
}
else
ret = 0;
if(ret >= 0)
data_fd = accept (fd, 0, 0);
close (fd);
/* Get address of remote host */
@ -2129,9 +2164,36 @@ process_request (Wire * w)
{
struct sockaddr_in sin;
int len;
int ret;
struct pollfd fds[1];
fds->fd = fd;
fds->events = POLLIN;
DBG (DBG_MSG, "process_request: waiting for data connection\n");
data_fd = accept (fd, 0, 0);
if(data_connect_timeout)
{
while (1)
{
ret = poll (fds, 1, data_connect_timeout);
if (ret < 0)
{
if (errno == EINTR)
continue;
else
{
DBG (DBG_ERR, "run_standalone: poll failed: %s\n", strerror (errno));
}
break;
}
break;
}
}
else
ret = 0;
if(ret >= 0)
data_fd = accept (fd, 0, 0);
close (fd);
/* Get address of remote host */
@ -2735,6 +2797,26 @@ read_config (void)
DBG (DBG_INFO, "read_config: data port range: %d - %d\n", data_port_lo, data_port_hi);
}
}
else if(strstr(config_line, "data_connect_timeout") != NULL)
{
optval = sanei_config_skip_whitespace (++optval);
if ((optval != NULL) && (*optval != '\0'))
{
val = strtol (optval, &endval, 10);
if (optval == endval)
{
DBG (DBG_ERR, "read_config: invalid value for data_connect_timeout\n");
continue;
}
else if ((val < 0) || (val > 65535))
{
DBG (DBG_ERR, "read_config: data_connect_timeout is invalid\n");
continue;
}
data_connect_timeout = val;
DBG (DBG_INFO, "read_config: data connect timeout: %d\n", data_connect_timeout);
}
}
}
fclose (fp);
DBG (DBG_INFO, "read_config: done reading config\n");