Print this page
    
SUS-56 libstmfproxy incorrectly checks socket() return code
    
      
        | Split | 
	Close | 
      
      | Expand all | 
      | Collapse all | 
    
    
          --- old/usr/src/lib/libstmfproxy/common/stmftransport.c
          +++ new/usr/src/lib/libstmfproxy/common/stmftransport.c
   1    1  /*
   2    2   * CDDL HEADER START
   3    3   *
   4    4   * The contents of this file are subject to the terms of the
   5    5   * Common Development and Distribution License (the "License").
   6    6   * You may not use this file except in compliance with the License.
   7    7   *
   8    8   * You can obtain a copy of the license at usr/src/OPENSOLARIS.LICENSE
   9    9   * or http://www.opensolaris.org/os/licensing.
  10   10   * See the License for the specific language governing permissions
  11   11   * and limitations under the License.
  12   12   *
  13   13   * When distributing Covered Code, include this CDDL HEADER in each
  14   14   * file and include the License file at usr/src/OPENSOLARIS.LICENSE.
  15   15   * If applicable, add the following below this CDDL HEADER, with the
  16   16   * fields enclosed by brackets "[]" replaced with your own identifying
  17   17   * information: Portions Copyright [yyyy] [name of copyright owner]
  18   18   *
  19   19   * CDDL HEADER END
  20   20   */
  21   21  /*
  22   22   * Copyright 2009 Sun Microsystems, Inc.  All rights reserved.
  23   23   * Use is subject to license terms.
  24   24   */
  25   25  
  26   26  #include <stdio.h>
  27   27  #include <stdlib.h>
  28   28  #include <string.h>
  29   29  #include <strings.h>
  30   30  #include <sys/types.h>
  31   31  #include <errno.h>
  32   32  #include <syslog.h>
  33   33  #include <unistd.h>
  34   34  #include <sys/types.h>
  35   35  #include <sys/socket.h>
  36   36  #include <sys/time.h>
  37   37  #include <netinet/in.h>
  38   38  #include <arpa/inet.h>
  39   39  #include <netdb.h>
  40   40  #include <sys/stat.h>
  41   41  #include <sys/sdt.h>
  42   42  #include <signal.h>
  43   43  #include <fcntl.h>
  44   44  #include <libstmfproxy.h>
  45   45  
  46   46  /*
  47   47   * NOTE:
  48   48   * This is demo code to be used with the existing demo proxy daemon
  49   49   * svc-stmfproxy in /usr/demo/comstar.
  50   50   */
  51   51  
  52   52  struct _s_handle {
  53   53          int     sockfd;
  54   54  };
  55   55  
  56   56  typedef struct _s_handle s_handle_t;
  57   57  
  58   58  static ssize_t
  59   59  pt_socket_recv(void *handle, void *buf, size_t len)
  60   60  {
  61   61          s_handle_t *sh = handle;
  62   62  
  63   63          return (recv(sh->sockfd, buf, len, MSG_WAITALL));
  64   64  }
  65   65  
  66   66  static ssize_t
  67   67  pt_socket_send(void *handle, void *buf, size_t len)
  68   68  {
  69   69          s_handle_t *sh = handle;
  70   70  
  71   71          return (send(sh->sockfd, buf, len, 0));
  72   72  }
  73   73  
  
    | 
      ↓ open down ↓ | 
    73 lines elided | 
    
      ↑ open up ↑ | 
  
  74   74  static void *
  75   75  pt_socket_connect(int server_node, char *server)
  76   76  {
  77   77          int sfd, new_sfd;
  78   78          s_handle_t *sh = NULL;
  79   79          int on = 1;
  80   80          struct sockaddr_in cli_addr, serv_addr;
  81   81          struct  sockaddr_in sin;
  82   82          int cliLen = sizeof (cli_addr);
  83   83  
  84      -        if ((sfd = socket(AF_INET, SOCK_STREAM, 0)) <= 0) {
       84 +        if ((sfd = socket(AF_INET, SOCK_STREAM, 0)) < 0) {
  85   85                  syslog(LOG_DAEMON|LOG_WARNING,
  86   86                      "socket() call failed: %d", errno);
  87   87                  return (NULL);
  88   88          }
  89   89  
  90   90          if (server_node) {
  91   91  
  92   92                  if (setsockopt(sfd, SOL_SOCKET, SO_REUSEADDR, &on,
  93   93                      sizeof (on)) < 0) {
  94   94                          syslog(LOG_DAEMON|LOG_WARNING,
  95   95                              "setsockopt() failed: %d", errno);
  96   96                          goto serv_out;
  97   97                  }
  98   98  
  99   99                  bzero(&serv_addr, sizeof (serv_addr));
 100  100                  serv_addr.sin_family = AF_INET;
 101  101                  serv_addr.sin_addr.s_addr = htonl(INADDR_ANY);
 102  102                  /* XXX get from smf? */
 103  103                  serv_addr.sin_port = htons(6543);
 104  104  
 105  105                  if (bind(sfd, (struct sockaddr *)&serv_addr,
 106  106                      sizeof (serv_addr)) < 0) {
 107  107                          syslog(LOG_DAEMON|LOG_WARNING, "bind() call failed: %d",
 108  108                              errno);
 109  109                          goto serv_out;
 110  110                  }
 111  111  
 112  112                  (void) listen(sfd, 5);
 113  113  
 114  114                  new_sfd = accept(sfd, (struct sockaddr *)&cli_addr, &cliLen);
 115  115  
 116  116                  if (new_sfd < 0) {
 117  117                          syslog(LOG_DAEMON|LOG_WARNING, "accept failed: %d",
 118  118                              errno);
 119  119                          goto serv_out;
 120  120                  }
 121  121                  sh = malloc(sizeof (*sh));
 122  122                  sh->sockfd = new_sfd;
 123  123  serv_out:
 124  124                  close(sfd);
 125  125          } else {
 126  126                  struct  hostent *hp;
 127  127  
 128  128                  /*
 129  129                   * Assume IP dot notation or if that fails, gethostbyname()
 130  130                   * If that fails, return
 131  131                   */
 132  132                  if ((inet_aton(server, &sin.sin_addr)) == 0) {
 133  133                          if ((hp = gethostbyname(server)) != NULL) {
 134  134                                  memcpy(&sin.sin_addr.s_addr, hp->h_addr,
 135  135                                      hp->h_length);
 136  136                          } else {
 137  137                                  syslog(LOG_DAEMON|LOG_CRIT,
 138  138                                      "Cannot get IP address for %s", server);
 139  139                                  (void) close(sfd);
 140  140                                  return (NULL);
 141  141                          }
 142  142                  } else {
 143  143                          fprintf(stderr,
 144  144                              "Sorry, cannot use ip address format\n");
 145  145                          (void) close(sfd);
 146  146                          return (NULL);
 147  147                  }
 148  148                  sin.sin_family = AF_INET;
 149  149                  /* XXX pass in from smf */
 150  150                  sin.sin_port = htons(6543);
 151  151  
 152  152                  while (connect(sfd, (struct sockaddr *)&sin,
 153  153                      sizeof (sin)) < 0) {
 154  154                          close(sfd);
 155  155                          if (errno == ECONNREFUSED) {
 156  156                                  /* get a fresh socket and retry */
 157  157                                  sfd = socket(AF_INET, SOCK_STREAM, 0);
 158  158                                  if (sfd < 0) {
 159  159                                          syslog(LOG_DAEMON|LOG_WARNING,
 160  160                                              "socket() call failed: %d", errno);
 161  161                                          return (NULL);
 162  162                                  }
 163  163                                  sleep(2);
 164  164                          } else {
 165  165                                  syslog(LOG_DAEMON|LOG_CRIT,
 166  166                                      "Cannot connect %s - %d", server, errno);
 167  167                                  return (NULL);
 168  168                          }
 169  169                  }
 170  170                  sh = malloc(sizeof (*sh));
 171  171                  sh->sockfd = sfd;
 172  172          }
 173  173          return (sh);
 174  174  }
 175  175  
 176  176  pt_ops_t pt_socket_ops = {
 177  177          pt_socket_connect,
 178  178          pt_socket_send,
 179  179          pt_socket_recv
 180  180  };
 181  181  
 182  182  int
 183  183  stmf_proxy_transport_init(char *transport, pt_ops_t **pt_ops)
 184  184  {
 185  185          if (strcmp(transport, "sockets") == 0) {
 186  186                  *pt_ops = &pt_socket_ops;
 187  187                  return (0);
 188  188          } else {
 189  189                  return (-1);
 190  190          }
 191  191  }
  
    | 
      ↓ open down ↓ | 
    97 lines elided | 
    
      ↑ open up ↑ | 
  
XXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXX