Add an optional connection timeout option for the net backend. This can be used to prevent the backend from hanging for several minutes when the saned server is unresponsive.

merge-requests/1/head
Julien BLACHE 2007-10-24 10:32:46 +00:00
rodzic 76b0c6d7e8
commit 4cf4d8dd7f
5 zmienionych plików z 119 dodań i 9 usunięć

Wyświetl plik

@ -1,3 +1,12 @@
2007-10-24 Julien Blache <jb@jblache.org>
* backends/net.c: Add an optional connection timeout for the
initial connection to saned. Based on a patch from Ryan Duryea
<rduryea@avanta.com>. Bump net backend version to 1.0.14.
* backends/net.conf.in: Add the new connect_timeout option and
adjust comments accordingly.
* doc/sane-net.man: Document the connect_timeout option and the
SANE_NET_TIMEOUT environment variable.
2007-10-19 Stephane Voltz <stef.dev@free.fr>
* tools/check-usb-chip.c: added detection of rts8801 and

Wyświetl plik

@ -89,13 +89,13 @@
#if defined (HAVE_GETADDRINFO) && defined (HAVE_GETNAMEINFO)
# define NET_USES_AF_INDEP
# ifdef ENABLE_IPV6
# define NET_VERSION "1.0.13 (AF-indep+IPv6)"
# define NET_VERSION "1.0.14 (AF-indep+IPv6)"
# else
# define NET_VERSION "1.0.13 (AF-indep)"
# define NET_VERSION "1.0.14 (AF-indep)"
# endif /* ENABLE_IPV6 */
#else
# undef ENABLE_IPV6
# define NET_VERSION "1.0.13"
# define NET_VERSION "1.0.14"
#endif /* HAVE_GETADDRINFO && HAVE_GETNAMEINFO */
static SANE_Auth_Callback auth_callback;
@ -105,6 +105,7 @@ static const SANE_Device **devlist;
static int client_big_endian; /* 1 == big endian; 0 == little endian */
static int server_big_endian; /* 1 == big endian; 0 == little endian */
static int depth; /* bits per pixel */
static int connect_timeout = -1; /* timeout for connection to saned */
#ifndef NET_USES_AF_INDEP
static int saned_port;
@ -290,6 +291,7 @@ connect_dev (Net_Device * dev)
int on = 1;
int level = -1;
#endif
struct timeval tv;
int i;
@ -317,6 +319,18 @@ connect_dev (Net_Device * dev)
continue;
}
/* Set SO_SNDTIMEO for the connection to saned */
if (connect_timeout > 0)
{
tv.tv_sec = connect_timeout;
tv.tv_usec = 0;
if (setsockopt (dev->ctl, SOL_SOCKET, SO_SNDTIMEO, &tv, sizeof(tv)) < 0)
{
DBG (1, "connect_dev: [%d] failed to set SO_SNDTIMEO (%s)\n", i, strerror (errno));
}
}
if (connect (dev->ctl, addrp->ai_addr, addrp->ai_addrlen) < 0)
{
DBG (1, "connect_dev: [%d] failed to connect (%s)\n", i, strerror (errno));
@ -348,6 +362,7 @@ connect_dev (Net_Device * dev)
int on = 1;
int level = -1;
#endif
struct timeval tv;
DBG (2, "connect_dev: trying to connect to %s\n", dev->name);
@ -369,6 +384,19 @@ connect_dev (Net_Device * dev)
sin = (struct sockaddr_in *) &dev->addr;
sin->sin_port = saned_port;
/* Set SO_SNDTIMEO for the connection to saned */
if (connect_timeout > 0)
{
tv.tv_sec = connect_timeout;
tv.tv_usec = 0;
if (setsockopt (dev->ctl, SOL_SOCKET, SO_SNDTIMEO, &tv, sizeof(tv)) < 0)
{
DBG (1, "connect_dev: [%d] failed to set SO_SNDTIMEO (%s)\n", i, strerror (errno));
}
}
if (connect (dev->ctl, &dev->addr, sizeof (dev->addr)) < 0)
{
DBG (1, "connect_dev: failed to connect (%s)\n", strerror (errno));
@ -378,6 +406,18 @@ connect_dev (Net_Device * dev)
DBG (3, "connect_dev: connection succeeded\n");
#endif /* NET_USES_AF_INDEP */
/* We're connected now, so reset SO_SNDTIMEO to the default value of 0 */
if (connect_timeout > 0)
{
tv.tv_sec = 0;
tv.tv_usec = 0;
if (setsockopt (dev->ctl, SOL_SOCKET, SO_SNDTIMEO, &tv, sizeof(tv)) < 0)
{
DBG (1, "connect_dev: [%d] failed to reset SO_SNDTIMEO (%s)\n", i, strerror (errno));
}
}
#ifdef TCP_NODELAY
# ifdef SOL_TCP
level = SOL_TCP;
@ -620,6 +660,7 @@ SANE_Status
sane_init (SANE_Int * version_code, SANE_Auth_Callback authorize)
{
char device_name[PATH_MAX];
const char *optval;
const char *env;
size_t len;
FILE *fp;
@ -693,6 +734,29 @@ sane_init (SANE_Int * version_code, SANE_Auth_Callback authorize)
if (!len)
continue; /* ignore empty lines */
/*
* Check for net backend options.
* Anything that isn't an option is a saned host.
*/
if (strstr(device_name, "connect_timeout") != NULL)
{
/* Look for the = sign; if it's not there, error out */
optval = strchr(device_name, '=');
if (!optval)
continue;
optval = sanei_config_skip_whitespace (++optval);
if ((optval != NULL) && (*optval != '\0'))
{
connect_timeout = atoi(optval);
DBG (2, "sane_init: connect timeout set to %d seconds\n", connect_timeout);
}
continue;
}
DBG (2, "sane_init: trying to add %s\n", device_name);
add_device (device_name, 0);
}
@ -747,6 +811,15 @@ sane_init (SANE_Int * version_code, SANE_Auth_Callback authorize)
DBG (1, "sane_init: not enough memory to duplicate "
"environment variable\n");
}
DBG (2, "sane_init: evaluating environment variable SANE_NET_TIMEOUT\n");
env = getenv ("SANE_NET_TIMEOUT");
if (env)
{
connect_timeout = atoi(env);
DBG (2, "sane_init: connect timeout set to %d seconds from env\n", connect_timeout);
}
DBG (2, "sane_init: done\n");
return SANE_STATUS_GOOD;
}

