Changeset 295 for trunk/src/sh_forward.c


Ignore:
Timestamp:
Oct 31, 2010, 10:36:04 AM (14 years ago)
Author:
katerina
Message:

Support for IPv6 (ticket #222).

File:
1 edited

Legend:

Unmodified
Added
Removed
  • trunk/src/sh_forward.c

    r283 r295  
    121121#endif
    122122
     123#include "sh_ipvx.h"
    123124#include "samhain.h"
    124125#include "sh_tiger.h"
     
    239240       * --> last part must be kept
    240241       */
    241       if (0 != is_numeric(name))
     242      if (0 != sh_ipvx_is_numeric(name))
    242243        {
    243244          SL_RETURN( name, _("sh_strip_domain"));
     
    21872188  char            FileType[5];
    21882189
    2189   struct sockaddr_in addr_peer;
     2190  struct sh_sockaddr addr_peer;
    21902191} sh_conn_t;
    21912192
     
    25922593#endif
    25932594
    2594 int check_addr (const char * claim, struct sockaddr_in addr_peer)
     2595int check_addr (const char * claim, struct sh_sockaddr * addr_peer)
    25952596{
    25962597  char               h_name[MAXHOSTNAMELEN + 1];
    25972598  char               h_peer[MAXHOSTNAMELEN + 1];
    2598   char               h_peer_IP[16];
    2599   char               tmp_peer_IP[16];
    2600   struct hostent   * he;
    2601   char            ** p = NULL;
    2602   int                i;
    2603   int                flag = 0;
     2599  char               h_peer_IP[SH_IP_BUF];
     2600  char               tmp_peer_IP[SH_IP_BUF];
     2601  char             * canonical;
     2602  char               numeric[SH_IP_BUF];
    26042603
    26052604  SL_ENTER(_("check_addr"));
     
    26142613  /* Make sure we have the canonical name for the client
    26152614   */
    2616   he = sh_gethostbyname (claim);
    2617 
    2618   if (he != NULL && he->h_name != NULL)
    2619     {
    2620       if (NULL == strchr(he->h_name, '.') && he->h_addr_list != NULL)
    2621         {
    2622           he = sh_gethostbyaddr(he->h_addr_list[0],
    2623                                 he->h_length,
    2624                                 he->h_addrtype);
    2625         }
    2626     }
     2615  canonical = sh_ipvx_canonical(claim, numeric, sizeof(numeric));
    26272616
    26282617  /* copy canonical name into h_name
    26292618   */
    2630   if (he != NULL && he->h_name != NULL)
    2631     {
    2632       sl_strlcpy(h_name, he->h_name, MAXHOSTNAMELEN + 1);
     2619  if (canonical != NULL)
     2620    {
     2621      sl_strlcpy(h_name, canonical, MAXHOSTNAMELEN + 1);
     2622      SH_FREE(canonical);
    26332623    }
    26342624  else
     
    26422632  /* get canonical name of socket peer
    26432633   */
    2644   he = sh_gethostbyaddr ((char *) &(addr_peer.sin_addr),
    2645                          sizeof(addr_peer.sin_addr),
    2646                          AF_INET);
    2647 
    2648   if (he != NULL && he->h_name != NULL)
    2649     {
    2650       if (0 == sl_strcmp(he->h_name, _("localhost")))
     2634  canonical = sh_ipvx_addrtoname(addr_peer);
     2635
     2636  if (canonical)
     2637    {
     2638      if (0 == sl_strcmp(canonical, _("localhost")))
    26512639        sl_strlcpy(h_peer, sh.host.name, MAXHOSTNAMELEN + 1);
    26522640      else
    2653         sl_strlcpy(h_peer, he->h_name, MAXHOSTNAMELEN + 1);
     2641        sl_strlcpy(h_peer, canonical, MAXHOSTNAMELEN + 1);
     2642      SH_FREE(canonical);
    26542643    }
    26552644  else
    26562645    {
    2657       sl_strlcpy(tmp_peer_IP,
    2658                  inet_ntoa (*(struct in_addr *) &(addr_peer.sin_addr)),
    2659                  16);
     2646      sh_ipvx_ntoa (tmp_peer_IP, sizeof(tmp_peer_IP), addr_peer);
    26602647      sh_error_handle(lookup_err, FIL__, __LINE__, 0, MSG_TCP_RESPEER,
    26612648                      claim, tmp_peer_IP);
     
    26632650    }
    26642651
    2665   sl_strlcpy(h_peer_IP,
    2666              inet_ntoa (*(struct in_addr *) he->h_addr),
    2667              16);
     2652  sh_ipvx_ntoa (h_peer_IP, sizeof(h_peer_IP), addr_peer);
    26682653
    26692654#if 0
     
    26762661  /* reverse lookup
    26772662   */
    2678   if (0 != sl_strncmp(_("127."),
    2679                       inet_ntoa (*(struct in_addr *) &(addr_peer.sin_addr)),
    2680                       4))
    2681     {
    2682       he = sh_gethostbyname(h_peer);
    2683      
    2684       if (he != NULL)
    2685         {
    2686           for (p = he->h_addr_list; *p; ++p)
    2687             {
    2688               if (0 == memcmp (*p, &(addr_peer.sin_addr),
    2689                                sizeof(addr_peer.sin_addr)))
    2690                 break;
    2691             }
    2692         }
    2693       if (he == NULL || *p == NULL)
    2694         {
    2695           sl_strlcpy(tmp_peer_IP,
    2696                      inet_ntoa (*(struct in_addr *) &(addr_peer.sin_addr)),
    2697                      16);
    2698           sh_error_handle(lookup_err, FIL__, __LINE__, 0, MSG_TCP_LOOKERS,
    2699                           claim, h_peer, tmp_peer_IP);
    2700           SL_RETURN ((0), _("check_addr"));
    2701         }
    2702     }
    2703 
    2704   sh_tolower(h_peer);
    2705   sh_tolower(h_name);
     2663  if (0 == sh_ipvx_reverse_check_ok (h_peer, ServerPort, addr_peer))
     2664    {
     2665      sh_ipvx_ntoa (tmp_peer_IP, sizeof(tmp_peer_IP), addr_peer);
     2666
     2667      sh_error_handle(lookup_err, FIL__, __LINE__, 0, MSG_TCP_LOOKERS,
     2668                      claim, h_peer, tmp_peer_IP);
     2669      SL_RETURN ((0), _("check_addr"));
     2670    }
     2671
     2672  /* Check whether claim and peer are identical
     2673   */
     2674
     2675  sh_tolower(h_peer); /* Canonical name of what the peer is     */
     2676  sh_tolower(h_name); /* Canonical name of what the peer claims */
    27062677
    27072678  if ((0 == sl_strcmp(h_peer, h_name)) || (0 == sl_strcmp(h_peer_IP, h_name)))
     
    27092680      SL_RETURN ((0), _("check_addr"));
    27102681    }
     2682#if !defined(USE_IPVX)
    27112683  else
    27122684    {
    2713       i = 0;
     2685      struct hostent   * he = sh_gethostbyname(h_peer);
     2686      int                i = 0;
     2687      int                flag = 0;
     2688
    27142689      while (he->h_aliases[i] != NULL)
    27152690        {
     
    27252700                        claim, h_peer);
    27262701    }
     2702#endif
    27272703
    27282704  SL_RETURN ((0), _("check_addr"));
     
    27422718{
    27432719  client_t * this_client;
    2744   char       peer_ip[16];
     2720  char       peer_ip[SH_IP_BUF];
     2721  char       numerical[SH_IP_BUF];
    27452722  char       peer_name[MAXHOSTNAMELEN+1];
    27462723  char     * search_string;
    2747   struct sockaddr_in peer_addr;
    2748   struct hostent   * he;
    2749   char    ** p = NULL;
     2724
     2725  struct sh_sockaddr peer_addr;
     2726  char             * canonical;
    27502727
    27512728  SL_ENTER(_("search_register"));
     
    27532730  if (UseSocketPeer == S_TRUE)
    27542731    {
    2755       peer_addr = conn->addr_peer;
    2756       sl_strlcpy(peer_ip,
    2757                  inet_ntoa (*(struct in_addr *) &(peer_addr.sin_addr)), 16);
     2732      memcpy(&peer_addr, &(conn->addr_peer), sizeof(struct sh_sockaddr));
     2733      sh_ipvx_ntoa (peer_ip, sizeof(peer_ip), &peer_addr);
    27582734
    27592735      /* get canonical name of socket peer
    27602736       */
    2761       he = sh_gethostbyaddr ((char *) &(peer_addr.sin_addr),
    2762                              sizeof(peer_addr.sin_addr),
    2763                              AF_INET);
    2764 
    2765       if (he != NULL && he->h_name != NULL)
    2766         {
    2767           if (0 == sl_strcmp(he->h_name, _("localhost")))
     2737      canonical = sh_ipvx_canonical(peer_ip, numerical, sizeof(numerical));
     2738
     2739      if (canonical != NULL)
     2740        {
     2741          if (0 == sl_strcmp(canonical, _("localhost")))
    27682742            sl_strlcpy(peer_name, sh.host.name, MAXHOSTNAMELEN + 1);
    27692743          else
    2770             sl_strlcpy(peer_name, he->h_name, MAXHOSTNAMELEN + 1);
    2771 
    2772           /* Reverse lookup
    2773            */
    2774           if (0 != sl_strncmp(peer_ip, _("127."), 4))
    2775             {
    2776               he = sh_gethostbyname(peer_name);
    2777              
    2778               if (he != NULL)
    2779               {
    2780                 for (p = he->h_addr_list; *p; ++p)
    2781                   {
    2782                     if (0 == memcmp (*p, &(peer_addr.sin_addr),
    2783                                      sizeof(peer_addr.sin_addr)))
    2784                       break;
    2785                   }
    2786               }
    2787               if (he == NULL || *p == NULL)
    2788               {
    2789                 /*
    2790                 sh_error_handle(lookup_err, FIL__, __LINE__, 0,
    2791                                 MSG_TCP_LOOKERS,
    2792                                 conn->buf[pos], peer_name, peer_ip);
    2793                 */
    2794                 sl_strlcpy(peer_name, peer_ip, MAXHOSTNAMELEN + 1);
    2795               }
    2796             }
    2797         }
    2798       else
     2744            sl_strlcpy(peer_name, canonical,    MAXHOSTNAMELEN + 1);
     2745          SH_FREE(canonical);
     2746        }
     2747
     2748      if (0 == sh_ipvx_reverse_check_ok (peer_name, ServerPort, &peer_addr))
    27992749        {
    28002750          sl_strlcpy(peer_name, peer_ip, MAXHOSTNAMELEN + 1);
    28012751        }
     2752
    28022753      search_string = peer_name;
    28032754    }
     
    28062757      search_string = &(conn->buf[pos]);
    28072758
    2808       if (0 != check_addr (search_string, conn->addr_peer))
     2759      if (0 != check_addr (search_string, &(conn->addr_peer)))
    28092760        {
    28102761          sh_error_handle((-1), FIL__, __LINE__, 0, MSG_TCP_BADCONN,
     
    36623613                   */
    36633614#if defined(SH_WITH_SERVER) && defined(HAVE_LIBPRELUDE)
    3664                   sh_error_set_peer_ip( inet_ntoa (*(struct in_addr *) &(conn->addr_peer.sin_addr)) );                       
     3615                  {
     3616                    char peer_ip[SH_IP_BUF];
     3617                    sh_ipvx_ntoa(peer_ip, sizeof(peer_ip), conn->addr_peer);
     3618                    sh_error_set_peer_ip( peer_ip );
     3619                  }                       
    36653620#endif
    36663621                  sh_error_set_peer(sh_strip_domain (conn->peer));
     
    46844639  int                errflag;
    46854640  int                rc;
    4686   struct sockaddr_in addr;
     4641  struct sh_sockaddr addr;
    46874642#ifdef SH_USE_LIBWRAP
    46884643  struct request_info request;
     
    46974652  SL_ENTER(_("sh_forward_accept"));
    46984653
    4699   rc = retry_accept(FIL__, __LINE__, sock,
    4700                     (struct sockaddr *) &addr, &addrlen);
     4654  rc = retry_accept(FIL__, __LINE__, sock, &addr, &addrlen);
    47014655
    47024656  if (rc >= 0)
     
    47144668
    47154669#ifdef SH_USE_LIBWRAP
    4716       sl_strlcpy(daemon, SH_INSTALL_NAME, 128);
     4670      sl_strlcpy(daemon, SH_INSTALL_NAME, sizeof(daemon));
    47174671      request_init(&request, RQ_DAEMON, daemon, RQ_FILE, rc, 0);
    47184672      fromhost(&request);
    47194673      if (!hosts_access(&request))
    47204674        {
    4721           sl_strlcpy(errbuf, _("Refused connection from "), 128);
    4722           sl_strlcat(errbuf,   eval_client(&request), 128);
     4675          sl_strlcpy(errbuf, _("Refused connection from "), sizeof(errbuf));
     4676          sl_strlcat(errbuf,   eval_client(&request), sizeof(errbuf));
    47234677
    47244678          sh_error_handle((-1), FIL__, __LINE__, 0, MSG_E_SUBGEN,
     
    47314685#endif
    47324686
    4733       memcpy (&(newconn->addr_peer), &addr, sizeof(struct sockaddr_in));
     4687      memcpy (&(newconn->addr_peer), &addr, sizeof(struct sh_sockaddr));
    47344688
    47354689      /* prepare for usage of connection
     
    47814735}
    47824736
    4783 static struct in_addr server_interface;
     4737static struct sh_sockaddr server_interface;
    47844738static int            use_server_interface = 0;
    47854739
     
    47914745      return 0;
    47924746    }
    4793   if (0 == /*@-unrecog@*/inet_aton(str, &server_interface)/*@+unrecog@*/)
     4747
     4748  if (0 == sh_ipvx_aton(str, &server_interface))
    47944749    {
    47954750      use_server_interface = 0;
    47964751      return -1;
    47974752    }
     4753
    47984754  use_server_interface = 1;
    47994755  return 0;
     
    48824838#ifdef INET_SYSLOG
    48834839#define INET_SUSPEND_TIME 180           /* equal to 3 minutes */
    4884 #define SH_MINSOCK 3
     4840#define SH_MINSOCK_DEFAULT 3
    48854841int create_syslog_socket (int flag);
    48864842static int recv_syslog_socket   (int fd);
    4887 static int syslog_sock = -1;
     4843static int syslog_sock[SH_SOCKMAX] = { -1 };
     4844static int syslog_sock_n = 0;
    48884845#else
    4889 #define SH_MINSOCK 2
    4890 #endif
    4891 
     4846#define SH_MINSOCK_DEFAULT 2
     4847#endif
     4848
     4849static int SH_MINSOCK = SH_MINSOCK_DEFAULT;
    48924850extern int pf_unix_fd;
    48934851
    48944852/* the tcp socket, and the function to establish it
    48954853 */
    4896 static int sh_tcp_sock = -1;
     4854static int sh_tcp_sock[SH_SOCKMAX] = { -1 };
     4855static int sh_tcp_sock_n = 0;
     4856
     4857static int do_socket(int domain, int type, int protocol,
     4858                     struct sockaddr * sa, int salen)
     4859{
     4860  int sock = -1;
     4861  int errnum = 0;
     4862  int flag   = 1; /* non-zero to enable an option */
     4863
     4864  /* create the socket, bind() it and listen()
     4865   */
     4866  if ((sock = socket(domain, type, protocol)) < 0 )
     4867    {
     4868      errnum = errno;
     4869      sh_forward_printerr (_("socket"), errnum, server_port, __LINE__);
     4870      return -1;
     4871    }
     4872  (void) retry_fcntl( FIL__, __LINE__, sock, F_SETFD, 1 );
     4873 
     4874  if ( setsockopt(sock, SOL_SOCKET, SO_REUSEADDR,
     4875                  (void *) &flag, sizeof(flag)) < 0 )
     4876    {
     4877      errnum = errno;
     4878      sh_forward_printerr (_("setsockopt"), errnum, server_port, __LINE__);
     4879      sl_close_fd (FIL__, __LINE__, sock);
     4880      return -1;
     4881    }
     4882 
     4883  if ( bind(sock, (struct sockaddr *) sa, salen) < 0)
     4884    {
     4885      if (errno != EADDRINUSE)
     4886        {
     4887          errnum = errno;
     4888          sh_forward_printerr (_("bind"), errnum, server_port, __LINE__);
     4889          sl_close_fd (FIL__, __LINE__, sock);
     4890          return -1;
     4891        }
     4892      else
     4893        {
     4894          sl_close_fd (FIL__, __LINE__, sock);
     4895          return -2;
     4896        }
     4897    }
     4898 
     4899  if ( retry_fcntl( FIL__, __LINE__, sock, F_SETFL, O_NONBLOCK ) < 0 )
     4900    {
     4901      errnum = errno;
     4902      sh_forward_printerr (_("fcntl"), errnum, server_port, __LINE__);
     4903      sl_close_fd (FIL__, __LINE__, sock);
     4904      return -1;
     4905    }
     4906 
     4907  if ( listen(sock, 64) < 0)
     4908    {
     4909      errnum = errno;
     4910      sh_forward_printerr (_("listen"), errnum, server_port, __LINE__);
     4911      sl_close_fd (FIL__, __LINE__, sock);
     4912      return -1;
     4913    }
     4914
     4915  return sock;
     4916}
    48974917
    48984918int sh_create_tcp_socket (void)
    48994919{
     4920#if defined(USE_IPVX)
     4921  struct addrinfo *ai;
     4922  struct addrinfo *p;
     4923  struct addrinfo hints;
     4924  char            port[32];
     4925#else
    49004926  struct sockaddr_in addr;
    49014927  int addrlen      = sizeof(addr);
     4928#endif
    49024929
    49034930  int sock   = -1;
    4904   int errnum = 0;
    4905   int flag   = 1; /* non-zero to enable an option */
    49064931
    49074932  SL_ENTER(_("sh_create_tcp_socket"));
     
    49094934  sh_forward_printerr (NULL, 0, server_port, __LINE__);
    49104935
    4911   /* create the socket, bind() it and listen()
    4912    */
    4913   if ((sock = socket(AF_INET, SOCK_STREAM, 0)) < 0 )
    4914     {
    4915       errnum = errno;
    4916       sh_forward_printerr (_("socket"), errnum, server_port, __LINE__);
    4917       SL_RETURN((-1), _("sl_create_tcp_socket"));
    4918     }
    4919   (void) retry_fcntl( FIL__, __LINE__, sock, F_SETFD, 1 );
    4920  
    4921   if ( setsockopt(sock, SOL_SOCKET, SO_REUSEADDR,
    4922                   (void *) &flag, sizeof(flag)) < 0 )
    4923     {
    4924       errnum = errno;
    4925       sh_forward_printerr (_("setsockopt"), errnum, server_port, __LINE__);
    4926       SL_RETURN((-1), _("sl_create_tcp_socket"));
    4927     }
    4928  
    4929   addr.sin_family      = AF_INET;
    4930   addr.sin_port        = htons(server_port);
     4936#if defined(USE_IPVX)
     4937  if (use_server_interface == 0)
     4938    {
     4939      memset (&hints, '\0', sizeof (hints));
     4940      hints.ai_flags = AI_PASSIVE | AI_ADDRCONFIG;
     4941      hints.ai_socktype = SOCK_STREAM;
     4942      sl_snprintf(port, sizeof(port), "%d", server_port);
     4943
     4944      if (getaddrinfo (NULL, port, &hints, &ai) != 0)
     4945        {
     4946          int errnum = errno;
     4947          sh_forward_printerr (_("getaddrinfo"), errnum, server_port, __LINE__);
     4948          sl_close_fd (FIL__, __LINE__, sock);
     4949          SL_RETURN((-1), _("sl_create_tcp_socket"));
     4950        }
     4951     
     4952      p = ai;
     4953     
     4954      while (p != NULL && sh_tcp_sock_n < SH_SOCKMAX)
     4955        {
     4956          sock = do_socket(p->ai_family, p->ai_socktype, p->ai_protocol,
     4957                           p->ai_addr, p->ai_addrlen);
     4958         
     4959          if (sock >= 0) {
     4960            if (sh_tcp_sock_n < SH_SOCKMAX) {
     4961              sh_tcp_sock[sh_tcp_sock_n] = sock;
     4962              ++sh_tcp_sock_n;
     4963            }
     4964            else {
     4965              sl_close_fd (FIL__, __LINE__, sock);
     4966            }   
     4967          } else if (sock == -1) {
     4968            freeaddrinfo (ai);
     4969            goto end;
     4970          }
     4971          p = p->ai_next;
     4972        }
     4973     
     4974      freeaddrinfo (ai);
     4975    }
     4976  else
     4977    {
     4978      sh_ipvx_set_port(&server_interface, server_port);
     4979
     4980      sock = do_socket(server_interface.ss_family, SOCK_STREAM, 0,
     4981                       sh_ipvx_sockaddr_cast(&server_interface),
     4982                       SH_SS_LEN(server_interface));
     4983     
     4984      if (sock >= 0) {
     4985        sh_tcp_sock[0] = sock;
     4986        sh_tcp_sock_n  = 1;
     4987      }
     4988    }         
     4989#else
    49314990  if (use_server_interface == 0)
    49324991    addr.sin_addr.s_addr = INADDR_ANY;
    49334992  else
    4934     memcpy(&addr.sin_addr, &server_interface, sizeof(struct in_addr));
     4993    memcpy(&addr, sh_ipvx_sockaddr_cast(&server_interface), addrlen);
     4994  addr.sin_family      = AF_INET;
     4995  addr.sin_port        = htons(server_port);
    49354996 
    4936   if ( bind(sock, (struct sockaddr *) &addr, addrlen) < 0)
    4937     {
    4938       errnum = errno;
    4939       sh_forward_printerr (_("bind"), errnum, server_port, __LINE__);
    4940       SL_RETURN((-1), _("sl_create_tcp_socket"));
    4941     }
    4942  
    4943   if ( retry_fcntl( FIL__, __LINE__, sock, F_SETFL, O_NONBLOCK ) < 0 )
    4944     {
    4945       errnum = errno;
    4946       sh_forward_printerr (_("fcntl"), errnum, server_port, __LINE__);
    4947       SL_RETURN((-1), _("sl_create_tcp_socket"));
    4948     }
    4949  
    4950   if ( listen(sock, 5) < 0)
    4951     {
    4952       errnum = errno;
    4953       sh_forward_printerr (_("listen"), errnum, server_port, __LINE__);
    4954       SL_RETURN((-1), _("sl_create_tcp_socket"));
    4955     }
    4956 
    4957   sh_tcp_sock = sock;
    4958 
    4959   SL_RETURN((sock), _("sl_create_tcp_socket"));
     4997  sock = do_socket(AF_INET, SOCK_STREAM, 0, (struct sockaddr *) &addr, addrlen);
     4998
     4999  if (sock >= 0) {
     5000      sh_tcp_sock[0] = sock;
     5001      sh_tcp_sock_n  = 1;
     5002  }
     5003
     5004#endif
     5005
     5006#if defined(USE_IPVX)
     5007 end:
     5008#endif
     5009  if (sh_tcp_sock_n > 1)
     5010    SH_MINSOCK += (sh_tcp_sock_n - 1);
     5011
     5012  SL_RETURN((sh_tcp_sock_n), _("sl_create_tcp_socket"));
    49605013}
    49615014
     
    49845037  int                nowconn;
    49855038  int                status;
    4986   int                high_fd;
     5039  int                high_fd = -1;
    49875040  register int       i;
    49885041  long               dummy = 0;
     
    50005053
    50015054  int setsize_fd;
     5055
     5056  int sock_tcp[2];
     5057  int sock_unix;
     5058#ifdef INET_SYSLOG
     5059  int sock_log[2];
     5060#endif
    50025061 
    50035062  SL_ENTER(_("sh_receive"));
     
    50155074      aud_exit(FIL__, __LINE__, EXIT_FAILURE);
    50165075    }
    5017   sock = sh_tcp_sock;
     5076
     5077  sock = sh_tcp_sock[0];
    50185078
    50195079  /* ****************************************************************
     
    50315091   */
    50325092  maxconn    = get_open_max() - 6;
     5093
    50335094  /* ugly fix for FreeBSD compiler warning; casting FD_SETSIZE in the
    50345095   * conditional expression does not suppress the warning... */
     
    50795140  /* conns[0] is the listen() socket. Always in read mode.
    50805141   */
    5081   conns[0].fd    = sock;
    5082   conns[0].state = CONN_READING;
    5083   high_fd = sock;
     5142  sock = 0;
     5143
     5144  sock_tcp[0] = 0;
     5145  while (sock < sh_tcp_sock_n)
     5146    {
     5147      conns[sock].fd    = sh_tcp_sock[sock];
     5148      conns[sock].state = CONN_READING;
     5149      high_fd = (sh_tcp_sock[sock] > high_fd) ? sh_tcp_sock[sock] : high_fd;
     5150      ++sock;
     5151    }
     5152  sock_tcp[1] = sock;
    50845153 
    5085   conns[1].fd    = pf_unix_fd;
    5086   conns[1].state = CONN_READING;
     5154  conns[sock].fd    = pf_unix_fd;
     5155  conns[sock].state = CONN_READING;
    50875156  high_fd = (pf_unix_fd > high_fd) ? pf_unix_fd : high_fd;
    5088  
     5157
     5158  sock_unix = sock;
     5159
     5160  ++sock;
     5161
    50895162#ifdef INET_SYSLOG
    5090   conns[2].fd = -1;
     5163  conns[sock].fd = -1;
     5164
    50915165  if ( sh_forward_printerr_final(1) < 0)
    50925166    {
     
    50955169      aud_exit(FIL__, __LINE__, EXIT_FAILURE);
    50965170    }
    5097   sock = syslog_sock;
    5098 
    5099   if (sock >= 0)
    5100     {
    5101       conns[2].fd    = sock;
    5102       conns[2].state = CONN_READING;
    5103       high_fd = (high_fd > conns[2].fd) ? high_fd : conns[2].fd;
     5171
     5172  sock_log[0] = sock;
     5173  sock_log[1] = sock;
     5174
     5175  if (syslog_sock_n > 0)
     5176    {
     5177      int s2;
     5178      for (s2 = 0; s2 < syslog_sock_n; ++s2)
     5179        {
     5180          conns[sock].fd    = syslog_sock[s2];
     5181          conns[sock].state = CONN_READING;
     5182          high_fd = (high_fd > conns[sock].fd) ? high_fd : conns[sock].fd;
     5183          ++sock;
     5184        }
     5185      sock_log[1] = sock;
     5186
    51045187    }
    51055188#endif
     
    51535236
    51545237            (void) sh_readconf_read ();
     5238
    51555239            for (i = SH_MINSOCK; i < maxconn; ++i)
    51565240              if (conns[i].state != CONN_FREE   &&
     
    52305314      FD_ZERO( &readset );
    52315315      FD_ZERO( &writeset );
    5232       FD_SET(conns[0].fd, &readset );
    5233       high_fd   = conns[0].fd;
    5234 
    5235       if (conns[1].fd > -1)
    5236         {
    5237           FD_SET(conns[1].fd, &readset );
    5238           high_fd   = (high_fd > conns[1].fd) ? high_fd : conns[1].fd;
     5316      high_fd = conns[0].fd;
     5317
     5318      for (sock = sock_tcp[0]; sock < sock_tcp[1]; ++sock)
     5319        {
     5320          FD_SET(conns[sock].fd, &readset );
     5321          high_fd   = (high_fd > conns[sock].fd) ? high_fd : conns[sock].fd;
     5322        }
     5323
     5324      if (conns[sock_unix].fd > -1)
     5325        {
     5326          FD_SET(conns[sock_unix].fd, &readset );
     5327          high_fd   = (high_fd > conns[sock_unix].fd) ? high_fd : conns[sock_unix].fd;
    52395328        }
    52405329
    52415330#ifdef INET_SYSLOG
    5242       if (conns[2].fd > -1)
    5243         {
    5244           FD_SET(conns[2].fd, &readset );
    5245           high_fd   = (high_fd > conns[2].fd) ? high_fd : conns[2].fd;
     5331      for (sock = sock_log[0]; sock < sock_log[1]; ++sock)
     5332        {
     5333          if (conns[sock].fd > -1)
     5334            {
     5335              FD_SET(conns[sock].fd, &readset );
     5336              high_fd   = (high_fd > conns[sock].fd) ? high_fd : conns[sock].fd;
     5337            }
    52465338        }
    52475339#endif
     
    54055497      /* New connection.
    54065498       */
    5407       if ( FD_ISSET(conns[0].fd , &readset )) /* a new connection   */
    5408         {
    5409           --num_sel;
    5410           status = 0;
    5411           if (nowconn < maxconn && sig_terminate == 0 && sig_termfast == 0)
     5499      for (sock = sock_tcp[0]; sock < sock_tcp[1]; ++sock)
     5500        {
     5501          if ( FD_ISSET(conns[sock].fd , &readset )) /* a new connection   */
    54125502            {
    5413               i = SH_MINSOCK;
    5414               while (i < maxconn)
     5503              --num_sel;
     5504              status = 0;
     5505              if (nowconn < maxconn && sig_terminate == 0 && sig_termfast == 0)
    54155506                {
    5416                   if (conns[i].state == CONN_FREE)
     5507                  /* Find a free slot to accept the connection
     5508                   */
     5509                  i = SH_MINSOCK;
     5510                  while (i < maxconn)
    54175511                    {
    5418                       status = sh_forward_accept (conns[0].fd, &conns[i]);
    5419                       if (status == 0)
     5512                      if (conns[i].state == CONN_FREE)
    54205513                        {
    5421                           high_fd =
    5422                             (high_fd > conns[i].fd ? high_fd : conns[i].fd);
    5423                           ++server_status.conn_open;
    5424                           ++server_status.conn_total;
    5425                           server_status.last = time (NULL);
     5514                          /* Here we run the accept() and copy the peer to
     5515                           * the free slot.
     5516                           */
     5517                          status = sh_forward_accept(conns[sock].fd, &conns[i]);
     5518                         
     5519                          if (status == 0)
     5520                            {
     5521                              high_fd =
     5522                                (high_fd > conns[i].fd ? high_fd : conns[i].fd);
     5523                              ++server_status.conn_open;
     5524                              ++server_status.conn_total;
     5525                              server_status.last = time (NULL);
     5526                            }
     5527                          break;
    54265528                        }
    5427                       break;
     5529                      ++i;
    54285530                    }
    5429                   ++i;
    54305531                }
     5532              /* This re-runs select to accept data on the new
     5533               * connection, rather than first dealing with old
     5534               * connections.
     5535               */
     5536              if (status == 0)
     5537                continue;
    54315538            }
    5432           if (status == 0)
    5433             continue;
    54345539        }
    54355540     
    54365541      /* check for commands on the socket
    54375542       */
    5438       if (conns[1].fd > (-1) && FD_ISSET(conns[1].fd , &readset ))
     5543      if (conns[sock_unix].fd > (-1) && FD_ISSET(conns[sock_unix].fd , &readset ))
    54395544        {
    54405545          sh_socket_poll();
     
    54425547
    54435548#ifdef INET_SYSLOG
    5444       if (conns[2].fd > (-1) && FD_ISSET(conns[2].fd , &readset ))
    5445         {
    5446           recv_syslog_socket (conns[2].fd);
     5549      for (sock = sock_log[0]; sock < sock_log[1]; ++sock)
     5550        {
     5551          if (conns[sock].fd > (-1) && FD_ISSET(conns[sock].fd , &readset ))
     5552            {
     5553              recv_syslog_socket (conns[sock].fd);
     5554            }
    54475555        }
    54485556#endif
     
    55035611
    55045612#ifdef INET_SYSLOG
    5505 
    5506 #ifdef HAVE_INET_ATON
    5507 static char * my_inet_ntoa(struct in_addr in)
    5508 {
    5509   return inet_ntoa(in);
    5510 }
    5511 #else
    5512 static char * my_inet_ntoa(struct in_addr in)
    5513 {
    5514   unsigned char a, b, c, d;
    5515   static char   foo[16];
    5516   char          bar[4];
    5517   memcpy (bar, &(in.s_addr), 4); /* memory alignment (?) */
    5518   memcpy (&a, &bar[0], 1);
    5519   memcpy (&b, &bar[1], 1);
    5520   memcpy (&c, &bar[2], 1);
    5521   memcpy (&d, &bar[3], 1);
    5522   sprintf(foo, "%d.%d.%d.%d",                       /* known to fit  */
    5523           (int) a, (int) b, (int) c, (int) d);
    5524   return foo;
    5525 }
    5526 #endif
    5527 
    55285613
    55295614/* Unlike Linux / FreeBSD, most systems don't define the stuff below
     
    56755760  char errbuf[SH_ERRBUF_SIZE];
    56765761
     5762  struct sh_sockaddr ss;
     5763  struct sockaddr * sa = (struct sockaddr *) &from;
     5764  char   namebuf[SH_BUFSIZE];
     5765
    56775766  /* The 6th argument in recvfrom is *socklen_t in Linux and *BSD,
    56785767   * but *int everywhere else. Because socklen_t is unsigned int, there
     
    56965785  res = recvfrom(fd,  buf,  1047, 0, (struct sockaddr *) &from, &fromlen);
    56975786
     5787  sh_ipvx_save(&ss, sa->sa_family, &from);
     5788  sh_ipvx_ntoa(namebuf, sizeof(namebuf), &ss);
     5789
    56985790  if (res > 0)
    56995791    {
     
    57155807          sh_error_handle((-1), FIL__, __LINE__, res, MSG_ERR_SYSLOG,
    57165808                          sh_error_message(res, errbuf, sizeof(errbuf)),
    5717                           my_inet_ntoa(from.sin_addr));
     5809                          namebuf);
    57185810          SL_RETURN( (-1), _("recv_syslog_socket"));
    57195811        }     
    57205812
    5721       TPT(( 0, FIL__, __LINE__, _("msg=<UDP message from %s>\n"),
    5722             my_inet_ntoa(from.sin_addr)));
     5813      TPT(( 0, FIL__, __LINE__, _("msg=<UDP message from %s>\n"), namebuf ));
     5814
    57235815      ptr = bptr;
    57245816      i = 0;
     
    57755867      sh_error_handle((-1), FIL__, __LINE__, res, MSG_ERR_SYSLOG,
    57765868                      sh_error_message(res, errbuf, sizeof(errbuf)),
    5777                       my_inet_ntoa(from.sin_addr));
     5869                      namebuf);
    57785870
    57795871      /* don't accept anything the next 2 seconds
     
    57905882}
    57915883
    5792 /* callerFlag == S_TRUE means override the enable_syslog_socket flag
    5793  */
    5794 int create_syslog_socket (int callerFlag)
     5884static int do_syslog_socket(int domain, int type, int protocol,
     5885                            struct sockaddr * sa, int salen)
    57955886{
    57965887  int                flag = 1;  /* non-zero to enable an option */
     
    57985889  int errnum;
    57995890  int res;
     5891
     5892  /* create the socket, bind() it and listen()
     5893   */
     5894  sock = socket(domain, type, protocol);
     5895
     5896  if (sock < 0)
     5897    {
     5898      errnum = errno;
     5899      sh_forward_printerr (_("syslog socket"), errnum, 514, __LINE__);
     5900      return -1;
     5901    }
     5902  (void) retry_fcntl( FIL__, __LINE__, sock, F_SETFD, 1 );
     5903 
     5904  if ( setsockopt(sock, SOL_SOCKET, SO_REUSEADDR,
     5905                  (void *) &flag, sizeof(flag)) < 0 )
     5906    {
     5907      errnum = errno;
     5908      sh_forward_printerr (_("syslog setsockopt SO_REUSEADDR"),
     5909                           errnum, 514, __LINE__);
     5910      return -1;
     5911    }
     5912
     5913#if defined(SO_BSDCOMPAT)
     5914  if ( setsockopt(sock, SOL_SOCKET, SO_BSDCOMPAT,
     5915                  (void *) &flag, sizeof(flag)) < 0 )
     5916    {
     5917      errnum = errno;
     5918      sh_forward_printerr (_("syslog setsockopt SO_BSDCOMPAT"),
     5919                           errnum, 514, __LINE__);
     5920      return -1;
     5921    }
     5922#endif
     5923 
     5924  res = bind(sock, sa, salen);
     5925
     5926  if ( res < 0)
     5927    {
     5928      errnum = errno;
     5929      sh_forward_printerr (_("syslog bind"), errnum, 514, __LINE__);
     5930      sl_close_fd(FIL__, __LINE__, sock);
     5931      return -1;
     5932    }
     5933  return sock;
     5934}
     5935
     5936/* callerFlag == S_TRUE means override the enable_syslog_socket flag
     5937 */
     5938int create_syslog_socket (int callerFlag)
     5939{
     5940  int sock;
     5941
     5942#if defined(USE_IPVX)
     5943  struct addrinfo *ai;
     5944  struct addrinfo *p;
     5945  struct addrinfo hints;
     5946#else
    58005947  struct sockaddr_in addr;
    58015948  int addrlen      = sizeof(addr);
     5949#endif
    58025950
    58035951  SL_ENTER(_("create_syslog_socket"));
     
    58115959          TPT(( 0, FIL__, __LINE__, _("msg=<close syslog socket>\n")));
    58125960          sl_close_fd(FIL__, __LINE__, syslog_sock);
    5813           syslog_sock = -1;
     5961          syslog_sock[0] = -1;
    58145962        }
    58155963      SL_RETURN((-1), _("create_syslog_socket"));
     
    58185966  sh_forward_printerr (NULL, 0, 514, __LINE__);
    58195967
    5820   /* create the socket, bind() it and listen()
    5821    */
    5822   sock = socket(AF_INET, SOCK_DGRAM, 0);
    5823 
    5824   if (sock < 0)
    5825     {
    5826       errnum = errno;
    5827       sh_forward_printerr (_("syslog socket"), errnum, 514, __LINE__);
    5828       SL_RETURN((-1), _("create_syslog_socket"));
    5829     }
    5830   (void) retry_fcntl( FIL__, __LINE__, sock, F_SETFD, 1 );
    5831  
    5832   if ( setsockopt(sock, SOL_SOCKET, SO_REUSEADDR,
    5833                   (void *) &flag, sizeof(flag)) < 0 )
    5834     {
    5835       errnum = errno;
    5836       sh_forward_printerr (_("syslog setsockopt SO_REUSEADDR"),
    5837                            errnum, 514, __LINE__);
    5838       SL_RETURN((-1), _("create_syslog_socket"));
    5839     }
    5840 
    5841 #if defined(SO_BSDCOMPAT)
    5842   if ( setsockopt(sock, SOL_SOCKET, SO_BSDCOMPAT,
    5843                   (void *) &flag, sizeof(flag)) < 0 )
    5844     {
    5845       errnum = errno;
    5846       sh_forward_printerr (_("syslog setsockopt SO_BSDCOMPAT"),
    5847                            errnum, 514, __LINE__);
    5848       SL_RETURN((-1), _("create_syslog_socket"));
    5849     }
    5850 #endif
    5851  
     5968#if !defined(USE_IPVX)
     5969
    58525970  memset(&addr, 0, sizeof(addr));
    58535971  addr.sin_family      = AF_INET;
    58545972  addr.sin_port        = htons(514);
    58555973 
    5856   res = bind(sock, (struct sockaddr *) &addr, addrlen);
    5857 
    5858   if ( res < 0)
     5974  do_syslog_socket(AF_INET, SOCK_DGRAM, 0, (struct sockaddr *) &addr, addrlen);
     5975
     5976  if (sock >= 0) {
     5977    syslog_sock[0] = sock;
     5978    syslog_sock_n  = 1;
     5979  }
     5980
     5981#else
     5982  memset (&hints, '\0', sizeof (hints));
     5983  hints.ai_flags = AI_PASSIVE | AI_ADDRCONFIG;
     5984  hints.ai_socktype = SOCK_DGRAM;
     5985  if (getaddrinfo (NULL, "syslog", &hints, &ai) != 0)
    58595986    {
    58605987      errnum = errno;
    5861       sh_forward_printerr (_("syslog bind"), errnum, 514, __LINE__);
    5862       sl_close_fd(FIL__, __LINE__, sock);
     5988      sh_forward_printerr (_("getaddrinfo"), errnum, 514, __LINE__);
     5989      sl_close_fd (FIL__, __LINE__, sock);
    58635990      SL_RETURN((-1), _("create_syslog_socket"));
    58645991    }
    5865 
    5866   syslog_sock = sock;
    5867 
    5868   SL_RETURN((sock), _("create_syslog_socket"));
     5992 
     5993  p = ai;
     5994
     5995  while (p != NULL && syslog_sock_n < SH_SOCKMAX)
     5996    {
     5997      sock = do_syslog_socket(p->ai_family, p->ai_socktype, p->ai_protocol,
     5998                              p->ai_addr, p->ai_addrlen);
     5999     
     6000      if (sock >= 0) {
     6001        if (syslog_sock_n < SH_SOCKMAX) {
     6002          syslog_sock[syslog_sock_n] = sock;
     6003          ++syslog_sock_n;
     6004        }
     6005        else {
     6006          sl_close_fd (FIL__, __LINE__, sock);
     6007        }   
     6008      } else if (sock == -1) {
     6009        freeaddrinfo (ai);
     6010        goto end;
     6011      }
     6012      p = p->ai_next;
     6013    }
     6014  freeaddrinfo (ai);
     6015#endif
     6016
     6017 end:
     6018  if (syslog_sock_n > 1)
     6019    SH_MINSOCK += (syslog_sock_n - 1);
     6020
     6021  SL_RETURN((syslog_sock_n), _("create_syslog_socket"));
    58696022}
    58706023/* #ifdef INET_SYSLOG */
Note: See TracChangeset for help on using the changeset viewer.