Skip to Content.
Sympa Menu

freetds - Re: [freetds] Setting ODBC timeouts

freetds AT lists.ibiblio.org

Subject: FreeTDS Development Group

List archive

Chronological Thread  
  • From: Chris Reeves <csr2 AT st-andrews.ac.uk>
  • To: FreeTDS Development Group <freetds AT lists.ibiblio.org>
  • Subject: Re: [freetds] Setting ODBC timeouts
  • Date: Tue, 19 Aug 2008 19:59:02 +0100

On Mon, Aug 18, 2008 at 08:58:25PM -0400, James K. Lowden wrote:
> Chris Reeves wrote:
> > I set the SQL_ATTR_LOGIN_TIMEOUT and SQL_ATTR_CONNECTION_TIMEOUT
> > attributes using SQLSetConnectAttr and later calls to SQLGetConnectAttr
> > suggest that these attributes have indeed been changed. Despite this, no
> > matter what I set these two attributes to, the login always takes 40
> > seconds to time out and the connection timeout appears to be 'infinite'.
> > The timeouts in /etc/freetds/freetds.conf are both set to 1. The code
> > I'm using runs along the following lines (but with additional error
> > checking included - all calls return SQL_SUCCESS).
>
> ODBC distinguishes between timeouts for connecting and logging in. db-lib
> does not, and the underlying function, tds_connect() appears not to,
> either. You are able to set and get SQL_ATTR_LOGIN_TIMEOUT and
> SQL_ATTR_CONNECTION_TIMEOUT, but they're not used by tds_connect().
>
> I identified this area as something that needs to be addressed a little
> while back. Basically, we need one function that connects and one that
> logs in, and each one can use its own timer. I haven't had time to work
> on it. Patches welcome.

http://msdn.microsoft.com/en-us/library/ms713605(VS.85).aspx and friends have
the following to say about timeouts:
SQL_ATTR_LOGIN_TIMEOUT (ODBC 1.0)
An SQLUINTEGER value corresponding to the number of seconds to wait for a
login request to complete before returning to the application.

SQL_ATTR_QUERY_TIMEOUT (ODBC 1.0)
An SQLUINTEGER value corresponding to the number of seconds to wait for an
SQL statement to execute before returning to the application.

SQL_ATTR_CONNECTION_TIMEOUT (ODBC 3.0)
An SQLUINTEGER value corresponding to the number of seconds to wait for
any request on the connection to complete before returning to the
application. The driver should return SQLSTATE HYT00 (Timeout expired)
anytime that it is possible to time out in a situation not associated with
query execution or login.

As before, I would say that the spec is somewhat open to interpretation. In my
mind it is clear that the login timeout applies to the login process and the
query timeout applies to statement execution. What is less clear is whether
the connection timeout applies only to communication that doesn't fall into
either of these categories or whether it applies to all communications,
*including* those falling into these categories. If the latter, then we would
also have to determine the interaction between the connection timeout and the
login and query timeouts.

I am unable to test the various timeouts and their interaction using the MS
ODBC driver as I don't have any MS-based machines here, however there may be a
clue elsewhere on the above page. SQL_ATTR_LOGIN_TIMEOUT must be set *before*
a connection is made, while SQL_ATTR_CONNECTION_TIMEOUT may be set before or
*after* a connection is made. This implies that the connection timeout does
not apply to (or interact with) the login timeout (although there are also
sensible counter-arguments).

I did checkout the latest source from CVS and spent half an hour or so looking
at it. At the moment odbc_connect uses dbc->attr.connection_timeout as the
timeout value, which corresponds to the SQL_ATTR_CONNECTION_TIMEOUT attribute.
If I set SQL_ATTR_CONNECTION_TIMEOUT instead of SQL_ATTR_LOGIN_TIMEOUT before
connecting then the login times out after the correct length of time when I
DROP the connection packets using iptables (when I simply unplug the network
cable it still takes 40 seconds regardless of what the timeouts are set to,
but I don't see this as an issue just now).

I do completely understand your point about the need to split tds_connect into
two separate functions. However based upon my interpretation of the spec
above, I would suggest that in the interim it would make more sense to use
SQL_ATTR_LOGIN_TIMEOUT when making the initial connection (and a one-line
patch to that effect is attached). This would also be consistent with what
db-lib does when the login timeout is set by dbsetlogintime(). Obviously this
timeout only applies to tds_connect. The packets sent as part of the login
process rely on the query timeout used by tds_goodwrite (as far as I can tell,
there is no way to time out when using SSL). You're right that this needs some
thinking about and a rewrite.

I haven't looked into query timeouts yet and I think this email is long enough
as it is. I'm willing to think about this and possibly submit a patch, but it
would be nice to know how the timeouts interact in the MS ODBC driver. Is
there anyone on the list that could test this and report back? Does setting
SQL_ATTR_CONNECTION_TIMEOUT have any effect on the login timeout or the query
timeout? And if so, is it taken in addition to these timeouts, or is the
smaller of the two timeouts used?

Cheers,
Chris
diff -Naur freetds.orig/src/odbc/odbc.c freetds/src/odbc/odbc.c
--- freetds.orig/src/odbc/odbc.c	2008-08-18 14:31:27.000000000 +0100
+++ freetds/src/odbc/odbc.c	2008-08-19 19:51:49.000000000 +0100
@@ -378,7 +378,7 @@
 
 	tds_fix_connection(connection);
 
-	connection->connect_timeout = dbc->attr.connection_timeout;
+	connection->connect_timeout = dbc->attr.login_timeout;
 
 	if (tds_connect(dbc->tds_socket, connection) == TDS_FAIL) {
 		tds_free_socket(dbc->tds_socket);



Archive powered by MHonArc 2.6.24.

Top of Page