Пример #1
0
/**
 * parses command line arguments and assigns
 * values to run time variables. relies on GNU
 * getopts included with this distribution.  
 */ 
void 
parse_cmdline( int argc, char *argv[] )
{
  int c = 0;
  int nhosts;

  while(( c = getopt_long( argc, argv, "VhvCDH:i", long_options, (int *)0)) != EOF ){
  switch( c ){
      case 'V':
        display_version( TRUE );
        break;
      case 'h':
        display_help();
        exit( EXIT_SUCCESS );
      case 'v':
        my.verbose = TRUE;
        break;
      case 'C':
        my.config = TRUE;
        break;
      case 'D':
        my.debug = TRUE;
        break;
      case 'i':
        my.images = TRUE;
        break;
      case 'H':
        {
          int ll;
          if(!strchr(optarg,':')) joe_fatal("no ':' in http-header");
          if((strlen(optarg) + strlen(my.extra) + 3) > 512)
              joe_fatal("too many headers");
          strcat(my.extra,optarg);
          strcat(my.extra,"\015\012");
        }
        break; 
    } /** end of switch( c )           **/
  }   /** end of while c = getopt_long **/
  nhosts = argc - optind;
  if( my.config ){ show_config( TRUE );   }
  if( !nhosts )  { display_help( TRUE );  }
  else{ my.url = strdup( argv[argc-1] );  }
} /* end of parse_cmdline */
Пример #2
0
char *stralloc(char *str)
{ 
  char *retval;
 
  retval=calloc(strlen(str)+1, 1);
  if(!retval) {
    joe_fatal("Fatal memory allocation error");
  }
  strcpy(retval, str);
  return retval;
} 
Пример #3
0
/**
 * scout main
 */  
