Skip to content

Commit

Permalink
Move initiateKeyUpdate to event queue
Browse files Browse the repository at this point in the history
Summary: InitiateKeyUpdate was implemented in a dangerous way, bypassing the event queue. To safely invoke the state machine in middle of a connection, we instead need to create a new pending event type, and insert an event into the queue.

Reviewed By: mingtaoy

Differential Revision: D50860258

fbshipit-source-id: 28bd4dbc4f4bffe6031700f871f481ca68398e42
  • Loading branch information
Huilin Chen authored and facebook-github-bot committed Nov 6, 2023
1 parent 7d37de5 commit b6bd537
Show file tree
Hide file tree
Showing 7 changed files with 56 additions and 29 deletions.
7 changes: 0 additions & 7 deletions fizz/client/FizzClient-inl.h
Original file line number Diff line number Diff line change
Expand Up @@ -57,13 +57,6 @@ Buf FizzClient<ActionMoveVisitor, SM>::getEarlyEkm(
length);
}

template <typename ActionMoveVisitor, typename SM>
void FizzClient<ActionMoveVisitor, SM>::initiateKeyUpdate(
KeyUpdateInitiation keyUpdateInitiation) {
this->addProcessingActions(this->machine_.processKeyUpdateInitiation(
this->state_, std::move(keyUpdateInitiation)));
}

template <typename ActionMoveVisitor, typename SM>
void FizzClient<ActionMoveVisitor, SM>::startActions(Actions actions) {
this->processActions(actions);
Expand Down
5 changes: 0 additions & 5 deletions fizz/client/FizzClient.h
Original file line number Diff line number Diff line change
Expand Up @@ -51,11 +51,6 @@ class FizzClient : public FizzBase<
const Buf& context,
uint16_t length) const;

/**
* Initialize a key update.
*/
void initiateKeyUpdate(KeyUpdateInitiation keyUpdateInitiation);

protected:
void visitActions(typename SM::CompletedActions& actions) override;

Expand Down
12 changes: 12 additions & 0 deletions fizz/protocol/FizzBase-inl.h
Original file line number Diff line number Diff line change
Expand Up @@ -16,6 +16,13 @@ void FizzBase<Derived, ActionMoveVisitor, StateMachine>::writeNewSessionTicket(
processPendingEvents();
}

template <typename Derived, typename ActionMoveVisitor, typename StateMachine>
void FizzBase<Derived, ActionMoveVisitor, StateMachine>::initiateKeyUpdate(
KeyUpdateInitiation kui) {
pendingEvents_.push_back(std::move(kui));
processPendingEvents();
}

