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;
}

Reply via email to