int 
main( int argc, char *argv[] )
{
  int x, result;                /* index, func. result*/
  struct sigaction  action;   
  CLIENT           *client;     /* defined in setup.h */  
 
  init_config();                /* defined in init.h */
  parse_cmdline(argc, argv);    /* defined above     */
  
  if( my.config ){
    /* see: init.h */  
    show_config( TRUE );    
  }

  memset( &action, 0, sizeof( action ));
  action.sa_handler = signal_handler;
  if( sigaction( SIGHUP, &action, NULL ))
    joe_error( "sigaction" );
  if( sigaction( SIGINT, &action, NULL))
    joe_error( "sigaction" );
  if( sigaction( SIGTERM, &action, NULL))
    joe_error( "sigaction" );

  /* cookie is an EXTERN, defined in setup */ 
  cookie = (COOKIE*)malloc( sizeof(COOKIE)); 
  if( !cookie ){ joe_fatal( "memory exhausted" ); }
  cookie->first = NULL;
  client = (CLIENT*)malloc(sizeof(CLIENT));
  if( !client ){ joe_fatal( "application memory exhausted" ); } 

  http_client( client );
  write_queue( my.showcodes );
  /**
   * exit program.
   */
  exit( EXIT_SUCCESS );	
} /* end of int main **/
Пример #4
0
BOOLEAN
SSL_initialize(CONN *C)
{
#ifdef HAVE_SSL
  int  i;
  int  serr;
  
  C->ssl    = NULL;
  C->ctx    = NULL;
  C->method = NULL;
  C->cert   = NULL; 
  
  SSL_load_error_strings();
  SSL_library_init();
  if(!my.ssl_key && my.ssl_cert) {
    my.ssl_key = my.ssl_cert;
  }
  if(!my.ssl_ciphers) {
    my.ssl_ciphers = stralloc(SSL_DEFAULT_CIPHER_LIST);
  } 

  C->method = SSLv23_client_method();
  if(C->method==NULL){
    SSL_error_stack();
    return FALSE;
  } 
  C->ctx = SSL_CTX_new(C->method);
  if(C->ctx==NULL){
    SSL_error_stack();
    return FALSE;
  } 

  SSL_CTX_set_mode(C->ctx, SSL_MODE_ENABLE_PARTIAL_WRITE|SSL_MODE_ACCEPT_MOVING_WRITE_BUFFER);
  SSL_CTX_set_session_cache_mode(C->ctx, SSL_SESS_CACHE_BOTH);
  SSL_CTX_set_timeout(C->ctx, my.ssl_timeout);
  if(my.ssl_ciphers){
    if(!SSL_CTX_set_cipher_list(C->ctx, my.ssl_ciphers)){
      joe_error("SSL_CTX_set_cipher_list");
      return FALSE;
    }
  }

  if(my.ssl_cert){
    if(!SSL_CTX_use_certificate_chain_file(C->ctx, my.ssl_cert)){
      SSL_error_stack(); /* dump the error stack */
      joe_fatal("Error reading certificate file: %s", my.ssl_cert);
    }
    for(i=0; i<3; i++){
      if(SSL_CTX_use_PrivateKey_file(C->ctx, my.ssl_key, SSL_FILETYPE_PEM))
        break;
      if(i<2 && ERR_GET_REASON(ERR_peek_error())==EVP_R_BAD_DECRYPT){
        SSL_error_stack(); /* dump the error stack */
        log_warning("Wrong pass phrase: retrying");
        continue;
      }
    }

    if(!SSL_CTX_check_private_key(C->ctx)){
      joe_error("Private key does not match the certificate");
      return FALSE;
    }
  }  

  C->ssl = SSL_new(C->ctx);
  if(C->ssl==NULL){
    SSL_error_stack();
    return FALSE;
  }
  SSL_set_fd(C->ssl, C->sock);
  serr = SSL_connect(C->ssl);
  return TRUE;
#else
  return FALSE;
#endif/*HAVE_SSL*/
}
Пример #5
0
int 
main(int argc, char *argv[])
{
  int            x; 
  int            result;
  DATA           D = new_data();
  CREW           crew;           /* thread pool - crew.h */
  LINES          *lines;         /* defined in setup.h   */
  CLIENT         *client;        /* defined in setup.h   */
  URL            **urls;         /* urls struct array    */
  pthread_t      cease;          /* the shutdown thread  */
  pthread_t      timer;          /* the timer thread     */
  pthread_attr_t scope_attr;     /* set to PTHREAD_SCOPE_SYSTEM */
  unsigned int   randrseed;      /* seed pthread_rand_np */
  char           exlogmsg[512];
  void *statusp;
  sigset_t sigs;

  sigemptyset(&sigs);
  sigaddset(&sigs, SIGHUP);
  sigaddset(&sigs, SIGINT);
  sigaddset(&sigs, SIGALRM);
  sigaddset(&sigs, SIGTERM);
  sigprocmask(SIG_BLOCK, &sigs, NULL);

  lines = xcalloc(sizeof(LINES),1);
  lines->index   = 0;
  lines->line    = NULL;

  memset(&my, 0, sizeof(struct CONFIG));

  parse_rc_cmdline(argc, argv); 
  if(init_config() < 0){        /* defined in init.h   */
    exit( EXIT_FAILURE );       /* polly was a girl... */
  } 
  parse_cmdline(argc, argv);    /* defined above       */
  ds_module_check();            /* check config integ  */

  if(my.get){
    my.cusers  = 1;
    my.reps    = 1;
    my.logging = FALSE;
    my.bench   = TRUE;
  } 

  if(my.config){
    show_config(TRUE);    
  }

  if(my.url != NULL){
    my.length = 1; 
  } else { 
    my.length = read_cfg_file( lines, my.file ); 
  }

  if(my.length == 0){ 
    display_help();
  }

  /* cookie is an EXTERN, defined in setup */ 
  cookie = xcalloc(sizeof(COOKIE), 1); 
  cookie->first = NULL;
  if((result = pthread_mutex_init( &(cookie->mutex), NULL)) !=0){
    joe_fatal( "pthread_mutex_init" );
  } 

  /* memory allocation for threads and clients */
  urls   = xmalloc(my.length * sizeof(URL));
  client = xmalloc(sizeof(CLIENT) * my.cusers);
  if((crew = new_crew(my.cusers, my.cusers, FALSE)) == NULL){
    joe_fatal("unable to allocate memory for %d simulated browser", my.cusers);  
  }

  /** 
   * determine the source of the url(s),
   * command line or file, and add them
   * to the urls struct.
   */
  if(my.url != NULL){
    urls[0]   =  add_url(my.url, 1);         /* from command line  */
  } else { 
    for(x = 0; x < my.length; x ++){
      urls[x] =  add_url(lines->line[x], x); /* from urls.txt file */
    }
  } 

  /**
   * display information about the siege
   * to the user and prepare for verbose 
   * output if necessary.
   */
  if(!my.get){
    fprintf(stderr, "** "); 
    display_version(FALSE);
    fprintf(stderr, "** Preparing %d concurrent users for battle.\n", my.cusers);
    fprintf(stderr, "The server is now under siege...");
    if(my.verbose){ fprintf(stderr, "\n"); }
	if(my.extralog) { 
		snprintf(exlogmsg, sizeof exlogmsg, "** Preparing %d concurrent users for battle.", my.cusers);
		log_extra(exlogmsg);
		log_extra("The server is now under siege...");
	}
  }

  /**
   * record start time before spawning threads
   * as the threads begin hitting the server as
   * soon as they are created.
   */
  data_set_start(D);

  /**
   * for each concurrent user, spawn a thread and
   * loop until condition or pthread_cancel from the
   * handler thread.
   */
  pthread_attr_init(&scope_attr);
  pthread_attr_setscope(&scope_attr, PTHREAD_SCOPE_SYSTEM);
#if defined(_AIX)
  /* AIX, for whatever reason, defies the pthreads standard and  *
   * creates threads detached by default. (see pthread.h on AIX) */
  pthread_attr_setdetachstate(&scope_attr, PTHREAD_CREATE_JOINABLE);
#endif

  /** 
   * invoke OpenSSL's thread safety
   */
#ifdef HAVE_SSL
  SSL_thread_setup();
#endif

  /**
   * create the signal handler and timer;  the
   * signal handler thread (cease) responds to
   * ctrl-C (sigterm) and the timer thread sends
   * sigterm to cease on time out.
   */
  if((result = pthread_create(&cease, NULL, (void*)sig_handler, (void*)crew)) < 0){
    joe_fatal("failed to create handler: %d\n", result);
  }
  if(my.secs > 0){
    if((result = pthread_create(&timer, NULL, (void*)siege_timer, (void*)cease)) < 0){
      joe_fatal("failed to create handler: %d\n", result);
    } 
  }
  
  randrseed = time(0);

  /**
   * loop until my.cusers and create a corresponding thread...
   */  
  for(x = 0; x < my.cusers && crew_get_shutdown(crew) != TRUE; x++){
    client[x].id              = x; 
    client[x].bytes           = 0;
    client[x].time            = 0.0;
    client[x].hits            = 0;
    client[x].code            = 0;
    client[x].ok200           = 0;   
    client[x].fail            = 0; 
    client[x].U               = urls;
    client[x].auth.www        = 0;
    client[x].auth.proxy      = 0;
    client[x].auth.type.www   = BASIC;
    client[x].auth.type.proxy = BASIC;
    client[x].rand_r_SEED     = pthread_rand_np(&randrseed);
    result = crew_add(crew, (void*)start_routine, &(client[x]));
    if(result == FALSE){ 
      my.verbose = FALSE;
      fprintf(stderr, "Unable to spawn additional threads; you may need to\n");
      fprintf(stderr, "upgrade your libraries or tune your system in order\n"); 
      fprintf(stderr, "to exceed %d users.\n", my.cusers);
      joe_fatal("system resources exhausted"); 
    }
  } /* end of for pthread_create */

  crew_join(crew, TRUE, &statusp);

#ifdef HAVE_SSL
  SSL_thread_cleanup();
#endif

  /**
   * collect all the data from all the threads that
   * were spawned by the run.
   */
  for(x = 0; x < ((crew_get_total(crew) > my.cusers || 
                   crew_get_total(crew)==0 ) ? my.cusers : crew_get_total(crew)); x++){
    data_increment_count(D, client[x].hits);
    data_increment_bytes(D, client[x].bytes);
    data_increment_total(D, client[x].time);
    data_increment_code (D, client[x].code);
    data_increment_ok200(D, client[x].ok200);
    data_increment_fail (D, client[x].fail);
    data_set_highest    (D, client[x].bigtime);
    data_set_lowest     (D, client[x].smalltime);
    client[x].rand_r_SEED = pthread_rand_np(&randrseed);
  } /* end of stats accumulation */
  
  /**
   * record stop time
   */
  data_set_stop(D);

  /**
   * cleanup crew
   */ 
  crew_destroy(crew);

  if(my.get){
    if(data_get_count(D) > 0){
      exit(EXIT_SUCCESS);
    } else {
      printf("[done]\n");
      exit(EXIT_FAILURE);
    }
  }

  /**
   * take a short nap  for  cosmetic  effect
   * this does NOT affect performance stats.
   */
  pthread_usleep_np(10000);
  if(my.verbose)
    fprintf(stderr, "done.\n");
  else
    fprintf(stderr, "\b      done.\n");
  if(my.extralog)
	log_extra("done.");

  /**
   * prepare and print statistics.
   */
  if(my.failures > 0 && my.failed >= my.failures){
    fprintf(stderr, "%s aborted due to excessive socket failure; you\n", program_name);
    fprintf(stderr, "can change the failure threshold in $HOME/.%src\n", program_name);
  }
  fprintf(stderr, "\bTransactions:\t\t%12u hits\n",        data_get_count(D));
  fprintf(stderr, "Availability:\t\t%12.2f %%\n",          data_get_count(D)==0 ? 0 :
                                                           (double)data_get_count(D) /
                                                           (data_get_count(D)+my.failed)
                                                           *100
  );
  fprintf(stderr, "Elapsed time:\t\t%12.2f secs\n",        data_get_elapsed(D));
  fprintf(stderr, "Data transferred:\t%12.2f MB\n",        data_get_megabytes(D)); /*%12llu*/
  fprintf(stderr, "Response time:\t\t%12.2f secs\n",       data_get_response_time(D));
  fprintf(stderr, "Transaction rate:\t%12.2f trans/sec\n", data_get_transaction_rate(D));
  fprintf(stderr, "Throughput:\t\t%12.2f MB/sec\n",        data_get_throughput(D));
  fprintf(stderr, "Concurrency:\t\t%12.2f\n",              data_get_concurrency(D));
  fprintf(stderr, "Successful transactions:%12u\n",        data_get_code(D)); 
  if(my.debug){
    fprintf(stderr, "HTTP OK received:\t%12u\n",             data_get_ok200(D));
  }
  fprintf(stderr, "Failed transactions:\t%12u\n",          my.failed);
  fprintf(stderr, "Longest transaction:\t%12.2f\n",        data_get_highest(D));
  fprintf(stderr, "Shortest transaction:\t%12.2f\n",       data_get_lowest(D));
  fprintf(stderr, " \n");
  if(my.mark)    mark_log_file(my.markstr);
  if(my.logging) log_transaction(D);

  data_destroy(D);
  if(my.url == NULL){
    for(x = 0; x < my.length; x++)
       xfree(lines->line[x]);
    xfree(lines->line);
    xfree(lines);
  }  

  exit(EXIT_SUCCESS);	
} /* end of int main **/
Пример #6
0
/**
 * parses command line arguments and assigns
 * values to run time variables. relies on GNU
 * getopts included with this distribution.  
 */ 
