Rewrote idleconn program to use libevent notification system.
This commit is contained in:
förälder
2b34faf907
incheckning
7748d1e6e3
@ -1,3 +1,8 @@
|
||||
2008-01-31 Ted Bullock <tbullock@canada.com>
|
||||
|
||||
* src/idleconn.c: Complete rewrite to use libevent backend; slight
|
||||
performance improvement thanks to use of libevent notification system
|
||||
|
||||
2007-11-16 Ted Bullock <tbullock@canada.com>
|
||||
|
||||
* configure.ac: Enable libevent dependancy
|
||||
|
@ -1,4 +1,5 @@
|
||||
* New in version 1.0.0
|
||||
** Complete re-write of idleconn.c to use libevent notification system
|
||||
|
||||
* New in version 0.9.1:
|
||||
** timer re-write to reduce memory and fix memory leaks
|
||||
|
@ -35,7 +35,11 @@
|
||||
#include <string.h> /* For strrchr() */
|
||||
#include <signal.h>
|
||||
#include <sys/types.h>
|
||||
#include <sys/socket.h>
|
||||
#include <netinet/in.h>
|
||||
#include <arpa/inet.h>
|
||||
#include <unistd.h>
|
||||
#include <inttypes.h>
|
||||
|
||||
#include <sys/time.h>
|
||||
#include <event.h>
|
||||
@ -48,14 +52,14 @@
|
||||
* Events allocated onto the heap
|
||||
*/
|
||||
static struct List *active_events = NULL;
|
||||
static struct List *inactive_events = NULL;
|
||||
|
||||
static const char *prog_name = NULL;
|
||||
static unsigned long num_conn = 0, num_closed = 0;
|
||||
static struct timeval start_time;
|
||||
static struct sockaddr_in server_addr;
|
||||
|
||||
static char *server = NULL;
|
||||
static int desired = 0;
|
||||
static int desired = 0; /* Number of desired connections */
|
||||
static int port = 0;
|
||||
|
||||
static void
|
||||
@ -64,6 +68,8 @@ cleanup()
|
||||
if (active_events != NULL) {
|
||||
while (!is_list_empty(active_events)) {
|
||||
Any_Type a = list_pop(active_events);
|
||||
struct event *evsock = (struct event *) a.vp;
|
||||
event_del(evsock);
|
||||
free(a.vp);
|
||||
}
|
||||
list_free(active_events);
|
||||
@ -85,7 +91,9 @@ sigint_exit(int fd, short event, void *arg)
|
||||
printf("%s: total # conn. created = %lu, close() rate = %g conn/sec\n",
|
||||
prog_name, num_conn, num_closed / delta_t);
|
||||
|
||||
#ifdef DEBUG
|
||||
printf("%s: caught SIGINT... Exiting.\n", __func__);
|
||||
#endif /* DEBUG */
|
||||
|
||||
evdns_shutdown(0);
|
||||
event_del(signal_int);
|
||||
@ -93,11 +101,45 @@ sigint_exit(int fd, short event, void *arg)
|
||||
cleanup();
|
||||
}
|
||||
|
||||
void
|
||||
reconnect(int sd, short event, void *arg)
|
||||
{
|
||||
struct sockaddr_in sin = server_addr;
|
||||
struct event *evsock = (struct event *) arg;
|
||||
|
||||
close(sd);
|
||||
num_closed++;
|
||||
|
||||
sd = socket(AF_INET, SOCK_STREAM, 0);
|
||||
|
||||
if (sd == -1) {
|
||||
perror("socket");
|
||||
exit(EXIT_FAILURE);
|
||||
}
|
||||
|
||||
if (connect(sd, (struct sockaddr *) &sin, sizeof(sin)) < 0) {
|
||||
perror("connect");
|
||||
cleanup();
|
||||
exit(EXIT_FAILURE);
|
||||
}
|
||||
|
||||
event_set(evsock, sd, EV_READ, reconnect, evsock);
|
||||
event_add(evsock, NULL);
|
||||
num_conn++;
|
||||
|
||||
}
|
||||
|
||||
/*
|
||||
* For the explanation of these parameters, please refer to the libevent evdns
|
||||
* callback API
|
||||
*/
|
||||
void
|
||||
dns_lookup_callback(int result, char type, int count, int ttl, void *addresses,
|
||||
void *arg)
|
||||
{
|
||||
uint8_t i;
|
||||
uint32_t i;
|
||||
uint8_t oct[4];
|
||||
struct in_addr *address_list = (struct in_addr *) addresses;
|
||||
|
||||
if (result != DNS_ERR_NONE) {
|
||||
printf("DNS Lookup: result(%d)\n",
|
||||
@ -105,22 +147,55 @@ dns_lookup_callback(int result, char type, int count, int ttl, void *addresses,
|
||||
exit(EXIT_FAILURE);
|
||||
}
|
||||
|
||||
printf("Resolved %s\n", server);
|
||||
memset(&server_addr, 0, sizeof(server_addr));
|
||||
server_addr.sin_family = AF_INET;
|
||||
server_addr.sin_port = htons(port);
|
||||
server_addr.sin_addr = address_list[0];
|
||||
|
||||
/*
|
||||
* Echo the resolved address
|
||||
*/
|
||||
printf("Resolved %s\n\t(%s)\n", server, inet_ntoa(address_list[0]));
|
||||
|
||||
/*
|
||||
* Open the number of `desired` connections
|
||||
*/
|
||||
for (i = 0; i < desired; i++) {
|
||||
struct sockaddr_in sin;
|
||||
int sd = socket(AF_INET, SOCK_STREAM, 0);
|
||||
|
||||
struct event *evsock = NULL;
|
||||
|
||||
if (sd == -1) {
|
||||
perror("socket");
|
||||
continue;
|
||||
}
|
||||
|
||||
sin = server_addr;
|
||||
|
||||
if (connect(sd, (struct sockaddr *) &sin, sizeof(sin)) < 0) {
|
||||
perror("connect");
|
||||
cleanup();
|
||||
exit(EXIT_FAILURE);
|
||||
}
|
||||
|
||||
evsock = (struct event *) malloc(sizeof(struct event));
|
||||
|
||||
if (evsock == NULL) {
|
||||
cleanup();
|
||||
exit(EXIT_FAILURE);
|
||||
}
|
||||
|
||||
event_set(evsock, sd, EV_READ, reconnect, evsock);
|
||||
list_push(active_events, (Any_Type) (void *) evsock);
|
||||
num_conn++;
|
||||
|
||||
event_add(evsock, NULL);
|
||||
|
||||
for (i = 0; i < count; ++i) {
|
||||
uint32_t *address_list = (uint32_t *) addresses;
|
||||
uint8_t oct[4];
|
||||
oct[0] = (uint8_t) (address_list[i] & 0x000000ff);
|
||||
oct[1] = (uint8_t) ((address_list[i] & 0x0000ff00) >> 8);
|
||||
oct[2] = (uint8_t) ((address_list[i] & 0x00ff0000) >> 16);
|
||||
oct[3] = (uint8_t) ((address_list[i] & 0xff000000) >> 24);
|
||||
printf("\t(%u.%u.%u.%u)\n", oct[0], oct[1], oct[2], oct[3]);
|
||||
}
|
||||
|
||||
|
||||
}
|
||||
|
||||
void
|
||||
int
|
||||
main(int argc, char *argv[])
|
||||
{
|
||||
struct event signal_int;
|
||||
@ -129,10 +204,6 @@ main(int argc, char *argv[])
|
||||
if (active_events == NULL)
|
||||
goto init_failure;
|
||||
|
||||
inactive_events = list_create();
|
||||
if (inactive_events == NULL)
|
||||
goto init_failure;
|
||||
|
||||
event_init();
|
||||
evdns_init();
|
||||
|
||||
@ -181,4 +252,9 @@ main(int argc, char *argv[])
|
||||
init_failure:
|
||||
cleanup();
|
||||
exit(EXIT_FAILURE);
|
||||
|
||||
/*
|
||||
* Should never reach here
|
||||
*/
|
||||
return 0;
|
||||
}
|
||||
|
Laddar…
Referens i nytt ärende
Block a user