]>
git.ipfire.org Git - thirdparty/openssl.git/blob - test/ossl_shim/async_bio.cc
2 * Copyright 1995-2016 The OpenSSL Project Authors. All Rights Reserved.
4 * Licensed under the OpenSSL license (the "License"). You may not use
5 * this file except in compliance with the License. You can obtain a copy
6 * in the file LICENSE in the source distribution or at
7 * https://www.openssl.org/source/license.html
10 #include "async_bio.h"
15 #include <openssl/bio.h>
16 #include <openssl/crypto.h>
23 bool enforce_write_quota
;
28 AsyncBio
*GetData(BIO
*bio
) {
29 return (AsyncBio
*)BIO_get_data(bio
);
32 static int AsyncWrite(BIO
*bio
, const char *in
, int inl
) {
33 AsyncBio
*a
= GetData(bio
);
34 if (a
== NULL
|| BIO_next(bio
) == NULL
) {
38 if (!a
->enforce_write_quota
) {
39 return BIO_write(BIO_next(bio
), in
, inl
);
42 BIO_clear_retry_flags(bio
);
44 if (a
->write_quota
== 0) {
45 BIO_set_retry_write(bio
);
50 if (!a
->datagram
&& (size_t)inl
> a
->write_quota
) {
53 int ret
= BIO_write(BIO_next(bio
), in
, inl
);
55 BIO_copy_next_retry(bio
);
57 a
->write_quota
-= (a
->datagram
? 1 : ret
);
62 static int AsyncRead(BIO
*bio
, char *out
, int outl
) {
63 AsyncBio
*a
= GetData(bio
);
64 if (a
== NULL
|| BIO_next(bio
) == NULL
) {
68 BIO_clear_retry_flags(bio
);
70 if (a
->read_quota
== 0) {
71 BIO_set_retry_read(bio
);
76 if (!a
->datagram
&& (size_t)outl
> a
->read_quota
) {
79 int ret
= BIO_read(BIO_next(bio
), out
, outl
);
81 BIO_copy_next_retry(bio
);
83 a
->read_quota
-= (a
->datagram
? 1 : ret
);
88 static long AsyncCtrl(BIO
*bio
, int cmd
, long num
, void *ptr
) {
89 if (BIO_next(bio
) == NULL
) {
92 BIO_clear_retry_flags(bio
);
93 int ret
= BIO_ctrl(BIO_next(bio
), cmd
, num
, ptr
);
94 BIO_copy_next_retry(bio
);
98 static int AsyncNew(BIO
*bio
) {
99 AsyncBio
*a
= (AsyncBio
*)OPENSSL_malloc(sizeof(*a
));
103 memset(a
, 0, sizeof(*a
));
104 a
->enforce_write_quota
= true;
105 BIO_set_init(bio
, 1);
106 BIO_set_data(bio
, a
);
110 static int AsyncFree(BIO
*bio
) {
115 OPENSSL_free(BIO_get_data(bio
));
116 BIO_set_data(bio
, NULL
);
117 BIO_set_init(bio
, 0);
121 static long AsyncCallbackCtrl(BIO
*bio
, int cmd
, BIO_info_cb fp
)
123 if (BIO_next(bio
) == NULL
)
125 return BIO_callback_ctrl(BIO_next(bio
), cmd
, fp
);
128 static BIO_METHOD
*g_async_bio_method
= NULL
;
130 static const BIO_METHOD
*AsyncMethod(void)
132 if (g_async_bio_method
== NULL
) {
133 g_async_bio_method
= BIO_meth_new(BIO_TYPE_FILTER
, "async bio");
134 if ( g_async_bio_method
== NULL
135 || !BIO_meth_set_write(g_async_bio_method
, AsyncWrite
)
136 || !BIO_meth_set_read(g_async_bio_method
, AsyncRead
)
137 || !BIO_meth_set_ctrl(g_async_bio_method
, AsyncCtrl
)
138 || !BIO_meth_set_create(g_async_bio_method
, AsyncNew
)
139 || !BIO_meth_set_destroy(g_async_bio_method
, AsyncFree
)
140 || !BIO_meth_set_callback_ctrl(g_async_bio_method
, AsyncCallbackCtrl
))
143 return g_async_bio_method
;
148 bssl::UniquePtr
<BIO
> AsyncBioCreate() {
149 return bssl::UniquePtr
<BIO
>(BIO_new(AsyncMethod()));
152 bssl::UniquePtr
<BIO
> AsyncBioCreateDatagram() {
153 bssl::UniquePtr
<BIO
> ret(BIO_new(AsyncMethod()));
157 GetData(ret
.get())->datagram
= true;
161 void AsyncBioAllowRead(BIO
*bio
, size_t count
) {
162 AsyncBio
*a
= GetData(bio
);
166 a
->read_quota
+= count
;
169 void AsyncBioAllowWrite(BIO
*bio
, size_t count
) {
170 AsyncBio
*a
= GetData(bio
);
174 a
->write_quota
+= count
;
177 void AsyncBioEnforceWriteQuota(BIO
*bio
, bool enforce
) {
178 AsyncBio
*a
= GetData(bio
);
182 a
->enforce_write_quota
= enforce
;