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); }
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; }