HACKING file for libradsec (in Emacs -*- org -*- mode).
- Status as of libradsec-0.2.0.dev (2013-05-02).
-Status as of libradsec-0.0.4.dev (2013-05-06).
++Status as of libradsec-0.2.0.dev (2013-05-06).
* Build instructions
sh autogen.sh
- OpenSSL (1.0.1c-4) -- optional, for TLS and DTLS support
sudo apt-get install libssl-dev libssl1.0.0
--* Functionality and quality in 0.0.x
++* Functionality and quality in 0.2.x
** Not well tested
- reading config file
- [TCP] short read
# Shared library interface version, i.e. -version-info to Libtool,
# expressed as three integers CURRENT:REVISION:AGE.
#
- # CURRENT is the version number of the current interface.
- # Increment CURRENT when the library interface changes.
+ # CURRENT is the version number of the current interface. Increment
+ # CURRENT when the library interface has changed or has been extended.
#
# REVISION is the version number of the _implementation_ of the
- # CURRENT interface.
- # Set REVISION to 0 when CURRENT changes, else increment.
+ # CURRENT interface. Set REVISION to 0 when CURRENT changes, else
+ # increment.
#
# AGE is the number of interfaces this library implements, i.e. how
- # many versions before CURRENT that are supported.
- # Increment AGE when the library interface is _extended_.
- # Set AGE to 0 when the library interface is _changed_.
+ # many versions before CURRENT that are supported. Increment AGE when
+ # the library interface is _extended_. Set AGE to 0 when the library
+ # interface is _changed_.
+VER_CUR = 1
+VER_REV = 0
+VER_AGE = 0
- SUBDIRS = radius radsecproxy . include examples
+ SUBDIRS = radius radsecproxy include . examples
+ DIST_SUBDIRS = $(SUBDIRS) tests
INCLUDES = -I$(srcdir)/include
AM_CFLAGS = -Wall -Werror -g
util.c
if RS_ENABLE_TLS
-libradsec_la_SOURCES += tls.c
+ libradsec_la_SOURCES += tls.c
else
-libradsec_la_SOURCES += md5.c
+ libradsec_la_SOURCES += md5.c
endif
- EXTRA_DIST = HACKING LICENSE
+ libradsec_la_SOURCES += \
+ compat.h \
+ conn.h \
+ debug.h \
+ err.h \
+ event.h \
+ md5.h \
- packet.h \
+ peer.h \
+ radsec.h \
+ tcp.h \
+ tls.h \
+ udp.h \
+ util.h
+
-EXTRA_DIST = HACKING LICENSE libradsec.spec radsec.sym
-AM_DISTCHECK_CONFIGURE_FLAGS = --enable-tls --enable-tls-psk
++EXTRA_DIST = HACKING LICENSE radsec.sym
+EXTRA_libradsec_la_DEPENDENCIES = radsec.sym
-libradsec_la_LIBADD = radsecproxy/libradsec-radsecproxy.la radius/libradsec-radius.la
-libradsec_la_LDFLAGS = -version-info 0:0:0 -export-symbols $(srcdir)/radsec.sym
-libradsec_la_CFLAGS = $(AM_CFLAGS) -DHAVE_CONFIG_H -Werror # -DDEBUG -DDEBUG_LEVENT
+libradsec_la_CFLAGS = \
- $(AM_CFLAGS) -DHAVE_CONFIG_H -DDEBUG -DDEBUG_LEVENT
++ $(AM_CFLAGS) -DHAVE_CONFIG_H #-DDEBUG -DDEBUG_LEVENT
+libradsec_la_LDFLAGS = \
+ -version-info $(VER_CUR):$(VER_REV):$(VER_AGE) \
- -export-symbols radsec.sym
++ -export-symbols $(srcdir)/radsec.sym
+libradsec_la_LIBADD = \
+ radsecproxy/libradsec-radsecproxy.la \
+ radius/libradsec-radius.la
http://git.nordu.net/?p=radsecproxy.git;a=shortlog;h=refs/heads/libradsec
- The source code is licensed under a 3-clause BSD license. See LICENSE.
+ The source code is licensed under a 3-clause BSD license. See the
+ LICENSE file.
-Libradsec depends on
+Libradsec depends on
- libconfuse
- libevent2
- openssl (if configured with --enable-tls)
+For changes between releases, see the CHANGES file.
+
+
To compile the library and the examples, do something like
- sh autogen.sh && ./configure && make
+ sh autogen.sh && ./configure && make
- If any of the libraries are not found, try setting environment
- variable LDFLAGS at configure time like so:
+
+ There are a couple of options that can be used when configuring. See
+
+ ./configure --help
+
+ for the full list. Worth mentioning here is --enable-tls and
+ --enable-tls-psk.
+
+ If the preprocessor has a hard time finding some of the header files
+ are, try setting environment variable CPPFLAGS at configure
+ time. Example:
+
+ CPPFLAGS="-I/usr/local/include" ./configure --enable-tls
+
+ If the link editor has trouble finding any of the libraries needed,
+ try setting environment variable LDFLAGS at configure time. Example:
LDFLAGS="-L/usr/local/lib" ./configure --enable-tls
- /* Copyright 2011,2013 NORDUnet A/S. All rights reserved.
- See LICENSE for licensing information. */
+ /* Copyright 2011 NORDUnet A/S. All rights reserved.
+ See LICENSE for licensing information. */
+#ifdef _WIN32
+#define INLINE __inline
+#else
+#define INLINE inline
+#endif
+
ssize_t compat_send (int sockfd, const void *buf, size_t len, int flags);
ssize_t compat_recv (int sockfd, void *buf, size_t len, int flags);
# -*- Autoconf -*- script for libradsec.
- AC_PREREQ([2.65])
+ AC_PREREQ([2.63])
-AC_INIT([libradsec], [0.0.4.dev], [linus+libradsec@nordu.net])
+AC_INIT([libradsec], [0.2.0.dev], [linus+libradsec@nordu.net])
AC_CONFIG_MACRO_DIR([m4])
AC_CONFIG_SRCDIR([radsec.c])
AC_CONFIG_AUX_DIR([build-aux])
int
conn_activate_timeout (struct rs_connection *conn)
{
++ const struct rs_conn_base *connbase;
assert (conn);
++ connbase = TO_BASE_CONN (conn);
++ assert (connbase->ctx);
++ assert (connbase->ctx->evb);
assert (conn->tev);
- assert (conn->base_.ctx->evb);
- if (conn->base_.timeout.tv_sec || conn->base_.timeout.tv_usec)
- assert (conn->evb);
- if (conn->timeout.tv_sec || conn->timeout.tv_usec)
++ if (connbase->timeout.tv_sec || connbase->timeout.tv_usec)
{
rs_debug (("%s: activating timer: %d.%d\n", __func__,
- conn->base_.timeout.tv_sec, conn->base_.timeout.tv_usec));
- if (evtimer_add (conn->tev, &conn->base_.timeout))
- conn->timeout.tv_sec, conn->timeout.tv_usec));
- if (evtimer_add (conn->tev, &conn->timeout))
-- return rs_err_conn_push_fl (conn, RSE_EVENT, __FILE__, __LINE__,
-- "evtimer_add: %d", errno);
++ connbase->timeout.tv_sec, connbase->timeout.tv_usec));
++ if (evtimer_add (conn->tev, &connbase->timeout))
++ return rs_err_conn_push (conn, RSE_EVENT, "evtimer_add: %d", errno);
}
return RSE_OK;
}
}
int
-conn_cred_psk (const struct rs_connection *conn)
+baseconn_type_datagram_p (const struct rs_conn_base *connbase)
{
- return conn->realm->transport_cred &&
- conn->realm->transport_cred->type == RS_CRED_TLS_PSK;
+ return connbase->transport == RS_CONN_TYPE_UDP
+ || connbase->transport == RS_CONN_TYPE_DTLS;
}
+int
+baseconn_type_stream_p (const struct rs_conn_base *connbase)
+{
+ return connbase->transport == RS_CONN_TYPE_TCP
+ || connbase->transport == RS_CONN_TYPE_TLS;
+}
-/* Public functions. */
int
-rs_conn_create (struct rs_context *ctx,
- struct rs_connection **conn,
- const char *config)
+conn_cred_psk (const struct rs_connection *conn)
{
- struct rs_connection *c;
+ assert (conn);
- assert (conn->active_peer);
- return conn->active_peer->transport_cred &&
- conn->active_peer->transport_cred->type == RS_CRED_TLS_PSK;
++ return conn->active_peer != NULL
++ && conn->active_peer->transport_cred
++ && conn->active_peer->transport_cred->type == RS_CRED_TLS_PSK;
+}
- c = (struct rs_connection *) malloc (sizeof(struct rs_connection));
- if (!c)
- return rs_err_ctx_push_fl (ctx, RSE_NOMEM, __FILE__, __LINE__, NULL);
+void
+conn_init (struct rs_context *ctx, /* FIXME: rename connbase_init? */
+ struct rs_conn_base *connbase,
+ enum rs_conn_subtype type)
+{
+ switch (type)
+ {
+ case RS_CONN_OBJTYPE_BASE:
+ connbase->magic = RS_CONN_MAGIC_BASE;
+ break;
+ case RS_CONN_OBJTYPE_GENERIC:
+ connbase->magic = RS_CONN_MAGIC_GENERIC;
+ break;
+ case RS_CONN_OBJTYPE_LISTENER:
+ connbase->magic = RS_CONN_MAGIC_LISTENER;
+ break;
+ default:
+ assert ("invalid connection subtype" == NULL);
+ }
- memset (c, 0, sizeof(struct rs_connection));
- c->ctx = ctx;
- c->fd = -1;
+ connbase->ctx = ctx;
+ connbase->fd = -1;
+}
+
+int
+conn_configure (struct rs_context *ctx, /* FIXME: rename conbbase_configure? */
+ struct rs_conn_base *connbase,
+ const char *config)
+{
if (config)
{
struct rs_realm *r = rs_conf_find_realm (ctx, config);
int
rs_conn_disconnect (struct rs_connection *conn)
{
- int err = baseconn_close (TO_BASE_CONN (conn));
- conn->state = RS_CONN_STATE_UNDEFINED;
+ int err = 0;
+
+ assert (conn);
+
- if (conn->is_connected)
++ if (conn->state == RS_CONN_STATE_CONNECTED)
+ event_on_disconnect (conn);
+
- if (conn->bev)
++ if (TO_BASE_CONN (conn)->bev)
+ {
- bufferevent_free (conn->bev);
- conn->bev = NULL;
++ bufferevent_free (TO_BASE_CONN (conn)->bev);
++ TO_BASE_CONN (conn)->bev = NULL;
+ }
- if (conn->rev)
++ if (TO_BASE_CONN (conn)->rev)
+ {
- event_free (conn->rev);
- conn->rev = NULL;
++ event_free (TO_BASE_CONN (conn)->rev);
++ TO_BASE_CONN (conn)->rev = NULL;
+ }
- if (conn->wev)
++ if (TO_BASE_CONN (conn)->wev)
+ {
- event_free (conn->wev);
- conn->wev = NULL;
++ event_free (TO_BASE_CONN (conn)->wev);
++ TO_BASE_CONN (conn)->wev = NULL;
+ }
+
- err = evutil_closesocket (conn->fd);
- conn->fd = -1;
++ err = evutil_closesocket (TO_BASE_CONN (conn)->fd);
++ TO_BASE_CONN (conn)->fd = -1;
return err;
}
- /* Copyright 2011,2013 NORDUnet A/S. All rights reserved.
-/* Copyright 2011-2012 NORDUnet A/S. All rights reserved.
++/* Copyright 2011-2013 NORDUnet A/S. All rights reserved.
See LICENSE for licensing information. */
void event_on_disconnect (struct rs_connection *conn);
AUTOMAKE_OPTIONS = foreign
- INCLUDES = -I$(top_srcdir)/include
- AM_CFLAGS = -Wall -Werror -g -DDEBUG -DDEBUG_LEVENT
+ INCLUDES = -I$(top_srcdir)/include -I$(top_srcdir)
-AM_CFLAGS = -Wall -Werror -g
++AM_CFLAGS = -Wall -Werror -g #-DDEBUG -DDEBUG_LEVENT
-noinst_PROGRAMS = client
+LDADD = ../libradsec.la #-lefence
+CFLAGS = $(AM_CFLAGS) -DUSE_CONFIG_FILE
+
+noinst_PROGRAMS = client client2 server
client_SOURCES = client-blocking.c
-client_LDADD = ../libradsec.la #-lefence
-client_CFLAGS = $(AM_CFLAGS) -DUSE_CONFIG_FILE
+client2_SOURCES = client-dispatch.c
/** @file libradsec-impl.h
- @brief Libraray internal header file for libradsec. */
+ @brief Libraray internal header file for libradsec. */
- /* Copyright 2010,2011,2013 NORDUnet A/S. All rights reserved.
+ /* Copyright 2010-2013 NORDUnet A/S. All rights reserved.
See LICENSE for licensing information. */
#ifndef _RADSEC_RADSEC_IMPL_H_
cfg_t *cfg;
};
+/** Libradsec context. */
struct rs_context {
struct rs_config *config;
+ struct rs_realm *realms;
struct rs_alloc_scheme alloc_scheme;
struct rs_error *err;
+ struct event_base *evb;
};
-struct rs_connection {
+/** Base class for a connection. */
+struct rs_conn_base {
+ uint32_t magic; /* Must be one of RS_CONN_MAGIC_*. */
struct rs_context *ctx;
- struct rs_realm *realm; /* Owned by ctx. */
- struct event_base *evb; /* Event base. */
- struct event *tev; /* Timeout event. */
- struct rs_conn_callbacks callbacks;
- void *user_data;
+ struct rs_realm *realm; /* Owned by ctx. */
+ enum rs_conn_type transport;
+ /** For a listener, allowed client addr/port pairs.
+ For an outgoing connection, set of configured servers.
+ For an incoming connection, the peer (as the only entry). */
struct rs_peer *peers;
- struct rs_peer *active_peer;
- struct rs_error *err;
struct timeval timeout;
- char is_connecting; /* FIXME: replace with a single state member */
- char is_connected; /* FIXME: replace with a single state member */
- int fd; /* Socket. */
- int tryagain; /* For server failover. */
- int nextid; /* Next RADIUS packet identifier. */
- /* TCP transport specifics. */
- struct bufferevent *bev; /* Buffer event. */
- /* UDP transport specifics. */
- struct event *wev; /* Write event (for UDP). */
- struct event *rev; /* Read event (for UDP). */
- struct rs_packet *out_queue; /* Queue for outgoing UDP packets. */
+ int tryagain; /* For server failover. */
+ void *user_data;
+ struct rs_error *err;
+ int fd; /* Socket. */
+ /* TCP transport specifics. */
+ struct bufferevent *bev; /* Buffer event. */
+ /* UDP transport specifics. */
+ struct event *wev; /* Write event (for UDP). */
+ struct event *rev; /* Read event (for UDP). */
+};
+
-
+enum rs_conn_state {
+ RS_CONN_STATE_UNDEFINED = 0,
+ RS_CONN_STATE_CONNECTING,
+ RS_CONN_STATE_CONNECTED,
+};
+
+/** A generic connection. */
+struct rs_connection {
+ struct rs_conn_base base_;
+ struct event *tev; /* Timeout event. */
+ struct rs_conn_callbacks callbacks;
+ enum rs_conn_state state;
+ struct rs_peer *active_peer;
+ struct rs_message *out_queue; /* Queue for outgoing UDP packets. */
#if defined(RS_ENABLE_TLS)
- /* TLS specifics. */
+ /* TLS specifics. */
SSL_CTX *tls_ctx;
SSL *tls_ssl;
#endif
/** \file radsec.h
- \brief Public interface for libradsec. */
+ \brief Public interface for libradsec. */
- /* Copyright 2010,2011,2013 NORDUnet A/S. All rights reserved.
+ /* Copyright 2010-2013 NORDUnet A/S. All rights reserved.
See LICENSE for licensing information. */
#ifndef _RADSEC_RADSEC_H_
void rs_peer_set_retries(struct rs_peer *peer, int retries);
/************/
-/* Packet. */
+/* Message. */
/************/
-/** Create a packet associated with connection \a conn. */
-int rs_packet_create(struct rs_connection *conn, struct rs_packet **pkt_out);
-
-/** Free all memory allocated for packet \a pkt. */
-void rs_packet_destroy(struct rs_packet *pkt);
-
-/** Send packet \a pkt on the connection associated with \a pkt.
- \a user_data is passed to the \a rs_conn_packet_received_cb callback
- registered with the connection. If no callback is registered with
- the connection, the event loop is run by \a rs_packet_send and it
- blocks until the full packet has been sent. Note that sending can
- fail in several ways, f.ex. if the transmission protocol in use
- is connection oriented (\a RS_CONN_TYPE_TCP and \a RS_CONN_TYPE_TLS)
- and the connection can not be established. Also note that no
- retransmission is done, something that is required for connectionless
- transport protocols (\a RS_CONN_TYPE_UDP and \a RS_CONN_TYPE_DTLS).
- The "request" API with \a rs_request_send can help with this.
+/** Create a message associated with connection \a conn. */
+int rs_message_create(struct rs_connection *conn, struct rs_message **pkt_out);
+
+/** Free all memory allocated for message \a msg. */
+void rs_message_destroy(struct rs_message *msg);
+
+/** Send \a msg on the connection associated with \a msg.
+ If no callback is registered with the connection
+ (\a rs_conn_set_callbacks), the event loop is run by
+ \a rs_message_send and it blocks until the message has been
+ succesfully sent.
+
++ Note that sending can fail in several ways, f.ex. if the
++ transmission protocol in use is connection oriented
++ (\a RS_CONN_TYPE_TCP and \a RS_CONN_TYPE_TLS) and the connection
++ can not be established.
++
++ Also note that no retransmission is being done. This is required
++ for connectionless transport protocols (\a RS_CONN_TYPE_UDP and
++ \a RS_CONN_TYPE_DTLS). The "request" API with \a rs_request_send can
++ help with this.
+
\return On success, RSE_OK (0) is returned. On error, !0 is
returned and a struct \a rs_error is pushed on the error stack for
- the connection. The error can be accessed using \a
- rs_err_conn_pop. */
+ the connection. The error can be accessed using \a rs_err_conn_pop. */
-int rs_packet_send(struct rs_packet *pkt, void *user_data);
-
-/** Create a RADIUS authentication request packet associated with
- connection \a conn. Optionally, User-Name and User-Password
- attributes are added to the packet using the data in \a user_name
- and \a user_pw. */
-int rs_packet_create_authn_request(struct rs_connection *conn,
- struct rs_packet **pkt,
- const char *user_name,
- const char *user_pw);
-
-/*** Append \a tail to packet \a pkt. */
+int rs_message_send(struct rs_message *msg);
+
+/** Create a RADIUS authentication request message associated with
+ connection \a conn. Optionally, User-Name and User-Password
+ attributes are added to the message using the data in \a user_name
+ and \a user_pw.
+ FIXME: describe what RADIUS shared secret is being used */
+int rs_message_create_authn_request(struct rs_connection *conn,
+ struct rs_message **msg,
+ const char *user_name,
+ const char *user_pw);
+
+/*** Append \a tail to message \a msg. */
int
-rs_packet_append_avp(struct rs_packet *pkt,
- unsigned int attribute, unsigned int vendor,
- const void *data, size_t data_len);
+rs_message_append_avp(struct rs_message *msg,
+ unsigned int attribute, unsigned int vendor,
+ const void *data, size_t data_len);
-/*** Get pointer to \a pkt attribute value pairs. */
+/*** Get pointer to \a msg attribute value pairs. */
void
-rs_packet_avps(struct rs_packet *pkt, rs_avp ***vps);
+rs_message_avps(struct rs_message *msg, rs_avp ***vps);
-/*** Get RADIUS packet type of \a pkt. */
+/*** Get RADIUS message type of \a msg. */
unsigned int
-rs_packet_code(struct rs_packet *pkt);
+rs_message_code(struct rs_message *msg);
-/*** Get RADIUS AVP from \a pkt. */
+/*** Get RADIUS AVP from \a msg. */
rs_const_avp *
-rs_packet_find_avp(struct rs_packet *pkt, unsigned int attr, unsigned int vendor);
+rs_message_find_avp(struct rs_message *msg, unsigned int attr,
+ unsigned int vendor);
-/*** Set packet identifier in \a pkt; returns old identifier */
+/*** Set packet identifier in \a msg; returns old identifier */
int
-rs_packet_set_id (struct rs_packet *pkt, int id);
+rs_message_set_id (struct rs_message *msg, int id);
/************/
/* Config. */
/** Create a request associated with connection \a conn. */
int rs_request_create(struct rs_connection *conn, struct rs_request **req_out);
-/** Add RADIUS request message \a req_msg to request \a req.
- FIXME: Rename to rs_request_add_reqmsg? */
-void rs_request_add_reqpkt(struct rs_request *req, struct rs_packet *req_msg);
+/** Add RADIUS request message \a req_msg to request \a req. */
+void rs_request_add_reqmsg(struct rs_request *req, struct rs_message *req_msg);
/** Create a request associated with connection \a conn containing a
- newly created RADIUS authentication message, possibly with
- \a user_name and \a user_pw attributes. \a user_name and \a user_pw
- are optional and can be NULL. If \a user_name and \a user_pw are provided,
- \a secret must also be provided. \a secret is used for "hiding" the
- password. */
+ newly created RADIUS authentication message, possibly with \a
+ user_name and \a user_pw attributes. \a user_name and _user_pw
+ are optional and can be NULL. */
int rs_request_create_authn(struct rs_connection *conn,
struct rs_request **req_out,
const char *user_name,
- /* Copyright 2010,2011,2013 NORDUnet A/S. All rights reserved.
-/* Copyright 2010-2012 NORDUnet A/S. All rights reserved.
++/* Copyright 2010-2013 NORDUnet A/S. All rights reserved.
See LICENSE for licensing information. */
#if defined HAVE_CONFIG_H
- /* Copyright 2010,2011,2013 NORDUnet A/S. All rights reserved.
- See LICENSE for licensing information. */
-/* Copyright 2010-2011 NORDUnet A/S. All rights reserved.
++/* Copyright 2010-2013 NORDUnet A/S. All rights reserved.
+ See LICENSE for licensing information. */
#if defined HAVE_CONFIG_H
#include <config.h>
{
size_t n = 0;
- n = bufferevent_read (pkt->conn->bev, pkt->hdr, RS_HEADER_LEN);
+ n = bufferevent_read (TO_BASE_CONN(msg->conn)->bev, msg->hdr, RS_HEADER_LEN);
if (n == RS_HEADER_LEN)
{
- 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)
- {
- rs_debug (("%s: invalid packet length: %d\n",
- __func__, pkt->rpkt->length));
- rs_conn_disconnect (pkt->conn);
- return rs_err_conn_push (pkt->conn, RSE_INVALID_PKT,
- "invalid packet length: %d",
- pkt->rpkt->length);
- }
- memcpy (pkt->rpkt->data, pkt->hdr, RS_HEADER_LEN);
- bufferevent_setwatermark (pkt->conn->bev, EV_READ,
- pkt->rpkt->length - RS_HEADER_LEN, 0);
- rs_debug (("%s: packet header read, total pkt len=%d\n",
- __func__, pkt->rpkt->length));
+ msg->flags |= RS_MESSAGE_HEADER_READ;
+ msg->rpkt->length = (msg->hdr[2] << 8) + msg->hdr[3];
+ if (msg->rpkt->length < 20 || msg->rpkt->length > RS_MAX_PACKET_LEN)
- return rs_err_conn_push (msg->conn, RSE_INVALID_MSG,
- "invalid message length: %d",
- msg->rpkt->length);
++ {
++ rs_debug (("%s: invalid packet length: %d\n", __func__,
++ msg->rpkt->length));
++ rs_conn_disconnect (msg->conn);
++ return rs_err_conn_push (msg->conn, RSE_INVALID_MSG,
++ "invalid message length: %d",
++ msg->rpkt->length);
++ }
+ memcpy (msg->rpkt->data, msg->hdr, RS_HEADER_LEN);
+ bufferevent_setwatermark (TO_BASE_CONN(msg->conn)->bev, EV_READ,
+ msg->rpkt->length - RS_HEADER_LEN, 0);
+ rs_debug (("%s: message header read, total msg len=%d\n",
+ __func__, msg->rpkt->length));
}
else if (n < 0)
- {
- rs_debug (("%s: buffer frozen while reading header\n", __func__));
- }
+ rs_debug (("%s: buffer frozen while reading header\n", __func__));
else /* Error: libevent gave us less than the low watermark. */
- return rs_err_conn_push_fl (msg->conn, RSE_INTERNAL, __FILE__, __LINE__,
- "got %d octets reading header", n);
+ {
+ rs_debug (("%s: got: %d octets reading header\n", __func__, n));
- rs_conn_disconnect (pkg->conn);
- return rs_err_conn_push_fl (pkt->conn, RSE_INTERNAL, __FILE__, __LINE__,
- "got %d octets reading header", n);
++ rs_conn_disconnect (msg->conn);
++ return rs_err_conn_push (msg->conn, RSE_INTERNAL,
++ "got %d octets reading header", n);
+ }
+
- return 0;
+ return RSE_OK;
}
/** Read a message, check that it's valid RADIUS and hand it off to
- invalid code field
- attribute lengths >= 2
- attribute sizes adding up correctly */
- err = nr_packet_ok (pkt->rpkt);
- if (err != RSE_OK)
+ err = nr_packet_ok (msg->rpkt);
+ if (err)
- return rs_err_conn_push_fl (msg->conn, err, __FILE__, __LINE__,
- "invalid message");
+ {
+ rs_debug (("%s: %d: invalid packet\n", __func__, -err));
- rs_conn_disconnect (pkt->conn);
- return rs_err_conn_push_fl (pkt->conn, -err, __FILE__, __LINE__,
- "invalid packet");
- }
++ rs_conn_disconnect (msg->conn);
++ return rs_err_conn_push (msg->conn, -err, "invalid message");
++ }
#if defined (DEBUG)
/* Find out what happens if there's data left in the buffer. */
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);
+ if ((msg->flags & RS_MESSAGE_HEADER_READ) == 0)
+ if (_read_header (msg))
+ return; /* Invalid header. */
- if (_read_message (msg))
- return; /* Invalid message. */
++ _read_message (msg);
}
void
TESTS = test-udp
-check_PROGRAMS = test-udp udp-server
+check_PROGRAMS = test-udp udp-server tls-server
- test_udp_SOURCES = test-udp.c udp.c
- test_udp_LDADD = ../libradsec.la -lcgreen -lm
+ test_udp_SOURCES = test-udp.c udp.c udp.h
+ test_udp_LDADD = ../libradsec.la -lcunit -lm
- udp_server_SOURCES = udp-server.c udp.c
+ udp_server_SOURCES = udp-server.c udp.c udp.h
+
+tls_server_SOURCES = server.c
+tls_server_LDADD = ../libradsec.la
-
-/* Copyright 2011 NORDUnet A/S. All rights reserved.
+/* Copyright 2011,2013 NORDUnet A/S. All rights reserved.
- See LICENSE for licensing information. */
+ See LICENSE for licensing information. */
#if defined HAVE_CONFIG_H
#include <config.h>
_evcb (evutil_socket_t fd, short what, void *user_data)
{
int err;
- struct rs_packet *pkt = (struct rs_packet *) user_data;
+ struct rs_message *msg = (struct rs_message *) user_data;
- assert (msg);
- assert (msg->conn);
rs_debug (("%s: fd=%d what =", __func__, fd));
- if (what & EV_TIMEOUT) rs_debug ((" TIMEOUT"));
+ if (what & EV_TIMEOUT) rs_debug ((" TIMEOUT -- shouldn't happen!"));
if (what & EV_READ) rs_debug ((" READ"));
if (what & EV_WRITE) rs_debug ((" WRITE"));
rs_debug (("\n"));
- assert (pkt);
- assert (pkt->conn);
++ assert (msg);
++ assert (msg->conn);
if (what & EV_READ)
{
- /* Read a single UDP packet and stick it in USER_DATA. */
+ /* Read a single UDP packet and stick it in the struct
+ rs_message passed in user_data. */
/* TODO: Verify that unsolicited packets are dropped. */
ssize_t r = 0;
+ assert (msg->rpkt);
+ assert (msg->rpkt->data);
- assert (pkt->rpkt->data);
-
- r = compat_recv (fd, pkt->rpkt->data, RS_MAX_PACKET_LEN, MSG_TRUNC);
+ r = compat_recv (fd, msg->rpkt->data, RS_MAX_PACKET_LEN, MSG_TRUNC);
if (r == -1)
{
- int sockerr = evutil_socket_geterror (pkt->conn->fd);
+ int sockerr = evutil_socket_geterror (msg->conn->fd);
if (sockerr == EAGAIN)
{
/* FIXME: Really shouldn't happen since we've been told
}
/* Hard error. */
- rs_err_conn_push_fl (pkt->conn, RSE_SOCKERR, __FILE__, __LINE__,
- "%d: recv: %d (%s)", fd, sockerr,
- evutil_socket_error_to_string (sockerr));
- event_del (pkt->conn->tev);
+ rs_err_conn_push (msg->conn, RSE_SOCKERR,
+ "%d: recv: %d (%s)", fd, sockerr,
+ evutil_socket_error_to_string (sockerr));
+ event_del (msg->conn->tev);
- return;
+ goto err_out;
}
- event_del (pkt->conn->tev);
+ event_del (msg->conn->tev);
if (r < 20 || r > RS_MAX_PACKET_LEN) /* Short or long packet. */
{
- rs_err_conn_push (pkt->conn, RSE_INVALID_PKT,
- "invalid packet length: %d", r);
+ rs_err_conn_push (msg->conn, RSE_INVALID_MSG,
- "invalid message length: %d",
- msg->rpkt->length);
- return;
++ "invalid message length: %d", r);
+ goto err_out;
}
- pkt->rpkt->length = (pkt->rpkt->data[2] << 8) + pkt->rpkt->data[3];
- err = nr_packet_ok (pkt->rpkt);
+ msg->rpkt->length = (msg->rpkt->data[2] << 8) + msg->rpkt->data[3];
+ err = nr_packet_ok (msg->rpkt);
if (err)
{
- rs_err_conn_push_fl (msg->conn, err, __FILE__, __LINE__,
- "invalid message");
- return;
- rs_err_conn_push_fl (pkt->conn, -err, __FILE__, __LINE__,
- "invalid packet");
++ rs_err_conn_push (msg->conn, -err, "invalid message");
+ goto err_out;
}
- /* Hand over message to user. This changes ownership of pkt.
+ /* Hand over message to user. This changes ownership of msg.
Don't touch it afterwards -- it might have been freed. */
- if (pkt->conn->callbacks.received_cb)
- pkt->conn->callbacks.received_cb (pkt, pkt->conn->user_data);
+ if (msg->conn->callbacks.received_cb)
+ msg->conn->callbacks.received_cb (msg, msg->conn->base_.user_data);
}
else if (what & EV_WRITE)
{
- if (!pkt->conn->is_connected)
- event_on_connect (pkt->conn, pkt);
-
- if (pkt->conn->out_queue)
- if (_send (pkt->conn, fd) == RSE_OK)
- if (pkt->conn->callbacks.sent_cb)
- pkt->conn->callbacks.sent_cb (pkt->conn->user_data);
+ if (conn_originating_p (msg->conn))
+ {
+ /* We're a client. */
+ if (msg->conn->state == RS_CONN_STATE_CONNECTING)
+ event_on_connect_orig (msg->conn, msg);
+ }
+ else
+ {
+ /* We're a server. */
+ rs_debug (("%s: write event on terminating conn %p\n",
+ __func__, msg->conn));
+ }
+
+ if (msg->conn->out_queue)
+ if (_send (msg->conn, fd) == RSE_OK)
+ if (msg->conn->callbacks.sent_cb)
+ msg->conn->callbacks.sent_cb (msg->conn->base_.user_data);
}
+ return;
- #if defined (DEBUG)
- if (what & EV_TIMEOUT)
- rs_debug (("%s: timeout on UDP event, shouldn't happen\n", __func__));
- #endif
+ err_out:
- rs_conn_disconnect (pkt->conn);
++ rs_conn_disconnect (msg->conn);
}
int
/* Copyright 2011 NORDUnet A/S. All rights reserved.
- See LICENSE for licensing information. */
+ See LICENSE for licensing information. */
-int udp_init (struct rs_connection *conn, struct rs_packet *pkt);
+int udp_init (struct rs_connection *conn, struct rs_message *msg);
int udp_init_retransmit_timer (struct rs_connection *conn);