3 #include <freeradius/libradius.h>
4 #include <event2/event.h>
5 #include <event2/bufferevent.h>
7 #include "libradsec-impl.h"
13 _packet_create (struct rs_connection *conn, struct rs_packet **pkt_out)
22 return rs_conn_err_push (conn, RSE_NOMEM, __func__);
25 p = (struct rs_packet *) malloc (sizeof (struct rs_packet));
29 return rs_conn_err_push (conn, RSE_NOMEM, __func__);
31 memset (p, 0, sizeof (struct rs_packet));
40 rs_packet_create_acc_request (struct rs_connection *conn,
41 struct rs_packet **pkt_out,
42 const char *user_name, const char *user_pw)
44 struct rs_packet *pkt;
47 if (_packet_create (conn, pkt_out))
50 pkt->rpkt->code = PW_AUTHENTICATION_REQUEST;
52 if (rs_attr_create (conn, &attr, "User-Name", user_name))
54 rs_packet_add_attr (pkt, attr);
56 if (rs_attr_create (conn, &attr, "User-Password", user_pw))
58 /* FIXME: need this too? rad_pwencode(user_pw, &pwlen, SECRET, reqauth) */
59 rs_packet_add_attr (pkt, attr);
65 _event_cb (struct bufferevent *bev, short events, void *ctx)
67 struct rs_packet *pkt = (struct rs_packet *) ctx;
68 struct rs_connection *conn;
73 assert (pkt->conn->active_peer);
75 p = conn->active_peer;
78 if (events & BEV_EVENT_CONNECTED)
82 fprintf (stderr, "%s: connected\n", __func__);
84 rad_encode (pkt->rpkt, NULL, pkt->conn->active_peer->secret);
87 fprintf (stderr, "%s: about to send this to %s:\n", __func__, "<fixme>");
90 if (bufferevent_write(bev, pkt->rpkt->data, pkt->rpkt->data_len))
91 rs_conn_err_push_fl (pkt->conn, RSE_EVENT, __FILE__, __LINE__,
93 /* Packet will be freed in write callback. */
95 else if (events & BEV_EVENT_ERROR)
96 rs_conn_err_push_fl (pkt->conn, RSE_CONNERR, __FILE__, __LINE__, NULL);
100 rs_packet_destroy(struct rs_packet *pkt)
102 rad_free (&pkt->rpkt);
103 rs_free (pkt->conn->ctx, pkt);
107 _write_cb (struct bufferevent *bev, void *ctx)
109 struct rs_packet *pkt = (struct rs_packet *) ctx;
114 fprintf (stderr, "%s: packet written, breaking event loop\n", __func__);
116 if (event_base_loopbreak (pkt->conn->evb) < 0)
117 abort (); /* FIXME */
118 rs_packet_destroy (pkt);
122 _read_cb (struct bufferevent *bev, void *ctx)
124 struct rs_packet *pkt = (struct rs_packet *) ctx;
129 if (!pkt->hdr_read_flag)
131 n = bufferevent_read (pkt->conn->bev, pkt->hdr, 4);
134 uint16_t len = (pkt->hdr[2] << 8) + pkt->hdr[3];
135 uint8_t *buf = rs_malloc (pkt->conn->ctx, len);
137 pkt->hdr_read_flag = 1;
140 rs_conn_err_push_fl (pkt->conn, RSE_NOMEM, __FILE__,
142 abort (); /* FIXME: recovering takes reading of packet */
144 pkt->rpkt->data = buf;
145 pkt->rpkt->data_len = len;
146 bufferevent_setwatermark (pkt->conn->bev, EV_READ, len - 4, 0);
148 fprintf (stderr, "%s: packet header read, pkt len=%d\n", __func__,
153 return; /* Buffer frozen, i suppose. Let's hope it thaws. */
157 return; /* Need more to complete header. */
161 printf ("%s: trying to read %d octets of packet data\n", __func__, pkt->rpkt->data_len - 4);
162 n = bufferevent_read (pkt->conn->bev, pkt->rpkt->data, pkt->rpkt->data_len - 4);
163 printf ("%s: read %d octets of packet data\n", __func__, n);
164 if (n == pkt->rpkt->data_len - 4)
166 bufferevent_disable (pkt->conn->bev, EV_READ);
167 pkt->hdr_read_flag = 0;
168 memset (pkt->hdr, 0, sizeof(*pkt->hdr));
170 fprintf (stderr, "%s: complete packet read\n", __func__);
172 if (event_base_loopbreak (pkt->conn->evb) < 0)
173 abort (); /* FIXME */
178 _init_evb (struct rs_connection *conn)
183 event_enable_debug_mode ();
185 conn->evb = event_base_new ();
187 return rs_conn_err_push_fl (conn, RSE_EVENT, __FILE__, __LINE__,
194 _init_socket (struct rs_connection *conn, struct rs_peer *p)
199 p->s = socket (p->addr->ai_family, p->addr->ai_socktype,
200 p->addr->ai_protocol);
202 return rs_conn_err_push_fl (conn, RSE_SOME_ERROR, __FILE__, __LINE__,
208 static struct rs_peer *
209 _pick_peer (struct rs_connection *conn)
211 if (!conn->active_peer)
212 conn->active_peer = conn->peers;
213 return conn->active_peer;
217 _init_bev (struct rs_connection *conn, struct rs_peer *peer)
221 conn->bev = bufferevent_socket_new (conn->evb, peer->s, 0);
223 return rs_conn_err_push_fl (conn, RSE_EVENT, __FILE__, __LINE__,
224 "bufferevent_socket_new");
230 _do_connect (struct rs_peer *p)
232 if (bufferevent_socket_connect (p->conn->bev, p->addr->ai_addr,
233 p->addr->ai_addrlen) < 0)
234 rs_conn_err_push_fl (p->conn, RSE_EVENT, __FILE__, __LINE__,
235 "bufferevent_socket_connect");
237 p->is_connecting = 1;
241 _conn_open(struct rs_connection *conn, struct rs_packet *pkt)
245 if (_init_evb (conn))
248 p = _pick_peer (conn);
250 return rs_conn_err_push_fl (conn, RSE_NOPEER, __FILE__, __LINE__, NULL);
252 if (_init_socket (conn, p))
255 if (_init_bev (conn, p))
257 bufferevent_setcb (conn->bev, _read_cb, _write_cb, _event_cb, pkt);
259 if (!p->is_connected)
260 if (!p->is_connecting)
267 rs_packet_send (struct rs_connection *conn, struct rs_packet *pkt, void *data)
272 if (_conn_open (conn, pkt))
276 assert (conn->active_peer);
277 assert (conn->active_peer->s >= 0);
279 event_base_dispatch (conn->evb);
282 fprintf (stderr, "%s: event loop done\n", __func__);
283 assert (event_base_got_break(conn->evb));
290 rs_packet_receive(struct rs_connection *conn, struct rs_packet **pkt_out)
292 struct rs_packet *pkt;
296 if (_packet_create (conn, pkt_out))
301 if (_conn_open (conn, pkt))
305 assert (conn->active_peer);
306 assert (conn->active_peer->s >= 0);
308 bufferevent_setwatermark (conn->bev, EV_READ, 4, 0);
309 bufferevent_enable (conn->bev, EV_READ);
310 event_base_dispatch (conn->evb);
312 fprintf (stderr, "%s: event loop done\n", __func__);
313 assert (event_base_got_break(conn->evb));
317 fprintf (stderr, "%s: got this:\n", __func__);
318 rs_dump_packet (pkt);
325 rs_packet_add_attr(struct rs_packet *pkt, struct rs_attr *attr)
327 pairadd (&pkt->rpkt->vps, attr->vp);