template <typename Derived, typename ActionMoveVisitor, typename StateMachine>
void FizzBase<Derived, ActionMoveVisitor, StateMachine>::appWrite(AppWrite w) {
pendingEvents_.push_back(std::move(w));
Expand Down Expand Up @@ -81,6 +88,7 @@ void FizzBase<Derived, ActionMoveVisitor, StateMachine>::moveToErrorState(
break;
case detail::PendingEvent::Type::AppClose_E:
case detail::PendingEvent::Type::WriteNewSessionTicket_E:
case detail::PendingEvent::Type::KeyUpdateInitiation_E:
break;
}
}
Expand Down Expand Up @@ -182,6 +190,10 @@ void FizzBase<Derived, ActionMoveVisitor, StateMachine>::
actions.emplace(machine_.processAppCloseImmediate(state_));
}
break;
case detail::PendingEvent::Type::KeyUpdateInitiation_E:
actions.emplace(machine_.processKeyUpdateInitiation(
state_, std::move(*event.asKeyUpdateInitiation())));
break;
}
} else {
actionGuard_.reset();
Expand Down
16 changes: 11 additions & 5 deletions fizz/protocol/FizzBase.h
Original file line number Diff line number Diff line change
Expand Up @@ -16,11 +16,12 @@ namespace fizz {

namespace detail {

#define FIZZ_PENDING_EVENT(F, ...) \
F(AppWrite, __VA_ARGS__) \
F(EarlyAppWrite, __VA_ARGS__) \
F(AppClose, __VA_ARGS__) \
F(WriteNewSessionTicket, __VA_ARGS__)
#define FIZZ_PENDING_EVENT(F, ...) \
F(AppWrite, __VA_ARGS__) \
F(EarlyAppWrite, __VA_ARGS__) \
F(AppClose, __VA_ARGS__) \
F(WriteNewSessionTicket, __VA_ARGS__) \
F(KeyUpdateInitiation, __VA_ARGS__)

// `fizz::detail::PendingEvent` is declared here, rather than
// being declared as a private struct within `fizz::FizzBase` in order to
Expand Down Expand Up @@ -63,6 +64,11 @@ class FizzBase {
*/
void writeNewSessionTicket(WriteNewSessionTicket writeNewSessionTicket);

/**
* Called to initiate a key update.
*/
void initiateKeyUpdate(KeyUpdateInitiation keyUpdateInitiation);

/**
* Called to write application data.
*/
Expand Down
33 changes: 33 additions & 0 deletions fizz/protocol/test/FizzBaseTest.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -97,6 +97,15 @@ class TestStateMachine {
WriteNewSessionTicket ticket) {
return processWriteNewSessionTicket_(state, ticket);
}
MOCK_METHOD(
Future<Actions>,
processKeyUpdateInitiation_,
(const State&, KeyUpdateInitiation&));
Future<Actions> processKeyUpdateInitiation(
const State& state,
KeyUpdateInitiation kui) {
return processKeyUpdateInitiation_(state, kui);
}
MOCK_METHOD(Future<Actions>, processAppWrite_, (const State&, AppWrite&));
MOCK_METHOD(
Future<Actions>,
Expand Down Expand Up @@ -292,6 +301,30 @@ TEST_F(FizzBaseTest, TestWriteMulti) {
testFizz_->appWrite(appWrite("write2"));
}

TEST_F(FizzBaseTest, TestInitiateKeyUpdate) {
EXPECT_CALL(*TestStateMachine::instance, processAppWrite_(_, _))
.WillOnce(InvokeWithoutArgs([]() {
Actions actions;
actions.push_back(A1());
return actions;
}));
bool inCallback = false;
EXPECT_CALL(testFizz_->visitor_, a1())
.WillOnce(InvokeWithoutArgs([this, &inCallback] {
inCallback = true;
SCOPE_EXIT {
inCallback = false;
};
testFizz_->initiateKeyUpdate(KeyUpdateInitiation());
}));
EXPECT_CALL(*TestStateMachine::instance, processKeyUpdateInitiation_(_, _))
.WillOnce(InvokeWithoutArgs([&inCallback]() {
EXPECT_FALSE(inCallback);
return Actions();
}));
testFizz_->appWrite(AppWrite());
}

TEST_F(FizzBaseTest, TestAppClose) {
EXPECT_CALL(*TestStateMachine::instance, processAppClose(_))
.WillOnce(InvokeWithoutArgs([]() {
Expand Down
7 changes: 0 additions & 7 deletions fizz/server/FizzServer-inl.h
Original file line number Diff line number Diff line change
Expand Up @@ -64,13 +64,6 @@ Buf FizzServer<ActionMoveVisitor, SM>::getEarlyEkm(
length);
}

template <typename ActionMoveVisitor, typename SM>
void FizzServer<ActionMoveVisitor, SM>::initiateKeyUpdate(
KeyUpdateInitiation keyUpdateInitiation) {
this->addProcessingActions(this->machine_.processKeyUpdateInitiation(
this->state_, std::move(keyUpdateInitiation)));
}

template <typename ActionMoveVisitor, typename SM>
void FizzServer<ActionMoveVisitor, SM>::startActions(AsyncActions actions) {
folly::variant_match(
Expand Down
5 changes: 0 additions & 5 deletions fizz/server/FizzServer.h
Original file line number Diff line number Diff line change
Expand Up @@ -43,11 +43,6 @@ class FizzServer : public FizzBase<
const Buf& context,
uint16_t length) const;

/**
* Initialize a key update.
*/
void initiateKeyUpdate(KeyUpdateInitiation keyUpdateInitiation);

protected:
void visitActions(typename SM::CompletedActions& actions) override;

Expand Down

0 comments on commit b6bd537

Please sign in to comment.