连接超时机制

ODBC连接数据库时,可能会访问的主机未开机,或者输入的IP不存在等原因,不同的原因,ODBC会有不同的处理方式:

  1. 无法快速返回的情况

无法快速返回的情况包括主机未开机、IP不存在:

ODBC采用的是阻塞连接模式,在这种情况下,网络SOCKET的连接超时受平台控制,在Linux下受系统参数net.ipv4.tcp_syn_retries影响,这个参数默认值为6,根据系统参数规则,访问一个不存在的连接时会重试6次,每次等待时间(单位为秒)分别为2,4,8,16.32,64,算上首次连接的1秒,合计127秒,如果想降低超时时间,可以减小操作系统net.ipv4.tcp_syn_retries参数值,比如为3,这超时时间大约为20秒左右返回;Windows下默认等待约20几秒,没有找到控制方法。

  1. 可快速返回的情况

数据库未启动、客户端访问端口号错误、用户名和密码错误等情况,会快速返回,不会有等待。

自动重连机制

神通ODBC提供了ConnResetTimeOut参数设置重连的次数,且每次重试中间间隔1秒,每次重试的耗时由系统配置决定,比如在Linux环境下, 配置了net.ipv4.tcp_syn_retries为3,单次系统超时时间为20秒,ConnResetTimeOut配置为10,总的连接超时时间为(20+1)*10=210秒。

ConnResetTimeOut参数可以在数据源中配置,可以可以在连接字符串中配置。为了降低连接超时时间,需要将ConnResetTimeOut设置的尽量小!

断开连接

当应用程序结束了对数据源的使用之后,需要调用SQLDisconnect来断开和数据源的连接。SQLDisconnect释放所有分配在该连接句柄上的语句句柄, 并将驱动从数据源上断开。断开连接以后,应用程序可以调用SQLFreeHandle释放连接句柄。在程序退出前,应用程序还需要再调用SQLFreeHandle来释放环境句柄。

应用程序在断开连接之后,可以再次使用已经分配的连接句柄,可以去连接另一个数据源,或者去对同一个数据源进行重新连接。如果开启了连接池功能,执行SQLDisconnect后连接其实没有被真实关闭,而是回到连接池中。

连接关闭示例:

SQLDisconnect(hdbc);

SSL安全通信

ODBC支持通过openssl库与数据库端进行安全通信,需要有以下两个步骤:

1)通过设置连接句柄的OSCAR_ATTR_USE_SSL属性来开启是否启用安全连接:

SQLSetConnectAttr(hdbc1, OSCAR_ATTR_USE_SSL, (void*)OSCAR_SSL_ON, 0);

OSCAR_ATTR_USE_SSL属性有3个可选值:

  • OSCAR_SSL_DEFAULT 0 // 不采用新协议,采用传统的发包方式,连接非安全版本数据库服务器
  • OSCAR_SSL_ON 1 // 采用新协议,采用新协议的发包方式,连接安全版本数据库服务器端,并且要求采用SSL连接
  • OSCAR_SSL_OFF 2 //采用新协议,采用新协议的发包方式,连接安全版本数据库服务器端,并且要求采用非SSL连接

2)通过设置连接句柄的属性来设置客户端密钥证书的文件路径和证书密码:

SQLSetConnectAttr(hdbc1, OSCAR_ATTR_PEM_FILE, (void*)szPemFile, strlen(szPemFile));

SQLSetConnectAttr(hdbc1, OSCAR_ATTR_CA_FILE, (void*)szCAFile, strlen(szCAFile));

SQLSetConnectAttr(hdbc1, OSCAR_ATTR_KEY_FILE, (void*)szKeyFile, strlen(szKeyFile));

SQLSetConnectAttr(hdbc1, OSCAR_ATTR_SSL_PWD, (void*)szSSLPwd, strlen(szSSLPwd)));

SQLSetConnectAttr(hdbc1, OSCAR_ATTR_CIPHER_LIST, (void*)szCipherList, strlen(szCipherList));

设置好相关属性后,可调用SQLDriverConnect或SQLConnect连接数据库,这样就会采用安全连接。

  1. 完整示例
SQLRETURN       result;
SQLHDBC         hdbc1;
char *szPemFile = "/opt/ShenTong/admin/SYSDBA.crt";
char *szCAFile = "/opt/ShenTong/admin/ca.crt";
char *szKeyFile = "/opt/ShenTong/admin/SYSDBA.key";
char *szSSLPwd = "szoscar55123456$";
char *szCipherList = "tls1.3,TLS_AES_128_GCM_SHA256";
SQLAllocHandle(SQL_HANDLE_DBC, henv, &hdbc1);

//设置SSL相关属性
result = SQLSetConnectAttr(hdbc1, OSCAR_ATTR_USE_SSL, (void*)OSCAR_SSL_ON, 0);
result = SQLSetConnectAttr(hdbc1, OSCAR_ATTR_PEM_FILE, (void*)szPemFile, strlen(szPemFile));
result = SQLSetConnectAttr(hdbc1, OSCAR_ATTR_CA_FILE, (void*)szCAFile, strlen(szCAFile));
result = SQLSetConnectAttr(hdbc1, OSCAR_ATTR_KEY_FILE, (void*)szKeyFile, strlen(szKeyFile));
result = SQLSetConnectAttr(hdbc1, OSCAR_ATTR_SSL_PWD, (void*)szSSLPwd, strlen(szSSLPwd)));
result = SQLSetConnectAttr(hdbc1, OSCAR_ATTR_CIPHER_LIST, (void*)szCipherList, strlen(szCipherList));

注解

值得注意的是证书密码与数据库用户的密码不同,需要区别使用,登录数据库的用户名必须与生成客户端密钥的用户名一致!

注解

使用ssl安全连接时,用户可以指定SSL安全通信的加密协议及加密算法,加密协议及加密算法之间使用逗号进行分隔。

支持的协议版本有:ssl3、tls1、tls1.1、tls1.2、tls1.3,使用无效的协议版本时,将会无法连接数据库。

操作系统认证(免密)

神通ODBC驱动支持基于OS的免密认证登录,通过OS免密认证,用户可以在不使用用户名和密码时登录数据库,但仅限于应用程序和数据库在同一台主机上时可用;

详细配置方式:

  1. 数据库端:需要确认ENABLE_OPERATING_SYSTEM_AUTHENT参数已经开启,并在数据库端创建一个用户,用户名为:ops$+操作系统用户名,比如当前运行odbc的应用程序的操作系统用户是u1,则需要创建的用户的SQL语句如下:

create user ops$u1 IDENTIFIED EXTERNALLY;

2) odbc端:连接字符串中,需要添加连接选项UserOSAuth,比如:

Driver={OSCAR ODBC DRIVER};SERVER=localhost;DATABASE=osrdb;PORT=2003;UserOSAuth=1;

DSN=odsn;UserOSAuth=1;