}
ComboAddress sourceAddr;
+ std::string sourceItfName;
unsigned int sourceItf = 0;
size_t numberOfSockets = 1;
std::set<int> cpus;
if (parsed == false)
{
/* try to parse as interface name, or v4/v6@itf */
- string itfName = source.substr(pos == std::string::npos ? 0 : pos + 1);
- unsigned int itfIdx = if_nametoindex(itfName.c_str());
+ string sourceItfName = source.substr(pos == std::string::npos ? 0 : pos + 1);
+ unsigned int itfIdx = if_nametoindex(sourceItfName.c_str());
if (itfIdx != 0) {
if (pos == 0 || pos == std::string::npos) {
}
else
{
- warnlog("Dismissing source %s because '%s' is not a valid interface name", source, itfName);
+ warnlog("Dismissing source %s because '%s' is not a valid interface name", source, sourceItfName);
}
}
}
// do not construct DownstreamState now, it would try binding sockets.
return ret;
}
- ret=std::make_shared<DownstreamState>(serverAddr, sourceAddr, sourceItf, numberOfSockets);
+ ret=std::make_shared<DownstreamState>(serverAddr, sourceAddr, sourceItf, sourceItfName, numberOfSockets);
if(vars.count("qps")) {
int qpsVal=std::stoi(boost::get<string>(vars["qps"]));
fd = SSocket(remote.sin4.sin_family, SOCK_DGRAM, 0);
if (!IsAnyAddress(sourceAddr)) {
SSetsockopt(fd, SOL_SOCKET, SO_REUSEADDR, 1);
+ if (!sourceItfName.empty()) {
+#ifdef SO_BINDTODEVICE
+ int res = setsockopt(fd, SOL_SOCKET, SO_BINDTODEVICE, sourceItfName.c_str(), sourceItfName.length());
+ if (res != 0) {
+ infolog("Error setting up the interface on backend socket '%s': %s", remote.toStringWithPort(), stringerror());
+ }
+#endif
+ }
+
SBind(fd, sourceAddr);
}
try {
}
}
-DownstreamState::DownstreamState(const ComboAddress& remote_, const ComboAddress& sourceAddr_, unsigned int sourceItf_, size_t numberOfSockets): remote(remote_), sourceAddr(sourceAddr_), sourceItf(sourceItf_)
+DownstreamState::DownstreamState(const ComboAddress& remote_, const ComboAddress& sourceAddr_, unsigned int sourceItf_, const std::string& sourceItfName_, size_t numberOfSockets): sourceItfName(sourceItfName_), remote(remote_), sourceAddr(sourceAddr_), sourceItf(sourceItf_)
{
pthread_rwlock_init(&d_lock, nullptr);
id = getUniqueID();
{
typedef std::function<std::tuple<DNSName, uint16_t, uint16_t>(const DNSName&, uint16_t, uint16_t, dnsheader*)> checkfunc_t;
- DownstreamState(const ComboAddress& remote_, const ComboAddress& sourceAddr_, unsigned int sourceItf, size_t numberOfSockets);
- DownstreamState(const ComboAddress& remote_): DownstreamState(remote_, ComboAddress(), 0, 1) {}
+ DownstreamState(const ComboAddress& remote_, const ComboAddress& sourceAddr_, unsigned int sourceItf, const std::string& sourceItfName, size_t numberOfSockets);
+ DownstreamState(const ComboAddress& remote_): DownstreamState(remote_, ComboAddress(), 0, std::string(), 1) {}
~DownstreamState()
{
for (auto& fd : sockets) {
std::set<unsigned int> hashes;
mutable pthread_rwlock_t d_lock;
std::vector<int> sockets;
+ const std::string sourceItfName;
std::mutex socketsLock;
std::mutex connectLock;
std::unique_ptr<FDMultiplexer> mplexer{nullptr};