On Tue, 14 May 2002, Chris Parker wrote:

> At 01:57 PM 5/14/2002 +1200, Simon Allard wrote:
>
> >Is there a way to load balance modules?
> >
> >I can see how to do a failover, but I want to be able to load balance over
> >multiple ldap servers. Is that at all possible with the current code base?
>
> Not at the moment, no.  As Alan says: "Patches are welcome!"  :)
>
> -Chris
>
> --
>     \\\|||///  \          StarNet Inc.      \        Chris Parker
>     \ ~   ~ /   \       WX *is* Wireless!    \   Director, Engineering
>     | @   @ |    \   http://www.starnetwx.net \      (847) 963-0116
> oOo---(_)---oOo--\------------------------------------------------------
>                    \ Wholesale Internet Services - http://www.megapop.net
>
>
>
> -
> List info/subscribe/unsubscribe? See http://www.freeradius.org/list/users.html

OK, here is the smallest module ever for freeradius. rlm_loadbl. Just take a
number from rand() and do num % divisor where divisor is configurable. Then add
that number to a new attribute Load-Balancer. The idea is this:

users file:

DEFAULT Load-Balancer == 0, Autz-Type = "Ldap1"

DEFAULT Load-Balancer == 1, Autz-Type = "Ldap2"


radiusd.conf:

loadbl{
        divisor = 2
}

authorize{
        loadbl
        files
        autztype Ldap1{
                ldap1
        }
        autztype Ldap2{
                ldap2
        }
}

You will need to edit a few files for this to work:

src/include/radius.h: Add
#define PW_LOAD_BALANCER        1075

etc/raddb/dictionary: Add
ATTRIBUTE       Load-Balancer           1075    integer

If anyone is interested I could add it in the source.

--
Kostas Kalevras         Network Operations Center
[EMAIL PROTECTED]      National Technical University of Athens, Greece
Work Phone:             +30 10 7721861
'Go back to the shadow' Gandalf
/*
 * rlm_loadbl.c 
 *
 * Version:     $Id: rlm_loadbl.c,v 1.23 2001/02/20 20:51:33 pacman Exp $
 *
 *   This program is free software; you can redistribute it and/or modify
 *   it under the terms of the GNU General Public License as published by
 *   the Free Software Foundation; either version 2 of the License, or
 *   (at your option) any later version.
 *
 *   This program is distributed in the hope that it will be useful,
 *   but WITHOUT ANY WARRANTY; without even the implied warranty of
 *   MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
 *   GNU General Public License for more details.
 *
 *   You should have received a copy of the GNU General Public License
 *   along with this program; if not, write to the Free Software
 *   Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA  02111-1307  USA
 *
 * Copyright 2000  The FreeRADIUS server project
 * Copyright 2000  your name <your address>
 */

#include "autoconf.h"
#include "libradius.h"

#include <stdio.h>
#include <stdlib.h>


#include "radiusd.h"
#include "modules.h"
#include "conffile.h"

static const char rcsid[] = "$Id: rlm_loadbl.c,v 1.23 2001/02/20 20:51:33 pacman Exp 
$";

/*
 *      Define a structure for our module configuration.
 *
 *      These variables do not need to be in a structure, but it's
 *      a lot cleaner to do so, and a pointer to the structure can
 *      be used as the instance handle.
 */
typedef struct rlm_loadbl_t {
        int             divisor;
} rlm_loadbl_t;

/*
 *      A mapping of configuration file names to internal variables.
 *
 *      Note that the string is dynamically allocated, so it MUST
 *      be freed.  When the configuration file parse re-reads the string,
 *      it free's the old one, and strdup's the new one, placing the pointer
 *      to the strdup'd string into 'config.string'.  This gets around
 *      buffer over-flows.
 */
static CONF_PARSER module_config[] = {
  { "divisor", PW_TYPE_INTEGER,    offsetof(rlm_loadbl_t,divisor), NULL,   "2" },
  { NULL, -1, 0, NULL, NULL }           /* end the list */
};

/*
 *      Do any per-module initialization that is separate to each
 *      configured instance of the module.  e.g. set up connections
 *      to external databases, read configuration files, set up
 *      dictionary entries, etc.
 *
 *      If configuration information is given in the config section
 *      that must be referenced in later calls, store a handle to it
 *      in *instance otherwise put a null pointer there.
 */
static int loadbl_instantiate(CONF_SECTION *conf, void **instance)
{
        rlm_loadbl_t *data;
        
        /*
         *      Set up a storage area for instance data
         */
        data = rad_malloc(sizeof(*data));

        /*
         *      If the configuration parameters can't be parsed, then
         *      fail.
         */
        if (cf_section_parse(conf, data, module_config) < 0) {
                free(data);
                return -1;
        }
        
        *instance = data;
        
        return 0;
}

/*
 *      Find the named user in this modules database.  Create the set
 *      of attribute-value pairs to check and reply with for this user
 *      from the database. The authentication code only needs to check
 *      the password, the rest is done here.
 */
static int loadbl_authorize(void *instance, REQUEST *request)
{
        rlm_loadbl_t *data = (rlm_loadbl_t *) instance;
        VALUE_PAIR *vp;
        int num;

        /* quiet the compiler */
        instance = instance;
        request = request;

        num = rand();
        num %= data->divisor;

        
        if ((vp = paircreate(PW_LOAD_BALANCER, PW_TYPE_INTEGER)) == NULL) {
                radlog(L_ERR|L_CONS, "no memory");
                return RLM_MODULE_NOOP;
        }
        vp->lvalue = num;
        pairadd(&request->packet->vps, vp);

        return RLM_MODULE_OK;
}

/*
 *      The module name should be the only globally exported symbol.
 *      That is, everything else should be 'static'.
 *
 *      If the module needs to temporarily modify it's instantiation
 *      data, the type should be changed to RLM_TYPE_THREAD_UNSAFE.
 *      The server will then take care of ensuring that the module
 *      is single-threaded.
 */
module_t rlm_loadbl = {
        "loadbl",       
        RLM_TYPE_THREAD_SAFE,           /* type */
        NULL,                           /* initialization */
        loadbl_instantiate,             /* instantiation */
        {
                NULL,                   /* authentication */
                loadbl_authorize,       /* authorization */
                NULL,                   /* preaccounting */
                NULL,                   /* accounting */
                NULL                    /* checksimul */
        },
        NULL,                           /* detach */
        NULL,                           /* destroy */
};

Reply via email to