Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

QUIC Concurrency API Implementation #24257

Draft
wants to merge 24 commits into
base: feature/quic-server
Choose a base branch
from

Conversation

hlandau
Copy link
Member

@hlandau hlandau commented Apr 24, 2024

Status: In progress — debug and test. Not for review yet unless people are interested. Just putting this up for now as a preview of how the solution is going to work. Bit of a change as I usually don't put up drafts, but I figured I'd give people a view of what's going on.


This is a partial implementation of just enough of #24256 to fix #24166 intended for 3.4. It introduces necessary concurrency model concepts to allow applications to opt in to reliable blocking functionality if they want it, and allows them to forego it if they do not.

It adopts the concept of a QUIC Domain SSL object which was previously discussed in the Server API design document but at that time deferred for possible (post Server MVP) future implementation. Explicit concurrency control makes having explicit control over an event domain, and the ability to have multiple listeners in the same domain, highly desirable, and the internal architecture for this was already implemented anyway.

A new API is added to allow configuring a desired concurrency model.

@hlandau hlandau added branch: master Merge to master branch approval: review pending This pull request needs review by a committer approval: otc review pending This pull request needs review by an OTC member triaged: feature The issue/pr requests/adds a feature tests: present The PR has suitable tests present labels Apr 24, 2024
@hlandau hlandau requested a review from a team April 24, 2024 12:59
@hlandau hlandau self-assigned this Apr 24, 2024
if (setsockopt(lfd, SOL_SOCKET, SO_EXCLUSIVEADDRUSE, &on, sizeof(on)) < 0) {
BIO_closesocket(fd);
return -1;
}
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

why WSAsocketA here? Seems like you could just use BIO_socket in both cases, no?

Copy link
Member Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

This allows WSA_FLAG_NO_HANDLE_INHERIT to be set, which is the equivalent of O_CLOEXEC... BIO_socket does have an unused options flag so we could add this functionality to BIO_socket, of course, though that's a public API augmentation.

* unsignalling the notifier.
*/
while (rtor->signalled_notifier)
ossl_crypto_condvar_wait(rtor->notifier_cv, mutex);
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

You need to lock this mutex prior to reading/writing rtor->signaled_notifier, and unlock it again after the thread you are notifying has updated signaled_notifier. I believe if the mutex isn't owned by the calling thread at the time of the underlying pthread_cond_wait call, EINVAL is returned here:
https://pubs.opengroup.org/onlinepubs/7908799/xsh/pthread_cond_wait.html

Copy link
Member Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Yes — this code is always called with the mutex held. Incidentally, poll_two_descriptors unlocks the mutex before calling poll(2) and then relocks it.

Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I'm sorry, I see where poll_two_descriptors unlocks/relocks the mutex several times, but I never see where that mutex is first acquired.

Is the reactor mutex assigned in ossl_quic_reactor_init aliased from the qctx mutex that is also used in qctx_lock? That would explain why I can't find where rtor->mutex is explicitly locked.

Incidentally, while looking at this I noticed that all your usages of mutexes in QUIC are conditional on OPENSSL_THREADS being defined, which is good, but the above call to ossl_crypto_condvar_wait is not, implying that in a no-threads build, this code will pass a NULL pointer to ossl_crypto_condvar_wait, which I believe will cause -EINVAL to be returned. Not sure if thats a problem in an unthreaded build, but I thought I would point it out.

Copy link
Member Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Is the reactor mutex assigned in ossl_quic_reactor_init aliased from the qctx mutex that is also used in qctx_lock? That would explain why I can't find where rtor->mutex is explicitly locked.

Yes. The reactor does not allocate or own its own mutex, but uses the mutex donated from the quic_impl.c code. This is necessary so that it can unlock the mutex during the poll(2) call and then reacquire it.

Copy link
Member Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Incidentally, while looking at this I noticed that all your usages of mutexes in QUIC are conditional on OPENSSL_THREADS being defined, which is good, but the above call to ossl_crypto_condvar_wait is not, implying that in a no-threads build, this code will pass a NULL pointer to ossl_crypto_condvar_wait, which I believe will cause -EINVAL to be returned.

Good point. We need to have better CI coverage here...

@github-actions github-actions bot added the severity: ABI change This pull request contains ABI changes label Apr 29, 2024
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
approval: otc review pending This pull request needs review by an OTC member approval: review pending This pull request needs review by a committer branch: master Merge to master branch severity: ABI change This pull request contains ABI changes tests: present The PR has suitable tests present triaged: feature The issue/pr requests/adds a feature
Projects
Status: In progress
Status: In progress
Development

Successfully merging this pull request may close these issues.

None yet

2 participants