3
/* TODO port to windows, use thread */
4
#if defined(TDS_HAVE_PTHREAD_MUTEX) && HAVE_ALARM
8
#endif /* HAVE_UNISTD_H */
10
#if TIME_WITH_SYS_TIME
12
# include <sys/time.h>
17
# include <sys/time.h>
25
#endif /* HAVE_ERRNO_H */
28
#include <sys/socket.h>
29
#endif /* HAVE_SYS_SOCKET_H */
32
#include <netinet/in.h>
33
#endif /* HAVE_NETINET_IN_H */
40
test connection timeout
43
static char software_version[] = "$Id: timeout3.c,v 1.6 2007/11/26 18:12:31 freddy77 Exp $";
44
static void *no_unused_var_warn[] = { software_version, no_unused_var_warn };
46
static void init_connect(void);
51
if (SQLAllocEnv(&Environment) != SQL_SUCCESS) {
52
printf("Unable to allocate env\n");
56
SQLSetEnvAttr(Environment, SQL_ATTR_ODBC_VERSION, (SQLPOINTER) (SQL_OV_ODBC3), SQL_IS_UINTEGER);
58
if (SQLAllocConnect(Environment, &Connection) != SQL_SUCCESS) {
59
printf("Unable to allocate connection\n");
60
SQLFreeEnv(Environment);
65
static pthread_t fake_thread;
66
static TDS_SYS_SOCKET fake_sock;
68
static void *fake_thread_proc(void * arg);
71
init_fake_server(int ip_port)
73
struct sockaddr_in sin;
77
memset(&sin, 0, sizeof(sin));
78
sin.sin_addr.s_addr = INADDR_ANY;
79
sin.sin_port = htons((short) ip_port);
80
sin.sin_family = AF_INET;
82
if (TDS_IS_SOCKET_INVALID(s = socket(AF_INET, SOCK_STREAM, 0))) {
86
if (bind(s, (struct sockaddr *) &sin, sizeof(sin)) < 0) {
92
err = pthread_create(&fake_thread, NULL, fake_thread_proc, int2ptr(s));
94
perror("pthread_create");
101
fake_thread_proc(void * arg)
103
TDS_SYS_SOCKET s = ptr2int(arg);
106
struct sockaddr_in sin;
108
memset(&sin, 0, sizeof(sin));
111
if ((fake_sock = accept(s, (struct sockaddr *) &sin, &len)) < 0) {
118
/* just read and discard */
119
len = READSOCKET(fake_sock, buf, sizeof(buf));
122
if (len < 0 && sock_errno != TDSSOCK_EINPROGRESS)
129
main(int argc, char *argv[])
136
time_t start_time, end_time;
138
if (read_login_info())
142
* prepare our odbcinst.ini
143
* is better to do it before connect cause uniODBC cache INIs
144
* the name must be odbcinst.ini cause unixODBC accept only this name
147
FILE *f = fopen("odbcinst.ini", "w");
150
fprintf(f, "[FreeTDS]\nDriver = %s\n", DRIVER);
153
setenv("ODBCINSTINI", "./odbcinst.ini", 1);
154
setenv("SYSODBCINSTINI", "./odbcinst.ini", 1);
155
/* force unixODBC (only directory) */
156
setenv("ODBCSYSINI", ".", 1);
160
for (port = 12340; port < 12350; ++port)
161
if (!init_fake_server(port))
164
fprintf(stderr, "Cannot bind to a port\n");
167
printf("Fake server binded at port %d\n", port);
170
res = SQLSetConnectAttr(Connection, SQL_ATTR_CONNECTION_TIMEOUT, (SQLPOINTER) 10, sizeof(SQLINTEGER));
171
if (!SQL_SUCCEEDED(res))
172
ODBC_REPORT_ERROR("SQLSetConnectAttr error");
173
res = SQLSetConnectAttr(Connection, SQL_ATTR_LOGIN_TIMEOUT, (SQLPOINTER) 10, sizeof(SQLINTEGER));
174
if (!SQL_SUCCEEDED(res))
175
ODBC_REPORT_ERROR("SQLSetConnectAttr error");
177
/* this is expected to work with unixODBC */
178
printf("try to connect to our port just to check connection timeout\n");
179
sprintf(tmp, "DRIVER=FreeTDS;SERVER=127.0.0.1;Port=%d;TDS_Version=7.0;UID=test;PWD=test;DATABASE=tempdb;", port);
180
start_time = time(NULL);
181
res = SQLDriverConnect(Connection, NULL, (SQLCHAR *) tmp, SQL_NTS, (SQLCHAR *) tmp, sizeof(tmp), &len, SQL_DRIVER_NOPROMPT);
182
if (SQL_SUCCEEDED(res)) {
183
fprintf(stderr, "SQLDriverConnect should fail (res=%d)\n", (int) res);
186
end_time = time(NULL);
188
strcpy(sqlstate, "XXXXX");
190
res = SQLGetDiagRec(SQL_HANDLE_DBC, Connection, 1, (SQLCHAR *) sqlstate, NULL, (SQLCHAR *) tmp, sizeof(tmp), NULL);
191
if (!SQL_SUCCEEDED(res)) {
192
printf("SQLGetDiagRec should not fail\n");
196
CLOSESOCKET(fake_sock);
197
pthread_join(fake_thread, NULL);
199
printf("Message: %s - %s\n", sqlstate, tmp);
200
if (strcmp(sqlstate, "HYT00") || !strstr(tmp, "Timeout")) {
201
fprintf(stderr, "Invalid timeout message\n");
204
if (end_time - start_time < 10 || end_time - start_time > 16) {
205
fprintf(stderr, "Unexpected connect timeout (%d)\n", (int) (end_time - start_time));
213
#else /* !TDS_HAVE_PTHREAD_MUTEX */
217
printf("Not possible for this platform.\n");