From c3fd8c6bb3d78fe4b4f70afcd2df62f83d187e66 Mon Sep 17 00:00:00 2001 From: Ken Raeburn Date: Thu, 15 Jan 2009 00:59:27 +0000 Subject: [PATCH] Add new routine krb5int_net_writev using scatter-gather source. Use it from krb5_net_write to ensure testing and reduce duplication. Use it from krb5_write_message to avoid Nagle+DelayedAck problem. ticket: 6339 git-svn-id: svn://anonsvn.mit.edu/krb5/trunk@21749 dc483132-0cff-0310-8789-dd5450dbe970 --- src/lib/krb5/os/deps | 4 +-- src/lib/krb5/os/net_write.c | 51 ++++++++++++++++++++++++++----------- src/lib/krb5/os/os-proto.h | 5 +++- src/lib/krb5/os/write_msg.c | 13 +++++----- 4 files changed, 49 insertions(+), 24 deletions(-) diff --git a/src/lib/krb5/os/deps b/src/lib/krb5/os/deps index d86f8b25b..d868ada25 100644 --- a/src/lib/krb5/os/deps +++ b/src/lib/krb5/os/deps @@ -277,7 +277,7 @@ net_write.so net_write.po $(OUTPRE)net_write.$(OBJEXT): \ $(SRCTOP)/include/k5-plugin.h $(SRCTOP)/include/k5-thread.h \ $(SRCTOP)/include/krb5.h $(SRCTOP)/include/krb5/locate_plugin.h \ $(SRCTOP)/include/krb5/preauth_plugin.h $(SRCTOP)/include/port-sockets.h \ - $(SRCTOP)/include/socket-utils.h net_write.c + $(SRCTOP)/include/socket-utils.h net_write.c os-proto.h osconfig.so osconfig.po $(OUTPRE)osconfig.$(OBJEXT): \ $(BUILDTOP)/include/autoconf.h $(BUILDTOP)/include/krb5/krb5.h \ $(BUILDTOP)/include/osconf.h $(BUILDTOP)/include/profile.h \ @@ -429,7 +429,7 @@ write_msg.so write_msg.po $(OUTPRE)write_msg.$(OBJEXT): \ $(SRCTOP)/include/k5-plugin.h $(SRCTOP)/include/k5-thread.h \ $(SRCTOP)/include/krb5.h $(SRCTOP)/include/krb5/locate_plugin.h \ $(SRCTOP)/include/krb5/preauth_plugin.h $(SRCTOP)/include/port-sockets.h \ - $(SRCTOP)/include/socket-utils.h write_msg.c + $(SRCTOP)/include/socket-utils.h os-proto.h write_msg.c t_an_to_ln.so t_an_to_ln.po $(OUTPRE)t_an_to_ln.$(OBJEXT): \ $(BUILDTOP)/include/krb5/krb5.h $(COM_ERR_DEPS) $(SRCTOP)/include/krb5.h \ t_an_to_ln.c diff --git a/src/lib/krb5/os/net_write.c b/src/lib/krb5/os/net_write.c index e4981543a..35765fb38 100644 --- a/src/lib/krb5/os/net_write.c +++ b/src/lib/krb5/os/net_write.c @@ -1,7 +1,7 @@ /* * lib/krb5/os/net_write.c * - * Copyright 1987, 1988, 1990 by the Massachusetts Institute of Technology. + * Copyright 1987, 1988, 1990, 2009 by the Massachusetts Institute of Technology. * All Rights Reserved. * * Export of this software from the United States of America may @@ -26,6 +26,7 @@ */ #include "k5-int.h" +#include "os-proto.h" /* * krb5_net_write() writes "len" bytes from "buf" to the file @@ -37,25 +38,45 @@ */ int -krb5_net_write(krb5_context context, int fd, register const char *buf, int len) +krb5_net_write(krb5_context context, int fd, const char *buf, int len) { - int cc; - register int wrlen = len; - do { - cc = SOCKET_WRITE((SOCKET)fd, buf, wrlen); + sg_buf sg; + SG_SET(&sg, buf, len); + return krb5int_net_writev(context, fd, &sg, 1); +} + +int +krb5int_net_writev(krb5_context context, int fd, sg_buf *sgp, int nsg) +{ + int cc, len = 0; + SOCKET_WRITEV_TEMP tmp; + + while (nsg > 0) { + /* Skip any empty data blocks. */ + if (SG_LEN(sgp) == 0) { + sgp++, nsg--; + continue; + } + cc = SOCKET_WRITEV((SOCKET)fd, sgp, nsg, tmp); if (cc < 0) { if (SOCKET_ERRNO == SOCKET_EINTR) continue; - /* XXX this interface sucks! */ - errno = SOCKET_ERRNO; - - return(cc); + /* XXX this interface sucks! */ + errno = SOCKET_ERRNO; + return -1; } - else { - buf += cc; - wrlen -= cc; + len += cc; + while (cc > 0) { + if ((unsigned)cc < SG_LEN(sgp)) { + SG_ADVANCE(sgp, (unsigned)cc); + cc = 0; + } else { + cc -= SG_LEN(sgp); + sgp++, nsg--; + assert(nsg > 0 || cc == 0); + } } - } while (wrlen > 0); - return(len); + } + return len; } diff --git a/src/lib/krb5/os/os-proto.h b/src/lib/krb5/os/os-proto.h index 33acd0c46..bb2e00ec2 100644 --- a/src/lib/krb5/os/os-proto.h +++ b/src/lib/krb5/os/os-proto.h @@ -1,7 +1,7 @@ /* * lib/krb5/os/os-proto.h * - * Copyright 1990,1991 by the Massachusetts Institute of Technology. + * Copyright 1990,1991,2009 by the Massachusetts Institute of Technology. * All Rights Reserved. * * Export of this software from the United States of America may @@ -62,6 +62,9 @@ int _krb5_use_dns_realm (krb5_context); int _krb5_use_dns_kdc (krb5_context); int _krb5_conf_boolean (const char *); +/* The io vector is *not* const here, unlike writev()! */ +int krb5int_net_writev (krb5_context, int, sg_buf *, int); + #include "k5-thread.h" extern k5_mutex_t krb5int_us_time_mutex; diff --git a/src/lib/krb5/os/write_msg.c b/src/lib/krb5/os/write_msg.c index d75a32796..86b9275d7 100644 --- a/src/lib/krb5/os/write_msg.c +++ b/src/lib/krb5/os/write_msg.c @@ -1,7 +1,7 @@ /* * lib/krb5/os/write_msg.c * - * Copyright 1991 by the Massachusetts Institute of Technology. + * Copyright 1991, 2009 by the Massachusetts Institute of Technology. * All Rights Reserved. * * Export of this software from the United States of America may @@ -29,19 +29,20 @@ #include "k5-int.h" #include +#include "os-proto.h" krb5_error_code krb5_write_message(krb5_context context, krb5_pointer fdp, krb5_data *outbuf) { krb5_int32 len; int fd = *( (int *) fdp); + sg_buf sg[2]; len = htonl(outbuf->length); - if (krb5_net_write(context, fd, (char *)&len, 4) < 0) { - return(errno); - } - if (outbuf->length && (krb5_net_write(context, fd, outbuf->data, outbuf->length) < 0)) { - return(errno); + SG_SET(&sg[0], &len, 4); + SG_SET(&sg[1], outbuf->data, outbuf->length); + if (krb5int_net_writev(context, fd, sg, 2) < 0) { + return errno; } return(0); } -- 2.26.2