From 878ede3080ab2cfb627aca505c397d9765052996 Mon Sep 17 00:00:00 2001 From: Magnus Auvinen Date: Tue, 27 Oct 2009 14:38:53 +0000 Subject: major update with stuff --- src/engine/e_network_conn.c | 366 -------------------------------------------- 1 file changed, 366 deletions(-) delete mode 100644 src/engine/e_network_conn.c (limited to 'src/engine/e_network_conn.c') diff --git a/src/engine/e_network_conn.c b/src/engine/e_network_conn.c deleted file mode 100644 index 583dbe65..00000000 --- a/src/engine/e_network_conn.c +++ /dev/null @@ -1,366 +0,0 @@ -#include -#include -#include "e_config.h" -#include "e_network_internal.h" - -static void conn_reset_stats(NETCONNECTION *conn) -{ - mem_zero(&conn->stats, sizeof(conn->stats)); -} - -static void conn_reset(NETCONNECTION *conn) -{ - conn->seq = 0; - conn->ack = 0; - conn->remote_closed = 0; - - conn->state = NET_CONNSTATE_OFFLINE; - conn->last_send_time = 0; - conn->last_recv_time = 0; - conn->last_update_time = 0; - conn->token = -1; - mem_zero(&conn->peeraddr, sizeof(conn->peeraddr)); - - conn->buffer = ringbuf_init(conn->buffer_memory, sizeof(conn->buffer_memory), 0); - - mem_zero(&conn->construct, sizeof(conn->construct)); -} - - -const char *conn_error(NETCONNECTION *conn) -{ - return conn->error_string; -} - -static void conn_set_error(NETCONNECTION *conn, const char *str) -{ - str_copy(conn->error_string, str, sizeof(conn->error_string)); -} - -void conn_init(NETCONNECTION *conn, NETSOCKET socket) -{ - conn_reset(conn); - conn_reset_stats(conn); - conn->socket = socket; - mem_zero(conn->error_string, sizeof(conn->error_string)); -} - - -static void conn_ack(NETCONNECTION *conn, int ack) -{ - - while(1) - { - NETCHUNKDATA *resend = (NETCHUNKDATA *)ringbuf_first(conn->buffer); - if(!resend) - break; - - if(seq_in_backroom(resend->sequence, ack)) - ringbuf_popfirst(conn->buffer); - else - break; - } -} - -void conn_want_resend(NETCONNECTION *conn) -{ - conn->construct.flags |= NET_PACKETFLAG_RESEND; -} - -int conn_flush(NETCONNECTION *conn) -{ - int num_chunks = conn->construct.num_chunks; - if(!num_chunks && !conn->construct.flags) - return 0; - - /* send of the packets */ - conn->construct.ack = conn->ack; - send_packet(conn->socket, &conn->peeraddr, &conn->construct); - - /* update send times */ - conn->last_send_time = time_get(); - - /* clear construct so we can start building a new package */ - mem_zero(&conn->construct, sizeof(conn->construct)); - return num_chunks; -} - -static void conn_queue_chunk_ex(NETCONNECTION *conn, int flags, int data_size, const void *data, int sequence) -{ - unsigned char *chunk_data; - - /* check if we have space for it, if not, flush the connection */ - if(conn->construct.data_size + data_size + NET_MAX_CHUNKHEADERSIZE > sizeof(conn->construct.chunk_data)) - conn_flush(conn); - - /* pack all the data */ - chunk_data = &conn->construct.chunk_data[conn->construct.data_size]; - chunk_data = pack_chunk_header(chunk_data, flags, data_size, sequence); - mem_copy(chunk_data, data, data_size); - chunk_data += data_size; - - /* */ - conn->construct.num_chunks++; - conn->construct.data_size = (int)(chunk_data-conn->construct.chunk_data); - - /* set packet flags aswell */ - - if(flags&NET_CHUNKFLAG_VITAL && !(flags&NET_CHUNKFLAG_RESEND)) - { - /* save packet if we need to resend */ - NETCHUNKDATA *resend = (NETCHUNKDATA *)ringbuf_allocate(conn->buffer, sizeof(NETCHUNKDATA)+data_size); - if(resend) - { - resend->sequence = sequence; - resend->flags = flags; - resend->data_size = data_size; - resend->data = (unsigned char *)(resend+1); - resend->first_send_time = time_get(); - resend->last_send_time = resend->first_send_time; - mem_copy(resend->data, data, data_size); - } - else - { - /* out of buffer */ - conn_disconnect(conn, "too weak connection (out of buffer)"); - } - } -} - -void conn_queue_chunk(NETCONNECTION *conn, int flags, int data_size, const void *data) -{ - if(flags&NET_CHUNKFLAG_VITAL) - conn->seq = (conn->seq+1)%NET_MAX_SEQUENCE; - conn_queue_chunk_ex(conn, flags, data_size, data, conn->seq); -} - - -static void conn_send_control(NETCONNECTION *conn, int controlmsg, const void *extra, int extra_size) -{ - /* send the control message */ - conn->last_send_time = time_get(); - send_controlmsg(conn->socket, &conn->peeraddr, conn->ack, controlmsg, extra, extra_size); -} - -static void conn_resend_chunk(NETCONNECTION *conn, NETCHUNKDATA *resend) -{ - conn_queue_chunk_ex(conn, resend->flags|NET_CHUNKFLAG_RESEND, resend->data_size, resend->data, resend->sequence); - resend->last_send_time = time_get(); -} - -static void conn_resend(NETCONNECTION *conn) -{ - int resend_count = 0; - int first = 0, last = 0; - void *item = ringbuf_first(conn->buffer); - - while(item) - { - NETCHUNKDATA *resend = item; - - if(resend_count == 0) - first = resend->sequence; - last = resend->sequence; - - conn_resend_chunk(conn, resend); - item = ringbuf_next(conn->buffer, item); - resend_count++; - } - - if(config.debug) - dbg_msg("conn", "resent %d packets (%d to %d)", resend_count, first, last); -} - -int conn_connect(NETCONNECTION *conn, NETADDR *addr) -{ - if(conn->state != NET_CONNSTATE_OFFLINE) - return -1; - - /* init connection */ - conn_reset(conn); - conn->peeraddr = *addr; - mem_zero(conn->error_string, sizeof(conn->error_string)); - conn->state = NET_CONNSTATE_CONNECT; - conn_send_control(conn, NET_CTRLMSG_CONNECT, 0, 0); - return 0; -} - -void conn_disconnect(NETCONNECTION *conn, const char *reason) -{ - if(conn->state == NET_CONNSTATE_OFFLINE) - return; - - if(conn->remote_closed == 0) - { - if(reason) - conn_send_control(conn, NET_CTRLMSG_CLOSE, reason, strlen(reason)+1); - else - conn_send_control(conn, NET_CTRLMSG_CLOSE, 0, 0); - - conn->error_string[0] = 0; - if(reason) - str_copy(conn->error_string, reason, sizeof(conn->error_string)); - } - - conn_reset(conn); -} - -int conn_feed(NETCONNECTION *conn, NETPACKETCONSTRUCT *packet, NETADDR *addr) -{ - int64 now = time_get(); - conn->last_recv_time = now; - - /* check if resend is requested */ - if(packet->flags&NET_PACKETFLAG_RESEND) - conn_resend(conn); - - /* */ - if(packet->flags&NET_PACKETFLAG_CONTROL) - { - int ctrlmsg = packet->chunk_data[0]; - - if(ctrlmsg == NET_CTRLMSG_CLOSE) - { - conn->state = NET_CONNSTATE_ERROR; - conn->remote_closed = 1; - - if(packet->data_size) - { - /* make sure to sanitize the error string form the other party*/ - char str[128]; - if(packet->data_size < 128) - str_copy(str, (char *)packet->chunk_data, packet->data_size); - else - str_copy(str, (char *)packet->chunk_data, 128); - str_sanitize_strong(str); - - /* set the error string */ - conn_set_error(conn, str); - } - else - conn_set_error(conn, "no reason given"); - - if(config.debug) - dbg_msg("conn", "closed reason='%s'", conn_error(conn)); - return 0; - } - else - { - if(conn->state == NET_CONNSTATE_OFFLINE) - { - if(ctrlmsg == NET_CTRLMSG_CONNECT) - { - /* send response and init connection */ - conn_reset(conn); - conn->state = NET_CONNSTATE_PENDING; - conn->peeraddr = *addr; - conn->last_send_time = now; - conn->last_recv_time = now; - conn->last_update_time = now; - conn_send_control(conn, NET_CTRLMSG_CONNECTACCEPT, 0, 0); - if(config.debug) - dbg_msg("connection", "got connection, sending connect+accept"); - } - } - else if(conn->state == NET_CONNSTATE_CONNECT) - { - /* connection made */ - if(ctrlmsg == NET_CTRLMSG_CONNECTACCEPT) - { - conn_send_control(conn, NET_CTRLMSG_ACCEPT, 0, 0); - conn->state = NET_CONNSTATE_ONLINE; - if(config.debug) - dbg_msg("connection", "got connect+accept, sending accept. connection online"); - } - } - else if(conn->state == NET_CONNSTATE_ONLINE) - { - /* connection made */ - /* - if(ctrlmsg == NET_CTRLMSG_CONNECTACCEPT) - { - - }*/ - } - } - } - else - { - if(conn->state == NET_CONNSTATE_PENDING) - { - conn->state = NET_CONNSTATE_ONLINE; - if(config.debug) - dbg_msg("connection", "connecting online"); - } - } - - if(conn->state == NET_CONNSTATE_ONLINE) - { - - conn_ack(conn, packet->ack); - } - - return 1; -} - -int conn_update(NETCONNECTION *conn) -{ - int64 now = time_get(); - - if(conn->state == NET_CONNSTATE_OFFLINE || conn->state == NET_CONNSTATE_ERROR) - return 0; - - /* check for timeout */ - if(conn->state != NET_CONNSTATE_OFFLINE && - conn->state != NET_CONNSTATE_CONNECT && - (now-conn->last_recv_time) > time_freq()*10) - { - conn->state = NET_CONNSTATE_ERROR; - conn_set_error(conn, "timeout"); - } - - /* fix resends */ - if(ringbuf_first(conn->buffer)) - { - NETCHUNKDATA *resend = (NETCHUNKDATA *)ringbuf_first(conn->buffer); - - /* check if we have some really old stuff laying around and abort if not acked */ - if(now-resend->first_send_time > time_freq()*10) - { - conn->state = NET_CONNSTATE_ERROR; - conn_set_error(conn, "too weak connection (not acked for 10 seconds)"); - } - else - { - /* resend packet if we havn't got it acked in 1 second */ - if(now-resend->last_send_time > time_freq()) - conn_resend_chunk(conn, resend); - } - } - - /* send keep alives if nothing has happend for 250ms */ - if(conn->state == NET_CONNSTATE_ONLINE) - { - if(time_get()-conn->last_send_time > time_freq()/2) /* flush connection after 500ms if needed */ - { - int num_flushed_chunks = conn_flush(conn); - if(num_flushed_chunks && config.debug) - dbg_msg("connection", "flushed connection due to timeout. %d chunks.", num_flushed_chunks); - } - - if(time_get()-conn->last_send_time > time_freq()) - conn_send_control(conn, NET_CTRLMSG_KEEPALIVE, 0, 0); - } - else if(conn->state == NET_CONNSTATE_CONNECT) - { - if(time_get()-conn->last_send_time > time_freq()/2) /* send a new connect every 500ms */ - conn_send_control(conn, NET_CTRLMSG_CONNECT, 0, 0); - } - else if(conn->state == NET_CONNSTATE_PENDING) - { - if(time_get()-conn->last_send_time > time_freq()/2) /* send a new connect/accept every 500ms */ - conn_send_control(conn, NET_CTRLMSG_CONNECTACCEPT, 0, 0); - } - - return 0; -} -- cgit 1.4.1