[17108] in Kerberos_V5_Development
Re: [RFC][PATCH] krb5 => libverto main loop
daemon@ATHENA.MIT.EDU (Nathaniel McCallum)
Tue Aug 23 16:05:17 2011
From: Nathaniel McCallum <npmccallum@redhat.com>
To: Greg Hudson <ghudson@mit.edu>
Date: Tue, 23 Aug 2011 15:58:10 -0400
In-Reply-To: <1313624840.16540.115.camel@t410>
Content-Type: multipart/mixed; boundary="=-91aXUtl386fllPtBh1mm"
Message-ID: <1314129492.27040.10.camel@localhost>
Mime-Version: 1.0
Cc: "krbdev@mit.edu" <krbdev@mit.edu>
Errors-To: krbdev-bounces@mit.edu
--=-91aXUtl386fllPtBh1mm
Content-Type: text/plain; charset="UTF-8"
Content-Transfer-Encoding: 7bit
Attached is take #2, it should fix all the issues below except where
noted...
On Wed, 2011-08-17 at 19:47 -0400, Greg Hudson wrote:
> * Just as a point of information, at some point the code should change
> to not set up the routing socket if IPv4 and IPv6 pktinfo are both
> available. This is slightly complicated by the new design where
> loop_setup_routing_socket() is a separate call from
> loop_setup_network(). I expect we'll just move udp_flags from a field
> of struct socksetup to a pair of global booleans.
If we make IPv6 non-conditional that should essentially fix this
problem, right?
> * In net-server.c you use a 0-second timeout to emulate an idle event.
> Could this emulation be done inside libverto for back ends which don't
> support idle events?
No, libverto cannot emulate idle since it means something very different
than timeout of 0. This could have very bad effects for someone who asks
for idle and gets timeout instead (imagine 1000 idle events that should
be run gradually when there is nothing else to do, but are instead run
immediately, blocking processing of other requests).
In this case, timeout is acceptable since we just want to finish the
currently processing requests. But in general, timeout cannot emulate
idle.
> I'll reiterate the style issues I ran into while reviewing the patch. I
> mentioned all but the first of these by voice on Tuesday, but I spoke
> kind of quickly at that point:
> * Spaces around binary operators always (except . and ->).
> * No spaces before for-loop semicolons.
I did not see either of these... Perhaps my grep-fu isn't as good as
yours?
Nathaniel
--=-91aXUtl386fllPtBh1mm
Content-Disposition: attachment;
filename*0=0001-add-a-loop_-prefix-to-all-the-functions-involving-th.pat;
filename*1=ch
Content-Type: text/x-patch;
name="0001-add-a-loop_-prefix-to-all-the-functions-involving-th.patch";
charset="UTF-8"
Content-Transfer-Encoding: 7bit
>From fba2326fce58cd7f3fef17b59737aa14294810b7 Mon Sep 17 00:00:00 2001
From: Nathaniel McCallum <npmccallum@redhat.com>
Date: Tue, 23 Aug 2011 15:47:08 -0400
Subject: [PATCH 1/5] add a loop_ prefix to all the functions involving the
main loop
---
src/include/net-server.h | 19 ++++++++++---------
src/kadmin/server/ovsec_kadmd.c | 14 +++++++-------
src/kdc/main.c | 10 +++++-----
src/lib/apputils/net-server.c | 23 ++++++++++++-----------
4 files changed, 34 insertions(+), 32 deletions(-)
diff --git a/src/include/net-server.h b/src/include/net-server.h
index 6902abf..144156d 100644
--- a/src/include/net-server.h
+++ b/src/include/net-server.h
@@ -37,14 +37,15 @@ typedef struct _krb5_fulladdr {
/* exported from network.c */
extern volatile int signal_requests_exit, signal_requests_reset;
void init_addr(krb5_fulladdr *, struct sockaddr *);
-krb5_error_code add_udp_port(int port);
-krb5_error_code add_tcp_port(int port);
-krb5_error_code add_rpc_service(int port, u_long prognum, u_long versnum,
- void (*dispatch)());
-krb5_error_code setup_network(void *handle, const char *prog, int no_reconfig);
-krb5_error_code listen_and_process(void *handle, const char *prog,
- void (*reset)(void));
-void closedown_network(void);
+krb5_error_code loop_add_udp_port(int port);
+krb5_error_code loop_add_tcp_port(int port);
+krb5_error_code loop_add_rpc_service(int port, u_long prognum, u_long versnum,
+ void (*dispatch)());
+krb5_error_code loop_setup_network(void *handle, const char *prog,
+ int no_reconfig);
+krb5_error_code loop_listen_and_process(void *handle, const char *prog,
+ void (*reset)(void));
+void loop_closedown_network(void);
/* to be supplied by the server application */
@@ -55,7 +56,7 @@ void closedown_network(void);
* The first, dispatch(), is for normal processing of a request. The
* second, make_toolong_error(), is obviously for generating an error
* to send back when the incoming message is bigger than
- * listen_and_process can accept.
+ * loop_listen_and_process can accept.
*/
krb5_error_code dispatch (void *handle,
struct sockaddr *local_addr,
diff --git a/src/kadmin/server/ovsec_kadmd.c b/src/kadmin/server/ovsec_kadmd.c
index 04d8c4b..190297d 100644
--- a/src/kadmin/server/ovsec_kadmd.c
+++ b/src/kadmin/server/ovsec_kadmd.c
@@ -379,19 +379,19 @@ int main(int argc, char *argv[])
}
#define server_handle ((kadm5_server_handle_t)global_server_handle)
- if ((ret = add_udp_port(server_handle->params.kpasswd_port))
- || (ret = add_tcp_port(server_handle->params.kpasswd_port))
- || (ret = add_rpc_service(server_handle->params.kadmind_port,
+ if ((ret = loop_add_udp_port(server_handle->params.kpasswd_port))
+ || (ret = loop_add_tcp_port(server_handle->params.kpasswd_port))
+ || (ret = loop_add_rpc_service(server_handle->params.kadmind_port,
KADM, KADMVERS, kadm_1))
#ifndef DISABLE_IPROP
|| (server_handle->params.iprop_enabled
- ? (ret = add_rpc_service(server_handle->params.iprop_port,
+ ? (ret = loop_add_rpc_service(server_handle->params.iprop_port,
KRB5_IPROP_PROG, KRB5_IPROP_VERS,
krb5_iprop_prog_1))
: 0)
#endif
#undef server_handle
- || (ret = setup_network(global_server_handle, whoami, 0))) {
+ || (ret = loop_setup_network(global_server_handle, whoami, 0))) {
const char *e_txt = krb5_get_error_message (context, ret);
krb5_klog_syslog(LOG_ERR, _("%s: %s while initializing network, "
"aborting"), whoami, e_txt);
@@ -626,13 +626,13 @@ kterr:
if (nofork)
fprintf(stderr, _("%s: starting...\n"), whoami);
- listen_and_process(global_server_handle, whoami, reset_db);
+ loop_listen_and_process(global_server_handle, whoami, reset_db);
krb5_klog_syslog(LOG_INFO, _("finished, exiting"));
/* Clean up memory, etc */
svcauth_gssapi_unset_names();
kadm5_destroy(global_server_handle);
- closedown_network();
+ loop_closedown_network();
kadm5int_acl_finish(context, 0);
if(gss_changepw_name) {
(void) gss_release_name(&OMret, &gss_changepw_name);
diff --git a/src/kdc/main.c b/src/kdc/main.c
index cc89fab..a6a5751 100644
--- a/src/kdc/main.c
+++ b/src/kdc/main.c
@@ -1013,7 +1013,7 @@ int main(int argc, char **argv)
port = strtol(cp, &cp, 10);
if (cp == 0)
break;
- retval = add_udp_port(port);
+ retval = loop_add_udp_port(port);
if (retval)
goto net_init_error;
}
@@ -1027,7 +1027,7 @@ int main(int argc, char **argv)
port = strtol(cp, &cp, 10);
if (cp == 0)
break;
- retval = add_tcp_port(port);
+ retval = loop_add_tcp_port(port);
if (retval)
goto net_init_error;
}
@@ -1039,7 +1039,7 @@ int main(int argc, char **argv)
* children won't be able to re-open the listener sockets. Hopefully our
* platform has pktinfo support and doesn't need reconfigs.
*/
- if ((retval = setup_network(NULL, kdc_progname, (workers > 0)))) {
+ if ((retval = loop_setup_network(NULL, kdc_progname, (workers > 0)))) {
net_init_error:
kdc_err(kcontext, retval, _("while initializing network"));
finish_realms();
@@ -1071,11 +1071,11 @@ int main(int argc, char **argv)
krb5_klog_syslog(LOG_INFO, _("commencing operation"));
if (nofork)
fprintf(stderr, _("%s: starting...\n"), kdc_progname);
- if ((retval = listen_and_process(0, kdc_progname, reset_for_hangup))) {
+ if ((retval = loop_listen_and_process(0, kdc_progname, reset_for_hangup))) {
kdc_err(kcontext, retval, _("while processing network requests"));
errout++;
}
- closedown_network();
+ loop_closedown_network();
krb5_klog_syslog(LOG_INFO, _("shutting down"));
unload_preauth_plugins(kcontext);
unload_authdata_plugins(kcontext);
diff --git a/src/lib/apputils/net-server.c b/src/lib/apputils/net-server.c
index a1bbaa5..5afc3c0 100644
--- a/src/lib/apputils/net-server.c
+++ b/src/lib/apputils/net-server.c
@@ -64,7 +64,7 @@
volatile int signal_requests_exit = 0, signal_requests_reset = 0;
-static void closedown_network_sockets(void);
+static void loop_closedown_network_sockets(void);
/* Misc utility routines. */
static void
@@ -279,7 +279,7 @@ static struct select_state sstate;
static fd_set rpc_listenfds;
krb5_error_code
-add_udp_port(int port)
+loop_add_udp_port(int port)
{
int i;
void *tmp;
@@ -298,7 +298,7 @@ add_udp_port(int port)
}
krb5_error_code
-add_tcp_port(int port)
+loop_add_tcp_port(int port)
{
int i;
void *tmp;
@@ -317,7 +317,8 @@ add_tcp_port(int port)
}
krb5_error_code
-add_rpc_service(int port, u_long prognum, u_long versnum, void (*dispatchfn)())
+loop_add_rpc_service(int port, u_long prognum,
+ u_long versnum, void (*dispatchfn)())
{
int i;
void *tmp;
@@ -1092,7 +1093,7 @@ extern int krb5int_debug_sendto_kdc;
extern void (*krb5int_sendtokdc_debug_handler)(const void*, size_t);
krb5_error_code
-setup_network(void *handle, const char *prog, int no_reconfig)
+loop_setup_network(void *handle, const char *prog, int no_reconfig)
{
struct socksetup setup_data;
@@ -1798,7 +1799,7 @@ getcurtime(struct timeval *tvp)
}
krb5_error_code
-listen_and_process(void *handle, const char *prog, void (*reset)(void))
+loop_listen_and_process(void *handle, const char *prog, void (*reset)(void))
{
int nfound;
/* This struct contains 3 fd_set objects; on some platforms, they
@@ -1845,8 +1846,8 @@ listen_and_process(void *handle, const char *prog, void (*reset)(void))
}
if (sret == 0 && netchanged) {
network_reconfiguration_needed = 0;
- closedown_network_sockets();
- err = setup_network(handle, prog, 0);
+ loop_closedown_network_sockets();
+ err = loop_setup_network(handle, prog, 0);
if (err) {
com_err(prog, err, _("while reinitializing network"));
return err;
@@ -1878,7 +1879,7 @@ listen_and_process(void *handle, const char *prog, void (*reset)(void))
}
static void
-closedown_network_sockets()
+loop_closedown_network_sockets()
{
int i;
struct connection *conn;
@@ -1914,9 +1915,9 @@ closedown_network_sockets()
}
void
-closedown_network()
+loop_closedown_network()
{
- closedown_network_sockets();
+ loop_closedown_network_sockets();
FREE_SET_DATA(connections);
FREE_SET_DATA(udp_port_data);
FREE_SET_DATA(tcp_port_data);
--
1.7.6
--=-91aXUtl386fllPtBh1mm
Content-Disposition: attachment;
filename="0002-don-t-log-on-sigpipe-in-the-admin-server.patch"
Content-Type: text/x-patch;
name="0002-don-t-log-on-sigpipe-in-the-admin-server.patch";
charset="UTF-8"
Content-Transfer-Encoding: 7bit
>From 2f8183aeb90672ede05a6cd6650e6aa52bae06cb Mon Sep 17 00:00:00 2001
From: Nathaniel McCallum <npmccallum@redhat.com>
Date: Tue, 23 Aug 2011 11:58:03 -0400
Subject: [PATCH 2/5] don't log on sigpipe in the admin server
---
src/kadmin/server/ovsec_kadmd.c | 21 ++-------------------
1 files changed, 2 insertions(+), 19 deletions(-)
diff --git a/src/kadmin/server/ovsec_kadmd.c b/src/kadmin/server/ovsec_kadmd.c
index 190297d..3e81d9d 100644
--- a/src/kadmin/server/ovsec_kadmd.c
+++ b/src/kadmin/server/ovsec_kadmd.c
@@ -76,7 +76,6 @@ void setup_signal_handlers(iprop_role iproprole);
void request_exit(int);
void request_hup(int);
void reset_db(void);
-void sig_pipe(int);
#ifdef POSIX_SIGNALS
static struct sigaction s_action;
@@ -667,7 +666,7 @@ void setup_signal_handlers(iprop_role iproprole) {
(void) sigaction(SIGQUIT, &s_action, (struct sigaction *) NULL);
s_action.sa_handler = request_hup;
(void) sigaction(SIGHUP, &s_action, (struct sigaction *) NULL);
- s_action.sa_handler = sig_pipe;
+ s_action.sa_handler = SIG_IGN;
(void) sigaction(SIGPIPE, &s_action, (struct sigaction *) NULL);
#ifdef PURIFY
s_action.sa_handler = request_pure_report;
@@ -689,7 +688,7 @@ void setup_signal_handlers(iprop_role iproprole) {
signal(SIGTERM, request_exit);
signal(SIGQUIT, request_exit);
signal(SIGHUP, request_hup);
- signal(SIGPIPE, sig_pipe);
+ signal(SIGPIPE, SIG_IGN);
#ifdef PURIFY
signal(SIGUSR1, request_pure_report);
signal(SIGUSR2, request_pure_clear);
@@ -824,22 +823,6 @@ void request_exit(int signum)
}
/*
- * Function: sig_pipe
- *
- * Purpose: SIGPIPE handler
- *
- * Effects: krb5_klog_syslogs a message that a SIGPIPE occurred and returns,
- * thus causing the read() or write() to fail and, presumable, the RPC
- * to recover. Otherwise, the process aborts.
- */
-void sig_pipe(int unused)
-{
- krb5_klog_syslog(LOG_NOTICE, _("Warning: Received a SIGPIPE; probably a "
- "client aborted. Continuing."));
- return;
-}
-
-/*
* Function: build_princ_name
*
* Purpose: takes a name and a realm and builds a string that can be
--
1.7.6
--=-91aXUtl386fllPtBh1mm
Content-Disposition: attachment;
filename="0003-remove-purify-support-per-ghudson-s-request.patch"
Content-Type: text/x-patch;
name="0003-remove-purify-support-per-ghudson-s-request.patch";
charset="UTF-8"
Content-Transfer-Encoding: 7bit
>From 1415dbb23f797814a53e17d2099beff3bad21e5e Mon Sep 17 00:00:00 2001
From: Nathaniel McCallum <npmccallum@redhat.com>
Date: Tue, 23 Aug 2011 12:07:21 -0400
Subject: [PATCH 3/5] remove purify support (per ghudson's request)
---
src/kadmin/server/ovsec_kadmd.c | 67 ---------------------------------------
1 files changed, 0 insertions(+), 67 deletions(-)
diff --git a/src/kadmin/server/ovsec_kadmd.c b/src/kadmin/server/ovsec_kadmd.c
index 3e81d9d..b817f3a 100644
--- a/src/kadmin/server/ovsec_kadmd.c
+++ b/src/kadmin/server/ovsec_kadmd.c
@@ -59,15 +59,6 @@
#include "misc.h"
-#ifdef PURIFY
-#include "purify.h"
-
-int signal_pure_report = 0;
-int signal_pure_clear = 0;
-void request_pure_report(int);
-void request_pure_clear(int);
-#endif /* PURIFY */
-
#if defined(NEED_DAEMON_PROTO)
extern int daemon(int, int);
#endif
@@ -262,9 +253,6 @@ int main(int argc, char *argv[])
names[0].type = names[1].type = names[2].type = names[3].type =
nt_krb5_name_oid;
-#ifdef PURIFY
- purify_start_batch();
-#endif /* PURIFY */
whoami = (strrchr(argv[0], '/') ? strrchr(argv[0], '/')+1 : argv[0]);
nofork = 0;
@@ -668,12 +656,6 @@ void setup_signal_handlers(iprop_role iproprole) {
(void) sigaction(SIGHUP, &s_action, (struct sigaction *) NULL);
s_action.sa_handler = SIG_IGN;
(void) sigaction(SIGPIPE, &s_action, (struct sigaction *) NULL);
-#ifdef PURIFY
- s_action.sa_handler = request_pure_report;
- (void) sigaction(SIGUSR1, &s_action, (struct sigaction *) NULL);
- s_action.sa_handler = request_pure_clear;
- (void) sigaction(SIGUSR2, &s_action, (struct sigaction *) NULL);
-#endif /* PURIFY */
/*
* IProp will fork for a full-resync, we don't want to
@@ -689,10 +671,6 @@ void setup_signal_handlers(iprop_role iproprole) {
signal(SIGQUIT, request_exit);
signal(SIGHUP, request_hup);
signal(SIGPIPE, SIG_IGN);
-#ifdef PURIFY
- signal(SIGUSR1, request_pure_report);
- signal(SIGUSR2, request_pure_clear);
-#endif /* PURIFY */
/*
* IProp will fork for a full-resync, we don't want to
@@ -703,51 +681,6 @@ void setup_signal_handlers(iprop_role iproprole) {
#endif /* POSIX_SIGNALS */
}
-#ifdef PURIFY
-/*
- * Function: request_pure_report
- *
- * Purpose: sets flag saying the server got a signal and that it should
- * dump a purify report when convenient.
- *
- * Arguments:
- * Requires:
- * Effects:
- * Modifies:
- * sets signal_pure_report to one
- */
-
-void request_pure_report(int signum)
-{
- krb5_klog_syslog(LOG_DEBUG, "Got signal to request a Purify report");
- signal_pure_report = 1;
- return;
-}
-
-/*
- * Function: request_pure_clear
- *
- * Purpose: sets flag saying the server got a signal and that it should
- * dump a purify report when convenient, then clear the
- * purify tables.
- *
- * Arguments:
- * Requires:
- * Effects:
- * Modifies:
- * sets signal_pure_report to one
- * sets signal_pure_clear to one
- */
-
-void request_pure_clear(int signum)
-{
- krb5_klog_syslog(LOG_DEBUG, "Got signal to request a Purify report and clear the old Purify info");
- signal_pure_report = 1;
- signal_pure_clear = 1;
- return;
-}
-#endif /* PURIFY */
-
/*
* Function: request_hup
*
--
1.7.6
--=-91aXUtl386fllPtBh1mm
Content-Disposition: attachment;
filename*0=0004-remove-reset_db-since-it-is-no-longer-necessary-igno.pat;
filename*1=ch
Content-Type: text/x-patch;
name="0004-remove-reset_db-since-it-is-no-longer-necessary-igno.patch";
charset="UTF-8"
Content-Transfer-Encoding: 7bit
>From ebab123e5eb19d7604a5cf6021906b1ad497abe8 Mon Sep 17 00:00:00 2001
From: Nathaniel McCallum <npmccallum@redhat.com>
Date: Tue, 23 Aug 2011 12:25:23 -0400
Subject: [PATCH 4/5] remove reset_db() since it is no longer necessary;
ignore SIGHUP
---
src/kadmin/server/ovsec_kadmd.c | 60 ++-------------------------------------
1 files changed, 3 insertions(+), 57 deletions(-)
diff --git a/src/kadmin/server/ovsec_kadmd.c b/src/kadmin/server/ovsec_kadmd.c
index b817f3a..afef3dd 100644
--- a/src/kadmin/server/ovsec_kadmd.c
+++ b/src/kadmin/server/ovsec_kadmd.c
@@ -65,8 +65,6 @@ extern int daemon(int, int);
void setup_signal_handlers(iprop_role iproprole);
void request_exit(int);
-void request_hup(int);
-void reset_db(void);
#ifdef POSIX_SIGNALS
static struct sigaction s_action;
@@ -613,7 +611,7 @@ kterr:
if (nofork)
fprintf(stderr, _("%s: starting...\n"), whoami);
- loop_listen_and_process(global_server_handle, whoami, reset_db);
+ loop_listen_and_process(global_server_handle, whoami, NULL);
krb5_klog_syslog(LOG_INFO, _("finished, exiting"));
/* Clean up memory, etc */
@@ -652,9 +650,8 @@ void setup_signal_handlers(iprop_role iproprole) {
(void) sigaction(SIGINT, &s_action, (struct sigaction *) NULL);
(void) sigaction(SIGTERM, &s_action, (struct sigaction *) NULL);
(void) sigaction(SIGQUIT, &s_action, (struct sigaction *) NULL);
- s_action.sa_handler = request_hup;
- (void) sigaction(SIGHUP, &s_action, (struct sigaction *) NULL);
s_action.sa_handler = SIG_IGN;
+ (void) sigaction(SIGHUP, &s_action, (struct sigaction *) NULL);
(void) sigaction(SIGPIPE, &s_action, (struct sigaction *) NULL);
/*
@@ -669,7 +666,7 @@ void setup_signal_handlers(iprop_role iproprole) {
signal(SIGINT, request_exit);
signal(SIGTERM, request_exit);
signal(SIGQUIT, request_exit);
- signal(SIGHUP, request_hup);
+ signal(SIGHUP, SIG_IGN);
signal(SIGPIPE, SIG_IGN);
/*
@@ -682,57 +679,6 @@ void setup_signal_handlers(iprop_role iproprole) {
}
/*
- * Function: request_hup
- *
- * Purpose: sets flag saying the server got a signal and that it should
- * reset the database files when convenient.
- *
- * Arguments:
- * Requires:
- * Effects:
- * Modifies:
- * sets signal_requests_reset to one
- */
-
-void request_hup(int signum)
-{
- signal_requests_reset = 1;
- return;
-}
-
-/*
- * Function: reset_db
- *
- * Purpose: flushes the currently opened database files to disk.
- *
- * Arguments:
- * Requires:
- * Effects:
- *
- * Currently, just sets signal_requests_reset to 0. The kdb and adb
- * libraries used to be sufficiently broken that it was prudent to
- * close and reopen the databases periodically. They are no longer
- * that broken, so this function is not necessary.
- */
-void reset_db(void)
-{
-#ifdef notdef
- kadm5_ret_t ret;
- char *errmsg;
-
- if (ret = kadm5_flush(global_server_handle)) {
- krb5_klog_syslog(LOG_ERR, "FATAL ERROR! %s while flushing databases. "
- "Databases may be corrupt! Aborting.",
- krb5_get_error_message (context, ret));
- krb5_klog_close(context);
- exit(3);
- }
-#endif
-
- return;
-}
-
-/*
* Function: request_exit
*
* Purpose: sets flags saying the server got a signal and that it
--
1.7.6
--=-91aXUtl386fllPtBh1mm
Content-Disposition: attachment;
filename="0005-migrate-net-server-loop-to-use-libverto.patch"
Content-Type: text/x-patch;
name="0005-migrate-net-server-loop-to-use-libverto.patch";
charset="UTF-8"
Content-Transfer-Encoding: 7bit
>From 49b6dd78cca5472a54897fd5836465f5baf84acd Mon Sep 17 00:00:00 2001
From: Nathaniel McCallum <npmccallum@redhat.com>
Date: Tue, 23 Aug 2011 15:49:36 -0400
Subject: [PATCH 5/5] migrate net-server loop to use libverto
---
src/include/net-server.h | 18 +-
src/kadmin/server/Makefile.in | 2 +-
src/kadmin/server/ovsec_kadmd.c | 120 ++---
src/kdc/Makefile.in | 2 +-
src/kdc/main.c | 129 +++--
src/lib/apputils/net-server.c | 1130 +++++++++++++++++++--------------------
6 files changed, 667 insertions(+), 734 deletions(-)
diff --git a/src/include/net-server.h b/src/include/net-server.h
index 144156d..f74815e 100644
--- a/src/include/net-server.h
+++ b/src/include/net-server.h
@@ -29,23 +29,27 @@
#ifndef NET_SERVER_H
#define NET_SERVER_H
+#include <verto.h>
+
typedef struct _krb5_fulladdr {
krb5_address * address;
krb5_ui_4 port;
} krb5_fulladdr;
/* exported from network.c */
-extern volatile int signal_requests_exit, signal_requests_reset;
void init_addr(krb5_fulladdr *, struct sockaddr *);
+
+/* exported from net-server.c */
+verto_ctx *loop_init(verto_ev_type types);
krb5_error_code loop_add_udp_port(int port);
krb5_error_code loop_add_tcp_port(int port);
krb5_error_code loop_add_rpc_service(int port, u_long prognum, u_long versnum,
void (*dispatch)());
-krb5_error_code loop_setup_network(void *handle, const char *prog,
- int no_reconfig);
-krb5_error_code loop_listen_and_process(void *handle, const char *prog,
- void (*reset)(void));
-void loop_closedown_network(void);
+krb5_error_code loop_setup_routing_socket(verto_ctx *ctx, void *handle,
+ const char *progname);
+krb5_error_code loop_setup_network(verto_ctx *ctx, void *handle,
+ const char *progname);
+void loop_free(verto_ctx *ctx);
/* to be supplied by the server application */
@@ -56,7 +60,7 @@ void loop_closedown_network(void);
* The first, dispatch(), is for normal processing of a request. The
* second, make_toolong_error(), is obviously for generating an error
* to send back when the incoming message is bigger than
- * loop_listen_and_process can accept.
+ * the main loop can accept.
*/
krb5_error_code dispatch (void *handle,
struct sockaddr *local_addr,
diff --git a/src/kadmin/server/Makefile.in b/src/kadmin/server/Makefile.in
index 7872872..d656d24 100644
--- a/src/kadmin/server/Makefile.in
+++ b/src/kadmin/server/Makefile.in
@@ -17,7 +17,7 @@ SRCS = kadm_rpc_svc.c server_stubs.c ovsec_kadmd.c schpw.c misc.c ipropd_svc.c
all:: $(PROG)
$(PROG): $(OBJS) $(KADMSRV_DEPLIBS) $(KRB5_BASE_DEPLIBS) $(APPUTILS_DEPLIB)
- $(CC_LINK) -o $(PROG) $(OBJS) $(APPUTILS_LIB) $(KADMSRV_LIBS) $(KDB_DEP_LIB) $(KRB5_BASE_LIBS)
+ $(CC_LINK) -o $(PROG) $(OBJS) $(APPUTILS_LIB) $(KADMSRV_LIBS) $(KDB_DEP_LIB) $(KRB5_BASE_LIBS) -lverto
install::
$(INSTALL_PROGRAM) $(PROG) ${DESTDIR}$(SERVER_BINDIR)/$(PROG)
diff --git a/src/kadmin/server/ovsec_kadmd.c b/src/kadmin/server/ovsec_kadmd.c
index afef3dd..6b1be0d 100644
--- a/src/kadmin/server/ovsec_kadmd.c
+++ b/src/kadmin/server/ovsec_kadmd.c
@@ -63,14 +63,6 @@
extern int daemon(int, int);
#endif
-void setup_signal_handlers(iprop_role iproprole);
-void request_exit(int);
-
-#ifdef POSIX_SIGNALS
-static struct sigaction s_action;
-#endif /* POSIX_SIGNALS */
-
-
#define TIMEOUT 15
gss_name_t gss_changepw_name = NULL, gss_oldchangepw_name = NULL;
@@ -234,6 +226,8 @@ int main(int argc, char *argv[])
kdb_log_context *log_ctx;
+ verto_ctx *ctx;
+
setlocale(LC_MESSAGES, "");
setvbuf(stderr, NULL, _IONBF, 0);
@@ -363,6 +357,18 @@ int main(int argc, char *argv[])
exit(1);
}
+ ctx = loop_init(VERTO_EV_TYPE_SIGNAL);
+ if (!ctx) {
+ krb5_klog_syslog(LOG_ERR,
+ _("%s: could not initialize loop, aborting"),
+ whoami);
+ fprintf(stderr, _("%s: could not initialize loop, aborting\n"),
+ whoami);
+ kadm5_destroy(global_server_handle);
+ krb5_klog_close(context);
+ exit(1);
+ }
+
#define server_handle ((kadm5_server_handle_t)global_server_handle)
if ((ret = loop_add_udp_port(server_handle->params.kpasswd_port))
|| (ret = loop_add_tcp_port(server_handle->params.kpasswd_port))
@@ -376,12 +382,13 @@ int main(int argc, char *argv[])
: 0)
#endif
#undef server_handle
- || (ret = loop_setup_network(global_server_handle, whoami, 0))) {
+ || (ret = loop_setup_network(ctx, global_server_handle, whoami))) {
const char *e_txt = krb5_get_error_message (context, ret);
krb5_klog_syslog(LOG_ERR, _("%s: %s while initializing network, "
"aborting"), whoami, e_txt);
fprintf(stderr, _("%s: %s while initializing network, aborting\n"),
whoami, e_txt);
+ loop_free(ctx);
kadm5_destroy(global_server_handle);
krb5_klog_close(context);
exit(1);
@@ -394,6 +401,7 @@ int main(int argc, char *argv[])
"names, failing."));
fprintf(stderr, _("%s: Cannot build GSS-API authentication names.\n"),
whoami);
+ loop_free(ctx);
kadm5_destroy(global_server_handle);
krb5_klog_close(context);
exit(1);
@@ -428,6 +436,7 @@ kterr:
if (ret) {
krb5_klog_syslog(LOG_ERR, "%s", krb5_get_error_message (context, ret));
fprintf(stderr, _("%s: Can't set up keytab for RPC.\n"), whoami);
+ loop_free(ctx);
kadm5_destroy(global_server_handle);
krb5_klog_close(context);
exit(1);
@@ -439,6 +448,7 @@ kterr:
fprintf(stderr, _("%s: Cannot set GSS-API authentication names.\n"),
whoami);
svcauth_gssapi_unset_names();
+ loop_free(ctx);
kadm5_destroy(global_server_handle);
krb5_klog_close(context);
exit(1);
@@ -461,6 +471,7 @@ kterr:
if (svcauth_gss_set_svc_name(GSS_C_NO_NAME) != TRUE) {
fprintf(stderr, _("%s: Cannot initialize RPCSEC_GSS service name.\n"),
whoami);
+ loop_free(ctx);
exit(1);
}
@@ -470,6 +481,7 @@ kterr:
fprintf(stderr, _("%s: Cannot initialize acl file: %s\n"),
whoami, errmsg);
svcauth_gssapi_unset_names();
+ loop_free(ctx);
kadm5_destroy(global_server_handle);
krb5_klog_close(context);
exit(1);
@@ -481,6 +493,7 @@ kterr:
krb5_klog_syslog(LOG_ERR, _("Cannot detach from tty: %s"), errmsg);
fprintf(stderr, _("%s: Cannot detach from tty: %s\n"), whoami, errmsg);
svcauth_gssapi_unset_names();
+ loop_free(ctx);
kadm5_destroy(global_server_handle);
krb5_klog_close(context);
exit(1);
@@ -492,6 +505,7 @@ kterr:
krb5_klog_syslog(LOG_ERR, _("Cannot create PID file %s: %s"),
pid_file, errmsg);
svcauth_gssapi_unset_names();
+ loop_free(ctx);
kadm5_destroy(global_server_handle);
krb5_klog_close(context);
exit(1);
@@ -504,6 +518,7 @@ kterr:
krb5_klog_syslog(LOG_ERR, _("Error getting random seed: %s, aborting"),
krb5_get_error_message(context, ret));
svcauth_gssapi_unset_names();
+ loop_free(ctx);
kadm5_destroy(global_server_handle);
krb5_klog_close(context);
exit(1);
@@ -529,6 +544,7 @@ kterr:
krb5_klog_syslog(LOG_ERR,
_("%s while mapping update log (`%s.ulog')"),
error_message(ret), params.dbname);
+ loop_free(ctx);
krb5_klog_close(context);
exit(1);
}
@@ -550,6 +566,7 @@ kterr:
krb5_klog_syslog(LOG_ERR,
_("Cannot create IProp RPC service (PROG=%d, VERS=%d), failing."),
KRB5_IPROP_PROG, KRB5_IPROP_VERS);
+ loop_free(ctx);
krb5_klog_close(context);
exit(1);
}
@@ -565,6 +582,7 @@ kterr:
fprintf(stderr,
_("%s: %s while getting IProp svc name, failing\n"),
whoami, error_message(ret));
+ loop_free(ctx);
krb5_klog_close(context);
exit(1);
}
@@ -600,24 +618,37 @@ kterr:
err.system_error);
}
+ loop_free(ctx);
exit(1);
}
free(kiprop_name);
#endif
}
- setup_signal_handlers(log_ctx->iproprole);
+ if (!verto_add_signal(ctx, VERTO_EV_FLAG_PERSIST,
+ VERTO_SIG_IGN, SIGHUP) ||
+ !verto_add_signal(ctx, VERTO_EV_FLAG_PERSIST,
+ VERTO_SIG_IGN, SIGPIPE)) {
+ krb5_klog_syslog(LOG_ERR, _("Error setting up main loop"));
+ svcauth_gssapi_unset_names();
+ kadm5_destroy(global_server_handle);
+ krb5_klog_close(context);
+ krb5_free_context(context);
+ loop_free(ctx);
+ exit(1);
+ }
+
krb5_klog_syslog(LOG_INFO, _("starting"));
if (nofork)
fprintf(stderr, _("%s: starting...\n"), whoami);
- loop_listen_and_process(global_server_handle, whoami, NULL);
+ verto_run(ctx);
krb5_klog_syslog(LOG_INFO, _("finished, exiting"));
/* Clean up memory, etc */
svcauth_gssapi_unset_names();
kadm5_destroy(global_server_handle);
- loop_closedown_network();
+ loop_free(ctx);
kadm5int_acl_finish(context, 0);
if(gss_changepw_name) {
(void) gss_release_name(&OMret, &gss_changepw_name);
@@ -637,71 +668,6 @@ kterr:
}
/*
- * Function: setup_signal_handlers
- *
- * Purpose: Setup signal handling functions using POSIX's sigaction()
- * if possible, otherwise with System V's signal().
- */
-
-void setup_signal_handlers(iprop_role iproprole) {
-#ifdef POSIX_SIGNALS
- (void) sigemptyset(&s_action.sa_mask);
- s_action.sa_handler = request_exit;
- (void) sigaction(SIGINT, &s_action, (struct sigaction *) NULL);
- (void) sigaction(SIGTERM, &s_action, (struct sigaction *) NULL);
- (void) sigaction(SIGQUIT, &s_action, (struct sigaction *) NULL);
- s_action.sa_handler = SIG_IGN;
- (void) sigaction(SIGHUP, &s_action, (struct sigaction *) NULL);
- (void) sigaction(SIGPIPE, &s_action, (struct sigaction *) NULL);
-
- /*
- * IProp will fork for a full-resync, we don't want to
- * wait on it and we don't want the living dead procs either.
- */
- if (iproprole == IPROP_MASTER) {
- s_action.sa_handler = SIG_IGN;
- (void) sigaction(SIGCHLD, &s_action, (struct sigaction *) NULL);
- }
-#else /* POSIX_SIGNALS */
- signal(SIGINT, request_exit);
- signal(SIGTERM, request_exit);
- signal(SIGQUIT, request_exit);
- signal(SIGHUP, SIG_IGN);
- signal(SIGPIPE, SIG_IGN);
-
- /*
- * IProp will fork for a full-resync, we don't want to
- * wait on it and we don't want the living dead procs either.
- */
- if (iproprole == IPROP_MASTER)
- (void) signal(SIGCHLD, SIG_IGN);
-#endif /* POSIX_SIGNALS */
-}
-
-/*
- * Function: request_exit
- *
- * Purpose: sets flags saying the server got a signal and that it
- * should exit when convient.
- *
- * Arguments:
- * Requires:
- * Effects:
- * modifies signal_requests_exit which ideally makes the server exit
- * at some point.
- *
- * Modifies:
- * signal_requests_exit
- */
-
-void request_exit(int signum)
-{
- krb5_klog_syslog(LOG_DEBUG, _("Got signal to request exit"));
- signal_requests_exit = 1;
- return;
-}
-
-/*
* Function: build_princ_name
*
* Purpose: takes a name and a realm and builds a string that can be
diff --git a/src/kdc/Makefile.in b/src/kdc/Makefile.in
index f46cad3..76391c0 100644
--- a/src/kdc/Makefile.in
+++ b/src/kdc/Makefile.in
@@ -54,7 +54,7 @@ kdc5_err.h: kdc5_err.et
kdc5_err.o: kdc5_err.h
krb5kdc: $(OBJS) $(KADMSRV_DEPLIBS) $(KRB5_BASE_DEPLIBS) $(APPUTILS_DEPLIB)
- $(CC_LINK) -o krb5kdc $(OBJS) $(APPUTILS_LIB) $(KADMSRV_LIBS) $(KRB5_BASE_LIBS)
+ $(CC_LINK) -o krb5kdc $(OBJS) $(APPUTILS_LIB) $(KADMSRV_LIBS) $(KRB5_BASE_LIBS) -lverto
rtest: $(RT_OBJS) $(KDB5_DEPLIBS) $(KADM_COMM_DEPLIBS) $(KRB5_BASE_DEPLIBS)
$(CC_LINK) -o rtest $(RT_OBJS) $(KDB5_LIBS) $(KADM_COMM_LIBS) $(KRB5_BASE_LIBS)
diff --git a/src/kdc/main.c b/src/kdc/main.c
index a6a5751..8dec1fe 100644
--- a/src/kdc/main.c
+++ b/src/kdc/main.c
@@ -78,10 +78,7 @@ extern int daemon(int, int);
static void usage (char *);
-static krb5_sigtype request_exit (int);
-static krb5_sigtype request_hup (int);
-
-static void setup_signal_handlers (void);
+static void request_hup (verto_ctx *ctx, verto_ev *ev);
static krb5_error_code setup_sam (void);
@@ -93,10 +90,7 @@ static int nofork = 0;
static int workers = 0;
static const char *pid_file = NULL;
static int rkey_init_done = 0;
-
-#ifdef POSIX_SIGNALS
-static struct sigaction s_action;
-#endif /* POSIX_SIGNALS */
+static int signal_received = 0;
#define KRB5_KDC_MAX_REALMS 32
@@ -485,22 +479,17 @@ whoops:
return(kret);
}
-static krb5_sigtype
-request_exit(int signo)
+static void
+request_hup(verto_ctx *ctx, verto_ev *ev)
{
- signal_requests_exit = 1;
-
-#ifdef POSIX_SIGTYPE
- return;
-#else
- return(0);
-#endif
+ krb5_klog_reopen(get_context(NULL));
+ reset_for_hangup();
}
static krb5_sigtype
-request_hup(int signo)
+on_monitor_signal(int signo)
{
- signal_requests_reset = 1;
+ signal_received = signo;
#ifdef POSIX_SIGTYPE
return;
@@ -509,28 +498,6 @@ request_hup(int signo)
#endif
}
-static void
-setup_signal_handlers(void)
-{
-#ifdef POSIX_SIGNALS
- (void) sigemptyset(&s_action.sa_mask);
- s_action.sa_flags = 0;
- s_action.sa_handler = request_exit;
- (void) sigaction(SIGINT, &s_action, (struct sigaction *) NULL);
- (void) sigaction(SIGTERM, &s_action, (struct sigaction *) NULL);
- s_action.sa_handler = request_hup;
- (void) sigaction(SIGHUP, &s_action, (struct sigaction *) NULL);
- s_action.sa_handler = SIG_IGN;
- (void) sigaction(SIGPIPE, &s_action, (struct sigaction *) NULL);
-#else /* POSIX_SIGNALS */
- signal(SIGINT, request_exit);
- signal(SIGTERM, request_exit);
- signal(SIGHUP, request_hup);
- signal(SIGPIPE, SIG_IGN);
-#endif /* POSIX_SIGNALS */
-
- return;
-}
/*
* Kill the worker subprocesses given by pids[0..bound-1], skipping any which
@@ -564,10 +531,13 @@ terminate_workers(pid_t *pids, int bound, int num_active)
* function in error cases.
*/
static krb5_error_code
-create_workers(int num)
+create_workers(verto_ctx *ctx, int num)
{
int i, status, numleft;
pid_t pid, *pids;
+#ifdef POSIX_SIGNALS
+ struct sigaction s_action;
+#endif /* POSIX_SIGNALS */
/* Create child worker processes; return in each child. */
krb5_klog_syslog(LOG_INFO, _("creating %d worker processes"), num);
@@ -591,9 +561,28 @@ create_workers(int num)
pids[i] = pid;
}
+ /* We're going to use our own main loop here. */
+ loop_free(ctx);
+
+ /* Setup our signal handlers which will forward to the children. */
+#ifdef POSIX_SIGNALS
+ (void) sigemptyset(&s_action.sa_mask);
+ s_action.sa_flags = 0;
+ s_action.sa_handler = on_monitor_signal;
+ (void) sigaction(SIGINT, &s_action, (struct sigaction *) NULL);
+ (void) sigaction(SIGTERM, &s_action, (struct sigaction *) NULL);
+ (void) sigaction(SIGQUIT, &s_action, (struct sigaction *) NULL);
+ (void) sigaction(SIGHUP, &s_action, (struct sigaction *) NULL);
+#else /* POSIX_SIGNALS */
+ signal(SIGINT, on_monitor_signal);
+ signal(SIGTERM, on_monitor_signal);
+ signal(SIGQUIT, on_monitor_signal);
+ signal(SIGHUP, on_monitor_signal);
+#endif /* POSIX_SIGNALS */
+
/* Supervise the worker processes. */
numleft = num;
- while (!signal_requests_exit) {
+ while (!signal_received) {
/* Wait until a worker process exits or we get a signal. */
pid = wait(&status);
if (pid >= 0) {
@@ -612,18 +601,20 @@ create_workers(int num)
}
/* Propagate HUP signal to worker processes if we received one. */
- if (signal_requests_reset) {
- for (i = 0; i < num; i++) {
- if (pids[i] != -1)
- kill(pids[i], SIGHUP);
+ if (signal_received) {
+ krb5_klog_syslog(LOG_INFO,
+ _("signal %d received in supervisor"),
+ signal_received);
+
+ if (signal_received == SIGHUP) {
+ for (i = 0; i < num; i++) {
+ if (pids[i] != -1)
+ kill(pids[i], SIGHUP);
+ }
+ signal_received = 0;
}
- signal_requests_reset = 0;
}
}
- if (signal_requests_exit) {
- krb5_klog_syslog(LOG_INFO,
- _("shutdown signal received in supervisor"));
- }
terminate_workers(pids, num, numleft);
free(pids);
@@ -948,6 +939,7 @@ int main(int argc, char **argv)
{
krb5_error_code retval;
krb5_context kcontext;
+ verto_ctx *ctx;
int errout = 0;
int i;
@@ -989,7 +981,18 @@ int main(int argc, char **argv)
*/
initialize_realms(kcontext, argc, argv);
- setup_signal_handlers();
+ ctx = loop_init(VERTO_EV_TYPE_CHILD | VERTO_EV_TYPE_SIGNAL);
+ if (!ctx) {
+ kdc_err(kcontext, ENOMEM, _("while creating main loop"));
+ finish_realms();
+ return 1;
+ }
+
+ if (!verto_add_signal(ctx, VERTO_EV_FLAG_PERSIST, request_hup, SIGHUP)) {
+ kdc_err(kcontext, ENOMEM, _("while registering signal handler"));
+ finish_realms();
+ return 1;
+ }
load_preauth_plugins(kcontext);
load_authdata_plugins(kcontext);
@@ -1039,7 +1042,15 @@ int main(int argc, char **argv)
* children won't be able to re-open the listener sockets. Hopefully our
* platform has pktinfo support and doesn't need reconfigs.
*/
- if ((retval = loop_setup_network(NULL, kdc_progname, (workers > 0)))) {
+ if (workers > 0) {
+ retval = loop_setup_routing_socket(ctx, NULL, kdc_progname);
+ if (retval) {
+ kdc_err(kcontext, retval, _("while initializing routing socket"));
+ finish_realms();
+ return 1;
+ }
+ }
+ if ((retval = loop_setup_network(ctx, NULL, kdc_progname))) {
net_init_error:
kdc_err(kcontext, retval, _("while initializing network"));
finish_realms();
@@ -1060,7 +1071,7 @@ int main(int argc, char **argv)
}
if (workers > 0) {
finish_realms();
- retval = create_workers(workers);
+ retval = create_workers(ctx, workers);
if (retval) {
kdc_err(kcontext, errno, _("creating worker processes"));
return 1;
@@ -1071,11 +1082,9 @@ int main(int argc, char **argv)
krb5_klog_syslog(LOG_INFO, _("commencing operation"));
if (nofork)
fprintf(stderr, _("%s: starting...\n"), kdc_progname);
- if ((retval = loop_listen_and_process(0, kdc_progname, reset_for_hangup))) {
- kdc_err(kcontext, retval, _("while processing network requests"));
- errout++;
- }
- loop_closedown_network();
+
+ verto_run(ctx);
+ loop_free(ctx);
krb5_klog_syslog(LOG_INFO, _("shutting down"));
unload_preauth_plugins(kcontext);
unload_authdata_plugins(kcontext);
diff --git a/src/lib/apputils/net-server.c b/src/lib/apputils/net-server.c
index 5afc3c0..b886bbb 100644
--- a/src/lib/apputils/net-server.c
+++ b/src/lib/apputils/net-server.c
@@ -59,12 +59,13 @@
#include "fake-addrinfo.h"
#include "net-server.h"
+#include <signal.h>
+
/* XXX */
#define KDC5_NONET (-1779992062L)
-volatile int signal_requests_exit = 0, signal_requests_reset = 0;
-
-static void loop_closedown_network_sockets(void);
+static int tcp_or_rpc_data_counter;
+static int max_tcp_or_rpc_data_connections = 45;
/* Misc utility routines. */
static void
@@ -187,9 +188,9 @@ enum conn_type {
/* Per-connection info. */
struct connection {
- int fd;
+ void *handle;
+ const char *prog;
enum conn_type type;
- void (*service)(void *handle, struct connection *, const char *, int);
union {
/* Type-specific information. */
struct {
@@ -250,33 +251,47 @@ struct connection {
#define FREE_SET_DATA(set) \
(free(set.data), set.data = 0, set.max = 0, set.n = 0)
-
-/* Set<struct connection *> connections; */
-static SET(struct connection *) connections;
-#define n_sockets connections.n
-#define conns connections.data
-
-/* Set<u_short> udp_port_data, tcp_port_data; */
/*
* N.B.: The Emacs cc-mode indentation code seems to get confused if
* the macro argument here is one word only. So use "unsigned short"
* instead of the "u_short" we were using before.
*/
-static SET(unsigned short) udp_port_data, tcp_port_data;
-
struct rpc_svc_data {
u_short port;
u_long prognum;
u_long versnum;
void (*dispatch)();
};
-
+static SET(unsigned short) udp_port_data, tcp_port_data;
static SET(struct rpc_svc_data) rpc_svc_data;
+static SET(verto_ev *) events;
-#include "cm.h"
+static void
+do_break(verto_ctx *ctx, verto_ev *ev)
+{
+ krb5_klog_syslog(LOG_DEBUG, _("Got signal to request exit"));
+ verto_break(ctx);
+}
+
+verto_ctx *
+loop_init(verto_ev_type types)
+{
+ verto_ctx *ctx;
+
+ types |= VERTO_EV_TYPE_IO;
+ types |= VERTO_EV_TYPE_SIGNAL;
+ types |= VERTO_EV_TYPE_TIMEOUT;
+ ctx = verto_default(NULL, types);
+ if (!verto_add_signal(ctx, VERTO_EV_FLAG_PERSIST, do_break, SIGINT) ||
+ !verto_add_signal(ctx, VERTO_EV_FLAG_PERSIST, do_break, SIGTERM) ||
+ !verto_add_signal(ctx, VERTO_EV_FLAG_PERSIST, do_break, SIGQUIT) ||
+ !verto_add_signal(ctx, VERTO_EV_FLAG_PERSIST, VERTO_SIG_IGN, SIGPIPE)) {
+ verto_free(ctx);
+ return NULL;
+ }
-static struct select_state sstate;
-static fd_set rpc_listenfds;
+ return ctx;
+}
krb5_error_code
loop_add_udp_port(int port)
@@ -348,6 +363,8 @@ loop_add_rpc_service(int port, u_long prognum,
#include "foreachaddr.h"
struct socksetup {
+ verto_ctx *ctx;
+ void *handle;
const char *prog;
krb5_error_code retval;
int udp_flags;
@@ -355,12 +372,129 @@ struct socksetup {
#define UDP_DO_IPV6 2
};
-static struct connection *
+static void
+free_connection(struct connection *conn)
+{
+ if (!conn)
+ return;
+ if (conn->u.tcp.response)
+ krb5_free_data(get_context(conn->handle), conn->u.tcp.response);
+ if (conn->u.tcp.buffer)
+ free(conn->u.tcp.buffer);
+ if (conn->type == CONN_RPC_LISTENER && conn->u.rpc.transp != NULL)
+ svc_destroy(conn->u.rpc.transp);
+ free(conn);
+}
+
+static void
+remove_event_from_set(verto_ev *ev)
+{
+ verto_ev *tmp;
+ int i;
+
+ /* Remove the event from the events. */
+ FOREACH_ELT(events, i, tmp)
+ if (tmp == ev) {
+ DEL(events, i);
+ break;
+ }
+}
+
+static void
+free_socket(verto_ctx *ctx, verto_ev *ev)
+{
+ struct connection *conn = NULL;
+ fd_set fds;
+ int fd;
+
+ remove_event_from_set(ev);
+
+ /* Close the file descriptor. */
+ fd = verto_get_fd(ev);
+ krb5_klog_syslog(LOG_INFO, _("closing down fd %d"), fd);
+ close(fd);
+
+ /* Free the connection struct. */
+ conn = verto_get_private(ev);
+ if (conn) {
+ switch (conn->type) {
+ case CONN_RPC:
+ FD_ZERO(&fds);
+ FD_SET(fd, &fds);
+ svc_getreqset(&fds);
+ if (FD_ISSET(fd, &svc_fdset)) {
+ krb5_klog_syslog(LOG_ERR,
+ _("descriptor %d closed but still "
+ "in svc_fdset"),
+ fd);
+ }
+ /* Fall through. */
+ case CONN_TCP:
+ tcp_or_rpc_data_counter--;
+ break;
+ default:
+ break;
+ }
+
+ free_connection(conn);
+ }
+}
+
+static verto_ev *
+make_event(verto_ctx *ctx, verto_ev_flag flags, verto_callback callback,
+ int sock, struct connection *conn, int addevent)
+{
+ verto_ev *ev, *tmp;
+
+ ev = verto_add_io(ctx, flags, callback, sock);
+ if (!ev) {
+ com_err(conn->prog, ENOMEM, _("cannot create io event"));
+ return NULL;
+ }
+
+ if (addevent) {
+ if (!ADD(events, ev, tmp)) {
+ com_err(conn->prog, ENOMEM, _("cannot save event"));
+ verto_del(ev);
+ return NULL;
+ }
+ }
+
+ verto_set_private(ev, conn, free_socket);
+ return ev;
+}
+
+static verto_ev *
+convert_event(verto_ctx *ctx, verto_ev *ev, verto_ev_flag flags,
+ verto_callback callback)
+{
+ struct connection *conn;
+ verto_ev *newev;
+ int sock;
+
+ conn = verto_get_private(ev);
+ sock = verto_get_fd(ev);
+ if (sock < 0)
+ return NULL;
+
+ newev = make_event(ctx, flags, callback, sock, conn, 1);
+
+ /* Delete the read event without closing the socket
+ * or freeing the connection struct. */
+ if (newev) {
+ verto_set_private(ev, NULL, NULL); /* Reset the destructor. */
+ remove_event_from_set(ev); /* Remove it from the set. */
+ verto_del(ev);
+ }
+
+ return newev;
+}
+
+static verto_ev *
add_fd(struct socksetup *data, int sock, enum conn_type conntype,
- void (*service)(void *handle, struct connection *, const char *, int))
+ verto_ev_flag flags, verto_callback callback, int addevent)
{
struct connection *newconn;
- void *tmp;
#ifndef _WIN32
if (sock >= FD_SETSIZE) {
@@ -377,62 +511,43 @@ add_fd(struct socksetup *data, int sock, enum conn_type conntype,
_("cannot allocate storage for connection info"));
return 0;
}
- if (!ADD(connections, newconn, tmp)) {
- data->retval = ENOMEM;
- com_err(data->prog, ENOMEM, _("cannot save socket info"));
- free(newconn);
- return 0;
- }
-
memset(newconn, 0, sizeof(*newconn));
+ newconn->handle = data->handle;
+ newconn->prog = data->prog;
newconn->type = conntype;
- newconn->fd = sock;
- newconn->service = service;
- return newconn;
+
+ return make_event(data->ctx, flags, callback, sock, newconn, addevent);
}
-static void process_packet(void *handle, struct connection *, const char *,
- int);
-static void accept_tcp_connection(void *handle, struct connection *,
- const char *, int);
-static void process_tcp_connection(void *handle, struct connection *,
- const char *, int);
-static void accept_rpc_connection(void *handle, struct connection *,
- const char *, int);
-static void process_rpc_connection(void *handle, struct connection *,
- const char *, int);
-
-static struct connection *
+static void process_packet(verto_ctx *ctx, verto_ev *ev);
+static void accept_tcp_connection(verto_ctx *ctx, verto_ev *ev);
+static void process_tcp_connection_read(verto_ctx *ctx, verto_ev *ev);
+static void process_tcp_connection_write(verto_ctx *ctx, verto_ev *ev);
+static void accept_rpc_connection(verto_ctx *ctx, verto_ev *ev);
+static void process_rpc_connection(verto_ctx *ctx, verto_ev *ev);
+
+static verto_ev *
add_udp_fd(struct socksetup *data, int sock, int pktinfo)
{
return add_fd(data, sock, pktinfo ? CONN_UDP_PKTINFO : CONN_UDP,
- process_packet);
+ VERTO_EV_FLAG_IO_READ | VERTO_EV_FLAG_PERSIST,
+ process_packet, 1);
}
-static struct connection *
+static verto_ev *
add_tcp_listener_fd(struct socksetup *data, int sock)
{
- return add_fd(data, sock, CONN_TCP_LISTENER, accept_tcp_connection);
+ return add_fd(data, sock, CONN_TCP_LISTENER,
+ VERTO_EV_FLAG_IO_READ | VERTO_EV_FLAG_PERSIST,
+ accept_tcp_connection, 1);
}
-static struct connection *
-add_tcp_data_fd(struct socksetup *data, int sock)
+static verto_ev *
+add_tcp_read_fd(struct socksetup *data, int sock)
{
- return add_fd(data, sock, CONN_TCP, process_tcp_connection);
-}
-
-static void
-delete_fd(struct connection *xconn)
-{
- struct connection *conn;
- int i;
-
- FOREACH_ELT(connections, i, conn)
- if (conn == xconn) {
- DEL(connections, i);
- break;
- }
- free(xconn);
+ return add_fd(data, sock, CONN_TCP,
+ VERTO_EV_FLAG_IO_READ | VERTO_EV_FLAG_PERSIST,
+ process_tcp_connection_read, 1);
}
/*
@@ -494,21 +609,24 @@ create_server_socket(struct socksetup *data, struct sockaddr *addr, int type)
return sock;
}
-static struct connection *
+static verto_ev *
add_rpc_listener_fd(struct socksetup *data, struct rpc_svc_data *svc, int sock)
{
struct connection *conn;
+ verto_ev *ev;
- conn = add_fd(data, sock, CONN_RPC_LISTENER, accept_rpc_connection);
- if (conn == NULL)
+ ev = add_fd(data, sock, CONN_RPC_LISTENER, VERTO_EV_FLAG_IO_READ,
+ accept_rpc_connection, 1);
+ if (ev == NULL)
return NULL;
+ conn = verto_get_private(ev);
conn->u.rpc.transp = svctcp_create(sock, 0, 0);
if (conn->u.rpc.transp == NULL) {
krb5_klog_syslog(LOG_ERR,
_("Cannot create RPC service: %s; continuing"),
strerror(errno));
- delete_fd(conn);
+ verto_del(ev);
return NULL;
}
@@ -517,17 +635,19 @@ add_rpc_listener_fd(struct socksetup *data, struct rpc_svc_data *svc, int sock)
krb5_klog_syslog(LOG_ERR,
_("Cannot register RPC service: %s; continuing"),
strerror(errno));
- delete_fd(conn);
+ verto_del(ev);
return NULL;
}
- return conn;
+ return ev;
}
-static struct connection *
+static verto_ev *
add_rpc_data_fd(struct socksetup *data, int sock)
{
- return add_fd(data, sock, CONN_RPC, process_rpc_connection);
+ return add_fd(data, sock, CONN_RPC,
+ VERTO_EV_FLAG_IO_READ | VERTO_EV_FLAG_PERSIST,
+ process_rpc_connection, 1);
}
static const int one = 1;
@@ -637,9 +757,6 @@ setup_tcp_listener_ports(struct socksetup *data)
if (add_tcp_listener_fd(data, s4) == NULL)
close(s4);
else {
- FD_SET(s4, &sstate.rfds);
- if (s4 >= sstate.max)
- sstate.max = s4 + 1;
krb5_klog_syslog(LOG_INFO, _("listening on fd %d: tcp %s"),
s4, paddr((struct sockaddr *)&sin4));
}
@@ -650,9 +767,6 @@ setup_tcp_listener_ports(struct socksetup *data)
close(s6);
s6 = -1;
} else {
- FD_SET(s6, &sstate.rfds);
- if (s6 >= sstate.max)
- sstate.max = s6 + 1;
krb5_klog_syslog(LOG_INFO, _("listening on fd %d: tcp %s"),
s6, paddr((struct sockaddr *)&sin6));
}
@@ -704,13 +818,9 @@ setup_rpc_listener_ports(struct socksetup *data)
if (add_rpc_listener_fd(data, &svc, s4) == NULL)
close(s4);
- else {
- FD_SET(s4, &sstate.rfds);
- if (s4 >= sstate.max)
- sstate.max = s4 + 1;
+ else
krb5_klog_syslog(LOG_INFO, _("listening on fd %d: rpc %s"),
s4, paddr((struct sockaddr *)&sin4));
- }
#ifdef KRB5_USE_INET6
if (ipv6_enabled()) {
@@ -722,18 +832,13 @@ setup_rpc_listener_ports(struct socksetup *data)
if (add_rpc_listener_fd(data, &svc, s6) == NULL)
close(s6);
- else {
- FD_SET(s6, &sstate.rfds);
- if (s6 >= sstate.max)
- sstate.max = s6 + 1;
+ else
krb5_klog_syslog(LOG_INFO, _("listening on fd %d: rpc %s"),
s6, paddr((struct sockaddr *)&sin6));
- }
}
#endif
}
- FD_ZERO(&rpc_listenfds);
- rpc_listenfds = svc_fdset;
+
return 0;
}
@@ -789,7 +894,7 @@ setup_udp_pktinfo_ports(struct socksetup *data)
}
#else /* no pktinfo compile-time support */
static void
-setup_udp_pktinfo_ports(struct socksetup *data)
+setup_udp_pktinfo_ports(verto_ctx *ctx, struct socksetup *data)
{
}
#endif
@@ -829,9 +934,6 @@ setup_udp_port_1(struct socksetup *data, struct sockaddr *addr,
close(sock);
return 1;
}
- FD_SET (sock, &sstate.rfds);
- if (sock >= sstate.max)
- sstate.max = sock + 1;
}
return 0;
}
@@ -939,8 +1041,6 @@ scan_for_newlines:
}
#endif
-static int network_reconfiguration_needed = 0;
-
#ifdef HAVE_STRUCT_RT_MSGHDR
#include <net/route.h>
@@ -969,13 +1069,87 @@ rtm_type_name(int type)
}
static void
-process_routing_update(void *handle, struct connection *conn, const char *prog,
- int selflags)
+do_network_reconfig(verto_ctx *ctx, verto_ev *ev)
+{
+ struct connection *conn = verto_get_private(ev);
+ assert(loop_setup_network(ctx, conn->handle, conn->prog) == 0);
+}
+
+static int
+routing_update_needed(struct rt_msghdr *rtm) {
+ switch (rtm->rtm_type) {
+ case RTM_ADD:
+ case RTM_DELETE:
+ case RTM_NEWADDR:
+ case RTM_DELADDR:
+ case RTM_IFINFO:
+ case RTM_OLDADD:
+ case RTM_OLDDEL:
+ /*
+ * Some flags indicate routing table updates that don't
+ * indicate local address changes. They may come from
+ * redirects, or ARP, etc.
+ *
+ * This set of symbols is just an initial guess based on
+ * some messages observed in real life; working out which
+ * other flags also indicate messages we should ignore,
+ * and which flags are portable to all system and thus
+ * don't need to be conditionalized, is left as a future
+ * exercise.
+ */
+#ifdef RTF_DYNAMIC
+ if (rtm->rtm_flags & RTF_DYNAMIC)
+ break;
+#endif
+#ifdef RTF_CLONED
+ if (rtm->rtm_flags & RTF_CLONED)
+ break;
+#endif
+#ifdef RTF_LLINFO
+ if (rtm->rtm_flags & RTF_LLINFO)
+ break;
+#endif
+#if 0
+ krb5_klog_syslog(LOG_DEBUG,
+ "network reconfiguration message (%s) received",
+ rtm_type_name(rtm->rtm_type));
+#endif
+ return 1;
+ case RTM_RESOLVE:
+#ifdef RTM_NEWMADDR
+ case RTM_NEWMADDR:
+ case RTM_DELMADDR:
+#endif
+ case RTM_MISS:
+ case RTM_REDIRECT:
+ case RTM_LOSING:
+ case RTM_GET:
+ /* Not interesting. */
+#if 0
+ krb5_klog_syslog(LOG_DEBUG, "routing msg not interesting");
+#endif
+ break;
+ default:
+ krb5_klog_syslog(LOG_INFO,
+ _("unhandled routing message type %d, "
+ "will reconfigure just for the fun of it"),
+ rtm->rtm_type);
+ return 1;
+ }
+
+ return 0;
+}
+
+static void
+process_routing_update(verto_ctx *ctx, verto_ev *ev)
{
- int n_read;
+ int n_read, fd;
struct rt_msghdr rtm;
+ struct connection *conn;
- while ((n_read = read(conn->fd, &rtm, sizeof(rtm))) > 0) {
+ fd = verto_get_fd(ev);
+ conn = verto_get_private(ev);
+ while ((n_read = read(fd, &rtm, sizeof(rtm))) > 0) {
if (n_read < sizeof(rtm)) {
/* Quick hack to figure out if the interesting
fields are present in a short read.
@@ -1007,73 +1181,31 @@ process_routing_update(void *handle, struct connection *conn, const char *prog,
_("read %d from routing socket but msglen is %d"),
n_read, rtm.rtm_msglen);
}
- switch (rtm.rtm_type) {
- case RTM_ADD:
- case RTM_DELETE:
- case RTM_NEWADDR:
- case RTM_DELADDR:
- case RTM_IFINFO:
- case RTM_OLDADD:
- case RTM_OLDDEL:
- /*
- * Some flags indicate routing table updates that don't
- * indicate local address changes. They may come from
- * redirects, or ARP, etc.
- *
- * This set of symbols is just an initial guess based on
- * some messages observed in real life; working out which
- * other flags also indicate messages we should ignore,
- * and which flags are portable to all system and thus
- * don't need to be conditionalized, is left as a future
- * exercise.
- */
-#ifdef RTF_DYNAMIC
- if (rtm.rtm_flags & RTF_DYNAMIC)
- break;
-#endif
-#ifdef RTF_CLONED
- if (rtm.rtm_flags & RTF_CLONED)
- break;
-#endif
-#ifdef RTF_LLINFO
- if (rtm.rtm_flags & RTF_LLINFO)
- break;
-#endif
-#if 0
- krb5_klog_syslog(LOG_DEBUG,
- "network reconfiguration message (%s) received",
- rtm_type_name(rtm.rtm_type));
-#endif
- network_reconfiguration_needed = 1;
- break;
- case RTM_RESOLVE:
-#ifdef RTM_NEWMADDR
- case RTM_NEWMADDR:
- case RTM_DELMADDR:
-#endif
- case RTM_MISS:
- case RTM_REDIRECT:
- case RTM_LOSING:
- case RTM_GET:
- /* Not interesting. */
-#if 0
- krb5_klog_syslog(LOG_DEBUG, "routing msg not interesting");
-#endif
- break;
- default:
- krb5_klog_syslog(LOG_INFO,
- _("unhandled routing message type %d, "
- "will reconfigure just for the fun of it"),
- rtm.rtm_type);
- network_reconfiguration_needed = 1;
- break;
+
+ if (routing_update_needed(&rtm)) {
+ /* Ideally we would use idle here instead of timeout. However, idle
+ * is not universally supported yet in all backends. So let's just
+ * use timeout for now to avoid locking into a loop. */
+ ev = verto_add_timeout(ctx, VERTO_EV_FLAG_NONE,
+ do_network_reconfig, 0);
+ verto_set_private(ev, conn, NULL);
+ assert(ev);
}
}
}
+#endif
-static void
-setup_routing_socket(struct socksetup *data)
+krb5_error_code
+loop_setup_routing_socket(verto_ctx *ctx, void *handle, const char *progname)
{
+#ifdef HAVE_STRUCT_RT_MSGHDR
+ struct socksetup data;
+
+ data.ctx = ctx;
+ data.handle = handle;
+ data.prog = progname;
+ data.retval = 0;
+
int sock = socket(PF_ROUTE, SOCK_RAW, 0);
if (sock < 0) {
int e = errno;
@@ -1081,37 +1213,38 @@ setup_routing_socket(struct socksetup *data)
strerror(e));
} else {
krb5_klog_syslog(LOG_INFO, _("routing socket is fd %d"), sock);
- add_fd(data, sock, CONN_ROUTING, process_routing_update);
setnbio(sock);
- FD_SET(sock, &sstate.rfds);
+ add_fd(&data, sock, CONN_ROUTING,
+ VERTO_EV_FLAG_IO_READ | VERTO_EV_FLAG_PERSIST,
+ process_routing_update, 0);
}
-}
#endif
+ return 0;
+}
/* XXX */
-extern int krb5int_debug_sendto_kdc;
extern void (*krb5int_sendtokdc_debug_handler)(const void*, size_t);
krb5_error_code
-loop_setup_network(void *handle, const char *prog, int no_reconfig)
+loop_setup_network(verto_ctx *ctx, void *handle, const char *prog)
{
struct socksetup setup_data;
+ verto_ev *ev;
+ int i;
- FD_ZERO(&sstate.rfds);
- FD_ZERO(&sstate.wfds);
- FD_ZERO(&sstate.xfds);
- sstate.max = 0;
-
- /* krb5int_debug_sendto_kdc = 1; */
krb5int_sendtokdc_debug_handler = klog_handler;
+ /* Close any open connections. */
+ FOREACH_ELT(events, i, ev)
+ verto_del(ev);
+ events.n = 0;
+
+ setup_data.ctx = ctx;
+ setup_data.handle = handle;
setup_data.prog = prog;
setup_data.retval = 0;
krb5_klog_syslog(LOG_INFO, _("setting up network..."));
-#ifdef HAVE_STRUCT_RT_MSGHDR
- if (!no_reconfig)
- setup_routing_socket(&setup_data);
-#endif
+
/*
* To do: Use RFC 2292 interface (or follow-on) and IPV6_PKTINFO,
* so we might need only one UDP socket; fall back to binding
@@ -1127,8 +1260,8 @@ loop_setup_network(void *handle, const char *prog, int no_reconfig)
}
setup_tcp_listener_ports(&setup_data);
setup_rpc_listener_ports(&setup_data);
- krb5_klog_syslog (LOG_INFO, _("set up %d sockets"), (int)n_sockets);
- if (n_sockets == 0) {
+ krb5_klog_syslog (LOG_INFO, _("set up %d sockets"), (int) events.n);
+ if (events.n == 0) {
com_err(prog, 0, _("no sockets set up?"));
exit (1);
}
@@ -1359,8 +1492,7 @@ send_to_from(int s, void *buf, size_t len, int flags,
}
static void
-process_packet(void *handle, struct connection *conn, const char *prog,
- int selflags)
+process_packet(verto_ctx *ctx, verto_ev *ev)
{
int cc;
socklen_t saddr_len, daddr_len;
@@ -1371,8 +1503,13 @@ process_packet(void *handle, struct connection *conn, const char *prog,
krb5_data request;
krb5_data *response;
char pktbuf[MAX_DGRAM_SIZE];
- int port_fd = conn->fd;
+ int port_fd;
union aux_addressing_info auxaddr;
+ struct connection *conn;
+
+ port_fd = verto_get_fd(ev);
+ conn = verto_get_private(ev);
+ assert(port_fd >= 0);
response = NULL;
saddr_len = sizeof(saddr);
@@ -1391,7 +1528,7 @@ process_packet(void *handle, struct connection *conn, const char *prog,
*/
&& errno != ECONNREFUSED
)
- com_err(prog, errno, _("while receiving from network"));
+ com_err(conn->prog, errno, _("while receiving from network"));
return;
}
if (!cc)
@@ -1403,7 +1540,7 @@ process_packet(void *handle, struct connection *conn, const char *prog,
if (getnameinfo(ss2sa(&daddr), daddr_len, addrbuf, sizeof(addrbuf),
0, 0, NI_NUMERICHOST))
strlcpy(addrbuf, "?", sizeof(addrbuf));
- com_err(prog, 0, "pktinfo says local addr is %s", addrbuf);
+ com_err(conn->prog, 0, _("pktinfo says local addr is %s"), addrbuf);
}
#endif
@@ -1424,9 +1561,9 @@ process_packet(void *handle, struct connection *conn, const char *prog,
faddr.address = &addr;
init_addr(&faddr, ss2sa(&saddr));
/* This address is in net order. */
- retval = dispatch(handle, ss2sa(&daddr), &faddr, &request, &response, 0);
+ retval = dispatch(conn->handle, ss2sa(&daddr), &faddr, &request, &response, 0);
if (retval) {
- com_err(prog, retval, _("while dispatching (udp)"));
+ com_err(conn->prog, retval, _("while dispatching (udp)"));
return;
}
if (response == NULL)
@@ -1441,7 +1578,7 @@ process_packet(void *handle, struct connection *conn, const char *prog,
char saddrbuf[NI_MAXHOST], sportbuf[NI_MAXSERV];
char daddrbuf[NI_MAXHOST];
int e = errno;
- krb5_free_data(get_context(handle), response);
+ krb5_free_data(get_context(conn->handle), response);
if (getnameinfo((struct sockaddr *)&daddr, daddr_len,
daddrbuf, sizeof(daddrbuf), 0, 0,
NI_NUMERICHOST) != 0) {
@@ -1453,69 +1590,70 @@ process_packet(void *handle, struct connection *conn, const char *prog,
strlcpy(saddrbuf, "?", sizeof(saddrbuf));
strlcpy(sportbuf, "?", sizeof(sportbuf));
}
- com_err(prog, e, _("while sending reply to %s/%s from %s"),
+ com_err(conn->prog, e, _("while sending reply to %s/%s from %s"),
saddrbuf, sportbuf, daddrbuf);
return;
}
if ((size_t)cc != response->length) {
- com_err(prog, 0, _("short reply write %d vs %d\n"),
+ com_err(conn->prog, 0, _("short reply write %d vs %d\n"),
response->length, cc);
}
- krb5_free_data(get_context(handle), response);
+ krb5_free_data(get_context(conn->handle), response);
return;
}
-static int tcp_or_rpc_data_counter;
-static int max_tcp_or_rpc_data_connections = 45;
-
-static void kill_tcp_or_rpc_connection(void *, struct connection *,
- int isForcedClose);
-
static int
-kill_lru_tcp_or_rpc_connection(void *handle, struct connection *newconn)
+kill_lru_tcp_or_rpc_connection(void *handle, verto_ev *newev)
{
- struct connection *oldest_tcp = NULL;
- struct connection *c;
+ struct connection *c, *oldest_c = NULL;
+ verto_ev *ev, *oldest_ev = NULL;
int i, fd = -1;
krb5_klog_syslog(LOG_INFO, _("too many connections"));
- FOREACH_ELT (connections, i, c) {
- if (c->type != CONN_TCP && c->type != CONN_RPC)
+ FOREACH_ELT (events, i, ev) {
+ if (ev == newev)
continue;
- if (c == newconn)
+
+ c = verto_get_private(ev);
+ if (!c)
+ continue;
+ if (c->type != CONN_TCP && c->type != CONN_RPC)
continue;
#if 0
- krb5_klog_syslog(LOG_INFO, "fd %d started at %ld", c->fd,
+ krb5_klog_syslog(LOG_INFO, "fd %d started at %ld",
+ verto_get_fd(oldest_ev),
c->u.tcp.start_time);
#endif
- if (oldest_tcp == NULL
- || oldest_tcp->u.tcp.start_time > c->u.tcp.start_time)
- oldest_tcp = c;
+ if (oldest_c == NULL
+ || oldest_c->u.tcp.start_time > c->u.tcp.start_time) {
+ oldest_ev = ev;
+ oldest_c = c;
+ }
}
- if (oldest_tcp != NULL) {
+ if (oldest_c != NULL) {
krb5_klog_syslog(LOG_INFO, _("dropping %s fd %d from %s"),
c->type == CONN_RPC ? "rpc" : "tcp",
- oldest_tcp->fd, oldest_tcp->u.tcp.addrbuf);
- fd = oldest_tcp->fd;
- kill_tcp_or_rpc_connection(handle, oldest_tcp, 1);
+ verto_get_fd(oldest_ev), oldest_c->u.tcp.addrbuf);
+ verto_del(oldest_ev);
}
return fd;
}
static void
-accept_tcp_connection(void *handle, struct connection *conn, const char *prog,
- int selflags)
+accept_tcp_connection(verto_ctx *ctx, verto_ev *ev)
{
int s;
struct sockaddr_storage addr_s;
struct sockaddr *addr = (struct sockaddr *)&addr_s;
socklen_t addrlen = sizeof(addr_s);
struct socksetup sockdata;
- struct connection *newconn;
+ struct connection *newconn, *conn;
char tmpbuf[10];
+ verto_ev *newev;
- s = accept(conn->fd, addr, &addrlen);
+ conn = verto_get_private(ev);
+ s = accept(verto_get_fd(ev), addr, &addrlen);
if (s < 0)
return;
set_cloexec_fd(s);
@@ -1527,12 +1665,17 @@ accept_tcp_connection(void *handle, struct connection *conn, const char *prog,
#endif
setnbio(s), setnolinger(s), setkeepalive(s);
- sockdata.prog = prog;
+ sockdata.ctx = ctx;
+ sockdata.handle = conn->handle;
+ sockdata.prog = conn->prog;
sockdata.retval = 0;
- newconn = add_tcp_data_fd(&sockdata, s);
- if (newconn == NULL)
+ newev = add_tcp_read_fd(&sockdata, s);
+ newconn = verto_get_private(ev);
+ if (newev == NULL) {
+ verto_del(ev);
return;
+ }
if (getnameinfo((struct sockaddr *)&addr_s, addrlen,
newconn->u.tcp.addrbuf, sizeof(newconn->u.tcp.addrbuf),
@@ -1561,15 +1704,13 @@ accept_tcp_connection(void *handle, struct connection *conn, const char *prog,
newconn->u.tcp.start_time = time(0);
if (++tcp_or_rpc_data_counter > max_tcp_or_rpc_data_connections)
- kill_lru_tcp_or_rpc_connection(handle, newconn);
+ kill_lru_tcp_or_rpc_connection(conn->handle, newev);
if (newconn->u.tcp.buffer == 0) {
- com_err(prog, errno,
+ com_err(conn->prog, errno,
_("allocating buffer for new TCP session from %s"),
newconn->u.tcp.addrbuf);
- delete_fd(newconn);
- close(s);
- tcp_or_rpc_data_counter--;
+ verto_del(newev);
return;
}
newconn->u.tcp.offset = 0;
@@ -1577,92 +1718,126 @@ accept_tcp_connection(void *handle, struct connection *conn, const char *prog,
init_addr(&newconn->u.tcp.faddr, ss2sa(&newconn->u.tcp.addr_s));
SG_SET(&newconn->u.tcp.sgbuf[0], newconn->u.tcp.lenbuf, 4);
SG_SET(&newconn->u.tcp.sgbuf[1], 0, 0);
-
- FD_SET(s, &sstate.rfds);
- if (sstate.max <= s)
- sstate.max = s + 1;
}
static void
-kill_tcp_or_rpc_connection(void *handle, struct connection *conn,
- int isForcedClose)
+process_tcp_connection_read(verto_ctx *ctx, verto_ev *ev)
{
- assert(conn->type == CONN_TCP || conn->type == CONN_RPC);
- assert(conn->fd != -1);
-
- if (conn->u.tcp.response)
- krb5_free_data(get_context(handle), conn->u.tcp.response);
- if (conn->u.tcp.buffer)
- free(conn->u.tcp.buffer);
- FD_CLR(conn->fd, &sstate.rfds);
- FD_CLR(conn->fd, &sstate.wfds);
- if (sstate.max == conn->fd + 1)
- while (sstate.max > 0
- && ! FD_ISSET(sstate.max-1, &sstate.rfds)
- && ! FD_ISSET(sstate.max-1, &sstate.wfds)
- /* && ! FD_ISSET(sstate.max-1, &sstate.xfds) */
- )
- sstate.max--;
-
- /* In the non-forced case, the RPC runtime will close the descriptor for
- * us. */
- if (conn->type == CONN_TCP || isForcedClose) {
- close(conn->fd);
- }
-
- /* For RPC connections, call into RPC runtime to flush out any internal
- * state. */
- if (conn->type == CONN_RPC && isForcedClose) {
- fd_set fds;
-
- FD_ZERO(&fds);
- FD_SET(conn->fd, &fds);
+ struct connection *conn;
+ ssize_t nread;
+ size_t len;
+ int sock;
- svc_getreqset(&fds);
+ conn = verto_get_private(ev);
+ sock = verto_get_fd(ev);
- if (FD_ISSET(conn->fd, &svc_fdset)) {
- krb5_klog_syslog(LOG_ERR,
- _("descriptor %d closed but still in svc_fdset"),
- conn->fd);
+ /*
+ * Read message length and data into one big buffer, already allocated
+ * at connect time. If we have a complete message, we stop reading, so
+ * we should only be here if there is no data in the buffer, or only an
+ * incomplete message.
+ */
+ if (conn->u.tcp.offset < 4) {
+ /* msglen has not been computed. XXX Doing at least two reads
+ * here, letting the kernel worry about buffering. */
+ len = 4 - conn->u.tcp.offset;
+ nread = SOCKET_READ(sock,
+ conn->u.tcp.buffer + conn->u.tcp.offset, len);
+ if (nread < 0) /* error */
+ goto kill_tcp_connection;
+ if (nread == 0) /* eof */
+ goto kill_tcp_connection;
+ conn->u.tcp.offset += nread;
+ if (conn->u.tcp.offset == 4) {
+ unsigned char *p = (unsigned char *)conn->u.tcp.buffer;
+ conn->u.tcp.msglen = load_32_be(p);
+ if (conn->u.tcp.msglen > conn->u.tcp.bufsiz - 4) {
+ krb5_error_code err;
+ /* Message too big. */
+ krb5_klog_syslog(LOG_ERR, _("TCP client %s wants %lu bytes, "
+ "cap is %lu"), conn->u.tcp.addrbuf,
+ (unsigned long) conn->u.tcp.msglen,
+ (unsigned long) conn->u.tcp.bufsiz - 4);
+ /* XXX Should return an error. */
+ err = make_toolong_error (conn->handle,
+ &conn->u.tcp.response);
+ if (err) {
+ krb5_klog_syslog(LOG_ERR, _("error constructing "
+ "KRB_ERR_FIELD_TOOLONG error! %s"),
+ error_message(err));
+ goto kill_tcp_connection;
+ }
+ goto have_response;
+ }
}
+ } else {
+ /* msglen known. */
+ krb5_data request;
+ krb5_error_code err;
+ struct sockaddr_storage local_saddr;
+ socklen_t local_saddrlen = sizeof(local_saddr);
+ struct sockaddr *local_saddrp = NULL;
+
+ len = conn->u.tcp.msglen - (conn->u.tcp.offset - 4);
+ nread = SOCKET_READ(sock,
+ conn->u.tcp.buffer + conn->u.tcp.offset, len);
+ if (nread < 0) /* error */
+ goto kill_tcp_connection;
+ if (nread == 0) /* eof */
+ goto kill_tcp_connection;
+ conn->u.tcp.offset += nread;
+ if (conn->u.tcp.offset < conn->u.tcp.msglen + 4)
+ return;
+ /* Have a complete message, and exactly one message. */
+ request.length = conn->u.tcp.msglen;
+ request.data = conn->u.tcp.buffer + 4;
+
+ if (getsockname(sock, ss2sa(&local_saddr),
+ &local_saddrlen) == 0)
+ local_saddrp = ss2sa(&local_saddr);
+
+ err = dispatch(conn->handle, local_saddrp, &conn->u.tcp.faddr,
+ &request, &conn->u.tcp.response, 1);
+ if (err) {
+ com_err(conn->prog, err, _("while dispatching (tcp)"));
+ goto kill_tcp_connection;
+ }
+ if (conn->u.tcp.response == NULL)
+ goto kill_tcp_connection;
+ have_response:
+ /* Queue outgoing response. */
+ store_32_be(conn->u.tcp.response->length, conn->u.tcp.lenbuf);
+ SG_SET(&conn->u.tcp.sgbuf[1], conn->u.tcp.response->data,
+ conn->u.tcp.response->length);
+ conn->u.tcp.sgp = conn->u.tcp.sgbuf;
+ conn->u.tcp.sgnum = 2;
+
+ if (convert_event(ctx, ev,
+ VERTO_EV_FLAG_IO_WRITE | VERTO_EV_FLAG_PERSIST,
+ process_tcp_connection_write))
+ return;
}
- conn->fd = -1;
- delete_fd(conn);
- tcp_or_rpc_data_counter--;
-}
+ return;
-static void
-queue_tcp_outgoing_response(struct connection *conn)
-{
- store_32_be(conn->u.tcp.response->length, conn->u.tcp.lenbuf);
- SG_SET(&conn->u.tcp.sgbuf[1], conn->u.tcp.response->data,
- conn->u.tcp.response->length);
- conn->u.tcp.sgp = conn->u.tcp.sgbuf;
- conn->u.tcp.sgnum = 2;
- FD_SET(conn->fd, &sstate.wfds);
+kill_tcp_connection:
+ verto_del(ev);
}
static void
-process_tcp_connection(void *handle, struct connection *conn, const char *prog,
- int selflags)
+process_tcp_connection_write(verto_ctx *ctx, verto_ev *ev)
{
- int isForcedClose = 1; /* not used now, but for completeness */
+ struct connection *conn;
+ SOCKET_WRITEV_TEMP tmp;
+ ssize_t nwrote;
+ int sock;
- if (selflags & SSF_WRITE) {
- ssize_t nwrote;
- SOCKET_WRITEV_TEMP tmp;
+ conn = verto_get_private(ev);
+ sock = verto_get_fd(ev);
- nwrote = SOCKET_WRITEV(conn->fd, conn->u.tcp.sgp, conn->u.tcp.sgnum,
- tmp);
- if (nwrote < 0) {
- goto kill_tcp_connection;
- }
- if (nwrote == 0) {
- /* eof */
- isForcedClose = 0;
- goto kill_tcp_connection;
- }
+ nwrote = SOCKET_WRITEV(sock, conn->u.tcp.sgp,
+ conn->u.tcp.sgnum, tmp);
+ if (nwrote > 0) { /* non-error and non-eof */
while (nwrote) {
sg_buf *sgp = conn->u.tcp.sgp;
if ((size_t)nwrote < SG_LEN(sgp)) {
@@ -1676,354 +1851,133 @@ process_tcp_connection(void *handle, struct connection *conn, const char *prog,
abort();
}
}
- if (conn->u.tcp.sgnum == 0) {
- /*
- * Finished sending. We should go back to reading, though if we
- * sent a FIELD_TOOLONG error in reply to a length with the high
- * bit set, RFC 4120 says we have to close the TCP stream.
- */
- isForcedClose = 0;
- goto kill_tcp_connection;
- }
- } else if (selflags & SSF_READ) {
- /*
- * Read message length and data into one big buffer, already allocated
- * at connect time. If we have a complete message, we stop reading, so
- * we should only be here if there is no data in the buffer, or only an
- * incomplete message.
- */
- size_t len;
- ssize_t nread;
- if (conn->u.tcp.offset < 4) {
- /* msglen has not been computed. XXX Doing at least two reads
- * here, letting the kernel worry about buffering. */
- len = 4 - conn->u.tcp.offset;
- nread = SOCKET_READ(conn->fd,
- conn->u.tcp.buffer + conn->u.tcp.offset, len);
- if (nread < 0)
- /* error */
- goto kill_tcp_connection;
- if (nread == 0)
- /* eof */
- goto kill_tcp_connection;
- conn->u.tcp.offset += nread;
- if (conn->u.tcp.offset == 4) {
- unsigned char *p = (unsigned char *)conn->u.tcp.buffer;
- conn->u.tcp.msglen = load_32_be(p);
- if (conn->u.tcp.msglen > conn->u.tcp.bufsiz - 4) {
- krb5_error_code err;
- /* Message too big. */
- krb5_klog_syslog(LOG_ERR,
- _("TCP client %s wants %lu bytes, "
- "cap is %lu"), conn->u.tcp.addrbuf,
- (unsigned long) conn->u.tcp.msglen,
- (unsigned long) conn->u.tcp.bufsiz - 4);
- /* XXX Should return an error. */
- err = make_toolong_error (handle, &conn->u.tcp.response);
- if (err) {
- krb5_klog_syslog(LOG_ERR,
- _("error constructing "
- "KRB_ERR_FIELD_TOOLONG error! %s"),
- error_message(err));
- goto kill_tcp_connection;
- }
- goto have_response;
- }
- }
- } else {
- /* msglen known. */
- krb5_data request;
- krb5_error_code err;
- struct sockaddr_storage local_saddr;
- socklen_t local_saddrlen = sizeof(local_saddr);
- struct sockaddr *local_saddrp = NULL;
-
- len = conn->u.tcp.msglen - (conn->u.tcp.offset - 4);
- nread = SOCKET_READ(conn->fd,
- conn->u.tcp.buffer + conn->u.tcp.offset, len);
- if (nread < 0) /* error */
- goto kill_tcp_connection;
- if (nread == 0) /* eof */
- goto kill_tcp_connection;
- conn->u.tcp.offset += nread;
- if (conn->u.tcp.offset < conn->u.tcp.msglen + 4)
- return;
- /* Have a complete message, and exactly one message. */
- request.length = conn->u.tcp.msglen;
- request.data = conn->u.tcp.buffer + 4;
-
- if (getsockname(conn->fd, ss2sa(&local_saddr),
- &local_saddrlen) == 0)
- local_saddrp = ss2sa(&local_saddr);
-
- err = dispatch(handle, local_saddrp, &conn->u.tcp.faddr,
- &request, &conn->u.tcp.response, 1);
- if (err) {
- com_err(prog, err, _("while dispatching (tcp)"));
- goto kill_tcp_connection;
- }
- if (conn->u.tcp.response == NULL)
- goto kill_tcp_connection;
- have_response:
- queue_tcp_outgoing_response(conn);
- FD_CLR(conn->fd, &sstate.rfds);
- }
- } else
- abort();
- return;
+ /* If we still have more data to send, just return so that
+ * the main loop can call this function again when the socket
+ * is ready for more writing. */
+ if (conn->u.tcp.sgnum > 0)
+ return;
+ }
-kill_tcp_connection:
- kill_tcp_or_rpc_connection(handle, conn, isForcedClose);
+ /* Finished sending. We should go back to reading, though if we
+ * sent a FIELD_TOOLONG error in reply to a length with the high
+ * bit set, RFC 4120 says we have to close the TCP stream. */
+ verto_del(ev);
}
-static void
-service_conn(void *handle, struct connection *conn, const char *prog,
- int selflags)
+void
+loop_free(verto_ctx *ctx)
{
- conn->service(handle, conn, prog, selflags);
+ verto_free(ctx);
+ FREE_SET_DATA(events);
+ FREE_SET_DATA(udp_port_data);
+ FREE_SET_DATA(tcp_port_data);
+ FREE_SET_DATA(rpc_svc_data);
}
static int
-getcurtime(struct timeval *tvp)
-{
-#ifdef _WIN32
- struct _timeb tb;
- _ftime(&tb);
- tvp->tv_sec = tb.time;
- tvp->tv_usec = tb.millitm * 1000;
- return 0;
-#else
- return gettimeofday(tvp, 0) ? errno : 0;
-#endif
-}
-
-krb5_error_code
-loop_listen_and_process(void *handle, const char *prog, void (*reset)(void))
-{
- int nfound;
- /* This struct contains 3 fd_set objects; on some platforms, they
- can be rather large. Making this static avoids putting all
- that junk on the stack. */
- static struct select_state sout;
- size_t i;
- int sret, netchanged = 0;
- krb5_error_code err;
-
- if (conns == (struct connection **) NULL)
- return KDC5_NONET;
-
- while (!signal_requests_exit) {
- if (signal_requests_reset) {
- krb5_klog_reopen(get_context(handle));
- reset();
- signal_requests_reset = 0;
- }
-
- if (network_reconfiguration_needed) {
- /* No point in re-logging what we've just logged. */
- if (netchanged == 0) {
- krb5_klog_syslog(LOG_INFO,
- _("network reconfiguration needed"));
- }
- /* It might be tidier to add a timer-callback interface to the
- * control loop, but for this one use, it's not a big deal. */
- err = getcurtime(&sstate.end_time);
- if (err) {
- com_err(prog, err, _("while getting the time"));
- continue;
- }
- sstate.end_time.tv_sec += 3;
- netchanged = 1;
- } else
- sstate.end_time.tv_sec = sstate.end_time.tv_usec = 0;
-
- err = krb5int_cm_call_select(&sstate, &sout, &sret);
- if (err) {
- if (err != EINTR)
- com_err(prog, err, _("while selecting for network input(1)"));
- continue;
- }
- if (sret == 0 && netchanged) {
- network_reconfiguration_needed = 0;
- loop_closedown_network_sockets();
- err = loop_setup_network(handle, prog, 0);
- if (err) {
- com_err(prog, err, _("while reinitializing network"));
- return err;
- }
- netchanged = 0;
- }
- if (sret == -1) {
- if (errno != EINTR) {
- com_err(prog, errno,
- _("while selecting for network input(2)"));
- }
- continue;
- }
- nfound = sret;
- for (i=0; i<n_sockets && nfound > 0; i++) {
- int sflags = 0;
- if (conns[i]->fd < 0)
- abort();
- if (FD_ISSET(conns[i]->fd, &sout.rfds))
- sflags |= SSF_READ, nfound--;
- if (FD_ISSET(conns[i]->fd, &sout.wfds))
- sflags |= SSF_WRITE, nfound--;
- if (sflags)
- service_conn(handle, conns[i], prog, sflags);
- }
- }
- krb5_klog_syslog(LOG_INFO, _("shutdown signal received"));
- return 0;
-}
-
-static void
-loop_closedown_network_sockets()
+have_event_for_fd(int fd)
{
+ verto_ev *ev;
int i;
- struct connection *conn;
-
- if (conns == (struct connection **) NULL)
- return;
-
- FOREACH_ELT (connections, i, conn) {
- if (conn->fd >= 0) {
- krb5_klog_syslog(LOG_INFO, _("closing down fd %d"), conn->fd);
- (void) close(conn->fd);
- if (conn->type == CONN_RPC) {
- fd_set fds;
-
- FD_ZERO(&fds);
- FD_SET(conn->fd, &fds);
- svc_getreqset(&fds);
- }
- }
- if (conn->type == CONN_RPC_LISTENER) {
- if (conn->u.rpc.transp != NULL)
- svc_destroy(conn->u.rpc.transp);
- }
- DEL (connections, i);
- /*
- * There may also be per-connection data in the tcp structure
- * (tcp.buffer, tcp.response) that we're not freeing here. That should
- * only happen if we quit with a connection in progress.
- */
- free(conn);
+ FOREACH_ELT(events, i, ev) {
+ if (verto_get_fd(ev) == fd)
+ return 1;
}
-}
-void
-loop_closedown_network()
-{
- loop_closedown_network_sockets();
- FREE_SET_DATA(connections);
- FREE_SET_DATA(udp_port_data);
- FREE_SET_DATA(tcp_port_data);
- FREE_SET_DATA(rpc_svc_data);
+ return 0;
}
static void
-accept_rpc_connection(void *handle, struct connection *conn, const char *prog,
- int selflags)
+accept_rpc_connection(verto_ctx *ctx, verto_ev *ev)
{
struct socksetup sockdata;
+ struct connection *conn;
fd_set fds;
register int s;
- assert(selflags & SSF_READ);
+ conn = verto_get_private(ev);
- if ((selflags & SSF_READ) == 0)
- return;
-
- sockdata.prog = prog;
+ sockdata.ctx = ctx;
+ sockdata.handle = conn->handle;
+ sockdata.prog = conn->prog;
sockdata.retval = 0;
/* Service the woken RPC listener descriptor. */
FD_ZERO(&fds);
- FD_SET(conn->fd, &fds);
-
+ FD_SET(verto_get_fd(ev), &fds);
svc_getreqset(&fds);
/* Scan svc_fdset for any new connections. */
for (s = 0; s < FD_SETSIZE; s++) {
- /* sstate.rfds |= svc_fdset & ~(rpc_listenfds | sstate.rfds) */
- if (FD_ISSET(s, &svc_fdset) && !FD_ISSET(s, &rpc_listenfds)
- && !FD_ISSET(s, &sstate.rfds)) {
- struct connection *newconn;
- struct sockaddr_storage addr_s;
- struct sockaddr *addr = (struct sockaddr *)&addr_s;
- socklen_t addrlen = sizeof(addr_s);
- char tmpbuf[10];
+ struct sockaddr_storage addr_s;
+ struct sockaddr *addr = (struct sockaddr *) &addr_s;
+ socklen_t addrlen = sizeof(addr_s);
+ struct connection *newconn;
+ char tmpbuf[10];
+ verto_ev *newev;
+
+ /* If we already have this fd, continue. */
+ if (!FD_ISSET(s, &svc_fdset) || have_event_for_fd(s))
+ continue;
- newconn = add_rpc_data_fd(&sockdata, s);
- if (newconn == NULL)
- continue;
+ newev = add_rpc_data_fd(&sockdata, s);
+ newconn = verto_get_private(newev);
+ if (newev == NULL)
+ continue;
- set_cloexec_fd(s);
+ set_cloexec_fd(s);
#if 0
- setnbio(s), setnolinger(s), setkeepalive(s);
+ setnbio(s), setnolinger(s), setkeepalive(s);
#endif
- if (getpeername(s, addr, &addrlen) ||
- getnameinfo(addr, addrlen,
- newconn->u.tcp.addrbuf,
- sizeof(newconn->u.tcp.addrbuf),
- tmpbuf, sizeof(tmpbuf),
- NI_NUMERICHOST | NI_NUMERICSERV)) {
- strlcpy(newconn->u.tcp.addrbuf, "???",
- sizeof(newconn->u.tcp.addrbuf));
- } else {
- char *p, *end;
- p = newconn->u.tcp.addrbuf;
- end = p + sizeof(newconn->u.tcp.addrbuf);
- p += strlen(p);
- if ((size_t)(end - p) > 2 + strlen(tmpbuf)) {
- *p++ = '.';
- strlcpy(p, tmpbuf, end - p);
- }
+ if (getpeername(s, addr, &addrlen) ||
+ getnameinfo(addr, addrlen,
+ newconn->u.tcp.addrbuf,
+ sizeof(newconn->u.tcp.addrbuf),
+ tmpbuf, sizeof(tmpbuf),
+ NI_NUMERICHOST | NI_NUMERICSERV)) {
+ strlcpy(newconn->u.tcp.addrbuf, "???",
+ sizeof(newconn->u.tcp.addrbuf));
+ } else {
+ char *p, *end;
+ p = newconn->u.tcp.addrbuf;
+ end = p + sizeof(newconn->u.tcp.addrbuf);
+ p += strlen(p);
+ if ((size_t)(end - p) > 2 + strlen(tmpbuf)) {
+ *p++ = '.';
+ strlcpy(p, tmpbuf, end - p);
}
+ }
#if 0
- krb5_klog_syslog(LOG_INFO, "accepted RPC connection on socket %d "
- "from %s", s, newconn->u.tcp.addrbuf);
+ krb5_klog_syslog(LOG_INFO, _("accepted RPC connection on socket %d "
+ "from %s"), s, newconn->u.tcp.addrbuf);
#endif
- newconn->u.tcp.addr_s = addr_s;
- newconn->u.tcp.addrlen = addrlen;
- newconn->u.tcp.start_time = time(0);
+ newconn->u.tcp.addr_s = addr_s;
+ newconn->u.tcp.addrlen = addrlen;
+ newconn->u.tcp.start_time = time(0);
- if (++tcp_or_rpc_data_counter > max_tcp_or_rpc_data_connections)
- kill_lru_tcp_or_rpc_connection(handle, newconn);
+ if (++tcp_or_rpc_data_counter > max_tcp_or_rpc_data_connections)
+ kill_lru_tcp_or_rpc_connection(newconn->handle, newev);
- newconn->u.tcp.faddr.address = &newconn->u.tcp.kaddr;
- init_addr(&newconn->u.tcp.faddr, ss2sa(&newconn->u.tcp.addr_s));
-
- FD_SET(s, &sstate.rfds);
- if (sstate.max <= s)
- sstate.max = s + 1;
- }
+ newconn->u.tcp.faddr.address = &newconn->u.tcp.kaddr;
+ init_addr(&newconn->u.tcp.faddr, ss2sa(&newconn->u.tcp.addr_s));
}
}
static void
-process_rpc_connection(void *handle, struct connection *conn, const char *prog,
- int selflags)
+process_rpc_connection(verto_ctx *ctx, verto_ev *ev)
{
fd_set fds;
- assert(selflags & SSF_READ);
-
- if ((selflags & SSF_READ) == 0)
- return;
-
FD_ZERO(&fds);
- FD_SET(conn->fd, &fds);
-
+ FD_SET(verto_get_fd(ev), &fds);
svc_getreqset(&fds);
- if (!FD_ISSET(conn->fd, &svc_fdset))
- kill_tcp_or_rpc_connection(handle, conn, 0);
+ if (!FD_ISSET(verto_get_fd(ev), &svc_fdset))
+ verto_del(ev);
}
#endif /* INET */
--
1.7.6
--=-91aXUtl386fllPtBh1mm
Content-Type: text/plain; charset="us-ascii"
MIME-Version: 1.0
Content-Transfer-Encoding: 7bit
Content-Disposition: inline
_______________________________________________
krbdev mailing list krbdev@mit.edu
https://mailman.mit.edu/mailman/listinfo/krbdev
--=-91aXUtl386fllPtBh1mm--