Skip to content

Commit

Permalink
bind to outbound socket, and start of write()
Browse files Browse the repository at this point in the history
  • Loading branch information
alandekok committed Jul 12, 2017
1 parent c3ec3bb commit 7acaa83
Showing 1 changed file with 59 additions and 6 deletions.
65 changes: 59 additions & 6 deletions src/modules/rlm_radius/rlm_radius_udp.c
Expand Up @@ -26,16 +26,19 @@ RCSID("$Id$")
#include <freeradius-devel/radiusd.h>
#include <freeradius-devel/modules.h>
#include <freeradius-devel/io/application.h>
#include <freeradius-devel/udp.h>
#include <freeradius-devel/rad_assert.h>

#include "rlm_radius.h"

typedef struct rlm_radius_udp_t {
fr_ipaddr_t dst_ipaddr; //!< IP of the home server
fr_ipaddr_t dst_ipaddr; //!< IP of the home server
fr_ipaddr_t src_ipaddr; //!< IP we open our socket on
uint16_t dst_port; //!< port of the home server
char const *secret; //!< shared secret

char const *interface; //!< Interface to bind to.

uint32_t recv_buff; //!< How big the kernel's receive buffer should be.
uint32_t send_buff; //!< How big the kernel's send buffer should be.

Expand All @@ -59,6 +62,11 @@ typedef struct udp_io_ctx_t {
uint32_t max_packet_size; //!< our max packet size. may be different from the parent...
int fd; //!< file descriptor

fr_ipaddr_t dst_ipaddr; //!< IP of the home server. stupid 'const' issues..
fr_ipaddr_t src_ipaddr; //!< my source IP
uint16_t src_port; //!< my source port
uint16_t dst_port; //!< port of the home server

// @todo - track status-server, open, signaling, etc.

// @todo - track outstanding IDs, one per packet code...
Expand All @@ -67,6 +75,12 @@ typedef struct udp_io_ctx_t {
size_t buflen; //!< receive buffer length
} udp_io_ctx_t;

typedef struct request_ctx_t {
uint8_t header[20];

// @todo - timers, retransmits, etc
} request_ctx_t;


static const CONF_PARSER module_config[] = {
{ FR_CONF_IS_SET_OFFSET("ipaddr", FR_TYPE_COMBO_IP_ADDR, rlm_radius_udp_t, dst_ipaddr) },
Expand All @@ -75,6 +89,10 @@ static const CONF_PARSER module_config[] = {

{ FR_CONF_OFFSET("port", FR_TYPE_UINT16, rlm_radius_udp_t, dst_port) },

{ FR_CONF_OFFSET("secret", FR_TYPE_STRING | FR_TYPE_REQUIRED, rlm_radius_udp_t, secret) },

{ FR_CONF_OFFSET("interface", FR_TYPE_STRING, rlm_radius_udp_t, interface) },

{ FR_CONF_IS_SET_OFFSET("recv_buff", FR_TYPE_UINT32, rlm_radius_udp_t, recv_buff) },
{ FR_CONF_IS_SET_OFFSET("send_buff", FR_TYPE_UINT32, rlm_radius_udp_t, send_buff) },

Expand All @@ -89,6 +107,33 @@ static const CONF_PARSER module_config[] = {
};


static int mod_write(REQUEST *request, void *request_ctx, void *io_ctx)
{
udp_io_ctx_t *io = talloc_get_type_abort(io_ctx, udp_io_ctx_t);
request_ctx_t *track = (request_ctx_t *) request_ctx; /* not talloc'd */
ssize_t packet_len, data_size;

packet_len = fr_radius_encode(io->buffer, io->buflen, NULL, io->inst->secret, strlen(io->inst->secret),
request->packet->code, 0, request->packet->vps);
if (packet_len < 0) {
RDEBUG("Failed encoding packet: %s", fr_strerror());

// @todo - distinguish write errors from encode errors?
return -1;
}

data_size = udp_send(io->fd, io->buffer, packet_len, 0,
&io->dst_ipaddr, io->inst->dst_port,
// address->if_index,
0,
&io->src_ipaddr, io->src_port);

// @todo - put the packet into an RB tree, too, so we can find replies...
memcpy(&track->header ,io->buffer, 20);

return 1;
}

/** Get a printable name for the socket
*
*/
Expand All @@ -97,16 +142,16 @@ static char const *mod_get_name(TALLOC_CTX *ctx, void *io_ctx)
udp_io_ctx_t *io = talloc_get_type_abort(io_ctx, udp_io_ctx_t);
char src_buf[FR_IPADDR_STRLEN], dst_buf[FR_IPADDR_STRLEN];

fr_inet_ntop(dst_buf, sizeof(dst_buf), &io->inst->dst_ipaddr);
fr_inet_ntop(dst_buf, sizeof(dst_buf), &io->dst_ipaddr);

// @todo - make sure to get the local port number we're bound to

if (fr_ipaddr_is_inaddr_any(&io->inst->src_ipaddr)) {
return talloc_asprintf(ctx, "home server %s port %u", dst_buf, io->inst->dst_port);
return talloc_asprintf(ctx, "home server %s port %u", dst_buf, io->dst_port);
}

fr_inet_ntop(src_buf, sizeof(src_buf), &io->inst->src_ipaddr);
return talloc_asprintf(ctx, "from %s to home server %s port %u", src_buf, dst_buf, io->inst->dst_port);
return talloc_asprintf(ctx, "from %s to home server %s port %u", src_buf, dst_buf, io->dst_port);
}


Expand Down Expand Up @@ -164,7 +209,14 @@ static fr_connection_state_t mod_init(int *fd_out, void *io_ctx, void const *uct
return FR_CONNECTION_STATE_FAILED;
}

// @todo - make sure to get the local port number we're bound to
io->dst_ipaddr = inst->dst_ipaddr;
io->dst_port = inst->dst_port;
io->src_ipaddr = inst->src_ipaddr;

if (fr_socket_bind(fd, &io->src_ipaddr, &io->src_port, inst->interface) < 0) {
DEBUG("Failed binding RADIUS client UDP socket: %s", fr_strerror());
return FR_CONNECTION_STATE_FAILED;
}

// @todo - set recv_buff and send_buff socket options

Expand Down Expand Up @@ -275,15 +327,16 @@ fr_radius_client_io_t rlm_radius_udp = {
.magic = RLM_MODULE_INIT,
.name = "radius_udp",
.inst_size = sizeof(rlm_radius_udp_t),
.request_inst_size = sizeof(request_ctx_t),
.config = module_config,
.bootstrap = mod_bootstrap,
.instantiate = mod_instantiate,
.init = mod_init,
.open = mod_open,
.close = mod_close,
.get_name = mod_get_name,
#if 0
.write = mod_write,
#if 0
.flush = mod_flush,
.remove = mod_remove,
.read = mod_read,
Expand Down

0 comments on commit 7acaa83

Please sign in to comment.