106
108
char detail[1024]; /* Detail file */
107
109
char *secret; /* Secret */
108
110
char f_secret[256]; /* File secret */
111
int sleep_time; /* Time to sleep between sending packets */
112
int sleep_every; /* Sleep every so many packets */
113
int records_print; /* Print statistics after so many records */
118
uint32_t records_read; /* Records read */
119
uint32_t packets_sent; /* Packets sent */
120
uint32_t last_print_records; /* Records on last statistics printout */
390
402
for (i = 0; i < NR_SLOTS; i++) {
392
404
if (r->state == STATE_FULL && r->req->id == rep->id) {
405
if (rad_verify(rep, r->req, r_args->secret) != 0) {
406
librad_perror("rad_verify");
393
409
if (rad_decode(rep, r->req, r_args->secret) != 0) {
394
410
librad_perror("rad_decode");
533
549
* STATE_RUN: Reading from detail file, sending to server.
534
550
* STATE_BACKLOG: Reading from the detail.work file, for example
535
551
* 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.
552
* STATE_WAIT: Waiting for all outstanding requests to be handled.
553
* STATE_CLOSE: Reached end of detail.work file, waiting for
554
* outstanding requests, and removing the file.
555
* STATE_SHUTDOWN: Got SIG_TERM, waiting for outstanding requests
556
* and exiting program.
540
558
void loop(struct relay_misc *r_args)
543
561
struct relay_request *r;
544
562
struct timeval tv;
563
struct relay_stats stats;
547
time_t now, last_rename = 0;
566
time_t now, uptime, last_rename = 0;
549
568
int state = STATE_RUN;
556
575
id = ((int)getpid() & 0xff);
577
memset(&stats,0,sizeof(struct relay_stats));
578
stats.startup = time(NULL);
559
581
* Initialize all our slots, might as well do this right away.
561
583
for (i = 0; i < NR_SLOTS; i++) {
562
584
if ((slots[i].req = rad_alloc(1)) == NULL) {
563
librad_perror("radclient");
585
librad_perror("radrelay");
588
slots[i].state = STATE_EMPTY;
567
589
slots[i].retrans = 0;
568
590
slots[i].retrans_num = 0;
569
591
slots[i].timestamp = 0;
601
623
* filled slot, we can read from the detail file.
603
625
r = &slots[request_head];
604
if (fp && state != STATE_WAIT && state != STATE_SHUTDOWN &&
626
if (fp && (state == STATE_RUN || state == STATE_BACKLOG) &&
605
627
r->state != STATE_FULL) {
606
628
if (read_one(fp, r) == EOF) do {
631
* We've reached end of the <detail>.work
632
* It's going to be closed as soon as all
633
* outstanting requests are handled
635
if (state == STATE_BACKLOG) {
609
641
* End of file. See if the file has
610
642
* any size, and if we renamed less
611
643
* than 10 seconds ago or not.
621
653
last_rename = now;
625
* to <file>.work and create an
656
* We rename the file to <file>.work
657
* and create an empty new file.
628
if (state == STATE_RUN &&
629
detail_move(r_args->detail, work) == 0)
631
else if (state == STATE_BACKLOG)
659
if (detail_move(r_args->detail, work) == 0) {
661
fprintf(stderr, "Moving %s to %s\n",
662
r_args->detail, work);
664
* rlm_detail might still write
665
* something to <detail>.work if
666
* it opens <detail> before it is
667
* renamed (race condition)
670
state = STATE_BACKLOG;
633
672
fpos = ftell(fp);
634
673
fseek(fp, 0L, SEEK_SET);
674
rad_unlockfd(fileno(fp), 0);
635
675
fseek(fp, fpos, SEEK_SET);
636
rad_unlockfd(fileno(fp), 0);
677
if (r_args->records_print && state == STATE_RUN){
678
stats.records_read++;
679
if (stats.last_print_records - stats.records_read >= r_args->records_print){
681
uptime = (stats.startup == now) ? 1 : now - stats.startup;
682
fprintf(stderr, "%s: Running and Processing Records.\n",progname);
683
fprintf(stderr, "Seconds since startup: %ld\n",uptime);
684
fprintf(stderr, "Records Read: %d\n",stats.records_read);
685
fprintf(stderr, "Packets Sent: %d\n",stats.packets_sent);
686
fprintf(stderr, "Record Rate since startup: %.2f\n",
687
(double)stats.records_read / uptime);
688
fprintf(stderr, "Packet Rate since startup: %.2f\n",
689
(double)stats.packets_sent / uptime);
690
stats.last_print_records = stats.records_read;
638
693
if (r->state == STATE_FULL)
639
694
request_head = (request_head + 1) % NR_SLOTS;
656
711
* 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.
712
* finally empty, we can remove the <detail>.work
660
if (state == STATE_WAIT || state == STATE_SHUTDOWN) {
714
if (state == STATE_WAIT || state == STATE_CLOSE || state == STATE_SHUTDOWN) {
661
715
for (i = 0; i < NR_SLOTS; i++)
662
716
if (slots[i].state != STATE_EMPTY)
664
718
if (i == NR_SLOTS) {
668
if (state == STATE_SHUTDOWN) {
719
if (state == STATE_CLOSE) {
723
fprintf(stderr, "Unlink file %s\n", work);
726
else if (state == STATE_SHUTDOWN) {
669
727
for (i = 0; i < NR_SLOTS; i++) {
670
728
rad_free(&slots[i].req);
682
740
for (i = 0; i < NR_SLOTS; i++) {
683
741
if (slots[i].state == STATE_FULL) {
684
742
n += do_send(&slots[i], r_args->secret);
743
if ((n % r_args->sleep_every) == 0)
744
ms_sleep(r_args->sleep_time);
686
745
if (n > NR_SLOTS / 2)
749
if (r_args->records_print)
750
stats.packets_sent += n;
697
758
int find_shortname(char *shortname, char **host, char **secret)
699
760
CONF_SECTION *maincs, *cs;
702
* Ensure that the configuration is initialized.
704
memset(&mainconfig, 0, sizeof(mainconfig));
706
if ((maincs = read_radius_conf_file()) == NULL) {
707
fprintf(stderr, "Error reading radiusd.conf\n");
763
/* Lets go look for the new configuration files */
764
memset(&mainconfig, 0, sizeof(mainconfig)); /* for radlog() */
765
snprintf(buffer, sizeof(buffer), "%.200s/radiusd.conf", radius_dir);
766
if ((maincs = conf_read(NULL, 0, buffer, NULL)) == NULL) {
720
779
* or we find one that matches.
722
781
while (cs && strcmp(shortname, c_shortname)) {
725
782
cs = cf_subsection_find_next(cs, cs, "client");
727
784
c_shortname = cf_section_value_find(cs, "shortname");
745
802
fprintf(stderr, "Usage: radrelay [-a accounting_dir] [-d radius_dir] [-i local_ip] [-s secret]\n");
746
fprintf(stderr, "[-S secret_file] [-fx] <[-n shortname] [-r remote-server[:port]]> detailfile\n");
803
fprintf(stderr, "[-e sleep_every packets] [-t sleep_time (ms)] [-S secret_file] [-fx]\n");
804
fprintf(stderr, "[-R records_print] <[-n shortname] [-r remote-server[:port]]> detailfile\n");
747
805
fprintf(stderr, " -a accounting_dir Base accounting directory.\n");
748
806
fprintf(stderr, " -d radius_dir Base radius (raddb) directory.\n");
749
807
fprintf(stderr, " -f Stay in the foreground (don't fork).\n");
751
809
fprintf(stderr, " -i local_ip Use local_ip as source address.\n");
752
810
fprintf(stderr, " -n shortname Use the [shortname] entry from clients.conf for\n");
753
811
fprintf(stderr, " ip-adress and secret.\n");
812
fprintf(stderr, " -t sleep_time Sleep so much time (in ms) between sending packets. Default: %dms.\n",
814
fprintf(stderr, " -e sleep_every Sleep after sending so many packets. Default: %d\n",
815
DEFAULT_SLEEP_EVERY);
816
fprintf(stderr, " -R records_print If in foreground mode, print statistics after so many records read.\n");
754
817
fprintf(stderr, " -r remote-server The destination address/hostname.\n");
755
818
fprintf(stderr, " -s secret Server secret.\n");
756
819
fprintf(stderr, " -S secret_file Read server secret from file.\n");
780
843
memset((char *) r_args.detail, 0, 1024);
781
844
memset((char *) r_args.f_secret, 0, 256);
782
845
r_args.secret = NULL;
846
r_args.sleep_time = DEFAULT_SLEEP;
847
r_args.sleep_every = DEFAULT_SLEEP_EVERY;
784
849
shortname = NULL;
785
850
server_name = NULL;
798
863
* Process the options.
800
while ((c = getopt(argc, argv, "a:d:fhi:n:r:s:S:x")) != EOF) switch(c) {
865
while ((c = getopt(argc, argv, "a:d:fhi:t:e:n:r:R:s:S:x")) != EOF) switch(c) {
802
867
if (strlen(optarg) > 1021) {
803
868
fprintf(stderr, "%s: acct_dir to long\n", progname);
817
882
shortname = optarg;
885
r_args.sleep_time = atoi(optarg);
888
r_args.sleep_every = atoi(optarg);
892
fprintf(stderr, "%s: Not in foreground mode. Can't print statistics.\n",progname);
895
r_args.records_print = atoi(optarg);
820
898
server_name = optarg;