~ubuntu-branches/ubuntu/dapper/freeradius/dapper-updates

« back to all changes in this revision

Viewing changes to src/main/radrelay.c

  • Committer: Bazaar Package Importer
  • Author(s): Paul Hampson
  • Date: 2005-06-27 03:13:48 UTC
  • mfrom: (1.1.2 upstream)
  • Revision ID: james.westby@ubuntu.com-20050627031348-tu393q64vdle45ah
Tags: 1.0.4-2
* Fix my email address in the dpatches
* Remove extraneous ^g from man/man5/clients.conf.5
  - Created 04_bonus_control_code_in_clients_conf_5
* Correct handing of parameterless call of init script, and
  general init script neatening
  (Thanks to Derrick Karpo)
  Closes: #315438
* Correctly leave out the .in files in the examples
* Correctly use debhelper after splitting binary make target
  into binary-arch and binary-indep.
  (Thanks to Kurt Roeckx for actually hitting the bug)
  Closes: #315770
* Steal fix from CVS release_1_0 tree for rlm_sql quoted values.
  (Thanks to Nicolas Baradakis for the fix)
  - Upstream bugzilla #242, src/modules/rlm_sql/sql.c 1.79.2.2
  - Created 05_unbreak_quoted_sql_values

Show diffs side-by-side

added added

removed removed

Lines of Context:
26
26
 *
27
27
 */
28
28
char radrelay_rcsid[] =
29
 
"$Id: radrelay.c,v 1.22 2004/04/28 21:22:40 kkalev Exp $";
 
29
"$Id: radrelay.c,v 1.22.2.3 2005/06/07 18:57:40 aland Exp $";
30
30
 
31
31
#include "autoconf.h"
32
32
#include "libradius.h"
83
83
#define         STATE_BACKLOG   1
84
84
#define         STATE_WAIT      2
85
85
#define         STATE_SHUTDOWN  3
 
86
#define         STATE_CLOSE     4
86
87
 
87
88
#define         NR_SLOTS        64
88
89
 
116
117
 
117
118
struct relay_request slots[NR_SLOTS];
118
119
char id_map[256];
119
 
int request_head;
 
120
int request_head = 0;
120
121
int got_sigterm = 0;
121
122
int debug = 0;
122
123
 
203
204
{
204
205
        VALUE_PAIR *vp;
205
206
        char *s;
206
 
        char buf[256];
 
207
        char buf[2048];
207
208
        char key[32], val[32];
208
209
        int skip;
209
210
        long fpos;
228
229
        do {
229
230
                x = rad_lockfd_nonblock(fileno(fp), 0);
230
231
                if (x == -1)
231
 
                        ms_sleep(25);
232
 
        } while (x == -1 && i++ < 80);
 
232
                        ms_sleep(100);
 
233
        } while (x == -1 && i++ < 20);
233
234
 
234
235
        if (x == -1)
235
236
                return 0;
408
409
                                free (r->req->data);
409
410
                                r->req->data = NULL;
410
411
                        }
411
 
                        r->state = 0;
 
412
                        r->state = STATE_EMPTY;
412
413
                        r->retrans = 0;
413
414
                        r->retrans_num = 0;
414
415
                        r->timestamp = 0;
445
446
                        free (r->req->data);
446
447
                        r->req->data = NULL;
447
448
                }
448
 
                r->state = 0;
 
449
                r->state = STATE_EMPTY;
449
450
                r->retrans = 0;
450
451
                r->retrans_num = 0;
451
452
                r->timestamp = 0;
533
534
 *      STATE_RUN:      Reading from detail file, sending to server.
534
535
 *      STATE_BACKLOG:  Reading from the detail.work file, for example
535
536
 *                      after a crash or restart. Sending to server.
536
 
 *      STATE_WAIT:     Reached end-of-file, renamed detail to
537
 
 *                      detail.work, waiting for all outstanding
538
 
 *                      requests to be answered.
 
537
 *      STATE_WAIT:     Waiting for all outstanding requests to be handled.
 
538
 *      STATE_CLOSE:    Reached end of detail.work file, waiting for
 
539
 *                      outstanding requests, and removing the file.
 
540
 *      STATE_SHUTDOWN: Got SIG_TERM, waiting for outstanding requests
 
541
 *                      and exiting program.
539
542
 */
