Add new routine krb5int_net_writev using scatter-gather source.
authorKen Raeburn <raeburn@mit.edu>
Thu, 15 Jan 2009 00:59:27 +0000 (00:59 +0000)
committerKen Raeburn <raeburn@mit.edu>
Thu, 15 Jan 2009 00:59:27 +0000 (00:59 +0000)
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
src/lib/krb5/os/net_write.c
src/lib/krb5/os/os-proto.h
src/lib/krb5/os/write_msg.c

index d86f8b25bd0acd2af0c7282f16005c73a8c96155..d868ada25cb126385c3bc178b8ea443b30c11b68 100644 (file)
@@ -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
index e4981543aa94ac374df081055afa541e4296927b..35765fb3875406be4bc65ad5e74f0c3f6d6d4810 100644 (file)
@@ -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
  */
 
 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;
 }
index 33acd0c4663e458ae2585db79d9721b2358c0821..bb2e00ec20e6b4c88db241011b9b6b7b1bb7d2cb 100644 (file)
@@ -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;
 
index d75a32796def19e5edb4128ae6d8bbd8a5052319..86b9275d7450f84227635dc2d43900335130761d 100644 (file)
@@ -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
 
 #include "k5-int.h"
 #include <errno.h>
+#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);
 }