retry few times if there's a conflict in takeover handler address
MODIFY
quic/server/QuicServer.cpp
quic/server/QuicServer.cpp
@@ -278,6 +278,32 @@ void QuicServer::allowBeingTakenOver(const folly::SocketAddress& addr) {
takeoverHandlerInitialized_ = true;
}
+folly::SocketAddress QuicServer::overrideTakeoverHandlerAddress(
+ const folly::SocketAddress& addr) {
+ // synchronously bind workers to takeover handler port.
+ // This method should not be called from a worker
+ CHECK(!workers_.empty());
+ CHECK(!shutdown_);
+ CHECK(takeoverHandlerInitialized_) << "TakeoverHanders are not initialized. ";
+
+ // this function shouldn't be called from worker's thread
+ for (auto& worker : workers_) {
+ DCHECK(
+ // if the eventbase is not running, it returns true for isInEvbThread()
+ !worker->getEventBase()->isRunning() ||
+ !worker->getEventBase()->isInEventBaseThread());
+ }
+ folly::SocketAddress boundAddress;
+ for (auto& worker : workers_) {
+ worker->getEventBase()->runInEventBaseThreadAndWait([&] {
+ std::lock_guard<std::mutex> guard(startMutex_);
+ CHECK(initialized_);
+ boundAddress = worker->overrideTakeoverHandlerAddress(addr);
+ });
+ }
+ return boundAddress;
+}
+
void QuicServer::pauseRead() {
runOnAllWorkers([&](auto worker) mutable { worker->pauseRead(); });
}

MODIFY
quic/server/QuicServer.h
quic/server/QuicServer.h
@@ -227,6 +227,9 @@ class QuicServer : public QuicServerWorker::WorkerCallback,
*/
void allowBeingTakenOver(const folly::SocketAddress& addr);
+ folly::SocketAddress overrideTakeoverHandlerAddress(
+ const folly::SocketAddress& addr);
+
/*
* Setup and initialize the listening socket of the old server from the given
* address to forward misrouted packets belonging to that server during

MODIFY
quic/server/QuicServerPacketRouter.cpp
quic/server/QuicServerPacketRouter.cpp
@@ -24,12 +24,10 @@ TakeoverHandlerCallback::TakeoverHandlerCallback(
QuicServerWorker* worker,
TakeoverPacketHandler& takeoverPktHandler,
const TransportSettings& transportSettings,
- const folly::SocketAddress& address,
std::unique_ptr<folly::AsyncUDPSocket> socket)
: worker_(worker),
takeoverPktHandler_(takeoverPktHandler),
transportSettings_(transportSettings),
- address_(address),
socket_(std::move(socket)) {}
TakeoverHandlerCallback::~TakeoverHandlerCallback() {
@@ -39,9 +37,9 @@ TakeoverHandlerCallback::~TakeoverHandlerCallback() {
}
}
-void TakeoverHandlerCallback::bind() {
+void TakeoverHandlerCallback::bind(const folly::SocketAddress& addr) {
CHECK(socket_);
- socket_->bind(address_);
+ socket_->bind(addr);
socket_->resumeRead(this);
}
@@ -51,6 +49,11 @@ void TakeoverHandlerCallback::pause() {
}
}
+const folly::SocketAddress& TakeoverHandlerCallback::getAddress() const {
+ CHECK(socket_);
+ return socket_->address();
+}
+
int TakeoverHandlerCallback::getSocketFD() {
CHECK(socket_);
return socket_->getNetworkSocket().toFd();

MODIFY
quic/server/QuicServerPacketRouter.h
quic/server/QuicServerPacketRouter.h
@@ -114,7 +114,6 @@ class TakeoverHandlerCallback : public folly::AsyncUDPSocket::ReadCallback,
QuicServerWorker* worker,
TakeoverPacketHandler& takeoverPktHandler,
const TransportSettings& transportSettings,
- const folly::SocketAddress& address,
std::unique_ptr<folly::AsyncUDPSocket> socket);
// prevent copying
@@ -123,12 +122,14 @@ class TakeoverHandlerCallback : public folly::AsyncUDPSocket::ReadCallback,
virtual ~TakeoverHandlerCallback() override;
- void bind();
+ void bind(const folly::SocketAddress& addr);
void pause();
int getSocketFD();
+ const folly::SocketAddress& getAddress() const;
+
// AsyncUDPSocket ReadCallback methods
void getReadBuffer(void** buf, size_t* len) noexcept override;

MODIFY
quic/server/QuicServerWorker.cpp
quic/server/QuicServerWorker.cpp
@@ -513,12 +513,15 @@ void QuicServerWorker::allowBeingTakenOver(
// We instantiate and bind the TakeoverHandlerCallback to the given address.
// It is reset at shutdownAllConnections (i.e. only when the process dies).
takeoverCB_ = std::make_unique<TakeoverHandlerCallback>(
- this,
- takeoverPktHandler_,
- transportSettings_,
- address,
- std::move(socket));
- takeoverCB_->bind();
+ this, takeoverPktHandler_, transportSettings_, std::move(socket));
+ takeoverCB_->bind(address);
+}
+
+const folly::SocketAddress& QuicServerWorker::overrideTakeoverHandlerAddress(
+ const folly::SocketAddress& address) {
+ CHECK(takeoverCB_);
+ takeoverCB_->bind(address);
+ return takeoverCB_->getAddress();
}
void QuicServerWorker::startPacketForwarding(

MODIFY
quic/server/QuicServerWorker.h
quic/server/QuicServerWorker.h
@@ -95,6 +95,13 @@ class QuicServerWorker : public folly::AsyncUDPSocket::ReadCallback,
std::unique_ptr<folly::AsyncUDPSocket> socket,
const folly::SocketAddress& address);
+ /**
+ * Override listening address for takeover packets
+ * Returns const ref to SocketAddress representing the address it is bound to.
+ */
+ const folly::SocketAddress& overrideTakeoverHandlerAddress(
+ const folly::SocketAddress& address);
+
/**
* Setup address that the taken over quic server is listening to forward
* misrouted packets belonging to the old server.

retry few times if there's a conflict in takeover handler address

Reviewed By: sharma95

Differential Revision: D17403844

fbshipit-source-id: 3084335be30e2376a6888ba24e21aa63bb040e3e