aboutsummaryrefslogtreecommitdiff
path: root/src/lib/krb5/os/sendto_kdc.c
diff options
context:
space:
mode:
Diffstat (limited to 'src/lib/krb5/os/sendto_kdc.c')
-rw-r--r--src/lib/krb5/os/sendto_kdc.c58
1 files changed, 36 insertions, 22 deletions
diff --git a/src/lib/krb5/os/sendto_kdc.c b/src/lib/krb5/os/sendto_kdc.c
index 0f5b9f2..1b336a6 100644
--- a/src/lib/krb5/os/sendto_kdc.c
+++ b/src/lib/krb5/os/sendto_kdc.c
@@ -562,6 +562,7 @@ start_connection (struct conn_state *state, struct select_state *selstate)
state->state = CONNECTING;
} else {
dprint("connect failed: %m\n", SOCKET_ERRNO);
+ (void) closesocket(fd);
state->err = SOCKET_ERRNO;
state->state = FAILED;
return -2;
@@ -677,6 +678,25 @@ kill_conn(struct conn_state *conn, struct select_state *selstate, int err)
selstate->nfds--;
}
+/* Check socket for error. */
+static int
+get_so_error(int fd)
+{
+ int e, sockerr;
+ socklen_t sockerrlen;
+
+ sockerr = 0;
+ sockerrlen = sizeof(sockerr);
+ e = getsockopt(fd, SOL_SOCKET, SO_ERROR, &sockerr, &sockerrlen);
+ if (e != 0) {
+ /* What to do now? */
+ e = SOCKET_ERRNO;
+ dprint("getsockopt(SO_ERROR) on fd failed: %m\n", e);
+ return e;
+ }
+ return sockerr;
+}
+
/* Return nonzero only if we're finished and the caller should exit
its loop. This happens in two cases: We have a complete message,
or the socket has closed and no others are open. */
@@ -706,35 +726,29 @@ service_tcp_fd (struct conn_state *conn, struct select_state *selstate,
return e == 0;
}
if (ssflags & SSF_EXCEPTION) {
-#ifdef DEBUG
- int sockerr;
- socklen_t sockerrlen;
-#endif
handle_exception:
-#ifdef DEBUG
- sockerrlen = sizeof(sockerr);
- e = getsockopt(conn->fd, SOL_SOCKET, SO_ERROR,
- &sockerr, &sockerrlen);
- if (e != 0) {
- /* What to do now? */
- e = SOCKET_ERRNO;
- dprint("getsockopt(SO_ERROR) on exception fd failed: %m\n", e);
- goto kill_conn;
- }
- /* Okay, got the error back. Either way, kill the
- connection. */
- e = sockerr;
-#else
- e = 1; /* need only be non-zero */
-#endif
+ e = get_so_error(conn->fd);
+ if (e)
+ dprint("socket error on exception fd: %m", e);
+ else
+ dprint("no socket error info available on exception fd");
goto kill_conn;
}
/*
* Connect finished -- but did it succeed or fail?
* UNIX sets can_write if failed.
- * Try writing, I guess, and find out.
+ * Call getsockopt to see if error pending.
+ *
+ * (For most UNIX systems it works to just try writing the
+ * first time and detect an error. But Bill Dodd at IBM
+ * reports that some version of AIX, SIGPIPE can result.)
*/
+ e = get_so_error(conn->fd);
+ if (e) {
+ dprint("socket error on write fd: %m", e);
+ goto kill_conn;
+ }
conn->state = WRITING;
goto try_writing;
@@ -1073,7 +1087,7 @@ krb5int_sendto (krb5_context context, const krb5_data *message,
egress:
for (i = 0; i < n_conns; i++) {
if (conns[i].fd != INVALID_SOCKET)
- close(conns[i].fd);
+ closesocket(conns[i].fd);
if (conns[i].state == READING
&& conns[i].x.in.buf != 0
&& conns[i].x.in.buf != udpbuf)