[17130] in Kerberos_V5_Development
Re: [RFC][PATCH] krb5 => libverto main loop
daemon@ATHENA.MIT.EDU (Nathaniel McCallum)
Thu Sep 1 14:14:28 2011
From: Nathaniel McCallum <npmccallum@redhat.com>
To: Greg Hudson <ghudson@mit.edu>
Date: Thu, 01 Sep 2011 12:15:04 -0400
In-Reply-To: <1314259795.24488.53.camel@t410>
Content-Type: multipart/mixed; boundary="=-NouTxnhJxLZrjs+dlxmQ"
Message-ID: <1314893708.7344.4.camel@localhost>
Mime-Version: 1.0
Cc: "krbdev@mit.edu" <krbdev@mit.edu>
Errors-To: krbdev-bounces@mit.edu
--=-NouTxnhJxLZrjs+dlxmQ
Content-Type: text/plain; charset="UTF-8"
Content-Transfer-Encoding: 7bit
Take #3 (only patch #5 changed). All issues have been addressed in all
emails except as noted below. All tests currently pass up to gss-client
(which fails on current master).
On Thu, 2011-08-25 at 04:09 -0400, Greg Hudson wrote:
> In my review of the patches so far:
>
> * I don't understand patch 4. In the KDC (in patch 5) you set up a
> SIGHUP handler to preserve the behavior that a SIGHUP reopens the
> logfile, but in kadmind you appear to have eliminated this behavior,
> which seems wrong.
The SIGHUP handler in kadmind currently does nothing. I removed it so
that it doesn't need to be ported.
The SIGHUP handler in the KDC was merely ported to libverto.
--=-NouTxnhJxLZrjs+dlxmQ
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 0779c1978cd0f99780b2293e56ebe33925f0ecdc 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
Signed-off-by: Nathaniel McCallum <npmccallum@redhat.com>
---
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.1
--=-NouTxnhJxLZrjs+dlxmQ
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 80c57c2c0da258e779704debc92bc081ce767f65 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
Signed-off-by: Nathaniel McCallum <npmccallum@redhat.com>
---
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.1
--=-NouTxnhJxLZrjs+dlxmQ
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 11b97574e6b7a8c4bd83a78f93f9982bddd76b17 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)
Signed-off-by: Nathaniel McCallum <npmccallum@redhat.com>
---
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.1
--=-NouTxnhJxLZrjs+dlxmQ
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 1fb2a573af60a5076b3e5798e72aea0f416b063c 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
Signed-off-by: Nathaniel McCallum <npmccallum@redhat.com>
---
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.1
--=-NouTxnhJxLZrjs+dlxmQ
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 40909795621f965e6a0d770c38ab75cadbb7958f Mon Sep 17 00:00:00 2001
From: Nathaniel McCallum <npmccallum@redhat.com>
Date: Thu, 1 Sep 2011 12:07:42 -0400
Subject: [PATCH 5/5] migrate net-server loop to use libverto
Signed-off-by: Nathaniel McCallum <npmccallum@redhat.com>
---
src/include/net-server.h | 18 +-
src/kadmin/server/Makefile.in | 2 +-
src/kadmin/server/ovsec_kadmd.c | 121 ++---
src/kdc/Makefile.in | 2 +-
src/kdc/main.c | 121 +++--
src/lib/apputils/net-server.c | 1139 +++++++++++++++++++--------------------
6 files changed, 678 insertions(+), 725 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..85742ef 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,14 @@ int main(int argc, char *argv[])
: 0)
#endif
#undef server_handle
- || (ret = loop_setup_network(global_server_handle, whoami, 0))) {
+ || (ret = loop_setup_routing_socket(ctx, global_server_handle, whoami))
+ || (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 +402,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 +437,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 +449,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 +472,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 +482,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 +494,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 +506,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 +519,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 +545,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 +567,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 +583,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 +619,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 +669,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..dc88fdd 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,8 @@ 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 volatile int signal_received = 0;
+static volatile int sighup_received = 0;
#define KRB5_KDC_MAX_REALMS 32
@@ -485,10 +480,17 @@ whoops:
return(kret);
}
+static void
+request_hup(verto_ctx *ctx, verto_ev *ev)
+{
+ krb5_klog_reopen(kdc_context);
+ reset_for_hangup();
+}
+
static krb5_sigtype
-request_exit(int signo)
+on_monitor_signal(int signo)
{
- signal_requests_exit = 1;
+ signal_received = signo;
#ifdef POSIX_SIGTYPE
return;
@@ -498,9 +500,9 @@ request_exit(int signo)
}
static krb5_sigtype
-request_hup(int signo)
+on_monitor_sighup(int signo)
{
- signal_requests_reset = 1;
+ sighup_received = 1;
#ifdef POSIX_SIGTYPE
return;
@@ -509,29 +511,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
* are set to -1, and wait for them to exit (so that we know the ports are no
@@ -564,10 +543,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 +573,29 @@ 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);
+ s_action.sa_handler = on_monitor_sighup;
+ (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_sighup);
+#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 +614,17 @@ create_workers(int num)
}
/* Propagate HUP signal to worker processes if we received one. */
- if (signal_requests_reset) {
+ if (sighup_received == SIGHUP) {
+ sighup_received = 0;
for (i = 0; i < num; i++) {
if (pids[i] != -1)
kill(pids[i], SIGHUP);
}
- signal_requests_reset = 0;
}
}
- if (signal_requests_exit) {
- krb5_klog_syslog(LOG_INFO,
- _("shutdown signal received in supervisor"));
- }
+ if (signal_received)
+ krb5_klog_syslog(LOG_INFO, _("signal %d received in supervisor"),
+ signal_received);
terminate_workers(pids, num, numleft);
free(pids);
@@ -948,6 +949,7 @@ int main(int argc, char **argv)
{
krb5_error_code retval;
krb5_context kcontext;
+ verto_ctx *ctx;
int errout = 0;
int i;
@@ -989,7 +991,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 +1052,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 +1081,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 +1092,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..87c3bfa 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 {
@@ -215,6 +216,7 @@ struct connection {
} tcp;
struct {
SVCXPRT *transp;
+ int closed;
} rpc;
} u;
};
@@ -250,33 +252,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 +364,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 +373,133 @@ 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);
+
+ fd = verto_get_fd(ev);
+ conn = verto_get_private(ev);
+
+ /* Close the file descriptor. */
+ krb5_klog_syslog(LOG_INFO, _("closing down fd %d"), fd);
+ if (fd >= 0 && (!conn || conn->type != CONN_RPC || conn->u.rpc.closed))
+ close(fd);
+
+ /* Free the connection struct. */
+ if (conn) {
+ switch (conn->type) {
+ case CONN_RPC:
+ if (conn->u.rpc.closed) {
+ 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 +516,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 +614,25 @@ 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 | VERTO_EV_FLAG_PERSIST,
+ 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 +641,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 +763,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 +773,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 +824,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 +838,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 +900,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 +940,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 +1047,6 @@ scan_for_newlines:
}
#endif
-static int network_reconfiguration_needed = 0;
-
#ifdef HAVE_STRUCT_RT_MSGHDR
#include <net/route.h>
@@ -969,13 +1075,88 @@ 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)
{
- int n_read;
+ 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, 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 +1188,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 +1220,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 +1267,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 +1499,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 +1510,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 +1535,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 +1547,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 +1568,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 +1585,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 +1597,72 @@ 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);
+ if (oldest_c->type == CONN_RPC)
+ oldest_c->u.rpc.closed = 1;
+ 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 +1674,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);
+ if (newev == NULL) {
+ close(s);
return;
+ }
+ newconn = verto_get_private(newev);
if (getnameinfo((struct sockaddr *)&addr_s, addrlen,
newconn->u.tcp.addrbuf, sizeof(newconn->u.tcp.addrbuf),
@@ -1561,15 +1713,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 +1727,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 +1860,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);
+ if (newev == NULL)
+ continue;
+ newconn = verto_get_private(newev);
- 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.1
--=-NouTxnhJxLZrjs+dlxmQ
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
--=-NouTxnhJxLZrjs+dlxmQ--