extern const BIO_METHOD async_bio_method;
struct async_bio {
+ bool datagram;
size_t read_quota;
size_t write_quota;
};
return 0;
}
+ if (a->datagram) {
+ // Perform writes synchronously; the DTLS implementation drops any packets
+ // that failed to send.
+ return BIO_write(bio->next_bio, in, inl);
+ }
+
BIO_clear_retry_flags(bio);
if (a->write_quota == 0) {
return -1;
}
- if ((size_t)inl > a->write_quota) {
+ if (!a->datagram && (size_t)inl > a->write_quota) {
inl = a->write_quota;
}
int ret = BIO_write(bio->next_bio, in, inl);
return -1;
}
- if ((size_t)outl > a->read_quota) {
+ if (!a->datagram && (size_t)outl > a->read_quota) {
outl = a->read_quota;
}
int ret = BIO_read(bio->next_bio, out, outl);
if (ret <= 0) {
BIO_copy_next_retry(bio);
} else {
- a->read_quota -= ret;
+ a->read_quota -= (a->datagram ? 1 : ret);
}
return ret;
}
return BIO_new(&async_bio_method);
}
-void async_bio_allow_read(BIO *bio, size_t bytes) {
+BIO *async_bio_create_datagram() {
+ BIO *ret = BIO_new(&async_bio_method);
+ if (!ret) {
+ return NULL;
+ }
+ get_data(ret)->datagram = true;
+ return ret;
+}
+
+void async_bio_allow_read(BIO *bio, size_t count) {
async_bio *a = get_data(bio);
if (a == NULL) {
return;
}
- a->read_quota += bytes;
+ a->read_quota += count;
}
-void async_bio_allow_write(BIO *bio, size_t bytes) {
+void async_bio_allow_write(BIO *bio, size_t count) {
async_bio *a = get_data(bio);
if (a == NULL) {
return;
}
- a->write_quota += bytes;
+ a->write_quota += count;
}