Hi.
I use haproxy 1.4.6. when I configured it for my http servers with full
transparent mode, it works in a strange way.
Here is my configuration:
global
maxconn 40000
ulimit-n 80013
defaults
mode http
contimeout 4000
clitimeout 42000
srvtimeout 43000
balance roundrobin
listen VIP_Name 192.168.10.58:80
mode http
option forwardfor
source 0.0.0.0 usesrc clientip
cookie SERVERID insert nocache indirect
server server1 192.168.10.250:80 weight 1 cookie server1 check
option redispatch
After I start haproxy. I cann't connect to 192.168.10.58
But I wrote a small test program which listened on different port xxx.
I telnet the 192.168.10.58 xxx, it works, and after this. I reconnect
192.168.10.58 80, haproxy worked, but if I do not do any other
operations, about two minutes later, haproxy seemed not working again.
And I wrote a small kernel netfilter module for LOCAL_IN chain, the
SYN packet did route to local host, but no syn-ack.
my plateform is :
Linux lknc.hacking 2.6.32.12-115.fc12.i686.PAE #1 SMP Fri Apr 30
20:14:08 UTC 2010 i686 i686 i386 GNU/Linux
and I had set the correct ip rule and iptables rules, ip_forward, etc.
the attach is my test program. can you help me?
/*
* =====================================================================================
*
* Filename: example.c
*
* Description: i
*
* Version: 1.0
* Created: 2010年07月29日 12时13分41秒
* Revision: none
* Compiler: gcc
*
* Author: Xiaoyu Du (souldump), [email protected]
* Company:
*
* =====================================================================================
*/
#include <sys/epoll.h>
#include <sys/types.h>
#include <sys/socket.h>
#include <pthread.h>
#include <sys/select.h>
#include <unistd.h>
#include <signal.h>
#include <string.h>
#include <errno.h>
#include <netinet/in.h>
#include <time.h>
#include <stdio.h>
#include <stdlib.h>
#include <sys/time.h>
#include <fcntl.h>
#include <arpa/inet.h>
#define MAX 3000
#include <linux/tcp.h>
struct table{
char ID[10];
int fd;
int flag;
};
struct table client_table[MAX];
int open_listenfd(unsigned short port);
void do_use_fd(int fd)
{
printf("get client fd %d \n", fd);
}
void mysig(int no)
{
int i;
for(i=0;i<MAX;i++){
if(client_table[i].fd != 0)
{
close(client_table[i].fd);
}
}
exit(0);
}
void setnonblocking(int sock)
{
int opts;
opts=fcntl(sock,F_GETFL);
if(opts<0)
{
perror("fcntl(sock,GETFL)");
}
opts = opts|O_NONBLOCK;
if(fcntl(sock,F_SETFL,opts)<0)
{
perror("fcntl(sock,SETFL,opts)");
}
}
int main()
{
int listener,client,kdpfd,size = MAX,n,nfds,maxevents= 10,count=1;
int index;
struct sockaddr_in client_addr;
socklen_t client_addr_len = sizeof(struct sockaddr_in);
listener = open_listenfd(8000);
if (listener < 0)
{
printf("open_listenfd failed\n");
exit(-1);
}
#if 0
for (;;) {
// client = accept(listener, (struct sockaddr *)&client_addr, sizeof(client_addr));
client = accept(listener, NULL, NULL);
if(client < 0){
printf("accept failed :(%d) %s \n", errno, strerror(errno));
}
else{
printf("accept success %d\n",count++);
}
}
#endif
#if 1
struct epoll_event ev, events[maxevents];
signal(SIGINT,mysig);/* avoid CLOSE_WAIT */
kdpfd = epoll_create(1000);
if (kdpfd < 0) {
printf("epoll_create failed!\n");
}
setnonblocking(listener);
ev.events = EPOLLIN | EPOLLET;
ev.data.fd = listener;
if (epoll_ctl(kdpfd, EPOLL_CTL_ADD, listener, &ev) < 0 )
{
fprintf(stderr, "epoll set insertion error: fd=%d\n",listener);
exit(1);
}
for(;;)
{
nfds = epoll_wait(kdpfd, events, maxevents, -1);
for(n = 0; n < nfds; ++n)
{
if(events[n].data.fd == listener)
{
client = accept(listener, (struct sockaddr *)&client_addr, &client_addr_len);
if(client < 0){
perror("accept");
continue;
}
else{
char buff[128];
if (inet_ntop(AF_INET, &client_addr.sin_addr, buff, 128) == NULL)
printf("inet_ntop failed\n");
else
printf("accept client %s \n",buff);
struct sockaddr_in sa;
socklen_t len;
getpeername(client, (struct sockaddr *)&sa, &len);
printf( "对方IP:%s \n", inet_ntoa(sa.sin_addr));
if (client_addr.sin_addr.s_addr == sa.sin_addr.s_addr)
printf("not equal\n");
}
/* save SOCKET */
/*
for(index=0;index<MAX;index++)
{
if(client_table[index].fd == 0)
{
client_table[index].fd = client;
}
}
*/
/* use hash like */
client_table[client-4].fd = client;
//setnonblocking(client);
ev.events = EPOLLIN | EPOLLET;
ev.data.fd = client;
if (epoll_ctl(kdpfd, EPOLL_CTL_ADD, client, &ev) < 0)
{
fprintf(stderr, "epoll set insertion error: fd=%d\n",client);
return -1;
}
}
else
{
/* read data from client */
do_use_fd(events[n].data.fd);
}
}
}// end for(;;)
#endif
}//end main
int open_listenfd(unsigned short port)
{
int listenfd, optval = 1;
struct sockaddr_in serveraddr;
if( ( listenfd = socket( AF_INET, SOCK_STREAM, 0 )) < 0 )
{
return -1;
}
#define IP_FREEBIND 15
int one = 1;
int zero = 0;
struct linger nolinger = { .l_onoff = 1, .l_linger = 0 };
// setsockopt(listenfd, SOL_SOCKET, SO_REUSEPORT, (char *) &one, sizeof(one));
int accept_delay = 1;
setsockopt(listenfd, IPPROTO_TCP, TCP_DEFER_ACCEPT, &accept_delay, sizeof(accept_delay));
setsockopt(listenfd, SOL_SOCKET, SO_LINGER, (struct linger *) &nolinger, sizeof(struct linger));
if (setsockopt(listenfd, SOL_IP, IP_FREEBIND, (char *) &one, sizeof(one)) < 0)
printf("freebind option failed\n");
if( setsockopt( listenfd, SOL_SOCKET, SO_REUSEADDR, (const void*)&optval, sizeof(int) ) < 0 )
goto error;
#ifndef IP_TRANSPARENT
#define IP_TRANSPARENT 19
setsockopt(listenfd, SOL_IP, IP_TRANSPARENT, (char *) &one, sizeof(one));
#undef IP_TRANSPARENT
#endif
setsockopt(listenfd, IPPROTO_TCP, TCP_NODELAY, (char *) &one, sizeof(one));
setsockopt(listenfd, IPPROTO_TCP, TCP_QUICKACK, (char *) &zero, sizeof(zero));
setsockopt(listenfd, SOL_SOCKET, SO_KEEPALIVE, (char *) &one, sizeof(one));
bzero(( char* )&serveraddr, sizeof(serveraddr) );
serveraddr.sin_family = AF_INET;
serveraddr.sin_addr.s_addr = inet_addr("192.168.10.57");
// serveraddr.sin_addr.s_addr = htonl(INADDR_ANY);
serveraddr.sin_port = htons((unsigned short)99);
if( bind( listenfd, (struct sockaddr *)&serveraddr, sizeof(serveraddr) ) < 0 )
{
goto error ;
}
#if 0
struct sockaddr_in serv;
bzero(( char* )&serv, sizeof(serv) );
serv.sin_family = AF_INET;
serv.sin_addr.s_addr = inet_addr("192.168.10.51");
serv.sin_port = htons((unsigned short)80);
if (connect (listenfd, (struct sockaddr *)&serv, sizeof(struct sockaddr_in)) == -1)
{
printf("connect error!\n");
goto error;
}
else
printf("connect ok!\n");
#endif
if( listen( listenfd, 2000 ) < 0 )
goto error;
return listenfd;
error:
close(listenfd);
return -1;
}