void output_db() { struct sockaddr_in db_addr; int fd, flags, res; fd_set fdr, fdw; struct timeval timeout; fd = socket(AF_INET, SOCK_STREAM, 0); if (fd < 0) { do_debug(LOG_FATAL, "can't get socket\n"); } /* set socket fd noblock */ if((flags = fcntl(fd, F_GETFL, 0)) < 0) { close(fd); return; } if(fcntl(fd, F_SETFL, flags | O_NONBLOCK) < 0) { close(fd); return; } /* get db server address */ db_addr = *str2sa(conf.output_db_addr); if (connect(fd, (struct sockaddr*)&db_addr, sizeof(db_addr)) != 0) { if (errno != EINPROGRESS) { // EINPROGRESS close(fd); return; } else goto select; } else goto send; select: FD_ZERO(&fdr); FD_ZERO(&fdw); FD_SET(fd, &fdr); FD_SET(fd, &fdw); timeout.tv_sec = 2; timeout.tv_usec = 0; res = select(fd + 1, &fdr, &fdw, NULL, &timeout); if(res < 0) { close(fd); return; } if(res == 0) { close(fd); return; } send: send_sql_txt(fd); close(fd); }
void send_data_tcp(char *output_addr, char *data, int len) { int fd, flags, res; fd_set fdr, fdw; struct timeval timeout; struct sockaddr_in db_addr; fd = socket(AF_INET, SOCK_STREAM, 0); if (fd < 0) { do_debug(LOG_FATAL, "can't get socket"); } /* set socket fd noblock */ if ((flags = fcntl(fd, F_GETFL, 0)) < 0) { close(fd); return; } if (fcntl(fd, F_SETFL, flags | O_NONBLOCK) < 0) { close(fd); return; } /* get db server address */ db_addr = *str2sa(output_addr); if (connect(fd, (struct sockaddr*)&db_addr, sizeof(db_addr)) != 0) { if (errno != EINPROGRESS) { // EINPROGRESS close(fd); return; } else { goto select; } } else { goto send; } select: FD_ZERO(&fdr); FD_ZERO(&fdw); FD_SET(fd, &fdr); FD_SET(fd, &fdw); timeout.tv_sec = 2; timeout.tv_usec = 0; res = select(fd + 1, &fdr, &fdw, NULL, &timeout); if (res <= 0) { close(fd); return; } send: if (len > 0 && write(fd, data, len) != len) { do_debug(LOG_ERR, "output_db write error:dst:%s\terrno:%s\n",output_addr, strerror(errno)); } close(fd); }
int main(int argc, char *argv[]) { if(argc!=3) { printf("gatlinject <ip:port> <num socket>\n"); exit(1); } struct sockaddr_in target = str2sa((char *) argv[1]); // convert target information int maxconn = atoi(argv[2]); //number of sockets to connect to the target // internal variables definition int i, count, datacount; char message[] = "hello\n\n"; int messagelength = strlen(message); char buffer[1500]; int buffersize = strlen(buffer); struct statistics stats; memset(&stats,0x0,6 * sizeof(int)); pthread_t Statsthread; // time struct timeval start; struct timeval current; float elapsedtime; // catch SIGINT to exit in a clean way struct sigaction sa; memset(&sa, 0, sizeof(struct sigaction *)); sa.sa_handler = interrupt; sa.sa_flags = 0; sigemptyset (&(sa.sa_mask)); if(sigaction (SIGINT, &sa, NULL)!= 0) { perror("sigaction failed"); exit(1); } // the epoll file descriptor int epfd; // epoll structure that will contain the current network socket and event when epoll wakes up static struct epoll_event *events; static struct epoll_event event_mask; // create the special epoll file descriptor epfd = epoll_create(maxconn); // allocate enough memory to store all the events in the "events" structure if (NULL == (events = calloc(maxconn, sizeof(struct epoll_event)))) { perror("calloc events"); exit(1); }; // create and connect as much as needed for(i=0;i<maxconn;i++) if(create_and_connect(target, (int *) epfd) != 0) { perror("create and connect"); exit(1); } else stats.nbsock++; // start the thread that prints the statistics if( 0!= pthread_create (&Statsthread, NULL, (void *)printstats, &stats) ){ perror("stats thread"); exit(1); } gettimeofday(&start, NULL); do { /* wait for events on the file descriptors added into epfd * * if one of the socket that's contained into epfd is available for reading, writing, * is closed or have an error, this socket will be return in events[i].data.fd * and events[i].events will be set to the corresponding event * * count contain the number of returned events */ count = epoll_wait(epfd, events, maxconn, 1000); for(i=0;i<count;i++) { if (events[i].events & EPOLLOUT) //socket is ready for writing { // verify the socket is connected and doesn't return an error if(socket_check(events[i].data.fd) != 0) { perror("write socket_check"); continue; } else { if((datacount = send(events[i].data.fd, message, messagelength, 0)) < 0) { stats.error++; perror("send failed"); continue; } else { /* we just wrote on this socket, we don't want to write on it anymore * but we still want to read on it, so we modify the event mask to * remove EPOLLOUT from the events list */ event_mask.events = EPOLLIN | EPOLLRDHUP | EPOLLERR | EPOLLET; event_mask.data.fd = events[i].data.fd; if(epoll_ctl(epfd, EPOLL_CTL_MOD, events[i].data.fd, &event_mask) != 0) { perror("epoll_ctl, modify socket\n"); exit(1); } stats.reqsent++; stats.bytessent += datacount; } } } if (events[i].events & EPOLLIN) //socket is ready for writing { // verify the socket is connected and doesn't return an error if(socket_check(events[i].data.fd) != 0) { perror("read socket_check"); continue; } else { memset(buffer,0x0,buffersize); if((datacount = recv(events[i].data.fd, buffer, buffersize, 0)) < 0) { stats.error++; perror("recv failed"); continue; } else { stats.bytesrecv += datacount; stats.reprecv++; } } } if (events[i].events & (EPOLLRDHUP | EPOLLHUP)) //socket closed, delete and create a new one { // socket is closed, remove the socket from epoll and create a new one epoll_ctl(epfd, EPOLL_CTL_DEL, events[i].data.fd, NULL); if(close(events[i].data.fd)!=0) { perror("close"); continue; } else stats.nbsock--; if(create_and_connect(target, (int *) epfd) != 0) { perror("create and connect"); continue; } else stats.nbsock++; } if (events[i].events & EPOLLERR) { perror("epoll"); continue; } } } while(!stop); gettimeofday(¤t, NULL); elapsedtime = (current.tv_sec * 1000000 + current.tv_usec) - (start.tv_sec * 1000000 + start.tv_usec); printf("\n\nTime: %4.6f\nRequests sent: %d\nBytes sent: %d\nReponses received: %d\nBytes received: %d\nRates out: %4.6freq/s, %4.6fbytes/s\nRates in : %4.6frep/s, %4.6fbytes/s\nErrors: %d\n", elapsedtime/1000000, stats.reqsent, stats.bytessent, stats.reprecv, stats.bytesrecv, stats.reqsent/(elapsedtime/1000000), stats.bytessent/(elapsedtime/1000000), stats.reprecv/(elapsedtime/1000000), stats.bytesrecv/(elapsedtime/1000000), stats.error); return 0; }