540
543
void loop(struct relay_misc *r_args)
541
544
{
560
563
         */
561
564
        for (i = 0; i < NR_SLOTS; i++) {
562
565
                if ((slots[i].req = rad_alloc(1)) == NULL) {
563
 
                        librad_perror("radclient");
 
566
                        librad_perror("radrelay");
564
567
                        exit(1);
565
568
                }
566
 
                slots[i].state = 0;
 
569
                slots[i].state = STATE_EMPTY;
567
570
                slots[i].retrans = 0;
568
571
                slots[i].retrans_num = 0;
569
572
                slots[i].timestamp = 0;
601
604
                 *      filled slot, we can read from the detail file.
602
605
                 */
603
606
                r = &slots[request_head];
604
 
                if (fp && state != STATE_WAIT && state != STATE_SHUTDOWN &&
 
607
                if (fp && (state == STATE_RUN || state == STATE_BACKLOG) &&
605
608
                    r->state != STATE_FULL) {
606
609
                        if (read_one(fp, r) == EOF) do {
607
610
 
608
611
                                /*
 
612
                                 *      We've reached end of the <detail>.work
 
613
                                 *      It's going to be closed as soon as all
 
614
                                 *      outstanting requests are handled
 
615
                                 */
 
616
                                if (state == STATE_BACKLOG) {
 
617
                                        state = STATE_CLOSE;
 
618
                                        break;
 
619
                                }
 
620
 
 
621
                                /*
609
622
                                 *      End of file. See if the file has
610
623
                                 *      any size, and if we renamed less
611
624
                                 *      than 10 seconds ago or not.
621
634
                                last_rename = now;
622
635
 
623
636
                                /*
624
 
                                 *      We rename the file
625
 
                                 *      to <file>.work and create an
626
 
                                 *      empty new file.
 
637
                                 *      We rename the file to <file>.work
 
638
                                 *      and create an empty new file.
627
639
                                 */
628
 
                                if (state == STATE_RUN &&
629
 
                                    detail_move(r_args->detail, work) == 0)
630
 
                                        state = STATE_WAIT;
631
 
                                else if (state == STATE_BACKLOG)
632
 
                                        state = STATE_WAIT;
 
640
                                if (detail_move(r_args->detail, work) == 0) {
 
641
                                        if (debug_flag > 0)
 
642
                                                fprintf(stderr, "Moving %s to %s\n",
 
643
                                                        r_args->detail, work);
 
644
                                        /*
 
645
                                         *      rlm_detail might still write
 
646
                                         *      something to <detail>.work if
 
647
                                         *      it opens <detail> before it is
 
648
                                         *      renamed (race condition)
 
649
                                         */
 
650
                                        ms_sleep(1000);
 
651
                                        state = STATE_BACKLOG;
 
652
                                }
633
653
                                fpos = ftell(fp);
634
654
                                fseek(fp, 0L, SEEK_SET);
 
655
                                rad_unlockfd(fileno(fp), 0);
635
656
                                fseek(fp, fpos, SEEK_SET);
636
 
                                rad_unlockfd(fileno(fp), 0);
637
657
                        } while(0);
638
658
                        if (r->state == STATE_FULL)
639
659
                                request_head = (request_head + 1) % NR_SLOTS;
654
674
 
655
675
                /*
656
676
                 *      If we're in STATE_WAIT and all slots are
657
 
                 *      finally empty, we can copy the <detail>.work file
658
 
                 *      to the definitive detail file and resume.
 
677
                 *      finally empty, we can remove the <detail>.work
659
678
                 */
660
 
                if (state == STATE_WAIT || state == STATE_SHUTDOWN) {
 
679
                if (state == STATE_WAIT || state == STATE_CLOSE || state == STATE_SHUTDOWN) {
661
680
                        for (i = 0; i < NR_SLOTS; i++)
662
681
                                if (slots[i].state != STATE_EMPTY)
663
682
                                        break;
664
683
                        if (i == NR_SLOTS) {
665
 
                                if (fp) fclose(fp);
666
 
                                fp = NULL;
667
 
                                unlink(work);
668
 
                                if (state == STATE_SHUTDOWN) {
 
684
                                if (state == STATE_CLOSE) {
 
685
                                        if (fp) fclose(fp);
 
686
                                        fp = NULL;
 
687
                                        if (debug_flag > 0)
 
688
                                                fprintf(stderr, "Unlink file %s\n", work);
 
689
                                        unlink(work);
 
690
                                }
 
691
                                else if (state == STATE_SHUTDOWN) {
669
692
                                        for (i = 0; i < NR_SLOTS; i++) {
670
693
                                                rad_free(&slots[i].req);
671
694
                                        }
1005
1028
 
1006
1029
        return 0;
1007
1030
}
1008