summaryrefslogtreecommitdiff
path: root/lib/packet.c
diff options
context:
space:
mode:
Diffstat (limited to 'lib/packet.c')
-rw-r--r--lib/packet.c130
1 files changed, 109 insertions, 21 deletions
diff --git a/lib/packet.c b/lib/packet.c
index 652c495..90c8c31 100644
--- a/lib/packet.c
+++ b/lib/packet.c
@@ -66,11 +66,19 @@ static void
_event_cb (struct bufferevent *bev, short events, void *ctx)
{
struct rs_packet *pkt = (struct rs_packet *) ctx;
+ struct rs_connection *conn;
+ struct rs_peer *p;
assert (pkt);
assert (pkt->conn);
+ assert (pkt->conn->active_peer);
+ conn = pkt->conn;
+ p = conn->active_peer;
+
+ p->is_connecting = 0;
if (events & BEV_EVENT_CONNECTED)
{
+ p->is_connected = 1;
#if defined (DEBUG)
fprintf (stderr, "%s: connected\n", __func__);
#endif
@@ -110,32 +118,107 @@ _write_cb (struct bufferevent *bev, void *ctx)
rs_packet_destroy (pkt);
}
-int
-rs_packet_send (struct rs_connection *conn, struct rs_packet *pkt, void *data)
+static int
+_init_evb (struct rs_connection *conn)
{
- struct bufferevent *bev;
- struct rs_peer *p;
+ if (!conn->evb)
+ {
+#if defined (DEBUG)
+ event_enable_debug_mode ();
+#endif
+ conn->evb = event_base_new ();
+ if (!conn->evb)
+ return rs_conn_err_push_fl (conn, RSE_EVENT, __FILE__, __LINE__,
+ "event_base_new");
+ }
+ return RSE_OK;
+}
- assert (pkt->rpkt);
+static int
+_init_socket (struct rs_connection *conn, struct rs_peer *p)
+{
+ if (p->s < 0)
+ {
+ assert (p->addr);
+ p->s = socket (p->addr->ai_family, p->addr->ai_socktype,
+ p->addr->ai_protocol);
+ if (p->s < 0)
+ return rs_conn_err_push_fl (conn, RSE_SOME_ERROR, __FILE__, __LINE__,
+ strerror (errno));
+ }
+ return RSE_OK;
+}
- if (rs_conn_open (conn))
- return -1;
- p = conn->active_peer;
- assert (p);
+static struct rs_peer *
+_pick_peer (struct rs_connection *conn)
+{
+ if (!conn->active_peer)
+ conn->active_peer = conn->peers;
+ return conn->active_peer;
+}
- assert (conn->active_peer->s >= 0);
- bev = bufferevent_socket_new (conn->evb, conn->active_peer->s, 0);
- if (!bev)
- return rs_conn_err_push_fl (conn, RSE_EVENT, __FILE__, __LINE__,
- "bufferevent_socket_new");
- if (bufferevent_socket_connect (bev, p->addr->ai_addr, p->addr->ai_addrlen) < 0)
+static int
+_init_bev (struct rs_connection *conn, struct rs_peer *peer,
+ struct rs_packet *pkt)
+{
+ if (!conn->bev)
{
- bufferevent_free (bev);
- return rs_conn_err_push_fl (conn, RSE_EVENT, __FILE__, __LINE__,
- "bufferevent_socket_connect");
+ conn->bev = bufferevent_socket_new (conn->evb, peer->s, 0);
+ if (!conn->bev)
+ return rs_conn_err_push_fl (conn, RSE_EVENT, __FILE__, __LINE__,
+ "bufferevent_socket_new");
+ bufferevent_setcb (conn->bev, NULL, _write_cb, _event_cb, pkt);
}
+ return RSE_OK;
+}
+
+static void
+_do_connect (struct rs_peer *p)
+{
+ if (bufferevent_socket_connect (p->conn->bev, p->addr->ai_addr,
+ p->addr->ai_addrlen) < 0)
+ rs_conn_err_push_fl (p->conn, RSE_EVENT, __FILE__, __LINE__,
+ "bufferevent_socket_connect");
+ else
+ p->is_connecting = 1;
+}
+
+static int
+_conn_open(struct rs_connection *conn, struct rs_packet *pkt)
+{
+ struct rs_peer *p;
+
+ if (_init_evb (conn))
+ return -1;
+
+ p = _pick_peer (conn);
+ if (!p)
+ return rs_conn_err_push_fl (conn, RSE_NOPEER, __FILE__, __LINE__, NULL);
+
+ if (_init_socket (conn, p))
+ return -1;
+
+ if (_init_bev (conn, p, pkt))
+ return -1;
- bufferevent_setcb (bev, NULL, _write_cb, _event_cb, pkt);
+ if (!p->is_connected)
+ if (!p->is_connecting)
+ _do_connect (p);
+
+ return RSE_OK;
+}
+
+int
+rs_packet_send (struct rs_connection *conn, struct rs_packet *pkt, void *data)
+{
+ assert (conn);
+ assert (pkt->rpkt);
+ if (_conn_open (conn, pkt))
+ return -1;
+ assert (conn->evb);
+ assert (conn->bev);
+ assert (conn->active_peer);
+ assert (conn->active_peer->s >= 0);
event_base_dispatch (conn->evb);
#if defined (DEBUG)
fprintf (stderr, "%s: event loop done\n", __func__);
@@ -147,13 +230,18 @@ rs_packet_send (struct rs_connection *conn, struct rs_packet *pkt, void *data)
int rs_packet_receive(struct rs_connection *conn, struct rs_packet **pkt)
{
- return rs_conn_err_push_fl (conn, RSE_NOSYS, __FILE__, __LINE__,
- "%s: NYI", __func__);
+ //struct bufferevent *bev;
+
+ //skalleper;
+ //bufferevent_enable(bev, EV_READ);
+ return 0; /* FIXME */
}
+
void
rs_packet_add_attr(struct rs_packet *pkt, struct rs_attr *attr)
{
pairadd (&pkt->rpkt->vps, attr->vp);
attr->pkt = pkt;
}
+