Misc connection changes.

This commit is contained in:
Jan Vidar Krey 2009-08-27 14:15:18 +02:00
parent 96c006ee13
commit 29d6d59d36
3 changed files with 103 additions and 26 deletions

View File

@ -19,8 +19,8 @@
#include "uhub.h" #include "uhub.h"
#define NET_WANT_READ 0x0001 #define NET_WANT_READ NET_EVENT_READ
#define NET_WANT_WRITE 0x0002 #define NET_WANT_WRITE NET_EVENT_WRITE
#define NET_WANT_ACCEPT 0x0008 #define NET_WANT_ACCEPT 0x0008
#define NET_WANT_SSL_READ 0x0010 #define NET_WANT_SSL_READ 0x0010
#define NET_WANT_SSL_WRITE 0x0020 #define NET_WANT_SSL_WRITE 0x0020
@ -31,6 +31,7 @@
#define NET_PROCESSING_BUSY 0x8000 #define NET_PROCESSING_BUSY 0x8000
#define NET_CLEANUP 0x4000 #define NET_CLEANUP 0x4000
#define NET_INITIALIZED 0x2000 #define NET_INITIALIZED 0x2000
#define NET_TIMER_ENABLED 0x1000
extern struct hub_info* g_hub; extern struct hub_info* g_hub;
@ -66,6 +67,19 @@ static inline int net_con_convert_from_libevent_mask(int ev)
return events; return events;
} }
static void net_con_event(int fd, short ev, void *arg);
void net_con_set(struct net_connection* con)
{
int ev = 0;
if (net_con_flag_get(con, NET_WANT_READ | NET_WANT_SSL_READ)) ev |= EV_READ;
if (net_con_flag_get(con, NET_WANT_WRITE | NET_WANT_SSL_WRITE)) ev |= EV_WRITE;
event_set(&con->event, con->sd, ev, net_con_event, con);
event_add(&con->event, 0);
net_con_flag_set(con, NET_INITIALIZED);
}
static void net_con_event(int fd, short ev, void *arg) static void net_con_event(int fd, short ev, void *arg)
{ {
@ -126,12 +140,7 @@ static void net_con_event(int fd, short ev, void *arg)
} }
else else
{ {
int set_ev = 0; net_con_set(con);
if (net_con_flag_get(con, NET_WANT_READ)) set_ev |= EV_READ;
if (net_con_flag_get(con, NET_WANT_WRITE)) set_ev |= EV_WRITE;
event_set(&con->event, con->sd, set_ev, net_con_event, con);
event_add(&con->event, 0);
net_con_flag_set(con, NET_INITIALIZED);
} }
} }
@ -175,6 +184,8 @@ void net_con_initialize(struct net_connection* con, int sd, struct ip_addr_encap
#endif #endif
} }
void net_con_update(struct net_connection* con, int ev) void net_con_update(struct net_connection* con, int ev)
{ {
if (ev & NET_EVENT_READ) if (ev & NET_EVENT_READ)
@ -372,15 +383,19 @@ ssize_t net_con_recv(struct net_connection* con, void* buf, size_t len)
void net_con_set_timeout(struct net_connection* con, int seconds) void net_con_set_timeout(struct net_connection* con, int seconds)
{ {
struct timeval timeout = { seconds, 0 }; struct timeval timeout = { seconds, 0 };
net_con_clear_timeout(con);
evtimer_set(&con->timeout, net_con_event, con); evtimer_set(&con->timeout, net_con_event, con);
evtimer_add(&con->timeout, &timeout); evtimer_add(&con->timeout, &timeout);
net_con_flag_set(con, NET_TIMER_ENABLED);
} }
void net_con_clear_timeout(struct net_connection* con) void net_con_clear_timeout(struct net_connection* con)
{ {
if (evtimer_initialized(&con->timeout) && evtimer_pending(&con->timeout, 0)) if (net_con_flag_get(con, NET_TIMER_ENABLED))
{ {
evtimer_del(&con->timeout); evtimer_del(&con->timeout);
net_con_flag_unset(con, NET_TIMER_ENABLED);
} }
} }
@ -441,4 +456,38 @@ ssize_t net_con_ssl_handshake(struct net_connection* con, int ssl_mode)
} }
#endif /* SSL_SUPPORT */ #endif /* SSL_SUPPORT */
static void net_timer_event(int fd, short ev, void *arg)
{
struct net_timer* timer = (struct net_timer*) arg;
timer->callback(timer, timer->ptr);
}
void net_timer_initialize(struct net_timer* timer, net_timeout_cb callback, void* ptr)
{
timer->initialized = 0;
timer->callback = callback;
timer->ptr = ptr;
}
void net_timer_reset(struct net_timer* timer, int seconds)
{
struct timeval timeout = { seconds, 0 };
if (timer->initialized)
{
evtimer_del(&timer->timeout);
timer->initialized = 0;
}
evtimer_set(&timer->timeout, net_timer_event, timer);
evtimer_add(&timer->timeout, &timeout);
}
void net_timer_shutdown(struct net_timer* timer)
{
if (timer->initialized)
{
evtimer_del(&timer->timeout);
timer->initialized = 0;
}
timer->callback = 0;
timer->ptr = 0;
}

