- Package:
- keepalived
- Source:
- keepalived
- Description:
- Failover and monitoring daemon for LVS clusters
- Submitter:
- Bin Tian
- Date:
- 2022-07-04 17:36:08 UTC
- Severity:
- normal
- Tags:
If you add an unreachable route to one realserver, the healthchecker doesn't remove the realserver.
For example,
# ip ro add unreachable 10.1.8.48
# telnet 10.1.8.48 80
Trying 10.1.8.48...
telnet: Unable to connect to remote host: Network is unreachable
But HTTP_GET/SMTP_CHECK/TCP_CHECK isn't aware of the connect problem.
The following codes may be helpful to solve the problem
ipvs1:~# cat a.c
#include <stdio.h>
#include <sys/socket.h>
#include <netinet/in.h>
int main (void)
{
int ret, sock, status;
struct sockaddr_in sa = { AF_INET };
socklen_t slen = sizeof (status);
sa.sin_addr.s_addr = inet_addr ("10.1.8.48");
sa.sin_port = htons (80);
sock = socket (AF_INET, SOCK_STREAM, IPPROTO_TCP);
ret = connect (sock, (struct sockaddr *)&sa, sizeof (sa));
printf ("connect return %d\n", ret);
if (ret != 0)
perror ("connect: ");
/*
After calling connect, keepalived use getsockopt(SO_ERROR)
to get the connection status in function tcp_socket_state.
But it report no error in this case.
*/
ret = getsockopt (sock, SOL_SOCKET, SO_ERROR, (void *) &status, &slen);
if (ret != 0)
perror ("getsockopt: ");
printf ("status = %d\n", status);
};
ipvs1:~# gcc a.c
ipvs1:~# ./a.out
connect return -1
connect: : Network is unreachable
status = 0
ipvs1:~#
I made some corection to the test codes
ipvs1:~# cat a.c
#include <stdio.h>
#include <sys/socket.h>
#include <netinet/in.h>
#include <fcntl.h>
int main (void)
{
int ret, sock, status, flags;
struct sockaddr_in sa = { AF_INET };
socklen_t slen = sizeof (status);
sa.sin_addr.s_addr = inet_addr ("10.1.8.48");
sa.sin_port = htons (8088);
sock = socket (AF_INET, SOCK_STREAM, IPPROTO_TCP);
flags = fcntl(sock, F_GETFL);
fcntl (sock, F_SETFL, flags|O_NONBLOCK);
ret = connect (sock, (struct sockaddr *)&sa, sizeof (sa));
printf ("connect return %d\n", ret);
if (ret != 0)
perror ("connect: ");
/*
After calling connect, keepalived use getsockopt(SO_ERROR)
to get the connection status in function tcp_socket_state.
But it report no error in this case.
*/
ret = getsockopt (sock, SOL_SOCKET, SO_ERROR, (void *) &status, &slen);
if (ret != 0)
perror ("getsockopt: ");
printf ("status = %d\n", status);
};
ipvs1:~# gcc a.c
ipvs1:~# ./a.out
connect return -1
connect: : Network is unreachable
status = 0
ipvs1:~#
Bin Tian wrote: