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,
23 return rs_conn_err_push (conn, RSE_NOMEM, __func__);
27 p = (struct rs_packet *) malloc (sizeof (struct rs_packet));
31 return rs_conn_err_push (conn, RSE_NOMEM, __func__);
33 memset (p, 0, sizeof (struct rs_packet));
42 rs_packet_create_acc_request (struct rs_connection *conn,
43 struct rs_packet **pkt_out,
44 const char *user_name, const char *user_pw)
46 struct rs_packet *pkt;
49 if (_packet_create (conn, pkt_out, PW_AUTHENTICATION_REQUEST))
53 if (rs_attr_create (conn, &attr, "User-Name", user_name))
55 rs_packet_add_attr (pkt, attr);
57 if (rs_attr_create (conn, &attr, "User-Password", user_pw))
59 /* FIXME: need this too? rad_pwencode(user_pw, &pwlen, SECRET, reqauth) */
60 rs_packet_add_attr (pkt, attr);
66 _event_cb (struct bufferevent *bev, short events, void *ctx)
68 struct rs_packet *pkt = (struct rs_packet *) ctx;
69 struct rs_connection *conn;
74 assert (pkt->conn->active_peer);
76 p = conn->active_peer;
79 if (events & BEV_EVENT_CONNECTED)
83 fprintf (stderr, "%s: connected\n", __func__);
85 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 _init_evb (struct rs_connection *conn)
127 event_enable_debug_mode ();
129 conn->evb = event_base_new ();
131 return rs_conn_err_push_fl (conn, RSE_EVENT, __FILE__, __LINE__,
138 _init_socket (struct rs_connection *conn, struct rs_peer *p)
143 p->s = socket (p->addr->ai_family, p->addr->ai_socktype,
144 p->addr->ai_protocol);
146 return rs_conn_err_push_fl (conn, RSE_SOME_ERROR, __FILE__, __LINE__,
152 static struct rs_peer *
153 _pick_peer (struct rs_connection *conn)
155 if (!conn->active_peer)
156 conn->active_peer = conn->peers;
157 return conn->active_peer;
161 _init_bev (struct rs_connection *conn, struct rs_peer *peer,
162 struct rs_packet *pkt)
166 conn->bev = bufferevent_socket_new (conn->evb, peer->s, 0);
168 return rs_conn_err_push_fl (conn, RSE_EVENT, __FILE__, __LINE__,
169 "bufferevent_socket_new");
170 bufferevent_setcb (conn->bev, NULL, _write_cb, _event_cb, pkt);
176 _do_connect (struct rs_peer *p)
178 if (bufferevent_socket_connect (p->conn->bev, p->addr->ai_addr,
179 p->addr->ai_addrlen) < 0)
180 rs_conn_err_push_fl (p->conn, RSE_EVENT, __FILE__, __LINE__,
181 "bufferevent_socket_connect");
183 p->is_connecting = 1;
187 _conn_open(struct rs_connection *conn, struct rs_packet *pkt)
191 if (_init_evb (conn))
194 p = _pick_peer (conn);
196 return rs_conn_err_push_fl (conn, RSE_NOPEER, __FILE__, __LINE__, NULL);
198 if (_init_socket (conn, p))
201 if (_init_bev (conn, p, pkt))
204 if (!p->is_connected)
205 if (!p->is_connecting)
212 rs_packet_send (struct rs_connection *conn, struct rs_packet *pkt, void *data)
216 if (_conn_open (conn, pkt))
220 assert (conn->active_peer);
221 assert (conn->active_peer->s >= 0);
222 event_base_dispatch (conn->evb);
224 fprintf (stderr, "%s: event loop done\n", __func__);
225 assert (event_base_got_break(conn->evb));
231 int rs_packet_receive(struct rs_connection *conn, struct rs_packet **pkt)
233 //struct bufferevent *bev;
236 //bufferevent_enable(bev, EV_READ);
237 return 0; /* FIXME */
242 rs_packet_add_attr(struct rs_packet *pkt, struct rs_attr *attr)
244 pairadd (&pkt->rpkt->vps, attr->vp);