예제 #1
0
파일: pbsD_connect.c 프로젝트: dhill12/test
int validate_socket(

  int psock)

  {
  int            rc = PBSE_NONE;
  static char    id[] = "validate_socket";
  char           tmp_buf[LOCAL_LOG_BUF];
  char           write_buf[1024];
  char          *read_buf = NULL;
  long long      read_buf_len = 0;
  uid_t          myrealuid;
  int            local_socket = 0;
  int            parent_client_socket = 0;
  struct passwd *pwent;
  char          *err_msg = NULL;
  char          *l_server = NULL;
  int            l_server_len = 0;
  unsigned short af_family;
  long long      code = -1;
  int            write_buf_len = 0;
  int            local_errno;

  myrealuid = getuid();

  if ((pwent = getpwuid(myrealuid)) == NULL)
    {
    snprintf(tmp_buf, LOCAL_LOG_BUF, "cannot get account info: uid %d, errno %d (%s)\n", (int)myrealuid, errno, strerror(errno));
    log_event(PBSEVENT_ADMIN,PBS_EVENTCLASS_SERVER,id,tmp_buf);
    }
  else if ((rc = get_hostaddr_hostent_af(&local_errno, AUTH_IP, &af_family, &l_server, &l_server_len)) != PBSE_NONE)
    {
    }
  else if ((rc = get_parent_client_socket(psock, &parent_client_socket)) != PBSE_NONE)
    {
    }
  else
    {
    /* format is:
     * trq_system|trq_port|Validation_type|user|psock|
     */
    sprintf(write_buf, "%d|%s|%d|%d|%d|%s|%d|", (int)strlen(server_name), server_name, server_port, AUTH_TYPE_IFF, (int)strlen(pwent->pw_name), pwent->pw_name, parent_client_socket);
    /*
     * total_length|val
     */
    write_buf_len = strlen(write_buf);
    if ((local_socket = socket_get_tcp()) <= 0)
      {
      fprintf(stderr, "socket_get_tcp error\n");
      rc = PBSE_SOCKET_FAULT;
      }
    else if ((rc = socket_connect(&local_socket, l_server, l_server_len, AUTH_PORT, AF_INET, 0, &err_msg)) != PBSE_NONE)
      {
      fprintf(stderr, "socket_connect error (VERIFY THAT trqauthd IS RUNNING)\n");
      }
    else if ((rc = socket_write(local_socket, write_buf, write_buf_len)) != write_buf_len)
      {
      rc = PBSE_SOCKET_WRITE;
      fprintf(stderr, "socket_write error\n");
      }
    else if ((rc = socket_read_num(local_socket, &code)) != PBSE_NONE)
      {
      fprintf(stderr, "socket_read_num error\n");
      }
    else if ((rc = socket_read_str(local_socket, &read_buf, &read_buf_len)) != PBSE_NONE)
      {
      fprintf(stderr, "socket_read_str error\n");
      }
    else if ((rc = parse_daemon_response(code, read_buf_len, read_buf)) != PBSE_NONE)
      {
      fprintf(stderr, "parse_daemon_response error\n");
      }
    else
      {
      if (getenv("PBSDEBUG"))
        {
        fprintf(stderr, "%s : Connection authorized (server socket %d)\n", id, parent_client_socket);
        }
      socket_close(local_socket);
      }
    }
  if (rc != PBSE_NONE)
    {
    if (err_msg != NULL)
      {
      fprintf(stderr, "Error in connection to trqauthd (%d)-[%s]\n", rc, err_msg);
      }
    }
  if (err_msg != NULL)
    free(err_msg);
  if (read_buf != NULL)
    free(read_buf);
  return rc;
  }
