setting tcp keepalive on sybase connection
I would like to set tcp keepalives on a sybase connection. I am trying to get this to work on solaris 2.6 with sybase openclient 11.1.1.
I can get the file descriptor out of the sybase connection structure just fine, but when I try and turn keepalive on I get some variant of "Socket operation on non-socket", and keep alives aren't sent.
I have tried this with both "setsockopt(fd, SOL_SOCKET, SO_KEEPALIVE)" and "setsockopt(fd, IPPROTO_TCP, TCP_KEEPALIVE)" and through the awful XTI interfaces and it doesn't work. (With the XTI interfaces the returned status is T_NOTSUPPORTED.). I am quite sure I have the correct file descriptor (because running lsof shows the fd as a TCP connection to the data server.)
I have a test program that just creates a socket, connects to the dataserver, sets keep alive (via "setsock(.., SOL_SOCKET)") and that works just fine. I have turned down "ndd /dev/tcp tcp_keepalive_interval 10000" and see the probes every 10 seconds as expected.
Anyhow, I am just about to give up on this so if anyone has an idea it would be greatly appreciated.
Also, what's the difference between "setsockopt(..., SOL_SOCKET, SO_KEEPALIVE)" and "setsockopt(..., IPPROTO_TCP, TCP_KEEPALIVE)"?
Also, if you have a file descriptor from an XTI TCP/IP connection can you use "setsockopt/getsockopt" on that, or do you have to use "t_optmgmt" instead?
I am including the XTI code I am using below. Thanks.
-Sam
static int tliSetKeepalive(int fd)
{
struct t_optmgmt request, response;
struct {
struct t_opthdr header;
struct t_kpalive value;
} kpRequest, kpResponse;
memset(&kpRequest, 0, sizeof(kpRequest));
kpRequest.header.level = INET_TCP;
kpRequest.header.name = TCP_KEEPALIVE;
kpRequest.header.len = sizeof(kpRequest);
kpRequest.value.kp_onoff = T_YES;
kpRequest.value.kp_timeout = -1;
request.flags = T_NEGOTIATE;
request.opt.maxlen = request.opt.len = sizeof(kpRequest);
request.opt.buf = (char *)&kpRequest;
memset(&kpResponse, 0, sizeof(kpResponse));
kpResponse.header.len = sizeof(kpResponse);
response.flags = 0;
response.opt.maxlen = response.opt.len = sizeof(kpResponse);
response.opt.buf = (char *)&kpResponse;
if (t_optmgmt(fd, &request, &response) != 0 ) {
Logger log;
log << "could not set TCP_KEEPALIVE on socket with t_optmgmt, t_errno="
<< t_errno
<< endl;
return -1;
} else {
Logger log;
log << "set TCP_KEEPALIVE on socket " << fd
<< ", kp_onoff=" << kpResponse.value.kp_onoff
<< ", kp_timeout=" << kpResponse.value.kp_timeout
<< ", status=" << kpResponse.header.status
<< endl;
}
return 0;
}