From 5c60297a1eaab7b10d6f584ba329493a41b812d0 Mon Sep 17 00:00:00 2001 From: Linus Nordberg Date: Sun, 6 Mar 2011 15:53:58 +0100 Subject: Restructure code, moving most code out of packet.c Also, move copyright notice out of COPYING and into every file. --- lib/send.c | 128 +++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++ 1 file changed, 128 insertions(+) create mode 100644 lib/send.c (limited to 'lib/send.c') diff --git a/lib/send.c b/lib/send.c new file mode 100644 index 0000000..c49eaa9 --- /dev/null +++ b/lib/send.c @@ -0,0 +1,128 @@ +/* Copyright 2011 NORDUnet A/S. All rights reserved. + See the file COPYING for licensing information. */ + +#if defined HAVE_CONFIG_H +#include +#endif + +#include +#include +#include +#include +#include +#include "debug.h" +#include "packet.h" +#include "event.h" +#include "peer.h" +#include "tcp.h" +#include "udp.h" + +static int +_conn_open (struct rs_connection *conn, struct rs_packet *pkt) +{ + if (event_init_eventbase (conn)) + return -1; + + if (!conn->active_peer) + peer_pick_peer (conn); + if (!conn->active_peer) + return rs_err_conn_push_fl (conn, RSE_NOPEER, __FILE__, __LINE__, NULL); + + if (event_init_socket (conn, conn->active_peer)) + return -1; + + if (conn->realm->type == RS_CONN_TYPE_TCP + || conn->realm->type == RS_CONN_TYPE_TLS) + { + if (event_init_bufferevent (conn, conn->active_peer)) + return -1; + } + else + { + if (udp_init (conn, pkt)) + return -1; + } + + if (!conn->is_connected) + if (!conn->is_connecting) + event_do_connect (conn); + + return RSE_OK; +} + +static int +_conn_is_open_p (struct rs_connection *conn) +{ + return conn->active_peer && conn->is_connected; +} + +/* User callback used when we're dispatching for user. */ +static void +_wcb (void *user_data) +{ + struct rs_packet *pkt = (struct rs_packet *) user_data; + assert (pkt); + pkt->written_flag = 1; + if (pkt->conn->bev) + bufferevent_disable (pkt->conn->bev, EV_WRITE|EV_READ); + else + event_del (pkt->conn->wev); +} + +int +rs_packet_send (struct rs_packet *pkt, void *user_data) +{ + struct rs_connection *conn = NULL; + int err = 0; + + assert (pkt); + assert (pkt->conn); + conn = pkt->conn; + + if (_conn_is_open_p (conn)) + packet_do_send (pkt); + else + if (_conn_open (conn, pkt)) + return -1; + + assert (conn->evb); + assert (conn->active_peer); + assert (conn->fd >= 0); + + conn->user_data = user_data; + + if (conn->bev) /* TCP */ + { + bufferevent_setcb (conn->bev, NULL, tcp_write_cb, tcp_event_cb, pkt); + bufferevent_enable (conn->bev, EV_WRITE); + } + else /* UDP */ + { + err = event_add (conn->wev, NULL); + if (err < 0) + return rs_err_conn_push_fl (pkt->conn, RSE_EVENT, __FILE__, __LINE__, + "event_add: %s", + evutil_gai_strerror (err)); + } + + /* Do dispatch, unless the user wants to do it herself. */ + if (!conn->user_dispatch_flag) + { + conn->callbacks.sent_cb = _wcb; + conn->user_data = pkt; + rs_debug (("%s: entering event loop\n", __func__)); + err = event_base_dispatch (conn->evb); + if (err < 0) + return rs_err_conn_push_fl (pkt->conn, RSE_EVENT, __FILE__, __LINE__, + "event_base_dispatch: %s", + evutil_gai_strerror (err)); + rs_debug (("%s: event loop done\n", __func__)); + conn->callbacks.sent_cb = NULL; + conn->user_data = NULL; + + if (!pkt->written_flag) + return -1; + } + + return RSE_OK; +} -- cgit v1.1 From 41af6cd03dac4eb905d0d3de574d2e4f3f9600eb Mon Sep 17 00:00:00 2001 From: Linus Nordberg Date: Mon, 7 Mar 2011 09:53:40 +0100 Subject: Formatting changes. --- lib/send.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) (limited to 'lib/send.c') diff --git a/lib/send.c b/lib/send.c index c49eaa9..871d657 100644 --- a/lib/send.c +++ b/lib/send.c @@ -96,7 +96,7 @@ rs_packet_send (struct rs_packet *pkt, void *user_data) bufferevent_setcb (conn->bev, NULL, tcp_write_cb, tcp_event_cb, pkt); bufferevent_enable (conn->bev, EV_WRITE); } - else /* UDP */ + else /* UDP */ { err = event_add (conn->wev, NULL); if (err < 0) -- cgit v1.1 From cbcaa6a7c8f8a6704f6b4a68f260020957214a07 Mon Sep 17 00:00:00 2001 From: Linus Nordberg Date: Mon, 7 Mar 2011 15:23:40 +0100 Subject: Move verification of response packets up to a level where it makes sense. Replace the user_dispatch_flag on connections with conn_user_dispatch_p(). Remove the 'original' member from packet and instead have an upper layer verify. Rename packet valid_flag --> received_flag to reflect that we don't verify. Move _close_conn() --> conn_close(). Move packet flags into a single unsigned int, for portability. (_read_packet): Don't verify packet. (rs_conn_receive_packet): Don't touch PKT_OUT if there isn't a packet. (rs_conn_receive_packet): Verify packet using packet_verify_response(). --- lib/send.c | 17 ++++++++++++----- 1 file changed, 12 insertions(+), 5 deletions(-) (limited to 'lib/send.c') diff --git a/lib/send.c b/lib/send.c index 871d657..cc7fd71 100644 --- a/lib/send.c +++ b/lib/send.c @@ -14,9 +14,16 @@ #include "packet.h" #include "event.h" #include "peer.h" +#include "conn.h" #include "tcp.h" #include "udp.h" +/* RFC 5080 2.2.1. Retransmission Behavior */ +#define IRT 2 +#define MRC 5 +#define MRT 16 +#define MRD 30 + static int _conn_open (struct rs_connection *conn, struct rs_packet *pkt) { @@ -62,7 +69,7 @@ _wcb (void *user_data) { struct rs_packet *pkt = (struct rs_packet *) user_data; assert (pkt); - pkt->written_flag = 1; + pkt->flags |= rs_packet_sent_flag; if (pkt->conn->bev) bufferevent_disable (pkt->conn->bev, EV_WRITE|EV_READ); else @@ -100,27 +107,27 @@ rs_packet_send (struct rs_packet *pkt, void *user_data) { err = event_add (conn->wev, NULL); if (err < 0) - return rs_err_conn_push_fl (pkt->conn, RSE_EVENT, __FILE__, __LINE__, + return rs_err_conn_push_fl (conn, RSE_EVENT, __FILE__, __LINE__, "event_add: %s", evutil_gai_strerror (err)); } /* Do dispatch, unless the user wants to do it herself. */ - if (!conn->user_dispatch_flag) + if (!conn_user_dispatch_p (conn)) { conn->callbacks.sent_cb = _wcb; conn->user_data = pkt; rs_debug (("%s: entering event loop\n", __func__)); err = event_base_dispatch (conn->evb); if (err < 0) - return rs_err_conn_push_fl (pkt->conn, RSE_EVENT, __FILE__, __LINE__, + return rs_err_conn_push_fl (conn, RSE_EVENT, __FILE__, __LINE__, "event_base_dispatch: %s", evutil_gai_strerror (err)); rs_debug (("%s: event loop done\n", __func__)); conn->callbacks.sent_cb = NULL; conn->user_data = NULL; - if (!pkt->written_flag) + if ((pkt->flags & rs_packet_sent_flag) == 0) return -1; } -- cgit v1.1 From 1073de4a6139cf1b78ed82bc93e26be385cb76b1 Mon Sep 17 00:00:00 2001 From: Linus Nordberg Date: Tue, 8 Mar 2011 13:20:20 +0100 Subject: Don't return -1 to user but rather an error code. NOTE: Changes rs_conn_receive_packet() and rs_packet_send() only. --- lib/send.c | 5 ++++- 1 file changed, 4 insertions(+), 1 deletion(-) (limited to 'lib/send.c') diff --git a/lib/send.c b/lib/send.c index cc7fd71..af25144 100644 --- a/lib/send.c +++ b/lib/send.c @@ -128,7 +128,10 @@ rs_packet_send (struct rs_packet *pkt, void *user_data) conn->user_data = NULL; if ((pkt->flags & rs_packet_sent_flag) == 0) - return -1; + { + assert (rs_err_conn_peek_code (conn)); + return rs_err_conn_peek_code (conn); + } } return RSE_OK; -- cgit v1.1 From d464ebb9235fe78e6588e95d4d3333d5ee95ca48 Mon Sep 17 00:00:00 2001 From: Linus Nordberg Date: Tue, 8 Mar 2011 13:37:46 +0100 Subject: Timeout implemented in request objects, supported by TCP. TODO: UDP. --- lib/send.c | 6 ------ 1 file changed, 6 deletions(-) (limited to 'lib/send.c') diff --git a/lib/send.c b/lib/send.c index af25144..f169ff9 100644 --- a/lib/send.c +++ b/lib/send.c @@ -18,12 +18,6 @@ #include "tcp.h" #include "udp.h" -/* RFC 5080 2.2.1. Retransmission Behavior */ -#define IRT 2 -#define MRC 5 -#define MRT 16 -#define MRD 30 - static int _conn_open (struct rs_connection *conn, struct rs_packet *pkt) { -- cgit v1.1 From ce4d6dfe1728e5633a8f49fc4b16c36df0d23521 Mon Sep 17 00:00:00 2001 From: Linus Nordberg Date: Wed, 9 Mar 2011 10:18:06 +0100 Subject: Add retransmission timer support (UDP). --- lib/send.c | 4 ++++ 1 file changed, 4 insertions(+) (limited to 'lib/send.c') diff --git a/lib/send.c b/lib/send.c index f169ff9..0872471 100644 --- a/lib/send.c +++ b/lib/send.c @@ -35,6 +35,8 @@ _conn_open (struct rs_connection *conn, struct rs_packet *pkt) if (conn->realm->type == RS_CONN_TYPE_TCP || conn->realm->type == RS_CONN_TYPE_TLS) { + if (tcp_init_connect_timer (conn)) + return -1; if (event_init_bufferevent (conn, conn->active_peer)) return -1; } @@ -42,6 +44,8 @@ _conn_open (struct rs_connection *conn, struct rs_packet *pkt) { if (udp_init (conn, pkt)) return -1; + if (udp_init_retransmit_timer (conn)) + return -1; } if (!conn->is_connected) -- cgit v1.1 From 1a1e09bd5def4fae2a499294535b37805f79fde8 Mon Sep 17 00:00:00 2001 From: Linus Nordberg Date: Thu, 10 Mar 2011 08:08:32 +0100 Subject: [UDP] Don't crash on second packet. [UDP] Set the user_data member for the write callback in rs_packet_send() -- the one from udp_init() doesn't do much good at this point. --- lib/send.c | 2 ++ 1 file changed, 2 insertions(+) (limited to 'lib/send.c') diff --git a/lib/send.c b/lib/send.c index 0872471..a8ad1d5 100644 --- a/lib/send.c +++ b/lib/send.c @@ -103,6 +103,8 @@ rs_packet_send (struct rs_packet *pkt, void *user_data) } else /* UDP */ { + event_assign (conn->wev, conn->evb, event_get_fd (conn->wev), + EV_WRITE, event_get_callback (conn->wev), pkt); err = event_add (conn->wev, NULL); if (err < 0) return rs_err_conn_push_fl (conn, RSE_EVENT, __FILE__, __LINE__, -- cgit v1.1