You can also lower the number of interim acct-updates with:
ssg accounting [per-host|per-service] interval 60 (which in min)
Am Fre, 2003-08-22 um 03.53 schrieb Hindrik Buining:
> Hi all,
>
> I'm using freeradius as a radius server for a Cisco SSG (Service Selection
> Gateway) which
> we use to make people authenticate before they access the internet.
> We then charge for the volume of traffic used.
>
> The SSG sends large numbers (300+) of radius accounting alive packets back
> to back
> without waiting for a reply. With several thousand users (and hence
> accounting
> update packets) the burst rate of radius requests gets very high and
> freeradius drops requests.
>
> In threaded mode, freeradius drops the request if there are no threads
> available.
> In non-threaded mode, it doesn't process the requests fast enough for my
> needs.
>
> To get around the situation I wrote the following patch which does two
> things:
> 1. It increases the buffer size of the udp socket so the OS will buffer udp
> packets
> 2. It checks to make sure a thread is available to handle the request before
> it reads
> from the socket. If a thread is not available it sleeps for a mili
> second and tries again.
>
> I've found that running freeradius multithreaded backended into a db on
> multi-cpu
> machine increased by an order of magnitude the rate of accounting packets/s
> that can be processed.
>
> I'm running freeradius release 0.9.0_final on Solaris 8 on a variety of sun
> sparc boxes backended into
> Sybase and Postgresql. Freeradius was compiled under gcc 2.95.3
>
> It helped me.
> I hope it helps someone else too.
>
> Regards,
> - Hindrik
>
> -------------------------------------------------
> Hindrik Buining
> Senior Network Services Engineer
> Communications Unit
> University of New South Wales
> Sydney, Australia
> +61-2-9385-1144(w)
> +61-2-9385-1112(f)
> -------------------------------------------------
>
>
>
> *** radiusd.c.orig Thu Aug 14 13:49:00 2003
> --- radiusd.c Thu Aug 14 13:53:20 2003
> ***************
> *** 139,145 ****
> --- 139,147 ----
> static int refresh_request(REQUEST *request, void *data);
> #ifdef HAVE_PTHREAD_H
> extern int rad_spawn_child(REQUEST *, RAD_REQUEST_FUNP);
> + extern int threads_available();
> #else
> + static inline int threads_available() { return(1); }
> #ifdef ALLOW_CHILD_FORKS
> static int rad_spawn_child(REQUEST *, RAD_REQUEST_FUNP);
> #endif
> ***************
> *** 284,289 ****
> --- 286,303 ----
> struct sigaction act;
> #endif
> + /* Hindrik June 2003
> + * Variables used to increase the receive socket buffer size
> + */
> + int optval,optlen;
> +
> + /* Hindrik May 2003
> + * We want to sleep for a few mili seconds
> + */
> + struct timeval sleep_time;
> + sleep_time.tv_sec=0;
> + sleep_time.tv_usec = 1000;
> +
> syslog_facility = LOG_DAEMON;
> #ifdef OSFC2
> ***************
> *** 536,541 ****
> --- 550,564 ----
> perror ("acct socket");
> exit(1);
> }
> + optval = 256*1024;
> + optlen = sizeof(optval);
> + if( setsockopt(acctfd, SOL_SOCKET,
> + SO_RCVBUF, (void *)&optval, optlen)
> + ) {
> + perror( "Setting socket option");
> + exit(1);
> + }
> +
> sa = (struct sockaddr_in *) &salocal;
> memset ((char *) sa, '\0', sizeof(salocal));
> ***************
> *** 769,774 ****
> --- 792,800 ----
> #endif
> radlog(L_INFO, "Ready to process requests.");
> + #ifdef HAVE_PTHREAD_H
> + radlog(L_INFO, "Running with threads.");
> + #endif
> start_time = time(NULL);
> /*
> ***************
> *** 887,892 ****
> --- 913,924 ----
> }
> #endif
> +
> + while( !threads_available() ) {
> + radlog(L_ERR, "No threads available yet. Sleeping...");
> + select(0,NULL,NULL,NULL,&sleep_time);
> + }
> +
> status = select(max_fd + 1, &readfds, NULL, NULL, tv);
> #ifndef HAVE_PTHREAD_H
> /*
> ***************
> *** 2184,2189 ****
> --- 2216,2222 ----
> return request;
> }
> +
> /*
> * If we're using the thread pool, then the function in
> * 'threads.c' replaces this one.
> *** threads.c.orig Thu Aug 14 13:55:30 2003
> --- threads.c Thu Aug 14 13:50:32 2003
> ***************
> *** 209,215 ****
> self->thread_num);
> break;
> }
> -
> /*
> * Stupid implementations of sem_wait return on
> * signals, but don't return -1.
> --- 209,214 ----
> ***************
> *** 297,302 ****
> --- 296,337 ----
> free(handle);
> }
> +
> +
> + /*
> + * Check to see if we can process another request.
> + * Returns true if the threadpool is not full and all threads
> + * are busy.
> + *
> + *
> + */
> + int threads_available() {
> + THREAD_HANDLE *handle;
> +
> + /* printf("threads_available():\tThread Count: total %d, max
> %d\n",thread_pool.total_threads, thread_pool.max_threads); */
> +
> + /* If we can still span another thread than we have threads available */
> + if (thread_pool.total_threads < thread_pool.max_threads) {
> + return(1);
> + }
> +
> + /* Search the thread list looking for an available thread */
> + for (handle = thread_pool.head; handle != NULL; handle = handle->next){
> +
> + /* Ignore threads which aren't running. */
> + if( handle->status != THREAD_RUNNING ) {
> + continue;
> + }
> +
> + if (handle->request == NULL) {
> + /* radlog(L_INFO, "threads_available():\tFound a free request."); */
> + return(1); /* We've found an available thread */
> + }
> + }
> + return (0);
> +
> + }
> +
> /*
> * Spawn a new thread, and place it in the thread pool.
>
>
> -
> List info/subscribe/unsubscribe? See http://www.freeradius.org/list/users.html
>
-
List info/subscribe/unsubscribe? See http://www.freeradius.org/list/users.html