summaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorKen Raeburn <raeburn@mit.edu>2004-03-22 20:28:49 +0000
committerKen Raeburn <raeburn@mit.edu>2004-03-22 20:28:49 +0000
commitf37e1cb9857321ae08e43a8b056a02bd07697482 (patch)
tree1971f8512e870ba09b7445e029194c9252aa99f1
parent898f5b24bc0fd56d1f38f2a1640a7e46442f7757 (diff)
downloadkrb5-f37e1cb9857321ae08e43a8b056a02bd07697482.tar.gz
krb5-f37e1cb9857321ae08e43a8b056a02bd07697482.tar.xz
krb5-f37e1cb9857321ae08e43a8b056a02bd07697482.zip
* sendto_kdc.c (get_so_error): New function.
(service_tcp_fd): Call it for write fds as well as exception fds. ticket: 2426 tags: pullup git-svn-id: svn://anonsvn.mit.edu/krb5/trunk@16199 dc483132-0cff-0310-8789-dd5450dbe970
-rw-r--r--src/lib/krb5/os/ChangeLog2
-rw-r--r--src/lib/krb5/os/sendto_kdc.c55
2 files changed, 36 insertions, 21 deletions
diff --git a/src/lib/krb5/os/ChangeLog b/src/lib/krb5/os/ChangeLog
index c175ae0300..7b2d330edb 100644
--- a/src/lib/krb5/os/ChangeLog
+++ b/src/lib/krb5/os/ChangeLog
@@ -1,6 +1,8 @@
2004-03-22 Ken Raeburn <raeburn@mit.edu>
* sendto_kdc.c (krb5int_sendto): Initialize select_state.end_time.
+ (get_so_error): New function.
+ (service_tcp_fd): Call it for write fds as well as exception fds.
2004-03-18 Ezra Peisach <epeisach@mit.edu>
diff --git a/src/lib/krb5/os/sendto_kdc.c b/src/lib/krb5/os/sendto_kdc.c
index ba7b1c54a4..3f8eb777f1 100644
--- a/src/lib/krb5/os/sendto_kdc.c
+++ b/src/lib/krb5/os/sendto_kdc.c
@@ -707,6 +707,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. */
@@ -736,35 +755,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;