Mercurial > dropbear
comparison dbutil.c @ 1622:e11ed628708b
- Add adaptive authentication failure delay
- Rework monotonic_now/gettime_wrapper and use clock_gettime on more platforms
author | Matt Johnston <matt@ucc.asn.au> |
---|---|
date | Mon, 05 Nov 2018 23:36:34 +0800 |
parents | e75dab5bec71 |
children | dfbe947bdf0d |
comparison
equal
deleted
inserted
replaced
1621:8cdabd7d34aa | 1622:e11ed628708b |
---|---|
603 c |= (xa[i] ^ xb[i]); | 603 c |= (xa[i] ^ xb[i]); |
604 } | 604 } |
605 return c; | 605 return c; |
606 } | 606 } |
607 | 607 |
608 #if defined(__linux__) && defined(SYS_clock_gettime) | 608 /* higher-resolution monotonic timestamp, falls back to gettimeofday */ |
609 /* CLOCK_MONOTONIC_COARSE was added in Linux 2.6.32 but took a while to | 609 void gettime_wrapper(struct timespec *now) { |
610 reach userspace include headers */ | 610 struct timeval tv; |
611 #ifndef CLOCK_MONOTONIC_COARSE | |
612 #define CLOCK_MONOTONIC_COARSE 6 | |
613 #endif | |
614 /* Some old toolchains know SYS_clock_gettime but not CLOCK_MONOTONIC */ | |
615 #ifndef CLOCK_MONOTONIC | |
616 #define CLOCK_MONOTONIC 1 | |
617 #endif | |
618 static clockid_t get_linux_clock_source() { | |
619 struct timespec ts; | |
620 if (syscall(SYS_clock_gettime, CLOCK_MONOTONIC_COARSE, &ts) == 0) { | |
621 return CLOCK_MONOTONIC_COARSE; | |
622 } | |
623 | |
624 if (syscall(SYS_clock_gettime, CLOCK_MONOTONIC, &ts) == 0) { | |
625 return CLOCK_MONOTONIC; | |
626 } | |
627 return -1; | |
628 } | |
629 #endif | |
630 | |
631 time_t monotonic_now() { | |
632 #if DROPBEAR_FUZZ | 611 #if DROPBEAR_FUZZ |
633 if (fuzz.fuzzing) { | 612 if (fuzz.fuzzing) { |
634 /* time stands still when fuzzing */ | 613 /* time stands still when fuzzing */ |
635 return 5; | 614 now->tv_sec = 5; |
636 } | 615 now->tv_nsec = 0; |
637 #endif | 616 } |
617 #endif | |
618 | |
619 #if defined(HAVE_CLOCK_GETTIME) && defined(CLOCK_MONOTONIC) | |
620 /* POSIX monotonic clock. Newer Linux, BSD, MacOSX >10.12 */ | |
621 if (clock_gettime(CLOCK_MONOTONIC, now) == 0) { | |
622 return; | |
623 } | |
624 #endif | |
625 | |
638 #if defined(__linux__) && defined(SYS_clock_gettime) | 626 #if defined(__linux__) && defined(SYS_clock_gettime) |
639 { | 627 { |
640 static clockid_t clock_source = -2; | 628 /* Old linux toolchain - kernel might support it but not the build headers */ |
641 | 629 /* Also glibc <2.17 requires -lrt which we neglect to add */ |
642 if (clock_source == -2) { | 630 static int linux_monotonic_failed = 0; |
643 /* First run, find out which one works. | 631 if (!linux_monotonic_failed) { |
644 -1 will fall back to time() */ | 632 /* CLOCK_MONOTONIC isn't in some headers */ |
645 clock_source = get_linux_clock_source(); | 633 int clock_source_monotonic = 1; |
646 } | 634 if (syscall(SYS_clock_gettime, clock_source_monotonic, now) == 0) { |
647 | 635 return; |
648 if (clock_source >= 0) { | 636 } else { |
649 struct timespec ts; | 637 /* Don't try again */ |
650 if (syscall(SYS_clock_gettime, clock_source, &ts) != 0) { | 638 linux_monotonic_failed = 1; |
651 /* Intermittent clock failures should not happen */ | 639 } |
652 dropbear_exit("Clock broke"); | 640 } |
653 } | 641 } |
654 return ts.tv_sec; | 642 #endif /* linux fallback clock_gettime */ |
655 } | |
656 } | |
657 #endif /* linux clock_gettime */ | |
658 | 643 |
659 #if defined(HAVE_MACH_ABSOLUTE_TIME) | 644 #if defined(HAVE_MACH_ABSOLUTE_TIME) |
660 { | 645 { |
661 /* OS X, see https://developer.apple.com/library/mac/qa/qa1398/_index.html */ | 646 /* OS X pre 10.12, see https://developer.apple.com/library/mac/qa/qa1398/_index.html */ |
662 static mach_timebase_info_data_t timebase_info; | 647 static mach_timebase_info_data_t timebase_info; |
648 uint64_t scaled_time; | |
663 if (timebase_info.denom == 0) { | 649 if (timebase_info.denom == 0) { |
664 mach_timebase_info(&timebase_info); | 650 mach_timebase_info(&timebase_info); |
665 } | 651 } |
666 return mach_absolute_time() * timebase_info.numer / timebase_info.denom | 652 scaled_time = mach_absolute_time() * timebase_info.numer / timebase_info.denom; |
667 / 1e9; | 653 now->tv_sec = scaled_time / 1000000000; |
654 now->tv_nsec = scaled_time % 1000000000; | |
668 } | 655 } |
669 #endif /* osx mach_absolute_time */ | 656 #endif /* osx mach_absolute_time */ |
670 | 657 |
671 /* Fallback for everything else - this will sometimes go backwards */ | 658 /* Fallback for everything else - this will sometimes go backwards */ |
672 return time(NULL); | 659 gettimeofday(&tv, NULL); |
660 now->tv_sec = tv.tv_sec; | |
661 now->tv_nsec = 1000*tv.tv_usec; | |
662 } | |
663 | |
664 /* second-resolution monotonic timestamp */ | |
665 time_t monotonic_now() { | |
666 struct timespec ts; | |
667 gettime_wrapper(&ts); | |
668 return ts.tv_sec; | |
673 } | 669 } |
674 | 670 |
675 void fsync_parent_dir(const char* fn) { | 671 void fsync_parent_dir(const char* fn) { |
676 #ifdef HAVE_LIBGEN_H | 672 #ifdef HAVE_LIBGEN_H |
677 char *fn_dir = m_strdup(fn); | 673 char *fn_dir = m_strdup(fn); |