-/* Copyright 2011 NORDUnet A/S. All rights reserved.
- See the file COPYING for licensing information. */
+/* Copyright 2011-2013 NORDUnet A/S. All rights reserved.
+ See LICENSE for licensing information. */
#if defined HAVE_CONFIG_H
#include <config.h>
#include <event2/buffer.h>
#endif
-/* Read one RADIUS packet header. Return !0 on error. A return value
- of 0 means that we need more data. */
+/** Read one RADIUS packet header. Return !0 on error. */
static int
_read_header (struct rs_packet *pkt)
{
n = bufferevent_read (pkt->conn->bev, pkt->hdr, RS_HEADER_LEN);
if (n == RS_HEADER_LEN)
{
- pkt->flags |= rs_packet_hdr_read_flag;
+ pkt->flags |= RS_PACKET_HEADER_READ;
pkt->rpkt->length = (pkt->hdr[2] << 8) + pkt->hdr[3];
if (pkt->rpkt->length < 20 || pkt->rpkt->length > RS_MAX_PACKET_LEN)
{
return 0;
}
+/** Read a message, check that it's valid RADIUS and hand it off to
+ registered user callback.
+
+ The packet is read from the bufferevent associated with \a pkt and
+ the data is stored in \a pkt->rpkt.
+
+ Return 0 on success and !0 on failure. */
static int
_read_packet (struct rs_packet *pkt)
{
{
bufferevent_disable (pkt->conn->bev, EV_READ);
rs_debug (("%s: complete packet read\n", __func__));
- pkt->flags &= ~rs_packet_hdr_read_flag;
+ pkt->flags &= ~RS_PACKET_HEADER_READ;
memset (pkt->hdr, 0, sizeof(*pkt->hdr));
/* Checks done by rad_packet_ok:
assert (pkt->rpkt);
pkt->rpkt->sockfd = pkt->conn->fd;
- pkt->rpkt->vps = NULL;
+ pkt->rpkt->vps = NULL; /* FIXME: can this be done when initializing pkt? */
+
+ /* Read a message header if not already read, return if that
+ fails. Read a message and have it dispatched to the user
+ registered callback.
- if ((pkt->flags & rs_packet_hdr_read_flag) == 0)
+ Room for improvement: Peek inside buffer (evbuffer_copyout()) to
+ avoid the extra copying. */
+ if ((pkt->flags & RS_PACKET_HEADER_READ) == 0)
if (_read_header (pkt))
return; /* Error. */
_read_packet (pkt);
{
struct rs_packet *pkt = (struct rs_packet *) user_data;
struct rs_connection *conn = NULL;
- struct rs_peer *p = NULL;
int sockerr = 0;
#if defined (RS_ENABLE_TLS)
unsigned long tlserr = 0;
#endif
+#if defined (DEBUG)
+ struct rs_peer *p = NULL;
+#endif
assert (pkt);
assert (pkt->conn);
- assert (pkt->conn->active_peer);
conn = pkt->conn;
+#if defined (DEBUG)
+ assert (pkt->conn->active_peer);
p = conn->active_peer;
+#endif
conn->is_connecting = 0;
if (events & BEV_EVENT_CONNECTED)
{
if (conn->tev)
evtimer_del (conn->tev); /* Cancel connect timer. */
- event_on_connect (conn, pkt);
+ if (event_on_connect (conn, pkt))
+ {
+ event_on_disconnect (conn);
+ event_loopbreak (conn);
+ }
}
else if (events & BEV_EVENT_EOF)
{
{
rs_debug (("%s: %p times out on %s\n", __func__, p,
(events & BEV_EVENT_READING) ? "read" : "write"));
- rs_err_conn_push_fl (pkt->conn, RSE_TIMEOUT_IO, __FILE__, __LINE__, NULL);
+ rs_err_conn_push_fl (conn, RSE_TIMEOUT_IO, __FILE__, __LINE__, NULL);
}
else if (events & BEV_EVENT_ERROR)
{
if (sockerr == 0) /* FIXME: True that errno == 0 means closed? */
{
event_on_disconnect (conn);
- rs_err_conn_push_fl (pkt->conn, RSE_DISCO, __FILE__, __LINE__, NULL);
+ rs_err_conn_push_fl (conn, RSE_DISCO, __FILE__, __LINE__, NULL);
}
else
{
rs_debug (("%s: %d: %d (%s)\n", __func__, conn->fd, sockerr,
evutil_socket_error_to_string (sockerr)));
- rs_err_conn_push_fl (pkt->conn, RSE_SOCKERR, __FILE__, __LINE__,
+ rs_err_conn_push_fl (conn, RSE_SOCKERR, __FILE__, __LINE__,
"%d: %d (%s)", conn->fd, sockerr,
evutil_socket_error_to_string (sockerr));
}
{
rs_debug (("%s: openssl error: %s\n", __func__,
ERR_error_string (tlserr, NULL)));
- rs_err_conn_push_fl (pkt->conn, RSE_SSLERR, __FILE__, __LINE__,
+ rs_err_conn_push_fl (conn, RSE_SSLERR, __FILE__, __LINE__,
ERR_error_string (tlserr, NULL));
}
}