View File

@ -29,7 +29,22 @@
#define NET_EVENT_CLOSED 0x2000 /* Socket closed */ #define NET_EVENT_CLOSED 0x2000 /* Socket closed */
struct net_connection; struct net_connection;
struct net_timer;
typedef void (*net_connection_cb)(struct net_connection*, int event, void* ptr); typedef void (*net_connection_cb)(struct net_connection*, int event, void* ptr);
typedef void (*net_timeout_cb)(struct net_timer*, void* ptr);
struct net_timer
{
unsigned int initialized;
struct event timeout;
net_timeout_cb callback;
void* ptr;
};
extern void net_timer_initialize(struct net_timer* timer, net_timeout_cb callback, void* ptr);
extern void net_timer_reset(struct net_timer* timer, int seconds);
extern void net_timer_shutdown(struct net_timer* timer);
struct net_connection struct net_connection
{ {
@ -38,7 +53,7 @@ struct net_connection
void* ptr; /** data pointer */ void* ptr; /** data pointer */
net_connection_cb callback; /** Callback function */ net_connection_cb callback; /** Callback function */
struct event event; /** libevent struct for read/write events */ struct event event; /** libevent struct for read/write events */
struct event timeout; /** timeout handling */ struct event timeout; /** Used for internal timeout handling */
struct ip_addr_encap ipaddr; /** IP address of peer */ struct ip_addr_encap ipaddr; /** IP address of peer */
time_t last_recv; /** Timestamp for last recv() */ time_t last_recv; /** Timestamp for last recv() */
time_t last_send; /** Timestamp for last send() */ time_t last_send; /** Timestamp for last send() */

View File

@ -170,7 +170,8 @@ struct ADC_client
size_t s_offset; size_t s_offset;
size_t r_offset; size_t r_offset;
size_t timeout; size_t timeout;
struct net_connection con; struct net_connection* con;
struct net_timer* timer;
}; };
@ -273,7 +274,7 @@ static void client_reschedule_timeout(struct ADC_client* client)
client->timeout = get_wait_rand(MAX(next_timeout, 1)); client->timeout = get_wait_rand(MAX(next_timeout, 1));
if (!client->timeout) client->timeout++; if (!client->timeout) client->timeout++;
net_con_set_timeout(&client->con, client->timeout); net_timer_reset(client->timer, client->timeout);
} }
static void set_state_timeout(struct ADC_client* client, enum protocolState state) static void set_state_timeout(struct ADC_client* client, enum protocolState state)
@ -284,7 +285,7 @@ static void set_state_timeout(struct ADC_client* client, enum protocolState stat
static void send_client(struct ADC_client* client, char* msg) static void send_client(struct ADC_client* client, char* msg)
{ {
int ret = net_con_send(&client->con, msg, strlen(msg)); int ret = net_con_send(client->con, msg, strlen(msg));
if (cfg_debug > 1) if (cfg_debug > 1)
{ {
@ -312,7 +313,7 @@ static void send_client(struct ADC_client* client, char* msg)
static void ADC_client_on_connected(struct ADC_client* client) static void ADC_client_on_connected(struct ADC_client* client)
{ {
net_con_update(&client->con, NET_EVENT_READ); net_con_update(client->con, NET_EVENT_READ);
send_client(client, ADC_HANDSHAKE); send_client(client, ADC_HANDSHAKE);
set_state_timeout(client, ps_protocol); set_state_timeout(client, ps_protocol);
bot_output(client, LVL_INFO, "connected."); bot_output(client, LVL_INFO, "connected.");
@ -320,7 +321,10 @@ static void ADC_client_on_connected(struct ADC_client* client)
static void ADC_client_on_disconnected(struct ADC_client* client) static void ADC_client_on_disconnected(struct ADC_client* client)
{ {
net_con_close(&client->con); net_con_close(client->con);
hub_free(client->con);
client->con = 0;
bot_output(client, LVL_INFO, "disconnected."); bot_output(client, LVL_INFO, "disconnected.");
set_state_timeout(client, ps_none); set_state_timeout(client, ps_none);
} }
@ -366,7 +370,7 @@ static int recv_client(struct ADC_client* client)
ssize_t size = 0; ssize_t size = 0;
if (cfg_mode != mode_performance || (cfg_mode == mode_performance && (get_wait_rand(100) < (90 - (15 * cfg_level))))) if (cfg_mode != mode_performance || (cfg_mode == mode_performance && (get_wait_rand(100) < (90 - (15 * cfg_level)))))
{ {
size = net_con_recv(&client->con, &client->recvbuf[client->r_offset], ADC_BUFSIZE - client->r_offset); size = net_con_recv(client->con, &client->recvbuf[client->r_offset], ADC_BUFSIZE - client->r_offset);
} }
else else
{ {
@ -491,7 +495,7 @@ static int recv_client(struct ADC_client* client)
void ADC_client_connect(struct ADC_client* client) void ADC_client_connect(struct ADC_client* client)
{ {
int ret = net_connect(client->con.sd, (struct sockaddr*) &saddr, sizeof(struct sockaddr_in)); int ret = net_connect(client->con->sd, (struct sockaddr*) &saddr, sizeof(struct sockaddr_in));
if (ret == 0 || (ret == -1 && net_error() == EISCONN)) if (ret == 0 || (ret == -1 && net_error() == EISCONN))
{ {
ADC_client_on_connected(client); ADC_client_on_connected(client);
@ -500,7 +504,7 @@ void ADC_client_connect(struct ADC_client* client)
{ {
if (client->state != ps_conn) if (client->state != ps_conn)
{ {
net_con_update(&client->con, NET_EVENT_READ | NET_EVENT_WRITE); net_con_update(client->con, NET_EVENT_READ | NET_EVENT_WRITE);
set_state_timeout(client, ps_conn); set_state_timeout(client, ps_conn);
bot_output(client, LVL_INFO, "connecting..."); bot_output(client, LVL_INFO, "connecting...");
} }
@ -521,9 +525,9 @@ void ADC_client_wait_connect(struct ADC_client* client)
void ADC_client_disconnect(struct ADC_client* client) void ADC_client_disconnect(struct ADC_client* client)
{ {
if (client->con.sd != -1) if (client->con->sd != -1)
{ {
net_con_close(&client->con); net_con_close(client->con);
bot_output(client, LVL_INFO, "disconnected."); bot_output(client, LVL_INFO, "disconnected.");
if (running) if (running)
@ -685,6 +689,16 @@ static void perf_normal_action(struct ADC_client* client)
client_reschedule_timeout(client); client_reschedule_timeout(client);
} }
void timer_callback(struct net_timer* t, void* arg)
{
struct ADC_client* client = (struct ADC_client*) arg;
if (client->state == ps_none)
{
ADC_client_create(client, client->num);
ADC_client_connect(client);
}
}
void event_callback(struct net_connection* con, int events, void *arg) void event_callback(struct net_connection* con, int events, void *arg)
{ {
struct ADC_client* client = (struct ADC_client*) arg; struct ADC_client* client = (struct ADC_client*) arg;
@ -697,11 +711,6 @@ void event_callback(struct net_connection* con, int events, void *arg)
{ {
if (client->state == ps_none) if (client->state == ps_none)
{ {
if (client->con.sd == -1)
{
ADC_client_create(client, client->num);
}
ADC_client_connect(client); ADC_client_connect(client);
} }
} }
@ -735,7 +744,10 @@ int ADC_client_create(struct ADC_client* client, int num)
int sd = net_socket_create(PF_INET, SOCK_STREAM, IPPROTO_TCP); int sd = net_socket_create(PF_INET, SOCK_STREAM, IPPROTO_TCP);
if (sd == -1) return -1; if (sd == -1) return -1;
net_con_initialize(&client->con, sd, 0, event_callback, client, 0); client->con = hub_malloc(sizeof(struct net_connection));
client->timer = hub_malloc(sizeof(struct net_timer));
net_con_initialize(client->con, sd, 0, event_callback, client, 0);
net_timer_initialize(client->timer, timer_callback, client);
set_state_timeout(client, ps_none); set_state_timeout(client, ps_none);
return 0; return 0;
} }
@ -743,6 +755,7 @@ int ADC_client_create(struct ADC_client* client, int num)
void ADC_client_destroy(struct ADC_client* client) void ADC_client_destroy(struct ADC_client* client)
{ {
ADC_client_disconnect(client); ADC_client_disconnect(client);
net_timer_shutdown(client->timer);
} }