|
|
4be148 |
From 606e2ccc0a2546a23761f910482a55c5bf0f98ac Mon Sep 17 00:00:00 2001
|
|
|
4be148 |
From: "Robbie Harwood (frozencemetery)" <rharwood@club.cc.cmu.edu>
|
|
|
4be148 |
Date: Fri, 16 Aug 2013 14:48:55 -0400
|
|
|
4be148 |
Subject: [PATCH 06/13] Dispatch-style protocol switching for transport
|
|
|
4be148 |
|
|
|
4be148 |
Switch to using per-transport-type functions when a socket that we're
|
|
|
4be148 |
using to communicate with a server becomes readable or writable, and add
|
|
|
4be148 |
them as pointers to the connection state. The functions are passed the
|
|
|
4be148 |
name of the realm of the server being contacted, as we expect to need
|
|
|
4be148 |
this in the near future.
|
|
|
4be148 |
|
|
|
4be148 |
[nalin@redhat.com: replace macros with typedefs]
|
|
|
4be148 |
[nalin@redhat.com: compare transports with TCP_OR_UDP rather than with 0]
|
|
|
4be148 |
|
|
|
4be148 |
ticket: 7929
|
|
|
4be148 |
---
|
|
|
4be148 |
src/lib/krb5/os/changepw.c | 6 +-
|
|
|
4be148 |
src/lib/krb5/os/os-proto.h | 1 +
|
|
|
4be148 |
src/lib/krb5/os/sendto_kdc.c | 297 ++++++++++++++++++++++++-------------------
|
|
|
4be148 |
3 files changed, 171 insertions(+), 133 deletions(-)
|
|
|
4be148 |
|
|
|
4be148 |
diff --git a/src/lib/krb5/os/changepw.c b/src/lib/krb5/os/changepw.c
|
|
|
4be148 |
index a1c9885..0ee427d 100644
|
|
|
4be148 |
--- a/src/lib/krb5/os/changepw.c
|
|
|
4be148 |
+++ b/src/lib/krb5/os/changepw.c
|
|
|
4be148 |
@@ -261,9 +261,9 @@ change_set_password(krb5_context context,
|
|
|
4be148 |
callback_info.pfn_cleanup = kpasswd_sendto_msg_cleanup;
|
|
|
4be148 |
krb5_free_data_contents(callback_ctx.context, &chpw_rep);
|
|
|
4be148 |
|
|
|
4be148 |
- code = k5_sendto(callback_ctx.context, NULL, &sl, strategy,
|
|
|
4be148 |
- &callback_info, &chpw_rep, ss2sa(&remote_addr),
|
|
|
4be148 |
- &addrlen, NULL, NULL, NULL);
|
|
|
4be148 |
+ code = k5_sendto(callback_ctx.context, NULL, &creds->server->realm,
|
|
|
4be148 |
+ &sl, strategy, &callback_info, &chpw_rep,
|
|
|
4be148 |
+ ss2sa(&remote_addr), &addrlen, NULL, NULL, NULL);
|
|
|
4be148 |
if (code) {
|
|
|
4be148 |
/*
|
|
|
4be148 |
* Here we may want to switch to TCP on some errors.
|
|
|
4be148 |
diff --git a/src/lib/krb5/os/os-proto.h b/src/lib/krb5/os/os-proto.h
|
|
|
4be148 |
index f23dda5..e60ccd0 100644
|
|
|
4be148 |
--- a/src/lib/krb5/os/os-proto.h
|
|
|
4be148 |
+++ b/src/lib/krb5/os/os-proto.h
|
|
|
4be148 |
@@ -115,6 +115,7 @@ int _krb5_use_dns_kdc (krb5_context);
|
|
|
4be148 |
int _krb5_conf_boolean (const char *);
|
|
|
4be148 |
|
|
|
4be148 |
krb5_error_code k5_sendto(krb5_context context, const krb5_data *message,
|
|
|
4be148 |
+ const krb5_data *realm,
|
|
|
4be148 |
const struct serverlist *addrs,
|
|
|
4be148 |
k5_transport_strategy strategy,
|
|
|
4be148 |
struct sendto_callback_info *callback_info,
|
|
|
4be148 |
diff --git a/src/lib/krb5/os/sendto_kdc.c b/src/lib/krb5/os/sendto_kdc.c
|
|
|
4be148 |
index c6aae8e..28f1c4d 100644
|
|
|
4be148 |
--- a/src/lib/krb5/os/sendto_kdc.c
|
|
|
4be148 |
+++ b/src/lib/krb5/os/sendto_kdc.c
|
|
|
4be148 |
@@ -96,11 +96,18 @@ struct outgoing_message {
|
|
|
4be148 |
unsigned char msg_len_buf[4];
|
|
|
4be148 |
};
|
|
|
4be148 |
|
|
|
4be148 |
+struct conn_state;
|
|
|
4be148 |
+typedef krb5_boolean fd_handler_fn(krb5_context context,
|
|
|
4be148 |
+ const krb5_data *realm,
|
|
|
4be148 |
+ struct conn_state *conn,
|
|
|
4be148 |
+ struct select_state *selstate);
|
|
|
4be148 |
+
|
|
|
4be148 |
struct conn_state {
|
|
|
4be148 |
SOCKET fd;
|
|
|
4be148 |
enum conn_states state;
|
|
|
4be148 |
- int (*service)(krb5_context context, struct conn_state *,
|
|
|
4be148 |
- struct select_state *, int);
|
|
|
4be148 |
+ fd_handler_fn *service_connect;
|
|
|
4be148 |
+ fd_handler_fn *service_write;
|
|
|
4be148 |
+ fd_handler_fn *service_read;
|
|
|
4be148 |
struct remote_address addr;
|
|
|
4be148 |
struct incoming_message in;
|
|
|
4be148 |
struct outgoing_message out;
|
|
|
4be148 |
@@ -409,9 +416,9 @@ krb5_sendto_kdc(krb5_context context, const krb5_data *message,
|
|
|
4be148 |
return retval;
|
|
|
4be148 |
|
|
|
4be148 |
err = 0;
|
|
|
4be148 |
- retval = k5_sendto(context, message, &servers, strategy, NULL, reply,
|
|
|
4be148 |
- NULL, NULL, &server_used, check_for_svc_unavailable,
|
|
|
4be148 |
- &err;;
|
|
|
4be148 |
+ retval = k5_sendto(context, message, realm, &servers, strategy, NULL,
|
|
|
4be148 |
+ reply, NULL, NULL, &server_used,
|
|
|
4be148 |
+ check_for_svc_unavailable, &err;;
|
|
|
4be148 |
if (retval == KRB5_KDC_UNREACH) {
|
|
|
4be148 |
if (err == KDC_ERR_SVC_UNAVAILABLE) {
|
|
|
4be148 |
retval = KRB5KDC_ERR_SVC_UNAVAILABLE;
|
|
|
4be148 |
@@ -457,10 +464,10 @@ cleanup:
|
|
|
4be148 |
* connections already in progress
|
|
|
4be148 |
*/
|
|
|
4be148 |
|
|
|
4be148 |
-static int service_tcp_fd(krb5_context context, struct conn_state *conn,
|
|
|
4be148 |
- struct select_state *selstate, int ssflags);
|
|
|
4be148 |
-static int service_udp_fd(krb5_context context, struct conn_state *conn,
|
|
|
4be148 |
- struct select_state *selstate, int ssflags);
|
|
|
4be148 |
+static fd_handler_fn service_tcp_connect;
|
|
|
4be148 |
+static fd_handler_fn service_tcp_write;
|
|
|
4be148 |
+static fd_handler_fn service_tcp_read;
|
|
|
4be148 |
+static fd_handler_fn service_udp_read;
|
|
|
4be148 |
|
|
|
4be148 |
/* Set up the actual message we will send across the underlying transport to
|
|
|
4be148 |
* communicate the payload message, using one or both of state->out.sgbuf. */
|
|
|
4be148 |
@@ -505,9 +512,13 @@ add_connection(struct conn_state **conns, k5_transport transport,
|
|
|
4be148 |
state->server_index = server_index;
|
|
|
4be148 |
SG_SET(&state->out.sgbuf[1], NULL, 0);
|
|
|
4be148 |
if (transport == TCP) {
|
|
|
4be148 |
- state->service = service_tcp_fd;
|
|
|
4be148 |
+ state->service_connect = service_tcp_connect;
|
|
|
4be148 |
+ state->service_write = service_tcp_write;
|
|
|
4be148 |
+ state->service_read = service_tcp_read;
|
|
|
4be148 |
} else {
|
|
|
4be148 |
- state->service = service_udp_fd;
|
|
|
4be148 |
+ state->service_connect = NULL;
|
|
|
4be148 |
+ state->service_write = NULL;
|
|
|
4be148 |
+ state->service_read = service_udp_read;
|
|
|
4be148 |
|
|
|
4be148 |
if (*udpbufp == NULL) {
|
|
|
4be148 |
*udpbufp = malloc(MAX_DGRAM_SIZE);
|
|
|
4be148 |
@@ -788,9 +799,13 @@ maybe_send(krb5_context context, struct conn_state *conn,
|
|
|
4be148 |
}
|
|
|
4be148 |
|
|
|
4be148 |
static void
|
|
|
4be148 |
-kill_conn(struct conn_state *conn, struct select_state *selstate)
|
|
|
4be148 |
+kill_conn(krb5_context context, struct conn_state *conn,
|
|
|
4be148 |
+ struct select_state *selstate)
|
|
|
4be148 |
{
|
|
|
4be148 |
+ if (socktype_for_transport(conn->addr.transport) == SOCK_STREAM)
|
|
|
4be148 |
+ TRACE_SENDTO_KDC_TCP_DISCONNECT(context, &conn->addr);
|
|
|
4be148 |
cm_remove_fd(selstate, conn->fd);
|
|
|
4be148 |
+
|
|
|
4be148 |
closesocket(conn->fd);
|
|
|
4be148 |
conn->fd = INVALID_SOCKET;
|
|
|
4be148 |
conn->state = FAILED;
|
|
|
4be148 |
@@ -814,136 +829,157 @@ get_so_error(int fd)
|
|
|
4be148 |
return sockerr;
|
|
|
4be148 |
}
|
|
|
4be148 |
|
|
|
4be148 |
-/* Process events on a TCP socket. Return 1 if we get a complete reply. */
|
|
|
4be148 |
-static int
|
|
|
4be148 |
-service_tcp_fd(krb5_context context, struct conn_state *conn,
|
|
|
4be148 |
- struct select_state *selstate, int ssflags)
|
|
|
4be148 |
+/* Perform next step in sending. Return true on usable data. */
|
|
|
4be148 |
+static krb5_boolean
|
|
|
4be148 |
+service_dispatch(krb5_context context, const krb5_data *realm,
|
|
|
4be148 |
+ struct conn_state *conn, struct select_state *selstate,
|
|
|
4be148 |
+ int ssflags)
|
|
|
4be148 |
{
|
|
|
4be148 |
- int e = 0;
|
|
|
4be148 |
- ssize_t nwritten, nread;
|
|
|
4be148 |
- SOCKET_WRITEV_TEMP tmp;
|
|
|
4be148 |
- struct incoming_message *in = &conn->in;
|
|
|
4be148 |
- struct outgoing_message *out = &conn->out;
|
|
|
4be148 |
-
|
|
|
4be148 |
/* Check for a socket exception. */
|
|
|
4be148 |
- if (ssflags & SSF_EXCEPTION)
|
|
|
4be148 |
- goto kill_conn;
|
|
|
4be148 |
+ if (ssflags & SSF_EXCEPTION) {
|
|
|
4be148 |
+ kill_conn(context, conn, selstate);
|
|
|
4be148 |
+ return FALSE;
|
|
|
4be148 |
+ }
|
|
|
4be148 |
|
|
|
4be148 |
switch (conn->state) {
|
|
|
4be148 |
case CONNECTING:
|
|
|
4be148 |
- /* Check whether the connection succeeded. */
|
|
|
4be148 |
- e = get_so_error(conn->fd);
|
|
|
4be148 |
- if (e) {
|
|
|
4be148 |
- TRACE_SENDTO_KDC_TCP_ERROR_CONNECT(context, &conn->addr, e);
|
|
|
4be148 |
- goto kill_conn;
|
|
|
4be148 |
- }
|
|
|
4be148 |
- conn->state = WRITING;
|
|
|
4be148 |
+ assert(conn->service_connect != NULL);
|
|
|
4be148 |
+ return conn->service_connect(context, realm, conn, selstate);
|
|
|
4be148 |
+ case WRITING:
|
|
|
4be148 |
+ assert(conn->service_write != NULL);
|
|
|
4be148 |
+ return conn->service_write(context, realm, conn, selstate);
|
|
|
4be148 |
+ case READING:
|
|
|
4be148 |
+ assert(conn->service_read != NULL);
|
|
|
4be148 |
+ return conn->service_read(context, realm, conn, selstate);
|
|
|
4be148 |
+ default:
|
|
|
4be148 |
+ abort();
|
|
|
4be148 |
+ }
|
|
|
4be148 |
+}
|
|
|
4be148 |
|
|
|
4be148 |
- /* Record this connection's timeout for service_fds. */
|
|
|
4be148 |
- if (get_curtime_ms(&conn->endtime) == 0)
|
|
|
4be148 |
- conn->endtime += 10000;
|
|
|
4be148 |
+/* Initialize TCP transport. */
|
|
|
4be148 |
+static krb5_boolean
|
|
|
4be148 |
+service_tcp_connect(krb5_context context, const krb5_data *realm,
|
|
|
4be148 |
+ struct conn_state *conn, struct select_state *selstate)
|
|
|
4be148 |
+{
|
|
|
4be148 |
+ /* Check whether the connection succeeded. */
|
|
|
4be148 |
+ int e = get_so_error(conn->fd);
|
|
|
4be148 |
|
|
|
4be148 |
- /* Fall through. */
|
|
|
4be148 |
- case WRITING:
|
|
|
4be148 |
- TRACE_SENDTO_KDC_TCP_SEND(context, &conn->addr);
|
|
|
4be148 |
- nwritten = SOCKET_WRITEV(conn->fd, out->sgp, out->sg_count, tmp);
|
|
|
4be148 |
- if (nwritten < 0) {
|
|
|
4be148 |
- TRACE_SENDTO_KDC_TCP_ERROR_SEND(context, &conn->addr,
|
|
|
4be148 |
- SOCKET_ERRNO);
|
|
|
4be148 |
- goto kill_conn;
|
|
|
4be148 |
+ if (e) {
|
|
|
4be148 |
+ TRACE_SENDTO_KDC_TCP_ERROR_CONNECT(context, &conn->addr, e);
|
|
|
4be148 |
+ kill_conn(context, conn, selstate);
|
|
|
4be148 |
+ return FALSE;
|
|
|
4be148 |
+ }
|
|
|
4be148 |
+
|
|
|
4be148 |
+ conn->state = WRITING;
|
|
|
4be148 |
+
|
|
|
4be148 |
+ /* Record this connection's timeout for service_fds. */
|
|
|
4be148 |
+ if (get_curtime_ms(&conn->endtime) == 0)
|
|
|
4be148 |
+ conn->endtime += 10000;
|
|
|
4be148 |
+
|
|
|
4be148 |
+ return service_tcp_write(context, realm, conn, selstate);
|
|
|
4be148 |
+}
|
|
|
4be148 |
+
|
|
|
4be148 |
+/* Sets conn->state to READING when done. */
|
|
|
4be148 |
+static krb5_boolean
|
|
|
4be148 |
+service_tcp_write(krb5_context context, const krb5_data *realm,
|
|
|
4be148 |
+ struct conn_state *conn, struct select_state *selstate)
|
|
|
4be148 |
+{
|
|
|
4be148 |
+ ssize_t nwritten;
|
|
|
4be148 |
+ SOCKET_WRITEV_TEMP tmp;
|
|
|
4be148 |
+
|
|
|
4be148 |
+ TRACE_SENDTO_KDC_TCP_SEND(context, &conn->addr);
|
|
|
4be148 |
+ nwritten = SOCKET_WRITEV(conn->fd, conn->out.sgp, conn->out.sg_count, tmp);
|
|
|
4be148 |
+ if (nwritten < 0) {
|
|
|
4be148 |
+ TRACE_SENDTO_KDC_TCP_ERROR_SEND(context, &conn->addr, SOCKET_ERRNO);
|
|
|
4be148 |
+ kill_conn(context, conn, selstate);
|
|
|
4be148 |
+ return FALSE;
|
|
|
4be148 |
+ }
|
|
|
4be148 |
+ while (nwritten) {
|
|
|
4be148 |
+ sg_buf *sgp = conn->out.sgp;
|
|
|
4be148 |
+ if ((size_t)nwritten < SG_LEN(sgp)) {
|
|
|
4be148 |
+ SG_ADVANCE(sgp, (size_t)nwritten);
|
|
|
4be148 |
+ nwritten = 0;
|
|
|
4be148 |
+ } else {
|
|
|
4be148 |
+ nwritten -= SG_LEN(sgp);
|
|
|
4be148 |
+ conn->out.sgp++;
|
|
|
4be148 |
+ conn->out.sg_count--;
|
|
|
4be148 |
}
|
|
|
4be148 |
- while (nwritten) {
|
|
|
4be148 |
- sg_buf *sgp = out->sgp;
|
|
|
4be148 |
- if ((size_t) nwritten < SG_LEN(sgp)) {
|
|
|
4be148 |
- SG_ADVANCE(sgp, (size_t) nwritten);
|
|
|
4be148 |
- nwritten = 0;
|
|
|
4be148 |
- } else {
|
|
|
4be148 |
- nwritten -= SG_LEN(sgp);
|
|
|
4be148 |
- out->sgp++;
|
|
|
4be148 |
- out->sg_count--;
|
|
|
4be148 |
- }
|
|
|
4be148 |
+ }
|
|
|
4be148 |
+ if (conn->out.sg_count == 0) {
|
|
|
4be148 |
+ /* Done writing, switch to reading. */
|
|
|
4be148 |
+ cm_read(selstate, conn->fd);
|
|
|
4be148 |
+ conn->state = READING;
|
|
|
4be148 |
+ }
|
|
|
4be148 |
+ return FALSE;
|
|
|
4be148 |
+}
|
|
|
4be148 |
+
|
|
|
4be148 |
+/* Return true on usable data. */
|
|
|
4be148 |
+static krb5_boolean
|
|
|
4be148 |
+service_tcp_read(krb5_context context, const krb5_data *realm,
|
|
|
4be148 |
+ struct conn_state *conn, struct select_state *selstate)
|
|
|
4be148 |
+{
|
|
|
4be148 |
+ ssize_t nread;
|
|
|
4be148 |
+ int e = 0;
|
|
|
4be148 |
+ struct incoming_message *in = &conn->in;
|
|
|
4be148 |
+
|
|
|
4be148 |
+ if (in->bufsizebytes_read == 4) {
|
|
|
4be148 |
+ /* Reading data. */
|
|
|
4be148 |
+ nread = SOCKET_READ(conn->fd, &in->buf[in->pos], in->n_left);
|
|
|
4be148 |
+ if (nread <= 0) {
|
|
|
4be148 |
+ e = nread ? SOCKET_ERRNO : ECONNRESET;
|
|
|
4be148 |
+ TRACE_SENDTO_KDC_TCP_ERROR_RECV(context, &conn->addr, e);
|
|
|
4be148 |
+ kill_conn(context, conn, selstate);
|
|
|
4be148 |
+ return FALSE;
|
|
|
4be148 |
}
|
|
|
4be148 |
- if (out->sg_count == 0) {
|
|
|
4be148 |
- /* Done writing, switch to reading. */
|
|
|
4be148 |
- cm_read(selstate, conn->fd);
|
|
|
4be148 |
- conn->state = READING;
|
|
|
4be148 |
- in->bufsizebytes_read = 0;
|
|
|
4be148 |
- in->bufsize = 0;
|
|
|
4be148 |
- in->pos = 0;
|
|
|
4be148 |
- in->buf = NULL;
|
|
|
4be148 |
- in->n_left = 0;
|
|
|
4be148 |
+ in->n_left -= nread;
|
|
|
4be148 |
+ in->pos += nread;
|
|
|
4be148 |
+ if (in->n_left <= 0)
|
|
|
4be148 |
+ return TRUE;
|
|
|
4be148 |
+ } else {
|
|
|
4be148 |
+ /* Reading length. */
|
|
|
4be148 |
+ nread = SOCKET_READ(conn->fd, in->bufsizebytes + in->bufsizebytes_read,
|
|
|
4be148 |
+ 4 - in->bufsizebytes_read);
|
|
|
4be148 |
+ if (nread <= 0) {
|
|
|
4be148 |
+ e = nread ? SOCKET_ERRNO : ECONNRESET;
|
|
|
4be148 |
+ TRACE_SENDTO_KDC_TCP_ERROR_RECV_LEN(context, &conn->addr, e);
|
|
|
4be148 |
+ kill_conn(context, conn, selstate);
|
|
|
4be148 |
+ return FALSE;
|
|
|
4be148 |
}
|
|
|
4be148 |
- return 0;
|
|
|
4be148 |
-
|
|
|
4be148 |
- case READING:
|
|
|
4be148 |
+ in->bufsizebytes_read += nread;
|
|
|
4be148 |
if (in->bufsizebytes_read == 4) {
|
|
|
4be148 |
- /* Reading data. */
|
|
|
4be148 |
- nread = SOCKET_READ(conn->fd, &in->buf[in->pos], in->n_left);
|
|
|
4be148 |
- if (nread <= 0) {
|
|
|
4be148 |
- e = nread ? SOCKET_ERRNO : ECONNRESET;
|
|
|
4be148 |
- TRACE_SENDTO_KDC_TCP_ERROR_RECV(context, &conn->addr, e);
|
|
|
4be148 |
- goto kill_conn;
|
|
|
4be148 |
- }
|
|
|
4be148 |
- in->n_left -= nread;
|
|
|
4be148 |
- in->pos += nread;
|
|
|
4be148 |
- if (in->n_left <= 0)
|
|
|
4be148 |
- return 1;
|
|
|
4be148 |
- } else {
|
|
|
4be148 |
- /* Reading length. */
|
|
|
4be148 |
- nread = SOCKET_READ(conn->fd,
|
|
|
4be148 |
- in->bufsizebytes + in->bufsizebytes_read,
|
|
|
4be148 |
- 4 - in->bufsizebytes_read);
|
|
|
4be148 |
- if (nread <= 0) {
|
|
|
4be148 |
- e = nread ? SOCKET_ERRNO : ECONNRESET;
|
|
|
4be148 |
- TRACE_SENDTO_KDC_TCP_ERROR_RECV_LEN(context, &conn->addr, e);
|
|
|
4be148 |
- goto kill_conn;
|
|
|
4be148 |
+ unsigned long len = load_32_be(in->bufsizebytes);
|
|
|
4be148 |
+ /* Arbitrary 1M cap. */
|
|
|
4be148 |
+ if (len > 1 * 1024 * 1024) {
|
|
|
4be148 |
+ kill_conn(context, conn, selstate);
|
|
|
4be148 |
+ return FALSE;
|
|
|
4be148 |
}
|
|
|
4be148 |
- in->bufsizebytes_read += nread;
|
|
|
4be148 |
- if (in->bufsizebytes_read == 4) {
|
|
|
4be148 |
- unsigned long len = load_32_be(in->bufsizebytes);
|
|
|
4be148 |
- /* Arbitrary 1M cap. */
|
|
|
4be148 |
- if (len > 1 * 1024 * 1024)
|
|
|
4be148 |
- goto kill_conn;
|
|
|
4be148 |
- in->bufsize = in->n_left = len;
|
|
|
4be148 |
- in->pos = 0;
|
|
|
4be148 |
- in->buf = malloc(len);
|
|
|
4be148 |
- if (in->buf == NULL)
|
|
|
4be148 |
- goto kill_conn;
|
|
|
4be148 |
+ in->bufsize = in->n_left = len;
|
|
|
4be148 |
+ in->pos = 0;
|
|
|
4be148 |
+ in->buf = malloc(len);
|
|
|
4be148 |
+ if (in->buf == NULL) {
|
|
|
4be148 |
+ kill_conn(context, conn, selstate);
|
|
|
4be148 |
+ return FALSE;
|
|
|
4be148 |
}
|
|
|
4be148 |
}
|
|
|
4be148 |
- break;
|
|
|
4be148 |
-
|
|
|
4be148 |
- default:
|
|
|
4be148 |
- abort();
|
|
|
4be148 |
}
|
|
|
4be148 |
- return 0;
|
|
|
4be148 |
-
|
|
|
4be148 |
-kill_conn:
|
|
|
4be148 |
- TRACE_SENDTO_KDC_TCP_DISCONNECT(context, &conn->addr);
|
|
|
4be148 |
- kill_conn(conn, selstate);
|
|
|
4be148 |
- return 0;
|
|
|
4be148 |
+ return FALSE;
|
|
|
4be148 |
}
|
|
|
4be148 |
|
|
|
4be148 |
-/* Process events on a UDP socket. Return 1 if we get a reply. */
|
|
|
4be148 |
-static int
|
|
|
4be148 |
-service_udp_fd(krb5_context context, struct conn_state *conn,
|
|
|
4be148 |
- struct select_state *selstate, int ssflags)
|
|
|
4be148 |
+/* Process events on a UDP socket. Return true if we get a reply. */
|
|
|
4be148 |
+static krb5_boolean
|
|
|
4be148 |
+service_udp_read(krb5_context context, const krb5_data *realm,
|
|
|
4be148 |
+ struct conn_state *conn, struct select_state *selstate)
|
|
|
4be148 |
{
|
|
|
4be148 |
int nread;
|
|
|
4be148 |
|
|
|
4be148 |
- if (!(ssflags & (SSF_READ|SSF_EXCEPTION)))
|
|
|
4be148 |
- abort();
|
|
|
4be148 |
- if (conn->state != READING)
|
|
|
4be148 |
- abort();
|
|
|
4be148 |
-
|
|
|
4be148 |
nread = recv(conn->fd, conn->in.buf, conn->in.bufsize, 0);
|
|
|
4be148 |
if (nread < 0) {
|
|
|
4be148 |
TRACE_SENDTO_KDC_UDP_ERROR_RECV(context, &conn->addr, SOCKET_ERRNO);
|
|
|
4be148 |
- kill_conn(conn, selstate);
|
|
|
4be148 |
- return 0;
|
|
|
4be148 |
+ kill_conn(context, conn, selstate);
|
|
|
4be148 |
+ return FALSE;
|
|
|
4be148 |
}
|
|
|
4be148 |
conn->in.pos = nread;
|
|
|
4be148 |
- return 1;
|
|
|
4be148 |
+ return TRUE;
|
|
|
4be148 |
}
|
|
|
4be148 |
|
|
|
4be148 |
/* Return the maximum of endtime and the endtime fields of all currently active
|
|
|
4be148 |
@@ -965,7 +1001,7 @@ get_endtime(time_ms endtime, struct conn_state *conns)
|
|
|
4be148 |
static krb5_boolean
|
|
|
4be148 |
service_fds(krb5_context context, struct select_state *selstate,
|
|
|
4be148 |
time_ms interval, struct conn_state *conns,
|
|
|
4be148 |
- struct select_state *seltemp,
|
|
|
4be148 |
+ struct select_state *seltemp, const krb5_data *realm,
|
|
|
4be148 |
int (*msg_handler)(krb5_context, const krb5_data *, void *),
|
|
|
4be148 |
void *msg_handler_data, struct conn_state **winner_out)
|
|
|
4be148 |
{
|
|
|
4be148 |
@@ -977,7 +1013,7 @@ service_fds(krb5_context context, struct select_state *selstate,
|
|
|
4be148 |
|
|
|
4be148 |
e = get_curtime_ms(&endtime);
|
|
|
4be148 |
if (e)
|
|
|
4be148 |
- return 1;
|
|
|
4be148 |
+ return TRUE;
|
|
|
4be148 |
endtime += interval;
|
|
|
4be148 |
|
|
|
4be148 |
e = 0;
|
|
|
4be148 |
@@ -991,7 +1027,7 @@ service_fds(krb5_context context, struct select_state *selstate,
|
|
|
4be148 |
|
|
|
4be148 |
if (selret == 0)
|
|
|
4be148 |
/* Timeout, return to caller. */
|
|
|
4be148 |
- return 0;
|
|
|
4be148 |
+ return FALSE;
|
|
|
4be148 |
|
|
|
4be148 |
/* Got something on a socket, process it. */
|
|
|
4be148 |
for (state = conns; state != NULL; state = state->next) {
|
|
|
4be148 |
@@ -1003,7 +1039,7 @@ service_fds(krb5_context context, struct select_state *selstate,
|
|
|
4be148 |
if (!ssflags)
|
|
|
4be148 |
continue;
|
|
|
4be148 |
|
|
|
4be148 |
- if (state->service(context, state, selstate, ssflags)) {
|
|
|
4be148 |
+ if (service_dispatch(context, realm, state, selstate, ssflags)) {
|
|
|
4be148 |
int stop = 1;
|
|
|
4be148 |
|
|
|
4be148 |
if (msg_handler != NULL) {
|
|
|
4be148 |
@@ -1014,14 +1050,14 @@ service_fds(krb5_context context, struct select_state *selstate,
|
|
|
4be148 |
|
|
|
4be148 |
if (stop) {
|
|
|
4be148 |
*winner_out = state;
|
|
|
4be148 |
- return 1;
|
|
|
4be148 |
+ return TRUE;
|
|
|
4be148 |
}
|
|
|
4be148 |
}
|
|
|
4be148 |
}
|
|
|
4be148 |
}
|
|
|
4be148 |
if (e != 0)
|
|
|
4be148 |
- return 1;
|
|
|
4be148 |
- return 0;
|
|
|
4be148 |
+ return TRUE;
|
|
|
4be148 |
+ return FALSE;
|
|
|
4be148 |
}
|
|
|
4be148 |
|
|
|
4be148 |
/*
|
|
|
4be148 |
@@ -1052,7 +1088,8 @@ service_fds(krb5_context context, struct select_state *selstate,
|
|
|
4be148 |
|
|
|
4be148 |
krb5_error_code
|
|
|
4be148 |
k5_sendto(krb5_context context, const krb5_data *message,
|
|
|
4be148 |
- const struct serverlist *servers, k5_transport_strategy strategy,
|
|
|
4be148 |
+ const krb5_data *realm, const struct serverlist *servers,
|
|
|
4be148 |
+ k5_transport_strategy strategy,
|
|
|
4be148 |
struct sendto_callback_info* callback_info, krb5_data *reply,
|
|
|
4be148 |
struct sockaddr *remoteaddr, socklen_t *remoteaddrlen,
|
|
|
4be148 |
int *server_used,
|
|
|
4be148 |
@@ -1098,7 +1135,7 @@ k5_sendto(krb5_context context, const krb5_data *message,
|
|
|
4be148 |
if (maybe_send(context, state, message, sel_state, callback_info))
|
|
|
4be148 |
continue;
|
|
|
4be148 |
done = service_fds(context, sel_state, 1000, conns, seltemp,
|
|
|
4be148 |
- msg_handler, msg_handler_data, &winner);
|
|
|
4be148 |
+ realm, msg_handler, msg_handler_data, &winner);
|
|
|
4be148 |
}
|
|
|
4be148 |
}
|
|
|
4be148 |
|
|
|
4be148 |
@@ -1110,13 +1147,13 @@ k5_sendto(krb5_context context, const krb5_data *message,
|
|
|
4be148 |
if (maybe_send(context, state, message, sel_state, callback_info))
|
|
|
4be148 |
continue;
|
|
|
4be148 |
done = service_fds(context, sel_state, 1000, conns, seltemp,
|
|
|
4be148 |
- msg_handler, msg_handler_data, &winner);
|
|
|
4be148 |
+ realm, msg_handler, msg_handler_data, &winner);
|
|
|
4be148 |
}
|
|
|
4be148 |
|
|
|
4be148 |
/* Wait for two seconds at the end of the first pass. */
|
|
|
4be148 |
if (!done) {
|
|
|
4be148 |
done = service_fds(context, sel_state, 2000, conns, seltemp,
|
|
|
4be148 |
- msg_handler, msg_handler_data, &winner);
|
|
|
4be148 |
+ realm, msg_handler, msg_handler_data, &winner);
|
|
|
4be148 |
}
|
|
|
4be148 |
|
|
|
4be148 |
/* Make remaining passes over all of the connections. */
|
|
|
4be148 |
@@ -1126,14 +1163,14 @@ k5_sendto(krb5_context context, const krb5_data *message,
|
|
|
4be148 |
if (maybe_send(context, state, message, sel_state, callback_info))
|
|
|
4be148 |
continue;
|
|
|
4be148 |
done = service_fds(context, sel_state, 1000, conns, seltemp,
|
|
|
4be148 |
- msg_handler, msg_handler_data, &winner);
|
|
|
4be148 |
+ realm, msg_handler, msg_handler_data, &winner);
|
|
|
4be148 |
if (sel_state->nfds == 0)
|
|
|
4be148 |
break;
|
|
|
4be148 |
}
|
|
|
4be148 |
/* Wait for the delay backoff at the end of this pass. */
|
|
|
4be148 |
if (!done) {
|
|
|
4be148 |
done = service_fds(context, sel_state, delay, conns, seltemp,
|
|
|
4be148 |
- msg_handler, msg_handler_data, &winner);
|
|
|
4be148 |
+ realm, msg_handler, msg_handler_data, &winner);
|
|
|
4be148 |
}
|
|
|
4be148 |
if (sel_state->nfds == 0)
|
|
|
4be148 |
break;
|
|
|
4be148 |
--
|
|
|
4be148 |
2.1.0
|
|
|
4be148 |
|