summaryrefslogtreecommitdiffstats
path: root/ssl
diff options
context:
space:
mode:
authorBodo Möller <bodo@openssl.org>1999-07-02 13:55:32 +0000
committerBodo Möller <bodo@openssl.org>1999-07-02 13:55:32 +0000
commite105643595707085588ee43a29d607a56ddb1ed1 (patch)
tree47cba7caac38e766bc6721adbf513e4d287ac553 /ssl
parente0371fe4dc65ec62861e0ef293305442c0d97269 (diff)
New functions SSL[_CTX]_{set,get}_mode; the initial set of mode flags is
SSL_MODE_ENABLE_PARTIAL_WRITE, SSL_MODE_ACCEPT_MOVING_WRITE_BUFFER.
Diffstat (limited to 'ssl')
-rw-r--r--ssl/s2_pkt.c12
-rw-r--r--ssl/s3_pkt.c11
-rw-r--r--ssl/ssl.h34
-rw-r--r--ssl/ssl_lib.c5
4 files changed, 52 insertions, 10 deletions
diff --git a/ssl/s2_pkt.c b/ssl/s2_pkt.c
index 73c96f3c36..39d8010bde 100644
--- a/ssl/s2_pkt.c
+++ b/ssl/s2_pkt.c
@@ -391,8 +391,12 @@ int ssl2_write(SSL *s, const void *_buf, int len)
s->s2->wnum=tot;
return(i);
}
- if (i == (int)n) return(tot+i);
-
+ if ((i == (int)n) ||
+ (s->mode | SSL_MODE_ENABLE_PARTIAL_WRITE))
+ {
+ return(tot+i);
+ }
+
n-=i;
tot+=i;
}
@@ -406,7 +410,9 @@ static int write_pending(SSL *s, const unsigned char *buf, unsigned int len)
/* check that they have given us the same buffer to
* write */
- if ((s->s2->wpend_tot > (int)len) || (s->s2->wpend_buf != buf))
+ if ((s->s2->wpend_tot > (int)len) ||
+ ((s->s2->wpend_buf != buf) &&
+ (!s->mode & SSL_MODE_ACCEPT_MOVING_WRITE_BUFFER)))
{
SSLerr(SSL_F_WRITE_PENDING,SSL_R_BAD_WRITE_RETRY);
return(-1);
diff --git a/ssl/s3_pkt.c b/ssl/s3_pkt.c
index 4a195095d9..c9dc7cc616 100644
--- a/ssl/s3_pkt.c
+++ b/ssl/s3_pkt.c
@@ -468,7 +468,12 @@ int ssl3_write_bytes(SSL *s, int type, const void *_buf, int len)
if (type == SSL3_RT_HANDSHAKE)
ssl3_finish_mac(s,&(buf[tot]),i);
- if (i == (int)n) return(tot+i);
+ if ((i == (int)n) ||
+ (type == SSL3_RT_APPLICATION_DATA &&
+ (s->mode | SSL_MODE_ENABLE_PARTIAL_WRITE)))
+ {
+ return(tot+i);
+ }
n-=i;
tot+=i;
@@ -596,7 +601,9 @@ static int ssl3_write_pending(SSL *s, int type, const unsigned char *buf,
int i;
/* XXXX */
- if ((s->s3->wpend_tot > (int)len) || (s->s3->wpend_buf != buf)
+ if ((s->s3->wpend_tot > (int)len)
+ || ((s->s3->wpend_buf != buf) &&
+ (!s->mode & SSL_MODE_ACCEPT_MOVING_WRITE_BUFFER))
|| (s->s3->wpend_type != type))
{
SSLerr(SSL_F_SSL3_WRITE_PENDING,SSL_R_BAD_WRITE_RETRY);
diff --git a/ssl/ssl.h b/ssl/ssl.h
index d75d18dd26..e4478542b7 100644
--- a/ssl/ssl.h
+++ b/ssl/ssl.h
@@ -295,18 +295,39 @@ typedef struct ssl_session_st
#define SSL_OP_NETSCAPE_DEMO_CIPHER_CHANGE_BUG 0x80000000L
#define SSL_OP_ALL 0x000FFFFFL
+#define SSL_OP_NO_SSLv2 0x01000000L
+#define SSL_OP_NO_SSLv3 0x02000000L
+#define SSL_OP_NO_TLSv1 0x04000000L
+
+/* Allow SSL_write(..., n) to return r with 0 < r < n (i.e. report success
+ * when just a single record has been written): */
+#define SSL_MODE_ENABLE_PARTIAL_WRITE 0x00000001L
+/* Make it possible to retry SSL_write() with changed buffer location
+ * (buffer contents must stay the same!); this is not the default to avoid
+ * the misconception that non-blocking SSL_write() behaves like
+ * non-blocking write(): */
+#define SSL_MODE_ACCEPT_MOVING_WRITE_BUFFER 0x00000002L
+
+/* Note: SSL[_CTX]_set_{options,mode} use |= op on the previous value,
+ * they cannot be used to clear bits. */
+
#define SSL_CTX_set_options(ctx,op) \
SSL_CTX_ctrl(ctx,SSL_CTRL_OPTIONS,op,NULL)
#define SSL_CTX_get_options(ctx) \
SSL_CTX_ctrl(ctx,SSL_CTRL_OPTIONS,0,NULL)
#define SSL_set_options(ssl,op) \
- SSL_ctrl(ssl,SSL_CTRL_OPTIONS,0,NULL)
+ SSL_ctrl(ssl,SSL_CTRL_OPTIONS,op,NULL)
#define SSL_get_options(ssl) \
SSL_ctrl(ssl,SSL_CTRL_OPTIONS,0,NULL)
-#define SSL_OP_NO_SSLv2 0x01000000L
-#define SSL_OP_NO_SSLv3 0x02000000L
-#define SSL_OP_NO_TLSv1 0x04000000L
+#define SSL_CTX_set_mode(ctx,op) \
+ SSL_CTX_ctrl(ctx,SSL_CTRL_MODE,op,NULL)
+#define SSL_CTX_get_mode(ctx) \
+ SSL_CTX_ctrl(ctx,SSL_CTRL_MODE,0,NULL)
+#define SSL_set_mode(ssl,op) \
+ SSL_ctrl(ssl,SSL_CTRL_MODE,op,NULL)
+#define SSL_get_mode(ssl) \
+ SSL_ctrl(ssl,SSL_CTRL_MODE,0,NULL)
#define SSL_SESSION_CACHE_MAX_SIZE_DEFAULT (1024*20)
@@ -327,6 +348,7 @@ struct ssl_ctx_st
{
SSL_METHOD *method;
unsigned long options;
+ unsigned long mode;
STACK_OF(SSL_CIPHER) *cipher_list;
/* same as above but sorted for lookup */
@@ -605,7 +627,8 @@ struct ssl_st
STACK_OF(X509_NAME) *client_CA;
int references;
- unsigned long options;
+ unsigned long options; /* protocol behaviour */
+ unsigned long mode; /* API behaviour */
int first_packet;
int client_version; /* what was passed, used for
* SSLv3/TLS rolback check */
@@ -780,6 +803,7 @@ struct ssl_st
#define SSL_CTRL_SESS_TIMEOUTS 30
#define SSL_CTRL_SESS_CACHE_FULL 31
#define SSL_CTRL_OPTIONS 32
+#define SSL_CTRL_MODE 33
#define SSL_CTRL_GET_READ_AHEAD 40
#define SSL_CTRL_SET_READ_AHEAD 41
diff --git a/ssl/ssl_lib.c b/ssl/ssl_lib.c
index 95e8405cd7..89c5481fd8 100644
--- a/ssl/ssl_lib.c
+++ b/ssl/ssl_lib.c
@@ -215,6 +215,7 @@ SSL *SSL_new(SSL_CTX *ctx)
s->references=1;
s->server=(ctx->method->ssl_accept == ssl_undefined_function)?0:1;
s->options=ctx->options;
+ s->mode=ctx->mode;
SSL_clear(s);
CRYPTO_new_ex_data(ssl_meth,(char *)s,&s->ex_data);
@@ -695,6 +696,8 @@ long SSL_ctrl(SSL *s,int cmd,long larg,char *parg)
return(l);
case SSL_CTRL_OPTIONS:
return(s->options|=larg);
+ case SSL_CTRL_MODE:
+ return(s->mode|=larg);
default:
return(s->method->ssl_ctrl(s,cmd,larg,parg));
}
@@ -752,6 +755,8 @@ long SSL_CTX_ctrl(SSL_CTX *ctx,int cmd,long larg,char *parg)
return(ctx->stats.sess_cache_full);
case SSL_CTRL_OPTIONS:
return(ctx->options|=larg);
+ case SSL_CTRL_MODE:
+ return(ctx->mode|=larg);
default:
return(ctx->method->ssl_ctx_ctrl(ctx,cmd,larg,parg));
}