Exemplo n.º 1
0
int
tds_socketpair(int domain, int type, int protocol, int sv[2])
{
	struct sockaddr_in sa, sa2;
	SOCKLEN_T addrlen;
	TDS_SYS_SOCKET s;

	if (!sv)
		return -1;

	/* create a listener */
	s = socket(AF_INET, type, 0);
	if (TDS_IS_SOCKET_INVALID(s))
		return -1;

	sv[1] = INVALID_SOCKET;

	sv[0] = socket(AF_INET, type, 0);
	if (TDS_IS_SOCKET_INVALID(sv[0]))
		goto Cleanup;

	/* bind to a random port */
	sa.sin_family = AF_INET;
	sa.sin_addr.s_addr = htonl(INADDR_LOOPBACK);
	sa.sin_port = 0;
	if (bind(s, (struct sockaddr*) &sa, sizeof(sa)) < 0)
		goto Cleanup;
	if (listen(s, 1) < 0)
		goto Cleanup;

	/* connect to kernel choosen port */
	addrlen = sizeof(sa);
	if (tds_getsockname(s, (struct sockaddr*) &sa, &addrlen) < 0)
		goto Cleanup;
	if (connect(sv[0], (struct sockaddr*) &sa, sizeof(sa)) < 0)
		goto Cleanup;
	addrlen = sizeof(sa2);
	sv[1] = tds_accept(s, (struct sockaddr*) &sa2, &addrlen);
	if (TDS_IS_SOCKET_INVALID(sv[1]))
		goto Cleanup;

	/* check proper connection */
	addrlen = sizeof(sa);
	if (tds_getsockname(sv[0], (struct sockaddr*) &sa, &addrlen) < 0)
		goto Cleanup;
	addrlen = sizeof(sa2);
	if (tds_getpeername(sv[1], (struct sockaddr*) &sa2, &addrlen) < 0)
		goto Cleanup;
	if (sa.sin_family != sa2.sin_family || sa.sin_port != sa2.sin_port
	    || sa.sin_addr.s_addr != sa2.sin_addr.s_addr)
		goto Cleanup;

	CLOSESOCKET(s);
	return 0;

Cleanup:
	CLOSESOCKET(s);
	CLOSESOCKET(sv[0]);
	CLOSESOCKET(sv[1]);
	return -1;
}
Exemplo n.º 2
0
int
main(int argc, char **argv)
{
	SQLLEN sql_nts = SQL_NTS;
	const char *query;
	SQLINTEGER id = 0;
	char string[64];
	TDS_SYS_SOCKET last_socket;
	int port;
	const int num_inserts = 20;
	int is_freetds;

#ifdef _WIN32
	WSADATA wsaData;
	WSAStartup(MAKEWORD(1, 1), &wsaData);
#endif

	if (tds_mutex_init(&mtx))
		return 1;

	odbc_mark_sockets_opened();

	odbc_connect();

	/*
	 * this does not work if server is not connected with socket
	 * (ie ms driver connected locally)
	 */
	last_socket = odbc_find_last_socket();
	if (TDS_IS_SOCKET_INVALID(last_socket)) {
		fprintf(stderr, "Error finding last socket opened\n");
		return 1;
	}

	remote_addr_len = sizeof(remote_addr);
	if (tds_getpeername(last_socket, &remote_addr.sa, &remote_addr_len)) {
		fprintf(stderr, "Unable to get remote address\n");
		return 1;
	}

	is_freetds = odbc_driver_is_freetds();
	odbc_disconnect();

	/* init fake server, behave like a proxy */
	for (port = 12340; port < 12350; ++port)
		if (!init_fake_server(port))
			break;
	if (port == 12350) {
		fprintf(stderr, "Cannot bind to a port\n");
		return 1;
	}
	printf("Fake server bound at port %d\n", port);

	/* override connections */
	if (is_freetds) {
		setenv("TDSHOST", "127.0.0.1", 1);
		sprintf(string, "%d", port);
		setenv("TDSPORT", string, 1);

		odbc_connect();
	} else {
		char tmp[2048];
		SQLSMALLINT len;

		CHKAllocEnv(&odbc_env, "S");
		CHKAllocConnect(&odbc_conn, "S");
		sprintf(tmp, "DRIVER={SQL Server};SERVER=127.0.0.1,%d;UID=%s;PWD=%s;DATABASE=%s;Network=DBMSSOCN;", port, odbc_user, odbc_password, odbc_database);
		printf("connection string: %s\n", tmp);
		CHKDriverConnect(NULL, T(tmp), SQL_NTS, (SQLTCHAR *) tmp, sizeof(tmp)/sizeof(SQLTCHAR), &len, SQL_DRIVER_NOPROMPT, "SI");
		CHKAllocStmt(&odbc_stmt, "S");
	}

	/* real test */
	odbc_command("CREATE TABLE #test(i int, c varchar(40))");

	odbc_reset_statement();

	/* do not take into account connection statistics */
	tds_mutex_lock(&mtx);
	round_trips = 0;
	inserts = 0;
	tds_mutex_unlock(&mtx);

	query = "insert into #test values (?, ?)";

	CHKBindParameter(1, SQL_PARAM_INPUT, SQL_C_SLONG, SQL_INTEGER, sizeof(id), 0, &id, 0, &sql_nts, "SI");
	CHKBindParameter(2, SQL_PARAM_INPUT, SQL_C_CHAR, SQL_VARCHAR, sizeof(string), 0, string, 0, &sql_nts, "SI");

	CHKPrepare(T(query), SQL_NTS, "SI");
	tds_mutex_lock(&mtx);
	printf("%u round trips %u inserts\n", round_trips, inserts);
	tds_mutex_unlock(&mtx);

	for (id = 0; id < num_inserts; id++) {
		sprintf(string, "This is a test (%d)", (int) id);
		CHKExecute("SI");
		CHKFreeStmt(SQL_CLOSE, "S");
	}

	tds_mutex_lock(&mtx);
	printf("%u round trips %u inserts\n", round_trips, inserts);
	tds_mutex_unlock(&mtx);
	odbc_reset_statement();

	tds_mutex_lock(&mtx);
	if (inserts > 1 || round_trips > (unsigned) (num_inserts * 2 + 6)) {
		fprintf(stderr, "Too much round trips (%u) or insert (%u) !!!\n", round_trips, inserts);
		tds_mutex_unlock(&mtx);
		return 1;
	}
	printf("%u round trips %u inserts\n", round_trips, inserts);
	tds_mutex_unlock(&mtx);

#ifdef ENABLE_DEVELOPING
	/* check for SQL_RESET_PARAMS */
	tds_mutex_lock(&mtx);
	round_trips = 0;
	inserts = 0;
	tds_mutex_unlock(&mtx);

	CHKBindParameter(1, SQL_PARAM_INPUT, SQL_C_SLONG, SQL_INTEGER, sizeof(id), 0, &id, 0, &sql_nts, "SI");
	CHKBindParameter(2, SQL_PARAM_INPUT, SQL_C_CHAR, SQL_VARCHAR, sizeof(string), 0, string, 0, &sql_nts, "SI");

	CHKPrepare((SQLCHAR *) query, SQL_NTS, "SI");
	tds_mutex_lock(&mtx);
	printf("%u round trips %u inserts\n", round_trips, inserts);
	tds_mutex_unlock(&mtx);

	for (id = 0; id < num_inserts; id++) {
		CHKBindParameter(1, SQL_PARAM_INPUT, SQL_C_SLONG, SQL_INTEGER, sizeof(id), 0, &id, 0, &sql_nts, "SI");
		CHKBindParameter(2, SQL_PARAM_INPUT, SQL_C_CHAR, SQL_VARCHAR, sizeof(string), 0, string, 0, &sql_nts, "SI");

		sprintf(string, "This is a test (%d)", (int) id);
		CHKExecute("SI");
		CHKFreeStmt(SQL_RESET_PARAMS, "S");
	}

	tds_mutex_lock(&mtx);
	printf("%u round trips %u inserts\n", round_trips, inserts);
	tds_mutex_unlock(&mtx);
	odbc_reset_statement();

	tds_mutex_lock(&mtx);
	if (inserts > 1 || round_trips > num_inserts * 2 + 6) {
		fprintf(stderr, "Too much round trips (%u) or insert (%u) !!!\n", round_trips, inserts);
		tds_mutex_unlock(&mtx);
		return 1;
	}
	printf("%u round trips %u inserts\n", round_trips, inserts);
	tds_mutex_unlock(&mtx);
#endif

	odbc_disconnect();

	alarm(10);
	tds_thread_join(fake_thread, NULL);

	return 0;
}