Add refcounting to Mac and Linux QoS state to ensure it works properly with multiple clients
This means we can't control DSCP tagging per-client, but it shouldn't pose a big problem as routers that blackhole DSCP tagged traffic are pretty rare.
This commit is contained in:
@@ -584,16 +584,25 @@ namespace platf {
|
|||||||
return true;
|
return true;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// We can't track QoS state separately for each destination on this OS,
|
||||||
|
// so we keep a ref count to only disable QoS options when all clients
|
||||||
|
// are disconnected.
|
||||||
|
static std::atomic<int> qos_ref_count = 0;
|
||||||
|
|
||||||
class qos_t: public deinit_t {
|
class qos_t: public deinit_t {
|
||||||
public:
|
public:
|
||||||
qos_t(int sockfd, std::vector<std::tuple<int, int, int>> options):
|
qos_t(int sockfd, std::vector<std::tuple<int, int, int>> options):
|
||||||
sockfd(sockfd), options(options) {}
|
sockfd(sockfd), options(options) {
|
||||||
|
qos_ref_count++;
|
||||||
|
}
|
||||||
|
|
||||||
virtual ~qos_t() {
|
virtual ~qos_t() {
|
||||||
for (const auto &tuple : options) {
|
if (--qos_ref_count == 0) {
|
||||||
auto reset_val = std::get<2>(tuple);
|
for (const auto &tuple : options) {
|
||||||
if (setsockopt(sockfd, std::get<0>(tuple), std::get<1>(tuple), &reset_val, sizeof(reset_val)) < 0) {
|
auto reset_val = std::get<2>(tuple);
|
||||||
BOOST_LOG(warning) << "Failed to reset option: "sv << errno;
|
if (setsockopt(sockfd, std::get<0>(tuple), std::get<1>(tuple), &reset_val, sizeof(reset_val)) < 0) {
|
||||||
|
BOOST_LOG(warning) << "Failed to reset option: "sv << errno;
|
||||||
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -407,16 +407,25 @@ namespace platf {
|
|||||||
return true;
|
return true;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// We can't track QoS state separately for each destination on this OS,
|
||||||
|
// so we keep a ref count to only disable QoS options when all clients
|
||||||
|
// are disconnected.
|
||||||
|
static std::atomic<int> qos_ref_count = 0;
|
||||||
|
|
||||||
class qos_t: public deinit_t {
|
class qos_t: public deinit_t {
|
||||||
public:
|
public:
|
||||||
qos_t(int sockfd, std::vector<std::tuple<int, int, int>> options):
|
qos_t(int sockfd, std::vector<std::tuple<int, int, int>> options):
|
||||||
sockfd(sockfd), options(options) {}
|
sockfd(sockfd), options(options) {
|
||||||
|
qos_ref_count++;
|
||||||
|
}
|
||||||
|
|
||||||
virtual ~qos_t() {
|
virtual ~qos_t() {
|
||||||
for (const auto &tuple : options) {
|
if (--qos_ref_count == 0) {
|
||||||
auto reset_val = std::get<2>(tuple);
|
for (const auto &tuple : options) {
|
||||||
if (setsockopt(sockfd, std::get<0>(tuple), std::get<1>(tuple), &reset_val, sizeof(reset_val)) < 0) {
|
auto reset_val = std::get<2>(tuple);
|
||||||
BOOST_LOG(warning) << "Failed to reset option: "sv << errno;
|
if (setsockopt(sockfd, std::get<0>(tuple), std::get<1>(tuple), &reset_val, sizeof(reset_val)) < 0) {
|
||||||
|
BOOST_LOG(warning) << "Failed to reset option: "sv << errno;
|
||||||
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|||||||
Reference in New Issue
Block a user