Ejemplo n.º 1
0
static void* do_icmp_parse(void *arg)
{
	if (arg) {}

	while (1)
	{
		struct itun_packet *packet = packets_take(params->packets_receive);
		if (packet == NULL)
			break;

		struct connection_data *data = (struct connection_data *) packet->connection;

		switch (packet->header->type)
		{
			case TYPE_CONNECT:
			{
				struct connection_data *data = init_connection_data(packet);
				if (data == NULL)
					break;

				struct in_addr addr = {packet->client_ip};
				char *from_ip = inet_ntoa(addr);

				printf("Received connect packet from %s\n", from_ip);

				if (pthread_create(&data->server_connect, NULL, do_server_connect, (void *) data) == -1)
					error("Error %d occured in pthread_create(server_connect)", errno);
				break;
			}
			case TYPE_SHUTDOWN_READ:
			{
				if (is_shutdown_done(data, SHUTDOWN_WRITE))
					break;

				printf("Received SHUTDOWN_READ command\n");
				data_add(params->client_buffer, NULL, 0, data);

				break;
			}
			case TYPE_SHUTDOWN_WRITE:
			{
				if (is_shutdown_done(data, SHUTDOWN_READ))
					break;

				printf("Received SHUTDOWN_WRITE command\n");
				data_add(data->client_buffer, NULL, 0, data);

				break;
			}
			case TYPE_DATA:
			{
				printf("I->L readed %d bytes\n", packet->header->length);

				data_add(data->client_buffer, packet->data, packet->header->length, data);
				break;
			}
		}

		packets_free_packet(packet);
	}

	pthread_exit(NULL);
}
Ejemplo n.º 2
0
void start_client(config_t *config) {
  thread_t *threads=NULL;
  int i;
  int j;
  int rc;
  int  *status;
  int mode;
  conn_stats_t **tstat;
  pthread_attr_t attr;
  struct rlimit limits;
  struct sigaction action;
  sigset_t mask;
  getrlimit( RLIMIT_NPROC ,&limits);
  if(limits.rlim_max<config->threads+2) {
    error_at_line(0,0,__FILE__,__LINE__, "Insufficient resources: NPROC < %d\n", config->threads+2);
    return;
  }
  limits.rlim_cur=limits.rlim_max;
  setrlimit(RLIMIT_NPROC, &limits);
  
  threads=malloc(sizeof(thread_t)*config->threads);
  memset(threads, 0, sizeof(thread_t)*config->threads);
  
  for(i=0; i<config->threads; i++) {
    threads[i].thread_idx=i;
    if(config->recv_mode==ASYNC) {
      if(i%2) {
	mode=THREAD_ASYNC_RECV;
      } else {
	mode=THREAD_ASYNC_SEND;
      }
    } else {
      mode=THREAD_SYNC;
    }
    
    switch(mode) {
      case THREAD_SYNC:

	break;
      case THREAD_ASYNC_RECV:
	threads[i].mode=THREAD_ASYNC_RECV;
	break;
      case THREAD_ASYNC_SEND:
	threads[i].mode=THREAD_ASYNC_SEND;
	threads[i].read=&threads[i+1];
	threads[i].efd_write=epoll_create1(0);
	threads[i].write=&threads[i];	
	//Since we are in ASYNC mode, we are hiding the extra 2x threads
	//for stats keeping.	
	threads[i].thread_stats=&(config->stats->thread_stats[i/2]);
      default:
	break;
    }   
    threads[i].mode=mode;
    if(mode==THREAD_SYNC || mode==THREAD_ASYNC_SEND) {    
      	threads[i].conns=malloc(sizeof(connection_t)*config->conns_per_thread);
	memset(threads[i].conns,0,sizeof(connection_t)*config->conns_per_thread);
	threads[i].write=&threads[i];
	threads[i].efd_write=epoll_create1(0);
	if(mode==THREAD_SYNC) {
	  threads[i].read=&threads[i];
	  threads[i].efd_read=epoll_create1(0);	
	  threads[i].thread_stats=&(config->stats->thread_stats[i]);
	} else {
	  threads[i].read=&threads[i+1];
	//Since we are in ASYNC mode, we are hiding the extra 2x threads
	//for stats keeping.
	  threads[i].thread_stats=&(config->stats->thread_stats[i/2]);
	}
    } else {
	threads[i].read=&threads[i];
	threads[i].write=&threads[i-1];
	threads[i].efd_read=epoll_create1(0);
	threads[i].thread_stats=&(config->stats->thread_stats[i/2]);  
	threads[i].conns=threads[i-1].conns;
    }
    threads[i].cfg=config;
    if(mode==SYNC || i%2==0) {
      for(j=0; j<config->conns_per_thread; j++) {
	tstat=&threads[i].conns[j].conn_stats;
	threads[i].conns[j].conn_stats=&threads[i].thread_stats->conn_stats[j];
	threads[i].conns[j].cfg=config;
	init_connection_data(config, &threads[i].conns[j], mode);
      }
    }

  }
  if(config->mcast_wait) {
    //printf("mcast_wait\n");
    mcast_wait();
  }
  action.sa_flags=SA_SIGINFO;
  action.sa_sigaction=run_timeout;
  sigemptyset(&action.sa_mask);
  sigaction(SIG_RUNTIMEEXP, &action, NULL);
  sigemptyset(&mask);
  sigaddset(&mask, SIG_RUNTIMEEXP);
  if (sigprocmask(SIG_UNBLOCK, &mask, NULL) == -1) {
      perror("sigprocmask");
  }
  if(config->threads==1) {
    rc=(long int)client_thread((void*)&threads[0]);
  } else {
    for(i=0; i<config->threads; i++) {
      pthread_attr_init(&attr);
      pthread_attr_setdetachstate(&attr, PTHREAD_CREATE_JOINABLE);
      rc=pthread_create(&threads[i].id, &attr, client_thread, (void *)&threads[i]);
      pthread_attr_destroy(&attr);
    }
    for(i=0; i<config->threads; i++) {
      //printf("waiting on thread %d... ", i);
      rc=pthread_join(threads[i].id,(void **)&status);
      //printf("joined thread %d, status=%ld\n",(int)threads[i].id, (long int)status);
    }
  }
  sigemptyset(&mask);
  sigaddset(&mask, SIG_RUNTIMEEXP);
  if (sigprocmask(SIG_BLOCK, &mask, NULL) == -1) {
      perror("sigprocmask");
  }
  action.sa_flags=0;
  action.sa_handler=SIG_IGN;
  sigemptyset(&action.sa_mask);
  sigaction(SIG_RUNTIMEEXP, &action, NULL);
  
  for(i=0; i<config->threads; i++) {
    if(threads[i].conns) {
      for(j=0;j<config->conns_per_thread; j++) {
	if(threads[i].conns[j].req_buffer) {
	  free(threads[i].conns[j].req_buffer);
	}
	if(threads[i].conns[j].rx_buff) {
	  free(threads[i].conns[j].rx_buff);
	}
	if(threads[i].conns[j].tx_buffer) {
	  free(threads[i].conns[j].tx_buffer);
	}
	if(threads[i].conns[j].frame_buffer) {
	  free(threads[i].conns[j].frame_buffer);
	}

	//if(threads[i].conns[j].out_transactions) {
	//  free(threads[i].conns[j].out_transactions);
	//}
      }
      free(threads[i].conns);
      threads[i].read->conns=NULL;
      threads[i].write->conns=NULL;
    }
  }
  
  free(threads);
  return;
  
}