Rewrote idleconn program to use libevent notification system.

Cette révision appartient à :
tedbullock 2008-01-31 09:42:31 +00:00
Parent 2b34faf907
révision 7748d1e6e3
3 fichiers modifiés avec 101 ajouts et 19 suppressions

Voir le fichier

@ -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

Voir le fichier

@ -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

Voir le fichier

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