Wyświetl plik

@ -1,4 +1,13 @@
# This is the net config file. Each line names a host to attach to.
# This is the net backend config file.
## net backend options
# Timeout for the initial connection to saned. This will prevent the backend
# from blocking for several minutes trying to connect to an unresponsive
# saned host (network outage, host down, ...). Value in seconds.
# connect_timeout = 60
## saned hosts
# Each line names a host to attach to.
# If you list "localhost" then your backends can be accessed either
# directly or through the net backend. Going through the net backend
# may be necessary to access devices that need special privileges.

Wyświetl plik

@ -1,5 +1,5 @@
:backend "net" ; name of backend
:version "1.0.13"
:version "1.0.14"
:manpage "sane-net"
:url "http://www.penguin-breeder.org/?page=sane-net"

Wyświetl plik

@ -1,4 +1,4 @@
.TH sane-net 5 "8 Oct 2002" "@PACKAGEVERSION@" "SANE Scanner Access Now Easy"
.TH sane-net 5 "24 Oct 2007" "@PACKAGEVERSION@" "SANE Scanner Access Now Easy"
.IX sane-net
.SH NAME
sane-net \- SANE network backend
@ -35,10 +35,24 @@ An IPv6 address can be specified enclosed in square brackets:
.IR [::1] : device
.RE
.SH CONFIGURATION
The contents of the
The
.IR net.conf
file is a list of host names (or IP addresses) that should be contacted for
scan requests. Empty lines and lines starting with a hash mark (#) are
file contains both backend options and a list of host names (or IP
addresses) that should be contacted for scan requests. Anything that
isn't one of the options listed below will be treated as an host name.
.PP
.TP
.B connect_timeout = nsecs
Timeout (in seconds) for the initial connection to the
.I saned
server. This will prevent the backend from blocking for several
minutes trying to connect to an unresponsive
.I saned
host (network outage, host down, ...). The environment variable
.B SANE_NET_TIMEOUT
can also be used to specify the timeout at runtime.
.PP
Empty lines and lines starting with a hash mark (#) are
ignored. Note that IPv6 addresses in this file do not need to be enclosed
in square brackets. A sample configuration file is shown below:
.PP
@ -121,6 +135,11 @@ to "/tmp/config:" would result in directories "tmp/config", ".", and
A colon-separated list of host names or IP addresses to be contacted by this
backend.
.TP
.B SANE_NET_TIMEOUT
Number of seconds to wait for a response from the
.I saned
server for the initial connection request.
.TP
.B SANE_DEBUG_NET
If the library was compiled with debug support enabled, this
environment variable controls the debug level for this backend. E.g.,