void 
parse_cmdline(int argc, char *argv[])
{
  int c = 0;
  int nargs;
  while((c = getopt_long( argc, argv, "VhvCDglibr:t:f:d:c:u:m:H:R:A:E:", 
          long_options, (int *)0)) != EOF){
  switch(c){
      case 'V':
        display_version(TRUE);
        break;
      case 'h':
        display_help();
        exit(EXIT_SUCCESS);
      case 'D':
        my.debug = TRUE;
        break;
      case 'C':
        my.config = TRUE;
        break;
      case 'c':
        my.cusers  = atoi(optarg);
        break;
      case 'i':
        my.internet = TRUE;
        break;
      case 'b':
        my.bench    = TRUE;
        break;
      case 'd':
	/* XXX range checking? use strtol? */
        my.delay   = atoi(optarg);
	if(my.delay < 0){
	  my.delay = 0; 
	}
        break;
      case 'g':
        my.get = TRUE;
        break;
      case 'l':
        my.logging = TRUE;
        break;
      case 'm':
        my.mark    = TRUE;
        my.markstr = optarg;
        my.logging = TRUE; 
        break;
      case 'v':
        my.verbose = TRUE;
        break;
      case 'r':
        my.reps = atoi(optarg);
        break;
      case 't':
        parse_time(optarg);
        break;
      case 'f':
        memset(my.file, 0, sizeof(my.file));
        if(optarg == NULL) break; /*paranoia*/
        strncpy(my.file, optarg, strlen(optarg));
        break;
      case 'u':
        printf("-u has been deprecated.\n");
        display_help(); 
        exit(1);
        break;
      case 'A':
        strncpy(my.uagent, optarg, 255);
        break;
      case 'R':  
        /**
         * processed above 
         */
        break; 
      case 'H':
        {
          if(!strchr(optarg,':')) joe_fatal("no ':' in http-header");
          if((strlen(optarg) + strlen(my.extra) + 3) > 512)
              joe_fatal("too many headers");
          strcat(my.extra,optarg);
          strcat(my.extra,"\015\012");
        }
        break;
      case 'E':
	    my.extralog = TRUE;
		memset(my.exfile, 0, sizeof(my.exfile));
        if(optarg == NULL) break; /*paranoia*/
        strncpy(my.exfile, optarg, strlen(optarg));
		break;
    } /* end of switch( c )           */
  }   /* end of while c = getopt_long */
  nargs = argc - optind;
  if(nargs)
    my.url = xstrdup(argv[argc-1]); 
  if(my.get && my.url==NULL){
    puts("ERROR: -g/--get requires a commandline URL");
    exit(1);
  }
  return;
} /* end of parse_cmdline */