aboutsummaryrefslogtreecommitdiff
path: root/src/appl/gss-sample
diff options
context:
space:
mode:
authorKen Raeburn <raeburn@mit.edu>2005-10-21 01:17:20 +0000
committerKen Raeburn <raeburn@mit.edu>2005-10-21 01:17:20 +0000
commit8a0232c3f472df2ad46e571cddddca4356790a3b (patch)
treee761e4666a9497252fec907910a1f882f57f6af3 /src/appl/gss-sample
parent9f440638851a6ac799bfb8ef6af77f1b7b53e4c3 (diff)
downloadkrb5-8a0232c3f472df2ad46e571cddddca4356790a3b.zip
krb5-8a0232c3f472df2ad46e571cddddca4356790a3b.tar.gz
krb5-8a0232c3f472df2ad46e571cddddca4356790a3b.tar.bz2
Jeff's patches for a multi-threaded gss-sample suite, modified to not break the
single-threaded UNIX case. (Tested on Linux/x86.) Needs stylistic cleanup at some point. ticket: 3214 tags: pullup git-svn-id: svn://anonsvn.mit.edu/krb5/trunk@17445 dc483132-0cff-0310-8789-dd5450dbe970
Diffstat (limited to 'src/appl/gss-sample')
-rw-r--r--src/appl/gss-sample/ChangeLog33
-rw-r--r--src/appl/gss-sample/gss-client.c147
-rw-r--r--src/appl/gss-sample/gss-misc.c2
-rw-r--r--src/appl/gss-sample/gss-server.c165
4 files changed, 315 insertions, 32 deletions
diff --git a/src/appl/gss-sample/ChangeLog b/src/appl/gss-sample/ChangeLog
index b641880..25c4c3f 100644
--- a/src/appl/gss-sample/ChangeLog
+++ b/src/appl/gss-sample/ChangeLog
@@ -1,3 +1,36 @@
+2005-10-20 Ken Raeburn <raeburn@mit.edu>
+ Jeffrey Altman <jaltman@mit.edu>
+
+ * gss-server.c [!_WIN32]: Include port-sockets.h instead of the
+ various network-related UNIX header files.
+ (worker_bee): New function.
+ (main): Use it.
+ (max_threads): New variable.
+ (thread_count, hMutex, hEvent) [_WIN32]: New variables.
+ (InitHandles, CleanupHandles, WaitAndIncrementThreadCounter,
+ DecrementAndSignalThreadCounter) [_WIN32]: New functions.
+ (main) [_WIN32]: Accept new option -threads, and keep that many
+ threads going.
+ (usage) [_WIN32]: Document new option.
+
+ * gss-client.c [!_WIN32]: Include assert.h.
+ (max_threads): New variable.
+ (service_name, server_host, msg, mechanism, port, use_file,
+ gss_flags, min_stat, oid, mcount, ccount, auth_flag, wrap_flag,
+ encrypt_flag, mic_flag, v1_format): Moved variables to top level
+ from inside main.
+ (worker_bee): New function, with call_server call moved from
+ main.
+ (main): Call it.
+ (thread_count, hMutex, hEvent) [_WIN32]: New variables.
+ (InitHandles, CleanupHandles, WaitAndIncrementThreadCounter,
+ DecrementAndSignalThreadCounter) [_WIN32]: New functions.
+ (main) [_WIN32]: Accept new option -threads, and keep that many
+ threads going.
+ (usage) [_WIN32]: Document new option.
+
+ * gss-misc.c (send_token): Delete unused variable "len".
+
2004-03-08 Ken Raeburn <raeburn@mit.edu>
* Makefile.in (MY_SUBDIRS): Deleted.
diff --git a/src/appl/gss-sample/gss-client.c b/src/appl/gss-sample/gss-client.c
index f7b578a..d05ab41 100644
--- a/src/appl/gss-sample/gss-client.c
+++ b/src/appl/gss-sample/gss-client.c
@@ -20,7 +20,7 @@
* PERFORMANCE OF THIS SOFTWARE.
*/
/*
- * Copyright (C) 2003, 2004 by the Massachusetts Institute of Technology.
+ * Copyright (C) 2003, 2004, 2005 by the Massachusetts Institute of Technology.
* All rights reserved.
*
* Export of this software from the United States of America may
@@ -50,6 +50,7 @@
#include <windows.h>
#include <winsock.h>
#else
+#include <assert.h>
#include <unistd.h>
#include <ctype.h>
#include <sys/types.h>
@@ -69,7 +70,11 @@ static int verbose = 1;
static void usage()
{
fprintf(stderr, "Usage: gss-client [-port port] [-mech mechanism] [-d]\n");
- fprintf(stderr, " [-seq] [-noreplay] [-nomutual]\n");
+ fprintf(stderr, " [-seq] [-noreplay] [-nomutual]");
+#ifdef _WIN32
+ fprintf(stderr, " [-threads num]");
+#endif
+ fprintf(stderr, "\n");
fprintf(stderr, " [-f] [-q] [-ccount count] [-mcount count]\n");
fprintf(stderr, " [-v1] [-na] [-nw] [-nx] [-nm] host service msg\n");
exit(1);
@@ -595,20 +600,94 @@ static void parse_oid(char *mechanism, gss_OID *oid)
free(mechstr);
}
+static int max_threads = 1;
+
+#ifdef _WIN32
+static thread_count = 0;
+static HANDLE hMutex = NULL;
+static HANDLE hEvent = NULL;
+
+void
+InitHandles(void)
+{
+ hMutex = CreateMutex(NULL, FALSE, NULL);
+ hEvent = CreateEvent(NULL, FALSE, FALSE, NULL);
+}
+
+void
+CleanupHandles(void)
+{
+ CloseHandle(hMutex);
+ CloseHandle(hEvent);
+}
+
+BOOL
+WaitAndIncrementThreadCounter(void)
+{
+ for (;;) {
+ if (WaitForSingleObject(hMutex, INFINITE) == WAIT_OBJECT_0) {
+ if ( thread_count < max_threads ) {
+ thread_count++;
+ ReleaseMutex(hMutex);
+ return TRUE;
+ } else {
+ ReleaseMutex(hMutex);
+
+ if (WaitForSingleObject(hEvent, INFINITE) == WAIT_OBJECT_0) {
+ continue;
+ } else {
+ return FALSE;
+ }
+ }
+ } else {
+ return FALSE;
+ }
+ }
+}
+
+BOOL
+DecrementAndSignalThreadCounter(void)
+{
+ if (WaitForSingleObject(hMutex, INFINITE) == WAIT_OBJECT_0) {
+ if ( thread_count == max_threads )
+ ResetEvent(hEvent);
+ thread_count--;
+ ReleaseMutex(hMutex);
+ return TRUE;
+ } else {
+ return FALSE;
+ }
+}
+#endif
+
+static char *service_name, *server_host, *msg;
+static char *mechanism = 0;
+static u_short port = 4444;
+static int use_file = 0;
+static OM_uint32 gss_flags = GSS_C_MUTUAL_FLAG | GSS_C_REPLAY_FLAG;
+static OM_uint32 min_stat;
+static gss_OID oid = GSS_C_NULL_OID;
+static int mcount = 1, ccount = 1;
+static int auth_flag, wrap_flag, encrypt_flag, mic_flag, v1_format;
+
+void worker_bee(void * unused)
+{
+ if (call_server(server_host, port, oid, service_name,
+ gss_flags, auth_flag, wrap_flag, encrypt_flag, mic_flag,
+ v1_format, msg, use_file, mcount) < 0)
+ exit(1);
+
+#ifdef _WIN32
+ if ( max_threads > 1 )
+ DecrementAndSignalThreadCounter();
+#endif
+}
+
int main(argc, argv)
int argc;
char **argv;
{
- char *service_name, *server_host, *msg;
- char *mechanism = 0;
- u_short port = 4444;
- int use_file = 0;
- OM_uint32 gss_flags = GSS_C_MUTUAL_FLAG | GSS_C_REPLAY_FLAG;
- OM_uint32 min_stat;
- gss_OID oid = GSS_C_NULL_OID;
- int mcount = 1, ccount = 1;
int i;
- int auth_flag, wrap_flag, encrypt_flag, mic_flag, v1_format;
display_file = stdout;
auth_flag = wrap_flag = encrypt_flag = mic_flag = 1;
@@ -625,7 +704,15 @@ int main(argc, argv)
argc--; argv++;
if (!argc) usage();
mechanism = *argv;
- } else if (strcmp(*argv, "-d") == 0) {
+ }
+#ifdef _WIN32
+ else if (strcmp(*argv, "-threads") == 0) {
+ argc--; argv++;
+ if (!argc) usage();
+ max_threads = atoi(*argv);
+ }
+#endif
+ else if (strcmp(*argv, "-d") == 0) {
gss_flags |= GSS_C_DELEG_FLAG;
} else if (strcmp(*argv, "-seq") == 0) {
gss_flags |= GSS_C_SEQUENCE_FLAG;
@@ -664,6 +751,13 @@ int main(argc, argv)
if (argc != 3)
usage();
+#ifdef _WIN32
+ if (max_threads < 1) {
+ fprintf(stderr, "warning: there must be at least one thread\n");
+ max_threads = 1;
+ }
+#endif
+
server_host = *argv++;
service_name = *argv++;
msg = *argv++;
@@ -671,15 +765,34 @@ int main(argc, argv)
if (mechanism)
parse_oid(mechanism, &oid);
- for (i = 0; i < ccount; i++) {
- if (call_server(server_host, port, oid, service_name,
- gss_flags, auth_flag, wrap_flag, encrypt_flag, mic_flag,
- v1_format, msg, use_file, mcount) < 0)
- exit(1);
+ if (max_threads == 1) {
+ for (i = 0; i < ccount; i++) {
+ worker_bee(0);
+ }
+ } else {
+#ifdef _WIN32
+ for (i = 0; i < ccount; i++) {
+ if ( WaitAndIncrementThreadCounter() ) {
+ uintptr_t handle = _beginthread(worker_bee, 0, (void *)0);
+ if (handle == (uintptr_t)-1) {
+ exit(1);
+ }
+ } else {
+ exit(1);
+ }
+ }
+#else
+ /* boom */
+ assert(max_threads == 1);
+#endif
}
if (oid != GSS_C_NULL_OID)
(void) gss_release_oid(&min_stat, &oid);
+#ifdef _WIN32
+ CleanupHandles();
+#endif
+
return 0;
}
diff --git a/src/appl/gss-sample/gss-misc.c b/src/appl/gss-sample/gss-misc.c
index 1347a54..c912792 100644
--- a/src/appl/gss-sample/gss-misc.c
+++ b/src/appl/gss-sample/gss-misc.c
@@ -160,7 +160,7 @@ int send_token(s, flags, tok)
int flags;
gss_buffer_t tok;
{
- int len, ret;
+ int ret;
unsigned char char_flags = (unsigned char) flags;
unsigned char lenbuf[4];
diff --git a/src/appl/gss-sample/gss-server.c b/src/appl/gss-sample/gss-server.c
index e5adc61..dae67af 100644
--- a/src/appl/gss-sample/gss-server.c
+++ b/src/appl/gss-sample/gss-server.c
@@ -20,7 +20,7 @@
* PERFORMANCE OF THIS SOFTWARE.
*/
/*
- * Copyright (C) 2004 by the Massachusetts Institute of Technology.
+ * Copyright (C) 2004,2005 by the Massachusetts Institute of Technology.
* All rights reserved.
*
* Export of this software from the United States of America may
@@ -48,10 +48,7 @@
#include <windows.h>
#include <winsock.h>
#else
-#include <sys/types.h>
-#include <sys/socket.h>
-#include <sys/time.h>
-#include <netinet/in.h>
+#include "port-sockets.h"
#endif
#ifdef HAVE_UNISTD_H
#include <unistd.h>
@@ -70,7 +67,11 @@
static void usage()
{
- fprintf(stderr, "Usage: gss-server [-port port] [-verbose] [-once]\n");
+ fprintf(stderr, "Usage: gss-server [-port port] [-verbose] [-once]");
+#ifdef _WIN32
+ fprintf(stderr, " [-threads num]");
+#endif
+ fprintf(stderr, "\n");
fprintf(stderr, " [-inetd] [-export] [-logfile file] service_name\n");
exit(1);
}
@@ -554,6 +555,90 @@ static int sign_server(s, server_creds, export)
return(0);
}
+static int max_threads = 1;
+
+#ifdef _WIN32
+static thread_count = 0;
+static HANDLE hMutex = NULL;
+static HANDLE hEvent = NULL;
+
+void
+InitHandles(void)
+{
+ hMutex = CreateMutex(NULL, FALSE, NULL);
+ hEvent = CreateEvent(NULL, FALSE, FALSE, NULL);
+}
+
+void
+CleanupHandles(void)
+{
+ CloseHandle(hMutex);
+ CloseHandle(hEvent);
+}
+
+BOOL
+WaitAndIncrementThreadCounter(void)
+{
+ for (;;) {
+ if (WaitForSingleObject(hMutex, INFINITE) == WAIT_OBJECT_0) {
+ if ( thread_count < max_threads ) {
+ thread_count++;
+ ReleaseMutex(hMutex);
+ return TRUE;
+ } else {
+ ReleaseMutex(hMutex);
+
+ if (WaitForSingleObject(hEvent, INFINITE) == WAIT_OBJECT_0) {
+ continue;
+ } else {
+ return FALSE;
+ }
+ }
+ } else {
+ return FALSE;
+ }
+ }
+}
+
+BOOL
+DecrementAndSignalThreadCounter(void)
+{
+ if (WaitForSingleObject(hMutex, INFINITE) == WAIT_OBJECT_0) {
+ if ( thread_count == max_threads )
+ ResetEvent(hEvent);
+ thread_count--;
+ ReleaseMutex(hMutex);
+ return TRUE;
+ } else {
+ return FALSE;
+ }
+}
+#endif
+
+struct _work_plan {
+ int s;
+ gss_cred_id_t server_creds;
+ int export;
+};
+
+void
+worker_bee(void * param)
+{
+ struct _work_plan *work = (struct _work_plan *) param;
+
+ /* this return value is not checked, because there's
+ * not really anything to do if it fails
+ */
+ sign_server(work->s, work->server_creds, work->export);
+ closesocket(work->s);
+ free(work);
+
+#ifdef _WIN32
+ if ( max_threads > 1 )
+ DecrementAndSignalThreadCounter();
+#endif
+}
+
int
main(argc, argv)
int argc;
@@ -563,7 +648,6 @@ main(argc, argv)
gss_cred_id_t server_creds;
OM_uint32 min_stat;
u_short port = 4444;
- int s;
int once = 0;
int do_inetd = 0;
int export = 0;
@@ -576,7 +660,15 @@ main(argc, argv)
argc--; argv++;
if (!argc) usage();
port = atoi(*argv);
- } else if (strcmp(*argv, "-verbose") == 0) {
+ }
+#ifdef _WIN32
+ else if (strcmp(*argv, "-threads") == 0) {
+ argc--; argv++;
+ if (!argc) usage();
+ max_threads = atoi(*argv);
+ }
+#endif
+ else if (strcmp(*argv, "-verbose") == 0) {
verbose = 1;
} else if (strcmp(*argv, "-once") == 0) {
once = 1;
@@ -612,6 +704,18 @@ main(argc, argv)
if ((*argv)[0] == '-')
usage();
+#ifdef _WIN32
+ if (max_threads < 1) {
+ fprintf(stderr, "warning: there must be at least one thread\n");
+ max_threads = 1;
+ }
+
+ if (max_threads > 1 && do_inetd)
+ fprintf(stderr, "warning: one thread may be used in conjunction with inetd\n");
+
+ InitHandles();
+#endif
+
service_name = *argv;
if (server_acquire_creds(service_name, &server_creds) < 0)
@@ -627,23 +731,56 @@ main(argc, argv)
int stmp;
if ((stmp = create_socket(port)) >= 0) {
+ if (listen(stmp, max_threads == 1 ? 0 : max_threads) < 0)
+ perror("listening on socket");
+
do {
+ struct _work_plan * work = malloc(sizeof(struct _work_plan));
+
+ if ( work == NULL ) {
+ fprintf(stderr, "fatal error: out of memory");
+ break;
+ }
+
/* Accept a TCP connection */
- if ((s = accept(stmp, NULL, 0)) < 0) {
+ if ((work->s = accept(stmp, NULL, 0)) < 0) {
perror("accepting connection");
continue;
}
- /* this return value is not checked, because there's
- not really anything to do if it fails */
- sign_server(s, server_creds, export);
- close(s);
+
+ work->server_creds = server_creds;
+ work->export = export;
+
+ if (max_threads == 1) {
+ worker_bee((void *)work);
+ }
+#ifdef _WIN32
+ else {
+ if ( WaitAndIncrementThreadCounter() ) {
+ uintptr_t handle = _beginthread(worker_bee, 0, (void *)work);
+ if (handle == (uintptr_t)-1) {
+ closesocket(work->s);
+ free(work);
+ }
+ } else {
+ fprintf(stderr, "fatal error incrementing thread counter");
+ closesocket(work->s);
+ free(work);
+ break;
+ }
+ }
+#endif
} while (!once);
- close(stmp);
+ closesocket(stmp);
}
}
(void) gss_release_cred(&min_stat, &server_creds);
+#ifdef _WIN32
+ CleanupHandles();
+#endif
+
return 0;
}