예제 #2
0
/* Note, in extremely high load cases, the alloc value in /proc/net/sockstat can exceed the max value. This will substantially slow down throughput and generate connection failures (accept gets a EMFILE error). As the client is designed to run on each submit host, that issue shouldn't occur. The client must be restarted to clear out this issue. */
int start_listener(
    
  const char   *server_ip,
  int            server_port,
  void          *(*process_meth)(void *))

  {
  struct sockaddr_in  adr_svr;
  struct sockaddr_in  adr_client;
  int                 rc = PBSE_NONE;
  int                 sockoptval = 1;
  int                 len_inet = sizeof(struct sockaddr_in);
  int                *new_conn_port = NULL;
  int                 listen_socket = 0;
  int                 total_cntr = 0;
  pthread_t           tid;
  pthread_attr_t      t_attr;
  int objclass = 0;
  char msg_started[1024];

  memset(&adr_svr, 0, sizeof(adr_svr));
  adr_svr.sin_family = AF_INET;

  if (!(adr_svr.sin_port = htons(server_port)))
    {
    }
  else if ((adr_svr.sin_addr.s_addr = inet_addr(server_ip)) == INADDR_NONE)
    {
    rc = PBSE_SOCKET_FAULT;
    }
  else if ((listen_socket = socket_get_tcp()) < 0)
    {
    /* Can not get socket for listening */
    rc = PBSE_SOCKET_FAULT;
    }
  else if (bind(listen_socket, (struct sockaddr *)&adr_svr, sizeof(struct sockaddr_in)) == -1)
    {
    /* Can not bind local socket */
    rc = PBSE_SOCKET_FAULT;
    }
  else if (setsockopt(listen_socket, SOL_SOCKET, SO_REUSEADDR, (void *)&sockoptval, sizeof(sockoptval)) == -1)
    {
    rc = PBSE_SOCKET_FAULT;
    }
  else if (listen(listen_socket, 128) == -1)
    {
    /* Can not listener on local socket */
    rc = PBSE_SOCKET_LISTEN;
    }
  else if ((rc = pthread_attr_init(&t_attr)) != 0)
    {
    /* Can not init thread attribute structure */
    rc = PBSE_THREADATTR;
    }
  else if ((rc = pthread_attr_setdetachstate(&t_attr, PTHREAD_CREATE_DETACHED)) != 0)
    {
    /* Can not set thread initial state as detached */
    pthread_attr_destroy(&t_attr);
    }
  else
    {
    log_get_set_eventclass(&objclass, GETV);
    if (objclass == PBS_EVENTCLASS_TRQAUTHD)
      {
      snprintf(msg_started, sizeof(msg_started),
        "TORQUE authd daemon started and listening on IP:port %s:%d", server_ip, server_port);
      log_event(PBSEVENT_SYSTEM | PBSEVENT_FORCE, PBS_EVENTCLASS_TRQAUTHD,
        msg_daemonname, msg_started);
      }
    while (1)
      {
      if ((new_conn_port = (int *)calloc(1, sizeof(int))) == NULL)
        {
        printf("Error allocating new connection handle on accept.\n");
        break;
        }

      if ((*new_conn_port = accept(listen_socket, (struct sockaddr *)&adr_client, (socklen_t *)&len_inet)) == -1)
        {
        if (errno == EMFILE)
          {
          sleep(1);
          printf("Temporary pause\n");
          }
        else
          {
          printf("error in accept %s\n", strerror(errno));
          break;
          }
        
        errno = 0;
        free(new_conn_port);
        new_conn_port = NULL;
        }
      else
        {
        if (debug_mode == TRUE)
          {
          process_meth((void *)new_conn_port);
          }
        else
          {
          pthread_create(&tid, &t_attr, process_meth, (void *)new_conn_port);
          }
        }
      if (debug_mode == TRUE)
        {
        if (total_cntr % 1000 == 0)
          {
          printf("Total requests: %d\n", total_cntr);
          }
        total_cntr++;
        }
      }
    if (new_conn_port != NULL)
      {
      free(new_conn_port);
      }
    pthread_attr_destroy(&t_attr);
    log_event(PBSEVENT_JOB, PBS_EVENTCLASS_JOB, "net_srvr",
                "Socket close of network listener requested");
    }

  if (listen_socket != -1)
    close(listen_socket);

  return(rc);
  } /* END start_listener() */
예제 #3
0
int socket_get_tcp_priv()

{
    int priv_port = 0, local_socket = 0;
    int cntr = 0;
#ifdef HAVE_RRESVPORT
    int on = 1;
    struct linger l_delay;
#endif
    int rc = PBSE_NONE;
    struct sockaddr_in local;
    int flags;
    memset(&local, 0, sizeof(struct sockaddr_in));
    local.sin_family = AF_INET;

    /* If any of the following 2 succeed (negative conditions) jump to else below
     * else run the default */
#ifdef HAVE_RRESVPORT
    memset(&l_delay, 0, sizeof(struct linger));
    l_delay.l_onoff = 0;
    if ((local_socket = rresvport(&priv_port)) != -1)
    {
        if (setsockopt(local_socket, SOL_SOCKET, SO_REUSEADDR, &on, sizeof(int)) == -1)
        {
            rc = PBSE_SOCKET_FAULT;
        }
        else if (setsockopt(local_socket, SOL_SOCKET, SO_LINGER, &l_delay, sizeof(struct linger)) == -1)
        {
            rc = PBSE_SOCKET_FAULT;
        }
    }
    if (rc == PBSE_NONE)
    {
        /* Success case */
        priv_port = local_socket;
    }
    else if ((local_socket = socket_get_tcp()) > 0)
#else
#ifdef HAVE_BINDRESVPORT
    if ((local_socket = socket_get_tcp()) > 0)
    {
        if ((rc = bindresvport(local_socket, &local)) == 0)
        {
            /* Success case */
            priv_port = ntohs(local.sin_port);
        }
        else
        {
            rc = PBSE_SOCKET_FAULT;
        }
    }
    else
        rc = PBSE_SOCKET_FAULT;
    if (rc != PBSE_NONE)
#else /* Default */
    if ((local_socket = socket_get_tcp()) > 0)
#endif
#endif
    {
        /* According to the notes in the previous code:
         * bindresvport seems to cause connect() failures in some odd corner case
         * when talking to a local daemon.  So we'll only try this once and
         * fallback to the slow loop around bind() if connect() fails
         * with EADDRINUSE or EADDRNOTAVAIL.
         * http://www.supercluster.org/pipermail/torqueusers/2006-June/003740.html
         */

        flags = fcntl(local_socket, F_GETFL);
        flags |= O_NONBLOCK;
        fcntl(local_socket, F_SETFL, flags);

        priv_port = get_random_reserved_port();
        while (cntr < RES_PORT_RETRY)
        {
            if (++priv_port >= RES_PORT_END)
                priv_port = RES_PORT_START;
            local.sin_port = htons(priv_port);
            if (((rc = bind(local_socket, (struct sockaddr *)&local, sizeof(struct sockaddr))) < 0) &&
                    ((rc == EADDRINUSE) ||
                     (errno == EADDRNOTAVAIL) ||
                     (errno == EINVAL) ||
                     (rc == EINPROGRESS)))
            {
                cntr++;
            }
            else
            {
                rc = PBSE_NONE;
                break;
            }
        }
        if (cntr >= RES_PORT_RETRY)
        {
            close(local_socket);
            rc = PBSE_SOCKET_FAULT;
            errno = PBSE_SOCKET_FAULT;
            local_socket = -1;
        }
    }
    else
    {
        /* If something worked the first time you end up here */
        rc = PBSE_NONE;
    }
    if (rc != PBSE_NONE)
    {
        local_socket = -1;
    }
    return local_socket;
} /* END socket_get_tcp_priv() */