MacOS/X fixes

This commit is contained in:
Viktor Dukhovni
2016-05-22 16:59:25 -04:00
parent ffd0dda237
commit 529a91d69a
6 changed files with 102 additions and 37 deletions

View File

@@ -102,6 +102,12 @@ static struct getargs args[] = {
"daemon-child", 0 , arg_flag, &daemon_child,
"private argument, do not use", NULL
},
#ifdef __APPLE__
{
"bonjour", 0 , arg_flag, &do_bonjour,
"private argument, do not use", NULL
},
#endif
{ "addresses", 0, arg_strings, &addresses_str,
"addresses to listen on", "list of addresses" },
{ "disable-des", 0, arg_flag, &disable_des,

View File

@@ -47,6 +47,7 @@ struct port_desc{
static struct port_desc *ports;
static size_t num_ports;
static pid_t bonjour_pid = -1;
/*
* add `family, port, protocol' to the list with duplicate suppresion.
@@ -258,6 +259,7 @@ init_socket(krb5_context context,
d->s = rk_INVALID_SOCKET;
return;
}
rk_cloexec(d->s);
#if defined(HAVE_SETSOCKOPT) && defined(SOL_SOCKET) && defined(SO_REUSEADDR)
{
int one = 1;
@@ -833,11 +835,11 @@ handle_tcp(krb5_context context,
static void
handle_islive(int fd)
{
char buf[2];
char buf;
int ret;
ret = read(fd, buf, 2);
if (ret == 0)
ret = read(fd, &buf, 1);
if (ret != 1)
exit_flag = -1;
}
#endif
@@ -971,17 +973,28 @@ loop(krb5_context context, krb5_kdc_configuration *config,
#ifdef __APPLE__
static void
bonjour_kid(krb5_context context, krb5_kdc_configuration *config, int islive)
bonjour_kid(krb5_context context, krb5_kdc_configuration *config, const char *argv0, int *islive)
{
char buf[2];
char buf;
if (fork())
if (do_bonjour > 0) {
bonjour_announce(context, config);
while (read(0, &buf, 1) == 1)
continue;
_exit(0);
}
if ((bonjour_pid = fork()) != 0)
return;
bonjour_announce(context, config);
while (read(islive, buf, 1) != 0)
;
exit(0);
close(islive[0]);
if (dup2(islive[1], 0) == -1)
err(1, "failed to announce with bonjour (dup)");
if (islive[1] != 0)
close(islive[1]);
execlp(argv0, "kdc", "--bonjour", NULL);
err(1, "failed to announce with bonjour (exec)");
}
#endif
@@ -994,6 +1007,8 @@ kill_kids(pid_t *pids, int max_kids, int sig)
for (i=0; i < max_kids; i++)
if (pids[i] > 0)
kill(sig, pids[i]);
if (bonjour_pid > 0)
kill(sig, bonjour_pid);
}
static int
@@ -1001,6 +1016,7 @@ reap_kid(krb5_context context, krb5_kdc_configuration *config,
pid_t *pids, int max_kids, int options)
{
pid_t pid;
char *what;
int status;
int i;
@@ -1008,21 +1024,39 @@ reap_kid(krb5_context context, krb5_kdc_configuration *config,
if (pid < 1)
return 0;
for (i=0; i < max_kids; i++) {
if (pids[i] == pid)
break;
if (pid != bonjour_pid) {
for (i=0; i < max_kids; i++) {
if (pids[i] == pid)
break;
}
if (i == max_kids) {
/* XXXrcd: this should not happen, have to do something, though */
return 0;
}
}
if (i == max_kids) {
/* XXXrcd: this should not happen, have to do something, though */
return 0;
if (pid == bonjour_pid)
what = "bonjour";
else
what = "worker";
if (WIFEXITED(status))
kdc_log(context, config, 0, "KDC reaped %s process: %d, exit status: %d",
what, (int)pid, WEXITSTATUS(status));
else if (WIFSIGNALED(status))
kdc_log(context, config, 0, "KDC reaped %s process: %d, term signal %d%s",
what, (int)pid, WTERMSIG(status),
WCOREDUMP(status) ? " (core dumped)" : "");
else
kdc_log(context, config, 0, "KDC reaped %s process: %d",
what, (int)pid);
if (pid == bonjour_pid) {
bonjour_pid = (pid_t)-1;
return 0;
} else {
pids[i] = (pid_t)-1;
return 1;
}
/* XXXrcd: should likely log exit code and the like */
kdc_log(context, config, 0, "KDC worker process reaped: %d", pid);
pids[i] = (pid_t)-1;
return 1;
}
static int
@@ -1053,7 +1087,7 @@ select_sleep(int microseconds)
void
start_kdc(krb5_context context,
krb5_kdc_configuration *config)
krb5_kdc_configuration *config, const char *argv0)
{
struct timeval tv1;
struct timeval tv2;
@@ -1068,6 +1102,11 @@ start_kdc(krb5_context context,
int islive[2];
#endif
#ifdef __APPLE__
if (do_bonjour > 0)
bonjour_kid(context, config, argv0, NULL);
#endif
#ifdef HAVE_FORK
#ifdef _SC_NPROCESSORS_ONLN
if (max_kdcs < 1)
@@ -1099,9 +1138,10 @@ start_kdc(krb5_context context,
#ifdef HAVE_FORK
#ifdef __APPLE__
bonjour_kid(context, config, islive[1]); /* fork()s */
#endif
# ifdef __APPLE__
if (do_bonjour < 0)
bonjour_kid(context, config, argv0, islive);
# endif
kdc_log(context, config, 0, "KDC started master process pid=%d", getpid());
#else
@@ -1165,34 +1205,49 @@ start_kdc(krb5_context context,
close(islive[0]);
close(islive[1]);
gettimeofday(&tv1, NULL);
/* Close our listener sockets before terminating workers */
for (i = 0; i < ndescr; ++i)
clear_descr(&d[i]);
gettimeofday(&tv1, NULL);
tv2 = tv1;
/* Reap every 10ms, terminate stragglers once a second, give up after 10 */
for (;;) {
struct timeval tv3;
num_kdcs -= reap_kids(context, config, pids, max_kdcs);
if (num_kdcs == 0)
break;
if (num_kdcs == 0 && bonjour_pid <= 0)
goto end;
/*
* Using select to sleep will fail with EINTR if we receive a
* SIGCHLD. This is desirable.
*/
select_sleep(200000);
kill_kids(pids, max_kdcs, SIGTERM);
gettimeofday(&tv2, NULL);
if (tv2.tv_sec - tv1.tv_sec > 10)
select_sleep(10000);
gettimeofday(&tv3, NULL);
if (tv3.tv_sec - tv1.tv_sec > 10 ||
(tv3.tv_sec - tv1.tv_sec == 10 && tv3.tv_usec >= tv1.tv_usec))
break;
if (tv3.tv_sec - tv2.tv_sec > 1 ||
(tv3.tv_sec - tv2.tv_sec == 1 && tv3.tv_usec >= tv2.tv_usec)) {
kill_kids(pids, max_kdcs, SIGTERM);
tv2 = tv3;
}
}
/* Kill stragglers and reap every 200ms, give up after 15s */
for (;;) {
kill_kids(pids, max_kdcs, SIGKILL);
num_kdcs -= reap_kids(context, config, pids, max_kdcs);
if (num_kdcs == 0)
if (num_kdcs == 0 && bonjour_pid <= 0)
break;
select_sleep(200000);
gettimeofday(&tv2, NULL);
if (tv2.tv_sec - tv1.tv_sec > 15)
if (tv2.tv_sec - tv1.tv_sec > 15 ||
(tv2.tv_sec - tv1.tv_sec == 15 && tv2.tv_usec >= tv1.tv_usec))
break;
}
end:
kdc_log(context, config, 0, "KDC master process exiting", pid);
free(pids);
#else

View File

@@ -46,6 +46,7 @@ struct perf {
int detach_from_console = -1;
int daemon_child = -1;
int do_bonjour = -1;
static krb5_kdc_configuration *kdc_config;
static krb5_context kdc_context;

View File

@@ -101,6 +101,7 @@ extern int enable_http;
extern int detach_from_console;
extern int daemon_child;
extern int do_bonjour;
extern const struct units _kdc_digestunits[];
@@ -113,7 +114,7 @@ extern char *runas_string;
extern char *chroot_string;
void
start_kdc(krb5_context context, krb5_kdc_configuration *config);
start_kdc(krb5_context context, krb5_kdc_configuration *config, const char *argv0);
krb5_kdc_configuration *
configure(krb5_context context, int argc, char **argv, int *optidx);

View File

@@ -46,6 +46,7 @@ sig_atomic_t exit_flag = 0;
int detach_from_console = -1;
int daemon_child = -1;
int do_bonjour = -1;
static RETSIGTYPE
sigchld(int sig)
@@ -172,7 +173,7 @@ main(int argc, char **argv)
switch_environment();
start_kdc(context, config);
start_kdc(context, config, argv[0]);
krb5_free_context(context);
return 0;
}

View File

@@ -50,6 +50,7 @@
#endif
#include <evp.h>
#include <evp-hcrypto.h>
#include <evp-cc.h>
/*