/*
- * Copyright (C) 1989,1990,1991,1992,1993,1994,1995,2000,2001, 2003,2006,2007,2008 by the Massachusetts Institute of Technology,
+ * Copyright (C) 1989,1990,1991,1992,1993,1994,1995,2000,2001, 2003,2006,2007,2008,2009 by the Massachusetts Institute of Technology,
* Cambridge, MA, USA. All Rights Reserved.
*
* This software is being provided to you, the LICENSEE, by the
krb5_error_code krb5_read_message (krb5_context, krb5_pointer, krb5_data *);
krb5_error_code krb5_write_message (krb5_context, krb5_pointer, krb5_data *);
+krb5_error_code krb5int_write_messages (krb5_context, krb5_pointer, krb5_data *, int);
int krb5_net_read (krb5_context, int , char *, int);
int krb5_net_write (krb5_context, int , const char *, int);
/*
* lib/krb5/krb/sendauth.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
static const char sendauth_version[] = "KRB5_SENDAUTH_V1.0";
krb5_error_code KRB5_CALLCONV
-krb5_sendauth(krb5_context context, krb5_auth_context *auth_context, krb5_pointer fd, char *appl_version, krb5_principal client, krb5_principal server, krb5_flags ap_req_options, krb5_data *in_data, krb5_creds *in_creds, krb5_ccache ccache, krb5_error **error, krb5_ap_rep_enc_part **rep_result, krb5_creds **out_creds)
+krb5_sendauth(krb5_context context, krb5_auth_context *auth_context,
+ krb5_pointer fd, char *appl_version, krb5_principal client,
+ krb5_principal server, krb5_flags ap_req_options,
+ krb5_data *in_data, krb5_creds *in_creds, krb5_ccache ccache,
+ krb5_error **error, krb5_ap_rep_enc_part **rep_result,
+ krb5_creds **out_creds)
{
krb5_octet result;
krb5_creds creds;
krb5_creds * credsp = NULL;
krb5_creds * credspout = NULL;
krb5_error_code retval = 0;
- krb5_data inbuf, outbuf;
+ krb5_data inbuf, outbuf[2];
int len;
krb5_ccache use_ccache = 0;
* over the length of the application version strings followed
* by the string itself.
*/
- outbuf.length = strlen(sendauth_version) + 1;
- outbuf.data = (char *) sendauth_version;
- if ((retval = krb5_write_message(context, fd, &outbuf)))
- return(retval);
- outbuf.length = strlen(appl_version) + 1;
- outbuf.data = appl_version;
- if ((retval = krb5_write_message(context, fd, &outbuf)))
+ outbuf[0].length = strlen(sendauth_version) + 1;
+ outbuf[0].data = (char *) sendauth_version;
+ outbuf[1].length = strlen(appl_version) + 1;
+ outbuf[1].data = appl_version;
+ if ((retval = krb5int_write_messages(context, fd, outbuf, 2)))
return(retval);
/*
* Now, read back a byte: 0 means no error, 1 means bad sendauth
if ((retval = krb5_mk_req_extended(context, auth_context,
ap_req_options, in_data, credsp,
- &outbuf)))
+ &outbuf[0])))
goto error_return;
/*
* First write the length of the AP_REQ message, then write
* the message itself.
*/
- retval = krb5_write_message(context, fd, &outbuf);
- free(outbuf.data);
+ retval = krb5_write_message(context, fd, &outbuf[0]);
+ free(outbuf[0].data);
if (retval)
goto error_return;
#include <errno.h>
#include "os-proto.h"
+/* Try to write a series of messages with as few write(v) system calls
+ as possible, to avoid Nagle/DelayedAck problems. Cheating here a
+ little -- I know the only cases we have at the moment will send one
+ or two messages in a call. Sending more will work, but not as
+ efficiently. */
krb5_error_code
-krb5_write_message(krb5_context context, krb5_pointer fdp, krb5_data *outbuf)
+krb5int_write_messages(krb5_context context, krb5_pointer fdp, krb5_data *outbuf, int nbufs)
{
- krb5_int32 len;
- int fd = *( (int *) fdp);
- sg_buf sg[2];
+ int fd = *( (int *) fdp);
+
+ while (nbufs) {
+ int nbufs1;
+ sg_buf sg[4];
+ krb5_int32 len[2];
- len = htonl(outbuf->length);
- SG_SET(&sg[0], &len, 4);
- SG_SET(&sg[1], outbuf->data, outbuf->length);
- if (krb5int_net_writev(context, fd, sg, 2) < 0) {
+ if (nbufs > 1)
+ nbufs1 = 2;
+ else
+ nbufs1 = 1;
+ len[0] = htonl(outbuf[0].length);
+ SG_SET(&sg[0], &len[0], 4);
+ SG_SET(&sg[1], outbuf[0].data, outbuf[0].length);
+ if (nbufs1 == 2) {
+ len[1] = htonl(outbuf[1].length);
+ SG_SET(&sg[2], &len[1], 4);
+ SG_SET(&sg[3], outbuf[1].data, outbuf[1].length);
+ }
+ if (krb5int_net_writev(context, fd, sg, nbufs1 * 2) < 0) {
return errno;
}
- return(0);
+ outbuf += nbufs1;
+ nbufs -= nbufs1;
+ }
+ return(0);
+}
+
+krb5_error_code
+krb5_write_message(krb5_context context, krb5_pointer fdp, krb5_data *outbuf)
+{
+ return krb5int_write_messages(context, fdp, outbuf, 1);
}