Resolve a longstanding TODO to use makecleanup for closing the TUN device if it was not successfully opened. PiperOrigin-RevId: 373446111
diff --git a/quic/qbone/bonnet/tun_device.cc b/quic/qbone/bonnet/tun_device.cc index 86e68d7..65197cd 100644 --- a/quic/qbone/bonnet/tun_device.cc +++ b/quic/qbone/bonnet/tun_device.cc
@@ -10,6 +10,7 @@ #include <sys/ioctl.h> #include <sys/socket.h> +#include "absl/cleanup/cleanup.h" #include "quic/platform/api/quic_bug_tracker.h" #include "quic/platform/api/quic_logging.h" #include "quic/qbone/platform/kernel_interface.h" @@ -114,39 +115,41 @@ // 'persist' bit ambiguous. if_request.ifr_flags = IFF_TUN | IFF_MULTI_QUEUE | IFF_NO_PI; - // TODO(pengg): port MakeCleanup to quic/platform? This makes the call to - // CloseDevice nicer and less error-prone. // When the device is running with IFF_MULTI_QUEUE set, each call to open will // create a queue which can be used to read/write packets from/to the device. + bool successfully_opened = false; + auto cleanup = absl::MakeCleanup([this, &successfully_opened]() { + if (!successfully_opened) { + CloseDevice(); + } + }); + const std::string tun_device_path = absl::GetFlag(FLAGS_qbone_client_tun_device_path); int fd = kernel_.open(tun_device_path.c_str(), O_RDWR); if (fd < 0) { QUIC_PLOG(WARNING) << "Failed to open " << tun_device_path; - CloseDevice(); - return false; + return successfully_opened; } file_descriptor_ = fd; if (!CheckFeatures(fd)) { - CloseDevice(); - return false; + return successfully_opened; } if (kernel_.ioctl(fd, TUNSETIFF, reinterpret_cast<void*>(&if_request)) != 0) { QUIC_PLOG(WARNING) << "Failed to TUNSETIFF on fd(" << fd << ")"; - CloseDevice(); - return false; + return successfully_opened; } if (kernel_.ioctl( fd, TUNSETPERSIST, persist_ ? reinterpret_cast<void*>(&if_request) : nullptr) != 0) { QUIC_PLOG(WARNING) << "Failed to TUNSETPERSIST on fd(" << fd << ")"; - CloseDevice(); - return false; + return successfully_opened; } - return true; + successfully_opened = true; + return successfully_opened; } // TODO(pengg): might be better to use netlink socket, once we have a library to